UNPKG

nodebb-plugin-cloudstorage

Version:

Cloud storage plugin (GitHub, Cloudinary, ImageKit, S3) for NodeBB

108 lines (84 loc) 3.75 kB
'use strict' const crypto = require.main.require('crypto'), fs = require.main.require('fs'), debug = require('debug')('nodebb-plugin-cloudstorage:library'), controllers = require('./lib/controllers')(), errorHandler = require('./lib/errorHandler'), NodeBB_Controllers = require.main.require('./src/controllers'), NodeBB_Templates = require.main.require('benchpressjs') let plugin = {} plugin.controllers = controllers plugin.errorHandler = errorHandler plugin.staticAppPreload = function (params, callback) { // params = { app, middleware } debug('--------- staticAppPreload ---------') callback() } plugin.staticAppLoad = function (data, callback) { // data = { app, router, middleware, controllers } debug('--------- staticAppLoad ---------') data.router.get('/admin/plugins/cloudstorage', data.middleware.applyCSRF, data.middleware.admin.buildHeader, controllers.renderAdmin) data.router.get('/api/admin/plugins/cloudstorage', data.middleware.applyCSRF, controllers.renderAdmin) data.router.get('/cloudstorage/:sha', async (req, res) => { debug('--------- /cloudstorage/:sha ---------', req.params) const sha = req.params.sha const now = Date.now() const freshnessWindow = 5 * 60 * 1000 // 5 minutes const db = require.main.require('./src/database') const key = `cloudstorage:github:mapping:${sha}` const cached = await db.getObject(key) || {} if (!cached) { const fallback = req.query.f && Buffer.from(req.query.f, 'base64').toString('utf-8') if (fallback) { debug(`Redirecting to fallback URL: ${fallback}`) return res.redirect(fallback) // fallback URL } else { return res.status(404).send('File not found') } } let { cdnUrl, downloadUrl, lastChecked, useCdn } = cached lastChecked = parseInt(lastChecked, 10) || 0 useCdn = useCdn === true || /true/i.test(useCdn) // Check if we need to verify CDN if (!useCdn || !lastChecked || (now - lastChecked >= freshnessWindow)) { try { const response = await fetch(cdnUrl, { method: 'HEAD' }) if (response.ok) { debug(`CDN URL is live: ${cdnUrl}, response: ${response.status} ${response.statusText}`) useCdn = true } else { debug(`CDN URL is not live: ${cdnUrl}`) useCdn = false } } catch (err) { debug(`Error checking CDN URL: ${err}`) useCdn = false } // Update cached object await db.setObject(key, { ...cached, lastChecked: now, useCdn }) } else { debug(`Using cached CDN URL: ${cdnUrl}, useCdn: ${useCdn}`) } const url = useCdn ? cdnUrl : downloadUrl debug(`Redirecting to: ${url} (useCdn: ${useCdn}, downloadUrl: ${downloadUrl}, cached: ${JSON.stringify(cached)})`) res.redirect(url) }) controllers.loadSettings() //debug(params); callback() } plugin.filterUploadImage = function filterUploadImage(params, callback) { debug('--------- filterUploadImage ---------') const image = params.image new Promise((resolve, reject) => { fs.readFile(image.path, (error, data) => { if (error) return reject(error) const etag = crypto.createHash('md5').update(data).digest('hex') resolve({ data, etag }) }) }) .then(fileObject => { controllers.providersUpload(image, fileObject, callback) }) } module.exports = plugin