diff --git a/config.sample.js b/config.sample.js index e243a7e..c2bf5d4 100644 --- a/config.sample.js +++ b/config.sample.js @@ -49,7 +49,7 @@ module.exports = { This will load public/libs/cookieconsent/cookieconsent.min.{css,js} on homepage (configured from home.js). You may use this if you have some specific needs, since lolisafe by itself will not use Cookies at all. Instead it will use Local Storage for both authentication and preferences/states in Dashboard. - I'm not sure if Cookies Laws apply to Local Storage as well, although I supppose it makes sense if they do. + I'm not sure if Cookies Laws apply to Local Storage as well, although I suppose it makes sense if they do. NOTE: Enabling this will automatically push 'cookiepolicy' to pages array above. */ cookiePolicy: false, @@ -333,7 +333,7 @@ module.exports = { https://github.com/NingLin-P/clamdjs#scannerscanfilepath-timeout-chunksize groupBypass: Name of the lowest ranked group whose files will not be scanned. - Lowest ranked meanning that group AND any groups higher than it are included. + Lowest ranked meaning that group AND any groups higher than it are included. Example: 'moderator' = moderators, admins & superadmins. */ scan: { @@ -489,22 +489,35 @@ module.exports = { /* If you have a Page Rule in Cloudflare to cache everything in the album zip - API route (homeDomain/api/album/zip/*), with this option you can limit the + API route (e.g. homeDomain/api/album/zip/*), with this option you can limit the maximum total size of files in an album that can be zipped. - Cloudflare will not cache files bigger than 512MB. + It's worth nothing that Cloudflare will not cache files bigger than 512MB. + However, it's not recommended to do that in high-bandwidth sites anyway, + since long-caching of such huge files are against Cloudflare's Terms of Service. NOTE: Set to falsy value to disable max total size. */ zipMaxTotalSize: '512MB', /* - If you want to make it automatically call Cloudflare's API to purge cache on file delete, - fill your API key, email and your site's zone ID below, then set "purgeCache" to true. - This will only purge cache of the deleted file and its associated thumb. + If you want the service to automatically use Cloudflare API to purge cache on file deletion, + fill your zone ID below. It will only purge cache of the deleted file, and its thumbs if applicable. + Afterwards, you will have to choose any of the supported auth methods, which are: + API token, user service key, OR API key + email. + If more than one are provided, it will use the first one from left to right, but it will NOT + attempt to use the next methods even if the selected one fails (meaning there's no fallback mechanism). + Consult https://api.cloudflare.com/#getting-started-requests for differences. + API token configuration example: https://github.com/BobbyWibowo/lolisafe/pull/216#issue-440389284. + After everything is ready, you can then set "purgeCache" to true. */ - apiKey: '', - email: '', zoneId: '', - purgeCache: false + purgeCache: false, + + apiToken: '', + + userServiceKey: '', + + apiKey: '', + email: '' }, /* diff --git a/controllers/utilsController.js b/controllers/utilsController.js index 835797c..4658305 100644 --- a/controllers/utilsController.js +++ b/controllers/utilsController.js @@ -64,8 +64,9 @@ const statsCache = { } } -const cloudflareAuth = config.cloudflare && config.cloudflare.apiKey && - config.cloudflare.email && config.cloudflare.zoneId +const cloudflareAuth = config.cloudflare && config.cloudflare.zoneId && + (config.cloudflare.apiToken || config.cloudflare.userServiceKey || + (config.cloudflare.apiKey && config.cloudflare.email)) self.mayGenerateThumb = extname => { return (config.uploads.generateThumbs.image && self.imageExts.includes(extname)) || @@ -478,12 +479,13 @@ self.bulkDeleteFromDb = async (field, values, user) => { } self.purgeCloudflareCache = async (names, uploads, thumbs) => { - if (!Array.isArray(names) || !names.length || !cloudflareAuth) - return [{ - success: false, - files: [], - errors: ['An unexpected error occured.'] - }] + const errors = [] + if (!cloudflareAuth) + errors.push('Cloudflare auth is incomplete or missing') + if (!Array.isArray(names) || !names.length) + errors.push('Names array is invalid or empty') + if (errors.length) + return [{ success: false, files: [], errors }] let domain = config.domain if (!uploads) domain = config.homeDomain @@ -521,15 +523,24 @@ self.purgeCloudflareCache = async (names, uploads, thumbs) => { } try { + const headers = { + 'Content-Type': 'application/json' + } + if (config.cloudflare.apiToken) { + headers.Authorization = `Bearer ${config.cloudflare.apiToken}` + } else if (config.cloudflare.userServiceKey) { + headers['X-Auth-User-Service-Key'] = config.cloudflare.userServiceKey + } else if (config.cloudflare.apiKey && config.cloudflare.email) { + headers['X-Auth-Key'] = config.cloudflare.apiKey + headers['X-Auth-Email'] = config.cloudflare.email + } + const purge = await fetch(url, { method: 'POST', body: JSON.stringify({ files: chunk }), - headers: { - 'Content-Type': 'application/json', - 'X-Auth-Email': config.cloudflare.email, - 'X-Auth-Key': config.cloudflare.apiKey - } + headers }) + const response = await purge.json() result.success = response.success if (Array.isArray(response.errors) && response.errors.length)