feat: ConfigManager

This commit is contained in:
Bobby 2022-10-06 02:39:51 +07:00
parent 4c1716ceff
commit 95e5956313
No known key found for this signature in database
GPG Key ID: 941839794CBF5A09
18 changed files with 125 additions and 52 deletions

View File

@ -11,7 +11,7 @@ const utils = require('./utilsController')
const ServeStatic = require('./handlers/ServeStatic')
const ClientError = require('./utils/ClientError')
const ServerError = require('./utils/ServerError')
const config = require('./../config')
const config = require('./utils/ConfigManager')
const logger = require('./../logger')
const self = {
@ -25,7 +25,7 @@ const self = {
/** Preferences */
const homeDomain = utils.conf.homeDomain || utils.conf.domain
const homeDomain = config.homeDomain || config.domain
const albumsPerPage = config.dashboard
? Math.max(Math.min(config.dashboard.albumsPerPage || 0, 100), 1)
@ -491,14 +491,14 @@ self.get = async (req, res) => {
for (const file of files) {
if (req.locals.upstreamCompat) {
file.url = `${utils.conf.domain}/${file.name}`
file.url = `${config.domain}/${file.name}`
} else {
file.file = `${utils.conf.domain}/${file.name}`
file.file = `${config.domain}/${file.name}`
}
const extname = utils.extname(file.name)
if (utils.mayGenerateThumb(extname)) {
file.thumb = `${utils.conf.domain}/thumbs/${file.name.slice(0, -extname.length)}.png`
file.thumb = `${config.domain}/thumbs/${file.name.slice(0, -extname.length)}.png`
if (req.locals.upstreamCompat) {
file.thumbSquare = file.thumb
}

View File

@ -7,7 +7,7 @@ const perms = require('./permissionController')
const tokens = require('./tokenController')
const utils = require('./utilsController')
const ClientError = require('./utils/ClientError')
const config = require('./../config')
const config = require('./utils/ConfigManager')
// Don't forget to update min/max length of text inputs in auth.njk
// when changing these values.

View File

@ -2,7 +2,7 @@ const path = require('path')
const paths = require('./pathsController')
const ClientError = require('./utils/ClientError')
const ServerError = require('./utils/ServerError')
const config = require('./../config')
const config = require('./utils/ConfigManager')
const logger = require('./../logger')
const self = {

View File

@ -1,6 +1,6 @@
const jetpack = require('fs-jetpack')
const path = require('path')
const config = require('./../config')
const config = require('./utils/ConfigManager')
const self = {}

View File

@ -11,7 +11,7 @@ const perms = require('./permissionController')
const utils = require('./utilsController')
const ClientError = require('./utils/ClientError')
const ServerError = require('./utils/ServerError')
const config = require('./../config')
const config = require('./utils/ConfigManager')
const logger = require('./../logger')
/** Deprecated config options */
@ -1114,7 +1114,7 @@ self.sendUploadResponse = async (req, res, stored) => {
const map = {
name: entry.file.name,
original: entry.file.original,
url: `${utils.conf.domain ? `${utils.conf.domain}/` : ''}${entry.file.name}`,
url: `${config.domain ? `${config.domain}/` : ''}${entry.file.name}`,
hash: entry.file.hash,
size: Number(entry.file.size)
}
@ -1132,7 +1132,7 @@ self.sendUploadResponse = async (req, res, stored) => {
// If uploaded by user, add delete URL (intended for ShareX and its derivatives)
// Homepage uploader will not use this (use dashboard instead)
if (req.locals.user) {
map.deleteUrl = `${utils.conf.homeDomain || ''}/file/${entry.file.name}?delete`
map.deleteUrl = `${config.homeDomain || ''}/file/${entry.file.name}?delete`
}
if (entry.repeated) {
@ -1185,7 +1185,7 @@ self.list = async (req, res) => {
}
const albumid = req.path_parameters && Number(req.path_parameters.albumid)
const basedomain = utils.conf.domain
const basedomain = config.domain
// Thresholds for regular users (usergroups lower than moderator)
const MAX_WILDCARDS_IN_KEY = 2

View File

@ -0,0 +1,84 @@
const config = require('./../../config')
const logger = require('./../../logger')
const self = {}
// Allow some config options to be overriden via env vars
const overrides = {
PRIVATE: {
key: 'private',
type: 'boolean'
},
ENABLE_USER_ACCOUNTS: {
key: 'enableUserAccounts',
type: 'boolean'
},
SERVE_FILES_WITH_NODE: {
key: 'serveFilesWithNode',
type: 'boolean'
},
PORT: {
key: 'port',
type: 'number'
},
DOMAIN: 'domain',
HOME_DOMAIN: 'homeDomain',
TRUST_PROXY: {
key: 'trustProxy',
type: 'boolean'
},
SERVE_STATIC_QUICK: {
key: 'useServeStaticQuick',
type: 'boolean',
default: true
}
}
// Load from config file
for (const key of Object.keys(config)) {
self[key] = config[key]
}
// Parse environment variables overrides
for (const name of Object.keys(overrides)) {
if (typeof overrides[name] === 'object') {
const key = overrides[name].key
if (overrides[name].type === 'boolean') {
switch (process.env[name]) {
case '0':
case 'false':
self[key] = false
break
case '1':
case 'true':
self[key] = true
break
}
} else if (overrides[name].type === 'number') {
if (process.env[name] !== undefined) {
self[key] = parseInt(process.env[name], 10)
}
} else {
if (process.env[name] !== undefined) {
self[key] = process.env[name]
}
}
if (self[key] === undefined && overrides[name].default !== undefined) {
self[key] = overrides[name].default
}
} else if (typeof overrides[name] === 'string') {
const key = overrides[name]
if (process.env[name] !== undefined) {
self[key] = process.env[name]
}
} else {
logger.debug(`Invalid config override key: ${name}`)
}
}
logger.debug('ConfigManager initiated.')
module.exports = self

View File

@ -14,7 +14,7 @@ const perms = require('./permissionController')
const ClientError = require('./utils/ClientError')
const ServerError = require('./utils/ServerError')
const SimpleDataStore = require('./utils/SimpleDataStore')
const config = require('./../config')
const config = require('./utils/ConfigManager')
const logger = require('./../logger')
const devmode = process.env.NODE_ENV === 'development'
@ -24,13 +24,6 @@ const self = {
inspect: devmode && require('util').inspect,
db: knex(config.database),
conf: {
// Allow some config options to be overriden via env vars
port: process.env.PORT || config.port,
domain: process.env.DOMAIN || config.domain,
homeDomain: process.env.HOME_DOMAIN || config.homeDomain,
disableServeStaticQuick: process.env.SERVE_STATIC_QUICK === '0'
},
scan: {
instance: null,
version: null,
@ -151,8 +144,7 @@ if (typeof config.uploads.retentionPeriods === 'object' &&
self.retentions.enabled = true
}
}
} else if (Array.isArray(config.uploads.temporaryUploadAges) &&
config.uploads.temporaryUploadAges.length) {
} else if (Array.isArray(config.uploads.temporaryUploadAges) && config.uploads.temporaryUploadAges.length) {
self.retentions.periods._ = config.uploads.temporaryUploadAges
.filter((v, i, a) => Number.isFinite(v) && v >= 0)
self.retentions.default._ = self.retentions.periods._[0]

View File

@ -25,7 +25,6 @@ try {
const fs = require('fs')
const helmet = require('helmet')
const HyperExpress = require('hyper-express')
const NodeClam = require('clamscan')
// Check required config files
const configFiles = ['config.js', 'views/_globals.njk']
@ -39,9 +38,8 @@ for (const _file of configFiles) {
}
}
// Config files
const config = require('./config')
const versions = require('./src/versions')
// ConfigManager
const config = require('./controllers/utils/ConfigManager')
// lolisafe
logger.log('Starting lolisafe\u2026')
@ -65,6 +63,9 @@ const ServeStaticQuick = require('./controllers/middlewares/ServeStaticQuick')
// Handlers
const ServeStatic = require('./controllers/handlers/ServeStatic')
// Modules
const ScannerManager = require('./controllers/utils/ScannerManager')
// Routes
const album = require('./routes/album')
const api = require('./routes/api')
@ -211,14 +212,16 @@ if (config.cacheControl) {
}
// Init serve static middlewares for static assets
const ServeStaticClass = utils.conf.disableServeStaticQuick
? ServeLiveDirectory
: ServeStaticQuick
const ServeStaticClass = config.useServeStaticQuick
? ServeStaticQuick
: ServeLiveDirectory
// Static assets in /dist directory
const serveStaticDistInstance = new ServeStaticClass(paths.dist, {
setHeaders: setHeadersForStaticAssets
})
safe.use(serveStaticDistInstance.middleware)
// Static assets in /public directory
const serveStaticPublicInstance = new ServeStaticClass(paths.public, {
setHeaders: setHeadersForStaticAssets
@ -252,6 +255,7 @@ safe.use('/api', api)
// Re-map version strings if cache control is enabled (safe.fiery.me)
utils.versionStrings = {}
if (config.cacheControl) {
const versions = require('./src/versions')
for (const type in versions) {
utils.versionStrings[type] = `?_=${versions[type]}`
}
@ -326,17 +330,6 @@ safe.use('/api', api)
logger.log(`Git commit: ${utils.gitHash}`)
}
// ClamAV scanner
if (config.uploads.scan && config.uploads.scan.enabled) {
if (!config.uploads.scan.clamOptions) {
logger.error('Missing object config.uploads.scan.clamOptions (check config.sample.js)')
process.exit(1)
}
utils.scan.instance = await new NodeClam().init(config.uploads.scan.clamOptions)
utils.scan.version = await utils.scan.instance.getVersion().then(s => s.trim())
logger.log(`Connection established with ${utils.scan.version}`)
}
// Await all ServeLiveDirectory and ServeStaticQuick instances
await Promise.all([
serveStaticDistInstance.ready(),
@ -344,9 +337,13 @@ safe.use('/api', api)
serveLiveDirectoryCustomPagesInstance.ready()
])
// Init modules
// ClamAV scanner
await ScannerManager.init()
// Binds Express to port
await safe.listen(utils.conf.port)
logger.log(`lolisafe started on port ${utils.conf.port}`)
await safe.listen(config.port)
logger.log(`lolisafe started on port ${config.port}`)
// Cache control (safe.fiery.me)
// Purge Cloudflare cache

View File

@ -3,7 +3,7 @@ const routes = new Router()
const path = require('path')
const errors = require('./../controllers/errorsController')
const utils = require('./../controllers/utilsController')
const config = require('./../config')
const config = require('./../controllers/utils/ConfigManager')
routes.get('/a/:identifier', async (req, res) => {
const identifier = req.path_parameters && req.path_parameters.identifier

View File

@ -5,7 +5,7 @@ const auth = require('./../controllers/authController')
const tokens = require('./../controllers/tokenController')
const upload = require('./../controllers/uploadController')
const utils = require('./../controllers/utilsController')
const config = require('./../config')
const config = require('./../controllers/utils/ConfigManager')
routes.get('/check', async (req, res) => {
const obj = {

View File

@ -1,7 +1,7 @@
const { Router } = require('hyper-express')
const routes = new Router()
const utils = require('./../controllers/utilsController')
const config = require('./../config')
const config = require('./../controllers/utils/ConfigManager')
routes.get('/file/:identifier', async (req, res) => {
// Uploads identifiers parsing, etc., are strictly handled by client-side JS at src/js/file.js

View File

@ -2,7 +2,7 @@ const { Router } = require('hyper-express')
const routes = new Router()
const upload = require('./../controllers/uploadController')
const utils = require('./../controllers/utilsController')
const config = require('./../config')
const config = require('./../controllers/utils/ConfigManager')
routes.get('/nojs', async (req, res) => {
return res.render('nojs', {

View File

@ -1,7 +1,7 @@
const { Router } = require('hyper-express')
const routes = new Router()
const utils = require('./../controllers/utilsController')
const config = require('./../config')
const config = require('./../controllers/utils/ConfigManager')
const playerHandler = async (req, res) => {
// Uploads identifiers parsing, etc., are strictly handled by client-side JS at src/js/player.js

View File

@ -1,6 +1,6 @@
const jetpack = require('fs-jetpack')
const perms = require('./../controllers/permissionController')
const config = require('./../config')
const config = require('./utils/ConfigManager')
const map = {
files: {

View File

@ -1,7 +1,7 @@
{%- import '_globals.njk' as globals with context -%}
{# Set root domain here to inherit values from config file #}
{%- set root = utils.conf.homeDomain or utils.conf.domain -%}
{%- set root = config.homeDomain or config.domain -%}
{%- set title -%}
{%- if metaTitle -%}

View File

@ -4,7 +4,7 @@
{% set metaDesc = album.description | striptags | truncate(200, true, '…') %}
{% set metaUrl = '/' + album.url %}
{% set fileRoot = utils.conf.domain %}
{% set fileRoot = config.domain %}
{% set metaImage = fileRoot + '/' + album.thumb %}
{% extends "_layout.njk" %}

View File

@ -2,7 +2,7 @@
{% set metaTitle = "File" %}
{% set uploadRoot = utils.conf.domain %}
{% set uploadRoot = config.domain %}
{% set titleFormat = '%identifier% | ' + globals.name %}
{% extends "_layout.njk" %}

View File

@ -2,7 +2,7 @@
{% set metaTitle = "Player" %}
{% set uploadRoot = utils.conf.domain %}
{% set uploadRoot = config.domain %}
{% set titleFormat = '%identifier% | ' + globals.name %}
{% extends "_layout.njk" %}