mirror of
https://github.com/BobbyWibowo/lolisafe.git
synced 2025-01-19 01:31:34 +00:00
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.
This commit is contained in:
parent
20912a6dff
commit
8780d6429b
@ -631,14 +631,18 @@ uploadsController.processFilesForDisplay = async (req, res, files, existingFiles
|
|||||||
responseFiles.push(file)
|
responseFiles.push(file)
|
||||||
|
|
||||||
// We send response first before generating thumbnails and updating album timestamps
|
// We send response first before generating thumbnails and updating album timestamps
|
||||||
|
const nojs = req.path === '/nojs'
|
||||||
res.json({
|
res.json({
|
||||||
success: true,
|
success: true,
|
||||||
files: responseFiles.map(file => {
|
files: responseFiles.map(file => {
|
||||||
return {
|
const result = {
|
||||||
name: file.name,
|
name: file.name,
|
||||||
size: file.size,
|
size: file.size,
|
||||||
url: `${config.domain}/${file.name}`
|
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)
|
if (albumids.length)
|
||||||
await db.table('albums')
|
db.table('albums')
|
||||||
.whereIn('id', albumids)
|
.whereIn('id', albumids)
|
||||||
.update('editedAt', Math.floor(Date.now() / 1000))
|
.update('editedAt', Math.floor(Date.now() / 1000))
|
||||||
.catch(console.error)
|
.catch(console.error)
|
||||||
|
@ -306,15 +306,24 @@ utilsController.bulkDeleteFiles = async (field, values, user, set) => {
|
|||||||
.catch(console.error)
|
.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)
|
if (config.cloudflare.purgeCache)
|
||||||
utilsController.purgeCloudflareCache(filtered.map(file => file.name), true)
|
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
|
return failed
|
||||||
}
|
}
|
||||||
|
|
||||||
utilsController.purgeCloudflareCache = async (names, uploads, verbose) => {
|
utilsController.purgeCloudflareCache = async (names, uploads) => {
|
||||||
if (!cloudflareAuth) return false
|
if (!cloudflareAuth)
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
files: [],
|
||||||
|
errors: ['Missing auth.']
|
||||||
|
}
|
||||||
|
|
||||||
let domain = config.domain
|
let domain = config.domain
|
||||||
if (!uploads) domain = config.homeDomain
|
if (!uploads) domain = config.homeDomain
|
||||||
@ -332,8 +341,10 @@ utilsController.purgeCloudflareCache = async (names, uploads, verbose) => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
try {
|
|
||||||
const files = names.concat(thumbs)
|
const files = names.concat(thumbs)
|
||||||
|
let success = false
|
||||||
|
let errors = []
|
||||||
|
try {
|
||||||
const url = `https://api.cloudflare.com/client/v4/zones/${config.cloudflare.zoneId}/purge_cache`
|
const url = `https://api.cloudflare.com/client/v4/zones/${config.cloudflare.zoneId}/purge_cache`
|
||||||
const fetchPurge = await fetch(url, {
|
const fetchPurge = await fetch(url, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
@ -344,14 +355,13 @@ utilsController.purgeCloudflareCache = async (names, uploads, verbose) => {
|
|||||||
'X-Auth-Key': config.cloudflare.apiKey
|
'X-Auth-Key': config.cloudflare.apiKey
|
||||||
}
|
}
|
||||||
}).then(res => res.json())
|
}).then(res => res.json())
|
||||||
|
success = fetchPurge.success
|
||||||
if (Array.isArray(fetchPurge.errors) && fetchPurge.errors.length)
|
if (Array.isArray(fetchPurge.errors) && fetchPurge.errors.length)
|
||||||
fetchPurge.errors.forEach(error => console.error(`CF: ${error.code}: ${error.message}`))
|
errors = fetchPurge.errors.map(error => `${error.code}: ${error.message}`)
|
||||||
else if (verbose)
|
|
||||||
console.log(`URLs:\n${files.join('\n')}\n\nSuccess: ${fetchPurge.success}`)
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`CF: ${error.toString()}`)
|
errors.push(error.toString())
|
||||||
}
|
}
|
||||||
|
return { success, files, errors }
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = utilsController
|
module.exports = utilsController
|
||||||
|
43
lolisafe.js
43
lolisafe.js
@ -2,6 +2,7 @@ const config = require('./config')
|
|||||||
const api = require('./routes/api')
|
const api = require('./routes/api')
|
||||||
const album = require('./routes/album')
|
const album = require('./routes/album')
|
||||||
const nojs = require('./routes/nojs')
|
const nojs = require('./routes/nojs')
|
||||||
|
const utils = require('./controllers/utilsController')
|
||||||
const express = require('express')
|
const express = require('express')
|
||||||
const bodyParser = require('body-parser')
|
const bodyParser = require('body-parser')
|
||||||
const clamd = require('clamdjs')
|
const clamd = require('clamdjs')
|
||||||
@ -51,18 +52,25 @@ safe.use('/api/register/', limiter)
|
|||||||
safe.use(bodyParser.urlencoded({ extended: true }))
|
safe.use(bodyParser.urlencoded({ extended: true }))
|
||||||
safe.use(bodyParser.json())
|
safe.use(bodyParser.json())
|
||||||
|
|
||||||
|
// safe.fiery.me-exclusive cache control
|
||||||
if (config.cacheControl) {
|
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)
|
// s-max-age: 30 days (only cache in proxy server)
|
||||||
// Obviously we have to purge proxy cache on every update
|
// 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()
|
next()
|
||||||
})
|
})
|
||||||
|
|
||||||
const setHeaders = res => {
|
const setHeaders = res => {
|
||||||
res.set('Access-Control-Allow-Origin', '*')
|
res.set('Access-Control-Allow-Origin', '*')
|
||||||
// max-age: 30 days
|
res.set('Cache-Control', cacheControls.default)
|
||||||
res.set('Cache-Control', 'public, max-age=2592000, must-revalidate, proxy-revalidate, immutable, stale-while-revalidate=86400, stale-if-error=604800')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.serveFilesWithNode)
|
if (config.serveFilesWithNode)
|
||||||
@ -70,14 +78,20 @@ if (config.cacheControl) {
|
|||||||
|
|
||||||
safe.use('/', express.static('./public', { setHeaders }))
|
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) => {
|
safe.use(['/a', '/api', '/nojs'], (req, res, next) => {
|
||||||
res.set('Cache-Control', 'no-store')
|
res.set('Cache-Control', cacheControls.disable)
|
||||||
next()
|
next()
|
||||||
})
|
})
|
||||||
|
|
||||||
// But do cache album ZIPs
|
// Cache these in proxy server though
|
||||||
safe.use('/api/album/zip', (req, res, next) => {
|
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)
|
setHeaders(res)
|
||||||
next()
|
next()
|
||||||
})
|
})
|
||||||
@ -183,8 +197,19 @@ const start = async () => {
|
|||||||
process.stdout.write(` ${setSize} OK!\n`)
|
process.stdout.write(` ${setSize} OK!\n`)
|
||||||
}
|
}
|
||||||
|
|
||||||
safe.listen(config.port, () => {
|
safe.listen(config.port, async () => {
|
||||||
console.log(`lolisafe started on port ${config.port}`)
|
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
|
// NODE_ENV=development yarn start
|
||||||
if (process.env.NODE_ENV === 'development') {
|
if (process.env.NODE_ENV === 'development') {
|
||||||
// Add readline interface to allow evaluating arbitrary JavaScript from console
|
// Add readline interface to allow evaluating arbitrary JavaScript from console
|
||||||
|
@ -19,8 +19,7 @@
|
|||||||
"pm2": "pm2 start --name safe ./lolisafe.js",
|
"pm2": "pm2 start --name safe ./lolisafe.js",
|
||||||
"thumbs": "node ./scripts/thumbs.js",
|
"thumbs": "node ./scripts/thumbs.js",
|
||||||
"cfpurge": "node ./scripts/cfpurge.js",
|
"cfpurge": "node ./scripts/cfpurge.js",
|
||||||
"pull": "git stash; git pull; yarn; git stash pop",
|
"pull": "git stash; git pull; yarn; git stash pop"
|
||||||
"pm2restart": "pm2 restart safe; yarn cfpurge"
|
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bcrypt": "^2.0.1",
|
"bcrypt": "^2.0.1",
|
||||||
|
@ -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 { stripIndents } = require('./_utils')
|
||||||
const utils = require('./../controllers/utilsController')
|
const utils = require('./../controllers/utilsController')
|
||||||
const config = require('./../config')
|
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.
|
If not provided, this will default to frontend pages listed in "pages" array in config.js.
|
||||||
`))
|
`))
|
||||||
|
|
||||||
const filenames = args.length ? args : config.pages
|
const filenames = args.length ? args : config.pages.concat(['api/check'])
|
||||||
return utils.purgeCloudflareCache(filenames, Boolean(args.length), true)
|
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()
|
cfpurge.do()
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
v2: Images and config files (manifest.json, browserconfig.xml, etc).
|
v2: Images and config files (manifest.json, browserconfig.xml, etc).
|
||||||
v3: CSS and JS files (libs such as bulma, lazyload, etc).
|
v3: CSS and JS files (libs such as bulma, lazyload, etc).
|
||||||
#}
|
#}
|
||||||
{% set v1 = "m8kkW8tVUo" %}
|
{% set v1 = "W3UU4Gpu9a" %}
|
||||||
{% set v2 = "hiboQUzAzp" %}
|
{% set v2 = "hiboQUzAzp" %}
|
||||||
{% set v3 = "hiboQUzAzp" %}
|
{% set v3 = "hiboQUzAzp" %}
|
||||||
|
|
||||||
|
@ -42,6 +42,7 @@
|
|||||||
<div class="field uploads nojs">
|
<div class="field uploads nojs">
|
||||||
{% for file in files -%}
|
{% for file in files -%}
|
||||||
<div class="field">
|
<div class="field">
|
||||||
|
<p class="name is-unselectable">{{ file.original }}</p>
|
||||||
{% if errorMessage -%}
|
{% if errorMessage -%}
|
||||||
<p class="error">{{ errorMessage | safe }}</p>
|
<p class="error">{{ errorMessage | safe }}</p>
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
Loading…
Reference in New Issue
Block a user