diff --git a/.env.example b/.env.example index 615c806..b77e445 100644 --- a/.env.example +++ b/.env.example @@ -16,6 +16,8 @@ ADMIN_EMAIL=spamfree@matthieubessat.fr REDIS_HOST=localhost REDIS_PORT=6379 +REDIS_PASSWORD=root +REDIS_PREFIX=cond_ass BASE_URL=http://srv.espacecondorcet.org:8001 WEB_UI_URL=http://localhost:8080 diff --git a/assets/development/scripts/countdown.js b/assets/development/scripts/countdown.js index 4046167..91d1ed6 100644 --- a/assets/development/scripts/countdown.js +++ b/assets/development/scripts/countdown.js @@ -8,7 +8,9 @@ const secondsContainer = document.getElementById('seconds') let shown = false -const enableReload = window.location.pathname.indexOf('c') === -1 +//const enableReload = window.location.pathname.indexOf('c') === -1 + +enableReload = true function render() { let current = new Date() @@ -30,7 +32,8 @@ function render() { seconds = (String(seconds).length >= 2) ? seconds : '0' + seconds if (openDate <= current && enableReload) { - window.location.reload(false) + console.log('FINISHED!') + window.location = '/' } else { daysContainer.textContent = days hoursContainer.textContent = hours diff --git a/package.json b/package.json index e18e2b2..b507825 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,9 @@ "@fortawesome/free-regular-svg-icons": "^5.13.1", "@fortawesome/free-solid-svg-icons": "^5.13.1", "@types/cors": "^2.8.6", + "@types/events": "^3.0.0", "@types/express": "^4.17.6", + "@types/express-redis-cache": "^1.1.0", "@types/html-to-text": "^5.1.1", "@types/http-proxy-middleware": "^0.19.3", "@types/ioredis": "^4.17.0", @@ -27,6 +29,7 @@ "crypto-random-string": "^3.2.0", "dotenv": "^8.2.0", "express": "^4.17.1", + "express-redis-cache": "^1.1.3", "html-to-text": "^5.1.1", "http-proxy-middleware": "^1.0.5", "ioredis": "^4.17.3", diff --git a/src/app.ts b/src/app.ts index 93c8ad5..dcf45d7 100644 --- a/src/app.ts +++ b/src/app.ts @@ -16,6 +16,8 @@ import twig from 'twig' import EmailService from './EmailService' import ErrorController from './controllers/ErrorController' import { createProxyMiddleware, Filter, Options, RequestHandler } from 'http-proxy-middleware'; +import ExpressRedisCache from 'express-redis-cache' +import Utils from './Utils' process.env.TZ = "Europe/Paris" @@ -37,6 +39,24 @@ if (process.env.DISABLE_TWIG_CACHE === 'true') { twig.cache(false) } +const cache = ExpressRedisCache({ + host: process.env.REDIS_HOST, + port: process.env.REDIS_PORT, + auth_pass: process.env.REDIS_PASSWORD, + prefix: process.env.REDIS_PREFIX +}) + +const cacheDuration = { + home: 3600 * 0.75, + countdown: 3600 * 2, + page: 3600 * 6 +} + +// reset cache +cache.del('*', (err, deleted) => { + console.log('> App: Reset cache', err, deleted) +}) + let main = async () => { EmailService.init() @@ -54,16 +74,43 @@ let main = async () => { console.log('> App: Connected to mongodb') }) - app.set("twig options", { + app.set('twig options', { allow_async: true, strict_variables: false }) + app.set('cache', cache) + app.use(cors()) app.use(bodyParser.json()) - app.get('/', PublicController.home) - app.get('/c', PublicController.countdown) - app.get('/association/:slug', PublicController.organization) + app.get( + '/', + (req, res, next) => { + if (process.env.OPEN_DATE == null) { + next() + return + } + // redirect to countdown if needed + let isProposed = Utils.isStrUsable(req.query, 'only') + let byPass = req.query.bypass != null + let target: any = new Date(process.env.OPEN_DATE) + let now: any = new Date() + if (!byPass && !isProposed && target > now) { + return res.redirect('/c') + } else { + next() + } + + let withId = req.query.only != null + if (byPass || withId) { + res.use_express_redis_cache = false + } + }, + cache.route('/home', cacheDuration.home), + PublicController.home + ) + app.get('/c', cache.route('/c', cacheDuration.countdown), PublicController.countdown) + app.get('/association/:slug', cache.route(cacheDuration.page), PublicController.organization) app.get('/a-propos', PublicController.about) app.get('/mentions-legales', PublicController.legals) diff --git a/src/controllers/AdminOrganizationController.ts b/src/controllers/AdminOrganizationController.ts index 4becbff..a57f2e3 100644 --- a/src/controllers/AdminOrganizationController.ts +++ b/src/controllers/AdminOrganizationController.ts @@ -325,7 +325,23 @@ export default class AdminOrganizationController { link: EmailService.getBaseUrl() + '/association/' + extra.slugs[extra.slugs.length - 1] } ) - res.json({ success: true, data: updateData }) + + // finally, reset cache of version public and proposed of ALL the slug + // reset the cache of the home page because it is very important also. + const cache = req.app.get('cache') + let proposed = extra.slugs.map((slug: any) => slug + '?version=proposed') + extra.slugs.concat(proposed).forEach((elem: any) => { + console.log('Reset page', '/association/' + elem) + cache.del('/association/' + elem, (err: any, deleted: any) => { + console.log('> App: Reset cache of public page', err, deleted) + }) + }) + cache.del('/home', (err: any, deleted: any) => { + console.log('> App: Reset cache of public home', err, deleted) + }) + + res + .json({ success: true, data: updateData }) }).catch(err => res.status(400).json({ success: false, errors: err.errors !== undefined ? err.errors : err })) }).catch(err => res.status(400).json({ success: false, errors: err })) } diff --git a/src/controllers/PublicController.ts b/src/controllers/PublicController.ts index 1f96a9f..38c070f 100644 --- a/src/controllers/PublicController.ts +++ b/src/controllers/PublicController.ts @@ -23,14 +23,6 @@ export default class PublicController { static async home(req: express.Request, res: express.Response) { let isProposed = Utils.isStrUsable(req.query, 'only') - let byPass = req.query.bypass != null - let target: any = new Date(process.env.OPEN_DATE == null ? '01/01/1970 00:00' : process.env.OPEN_DATE) - let now: any = new Date() - if (!byPass && !isProposed && target > now) { - return res.render('countdown.twig', { - openDate: process.env.OPEN_DATE - }) - } // let client: IORedis.Redis = RedisService.getClient() // await client.set('hello', 'world') // res.json({ diff --git a/yarn.lock b/yarn.lock index d9e7858..a2418b9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -601,6 +601,20 @@ dependencies: "@types/express" "*" +"@types/events@*", "@types/events@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7" + integrity sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g== + +"@types/express-redis-cache@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@types/express-redis-cache/-/express-redis-cache-1.1.0.tgz#b0b0742c56c1de2672ad6873e8074a6c930afe0d" + integrity sha512-t9LUb5xd1EpdoyMIBk6IPgvWWIqRnGOpO9NS9qVyBHdhqRjEzSj4Z9hdrOUAkMFpG1mCOxjhPmS5zOuqUsNuhQ== + dependencies: + "@types/events" "*" + "@types/express" "*" + "@types/redis" "*" + "@types/express-serve-static-core@*": version "4.17.9" resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.9.tgz#2d7b34dcfd25ec663c25c85d76608f8b249667f1" @@ -762,13 +776,6 @@ resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e" integrity sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA== -"@types/normalize-url@^4.2.0": - version "4.2.0" - resolved "https://registry.yarnpkg.com/@types/normalize-url/-/normalize-url-4.2.0.tgz#b72486d1d87e70b2b94bd34d9300fe41c736f788" - integrity sha512-lMD7+DEzeaAWiJzVzlFJHWCRi/SConK0T/dMxIUYw+r0Et0xNo5yN9b0wa8NUgqECJfAbPYneecqDxQNyhTHnA== - dependencies: - normalize-url "*" - "@types/papaparse@^5.0.6": version "5.0.6" resolved "https://registry.yarnpkg.com/@types/papaparse/-/papaparse-5.0.6.tgz#4fee1a17dc24fed839d276c807f875bd653abbb4" @@ -791,6 +798,13 @@ resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.3.tgz#7ee330ba7caafb98090bece86a5ee44115904c2c" integrity sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA== +"@types/redis@*": + version "2.8.27" + resolved "https://registry.yarnpkg.com/@types/redis/-/redis-2.8.27.tgz#9bc89b472f3fc4a57a06c1823f2fc860c6c2fdf3" + integrity sha512-RRHarqPp3mgqHz+qzLVuQCJAIVaB3JBaczoj24QVVYu08wiCmB8vbOeNeK9lIH+pyT7+R/bbEPghAZZuhbZm0g== + dependencies: + "@types/node" "*" + "@types/sanitize-html@^1.23.3": version "1.23.3" resolved "https://registry.yarnpkg.com/@types/sanitize-html/-/sanitize-html-1.23.3.tgz#26527783aba3bf195ad8a3c3e51bd3713526fc0d" @@ -1146,6 +1160,13 @@ async-settle@^1.0.0: dependencies: async-done "^1.2.2" +async@^2.6.1: + version "2.6.3" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" + integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg== + dependencies: + lodash "^4.17.14" + asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" @@ -1742,6 +1763,11 @@ color@^3.1.2: color-convert "^1.9.1" color-string "^1.5.2" +colors@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" + integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== + combined-stream@^1.0.6, combined-stream@~1.0.6: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" @@ -2184,6 +2210,11 @@ dotenv@^8.2.0: resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.2.0.tgz#97e619259ada750eea3e4ea3e26bceea5424b16a" integrity sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw== +double-ended-queue@^2.1.0-0: + version "2.1.0-0" + resolved "https://registry.yarnpkg.com/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz#103d3527fd31528f40188130c841efdd78264e5c" + integrity sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw= + duplexer3@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" @@ -2442,6 +2473,15 @@ expect@^26.4.2: jest-message-util "^26.3.0" jest-regex-util "^26.0.0" +express-redis-cache@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/express-redis-cache/-/express-redis-cache-1.1.3.tgz#93eb6b09df1ff74a14a7f6caccb5d0d975010c62" + integrity sha512-7e9SwwGIv+bH0uc0Sy3KPCyYEGoGpwaBro+cLU8hVln1YbQIWoW8fOyv6/JRdaUmaBqATftdqm75OAIaBLmnjg== + dependencies: + async "^2.6.1" + colors "^1.3.0" + redis "^2.4.2" + express@^4.17.1: version "4.17.1" resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" @@ -4358,7 +4398,7 @@ lodash.sortby@^4.7.0: resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg= -lodash@^4.17.11, lodash@^4.17.15, lodash@^4.17.19: +lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19: version "4.17.20" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52" integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA== @@ -4836,11 +4876,6 @@ normalize-path@^3.0.0, normalize-path@~3.0.0: resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== -normalize-url@*, normalize-url@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-5.1.0.tgz#04b8f1b34ea49ff713fc20b2218eba41fb9974a3" - integrity sha512-UxHuSWsSAmzSqN+DSjasaZWQ3QPtEisHdlr4y9MJ5zg0RcImv5fQt8QM0izJSCdsdmhJGK+ubcTpJXwVDmwSVQ== - normalize-url@^4.1.0: version "4.5.0" resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.0.tgz#453354087e6ca96957bd8f5baf753f5982142129" @@ -5527,11 +5562,21 @@ redis-commands@1.5.0: resolved "https://registry.yarnpkg.com/redis-commands/-/redis-commands-1.5.0.tgz#80d2e20698fe688f227127ff9e5164a7dd17e785" integrity sha512-6KxamqpZ468MeQC3bkWmCB1fp56XL64D4Kf0zJSwDZbVLLm7KFkoIcHrgRvQ+sk8dnhySs7+yBg94yIkAK7aJg== +redis-commands@^1.2.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/redis-commands/-/redis-commands-1.6.0.tgz#36d4ca42ae9ed29815cdb30ad9f97982eba1ce23" + integrity sha512-2jnZ0IkjZxvguITjFTrGiLyzQZcTvaw8DAaCXxZq/dsHXz7KfMQ3OUJy7Tz9vnRtZRVz6VRCPDvruvU8Ts44wQ== + redis-errors@^1.0.0, redis-errors@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/redis-errors/-/redis-errors-1.2.0.tgz#eb62d2adb15e4eaf4610c04afe1529384250abad" integrity sha1-62LSrbFeTq9GEMBK/hUpOEJQq60= +redis-parser@^2.6.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/redis-parser/-/redis-parser-2.6.0.tgz#52ed09dacac108f1a631c07e9b69941e7a19504b" + integrity sha1-Uu0J2srBCPGmMcB+m2mUHnoZUEs= + redis-parser@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/redis-parser/-/redis-parser-3.0.0.tgz#b66d828cdcafe6b4b8a428a7def4c6bcac31c8b4" @@ -5539,6 +5584,15 @@ redis-parser@^3.0.0: dependencies: redis-errors "^1.0.0" +redis@^2.4.2: + version "2.8.0" + resolved "https://registry.yarnpkg.com/redis/-/redis-2.8.0.tgz#202288e3f58c49f6079d97af7a10e1303ae14b02" + integrity sha512-M1OkonEQwtRmZv4tEWF2VgpG0JWJ8Fv1PhlgT5+B+uNq2cA3Rt1Yt/ryoR+vQNOQcIEgdCdfH0jr3bDpihAw1A== + dependencies: + double-ended-queue "^2.1.0-0" + redis-commands "^1.2.0" + redis-parser "^2.6.0" + regenerator-runtime@^0.13.4: version "0.13.7" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz#cac2dacc8a1ea675feaabaeb8ae833898ae46f55"