From 8780d6429b55ea741e1c5633abc3f683de5d783e Mon Sep 17 00:00:00 2001 From: Bobby Wibowo Date: Wed, 9 Jan 2019 17:11:45 +0700 Subject: [PATCH] Updates NoJS uploader will now display the original file names in the results. lolisafe.js will now automaticaly purge Cloudflare's cache of frontend pages everytime it launches. Of course this only applies when cacheControl is on in config file. This sorta makes scripts/cfpurge.js script obsolete. --- controllers/uploadController.js | 8 ++++-- controllers/utilsController.js | 28 ++++++++++++++------- lolisafe.js | 43 ++++++++++++++++++++++++++------- package.json | 3 +-- scripts/cfpurge.js | 11 +++++++-- views/_globals.njk | 2 +- views/nojs.njk | 1 + 7 files changed, 71 insertions(+), 25 deletions(-) diff --git a/controllers/uploadController.js b/controllers/uploadController.js index 98994cc..2622b9a 100644 --- a/controllers/uploadController.js +++ b/controllers/uploadController.js @@ -631,14 +631,18 @@ uploadsController.processFilesForDisplay = async (req, res, files, existingFiles responseFiles.push(file) // We send response first before generating thumbnails and updating album timestamps + const nojs = req.path === '/nojs' res.json({ success: true, files: responseFiles.map(file => { - return { + const result = { name: file.name, size: file.size, url: `${config.domain}/${file.name}` } + // Add original name if it's /nojs route + if (nojs) result.original = file.original + return result }) }) @@ -652,7 +656,7 @@ uploadsController.processFilesForDisplay = async (req, res, files, existingFiles } if (albumids.length) - await db.table('albums') + db.table('albums') .whereIn('id', albumids) .update('editedAt', Math.floor(Date.now() / 1000)) .catch(console.error) diff --git a/controllers/utilsController.js b/controllers/utilsController.js index 66b0e78..498d937 100644 --- a/controllers/utilsController.js +++ b/controllers/utilsController.js @@ -306,15 +306,24 @@ utilsController.bulkDeleteFiles = async (field, values, user, set) => { .catch(console.error) } - // purgeCloudflareCache() is an async function, but let us not wait for it + // Purge Cloudflare's cache if necessary if (config.cloudflare.purgeCache) utilsController.purgeCloudflareCache(filtered.map(file => file.name), true) + .then(result => { + if (!result.errors.length) return + result.errors.forEach(error => console.error(`CF: ${error}`)) + }) return failed } -utilsController.purgeCloudflareCache = async (names, uploads, verbose) => { - if (!cloudflareAuth) return false +utilsController.purgeCloudflareCache = async (names, uploads) => { + if (!cloudflareAuth) + return { + success: false, + files: [], + errors: ['Missing auth.'] + } let domain = config.domain if (!uploads) domain = config.homeDomain @@ -332,8 +341,10 @@ utilsController.purgeCloudflareCache = async (names, uploads, verbose) => { } }) + const files = names.concat(thumbs) + let success = false + let errors = [] try { - const files = names.concat(thumbs) const url = `https://api.cloudflare.com/client/v4/zones/${config.cloudflare.zoneId}/purge_cache` const fetchPurge = await fetch(url, { method: 'POST', @@ -344,14 +355,13 @@ utilsController.purgeCloudflareCache = async (names, uploads, verbose) => { 'X-Auth-Key': config.cloudflare.apiKey } }).then(res => res.json()) - + success = fetchPurge.success if (Array.isArray(fetchPurge.errors) && fetchPurge.errors.length) - fetchPurge.errors.forEach(error => console.error(`CF: ${error.code}: ${error.message}`)) - else if (verbose) - console.log(`URLs:\n${files.join('\n')}\n\nSuccess: ${fetchPurge.success}`) + errors = fetchPurge.errors.map(error => `${error.code}: ${error.message}`) } catch (error) { - console.error(`CF: ${error.toString()}`) + errors.push(error.toString()) } + return { success, files, errors } } module.exports = utilsController diff --git a/lolisafe.js b/lolisafe.js index 626a867..188e7c0 100644 --- a/lolisafe.js +++ b/lolisafe.js @@ -2,6 +2,7 @@ const config = require('./config') const api = require('./routes/api') const album = require('./routes/album') const nojs = require('./routes/nojs') +const utils = require('./controllers/utilsController') const express = require('express') const bodyParser = require('body-parser') const clamd = require('clamdjs') @@ -51,18 +52,25 @@ safe.use('/api/register/', limiter) safe.use(bodyParser.urlencoded({ extended: true })) safe.use(bodyParser.json()) +// safe.fiery.me-exclusive cache control if (config.cacheControl) { - safe.use('/', (req, res, next) => { + const cacheControls = { + // max-age: 30 days + default: 'public, max-age=2592000, must-revalidate, proxy-revalidate, immutable, stale-while-revalidate=86400, stale-if-error=604800', // s-max-age: 30 days (only cache in proxy server) // Obviously we have to purge proxy cache on every update - res.set('Cache-Control', 'public, s-max-age=2592000, proxy-revalidate, immutable, stale-while-revalidate=86400, stale-if-error=604800') + proxyOnly: 'public, s-max-age=2592000, proxy-revalidate, immutable, stale-while-revalidate=86400, stale-if-error=604800', + disable: 'no-store' + } + + safe.use('/', (req, res, next) => { + res.set('Cache-Control', cacheControls.proxyOnly) next() }) const setHeaders = res => { res.set('Access-Control-Allow-Origin', '*') - // max-age: 30 days - res.set('Cache-Control', 'public, max-age=2592000, must-revalidate, proxy-revalidate, immutable, stale-while-revalidate=86400, stale-if-error=604800') + res.set('Cache-Control', cacheControls.default) } if (config.serveFilesWithNode) @@ -70,14 +78,20 @@ if (config.cacheControl) { safe.use('/', express.static('./public', { setHeaders })) - // Do NOT cache dynamic routes + // Do NOT cache these dynamic routes safe.use(['/a', '/api', '/nojs'], (req, res, next) => { - res.set('Cache-Control', 'no-store') + res.set('Cache-Control', cacheControls.disable) next() }) - // But do cache album ZIPs - safe.use('/api/album/zip', (req, res, next) => { + // Cache these in proxy server though + safe.use(['/api/check'], (req, res, next) => { + res.set('Cache-Control', cacheControls.proxyOnly) + next() + }) + + // Cache album ZIPs + safe.use(['/api/album/zip'], (req, res, next) => { setHeaders(res) next() }) @@ -183,8 +197,19 @@ const start = async () => { process.stdout.write(` ${setSize} OK!\n`) } - safe.listen(config.port, () => { + safe.listen(config.port, async () => { console.log(`lolisafe started on port ${config.port}`) + + // safe.fiery.me-exclusive cache control + if (config.cacheControl) { + process.stdout.write('Cache control enabled. Purging Cloudflare\'s cache ...') + const routes = config.pages.concat(['api/check']) + const result = await utils.purgeCloudflareCache(routes) + process.stdout.write(` ${result.errors.length ? 'ERROR' : `${result.files.length} OK`}!\n`) + if (result.errors.length) + result.errors.forEach(error => console.log(`CF: ${error}`)) + } + // NODE_ENV=development yarn start if (process.env.NODE_ENV === 'development') { // Add readline interface to allow evaluating arbitrary JavaScript from console diff --git a/package.json b/package.json index 537af66..f33d26b 100644 --- a/package.json +++ b/package.json @@ -19,8 +19,7 @@ "pm2": "pm2 start --name safe ./lolisafe.js", "thumbs": "node ./scripts/thumbs.js", "cfpurge": "node ./scripts/cfpurge.js", - "pull": "git stash; git pull; yarn; git stash pop", - "pm2restart": "pm2 restart safe; yarn cfpurge" + "pull": "git stash; git pull; yarn; git stash pop" }, "dependencies": { "bcrypt": "^2.0.1", diff --git a/scripts/cfpurge.js b/scripts/cfpurge.js index 828f296..7914ac0 100644 --- a/scripts/cfpurge.js +++ b/scripts/cfpurge.js @@ -1,3 +1,6 @@ +// This is sorta no longer in use since lolisafe.js will do this automatically +// everytime is launches. + const { stripIndents } = require('./_utils') const utils = require('./../controllers/utilsController') const config = require('./../config') @@ -18,8 +21,12 @@ cfpurge.do = async () => { If not provided, this will default to frontend pages listed in "pages" array in config.js. `)) - const filenames = args.length ? args : config.pages - return utils.purgeCloudflareCache(filenames, Boolean(args.length), true) + const filenames = args.length ? args : config.pages.concat(['api/check']) + const result = await utils.purgeCloudflareCache(filenames, Boolean(args.length)) + if (result.errors.length) + return result.errors.forEach(error => console.error(`CF: ${error}`)) + else + console.log(`URLs:\n${result.files.join('\n')}\n\nSuccess: ${result.success}`) } cfpurge.do() diff --git a/views/_globals.njk b/views/_globals.njk index 415d342..bb20d4b 100644 --- a/views/_globals.njk +++ b/views/_globals.njk @@ -15,7 +15,7 @@ v2: Images and config files (manifest.json, browserconfig.xml, etc). v3: CSS and JS files (libs such as bulma, lazyload, etc). #} -{% set v1 = "m8kkW8tVUo" %} +{% set v1 = "W3UU4Gpu9a" %} {% set v2 = "hiboQUzAzp" %} {% set v3 = "hiboQUzAzp" %} diff --git a/views/nojs.njk b/views/nojs.njk index 26dc6f5..19a8596 100644 --- a/views/nojs.njk +++ b/views/nojs.njk @@ -42,6 +42,7 @@
{% for file in files -%}
+

{{ file.original }}

{% if errorMessage -%}

{{ errorMessage | safe }}

{%- endif %}