diff --git a/server/controllers/MiscController.js b/server/controllers/MiscController.js index 591f8ccf2..ac7f88a8a 100644 --- a/server/controllers/MiscController.js +++ b/server/controllers/MiscController.js @@ -10,6 +10,7 @@ const Watcher = require('../Watcher') const libraryItemFilters = require('../utils/queries/libraryItemFilters') const cron = require('../libs/nodeCron') const { isObject, getTitleIgnorePrefix } = require('../utils/index') +const ServerSettings = require('../objects/settings/ServerSettings') const { sanitizeFilename } = require('../utils/fileUtils') const TaskManager = require('../managers/TaskManager') @@ -142,16 +143,23 @@ class MiscController { Logger.warn('Cannot disable iframe when ALLOW_IFRAME is enabled in environment') return res.status(400).send('Cannot disable iframe when ALLOW_IFRAME is enabled in environment') } - if (settingsUpdate.allowedOrigins && !Array.isArray(settingsUpdate.allowedOrigins)) { + const filteredUpdate = {} + for (const key in settingsUpdate) { + if (ServerSettings.patchableSettingsKeys.has(key)) { + filteredUpdate[key] = settingsUpdate[key] + } + } + + if (filteredUpdate.allowedOrigins && !Array.isArray(filteredUpdate.allowedOrigins)) { return res.status(400).send('allowedOrigins must be an array') } - const madeUpdates = Database.serverSettings.update(settingsUpdate) + const madeUpdates = Database.serverSettings.update(filteredUpdate) if (madeUpdates) { await Database.updateServerSettings() // If backup schedule is updated - update backup manager - if (settingsUpdate.backupSchedule !== undefined) { + if (filteredUpdate.backupSchedule !== undefined) { this.backupManager.updateCronSchedule() } } diff --git a/server/objects/settings/ServerSettings.js b/server/objects/settings/ServerSettings.js index f0bb4b201..0454161ee 100644 --- a/server/objects/settings/ServerSettings.js +++ b/server/objects/settings/ServerSettings.js @@ -5,7 +5,31 @@ const Logger = require('../../Logger') const User = require('../../models/User') const { sanitize } = require('../../utils/htmlSanitizer') +const PATCHABLE_SETTINGS_KEYS = new Set([ + 'scannerParseSubtitle', + 'scannerFindCovers', + 'scannerCoverProvider', + 'scannerPreferMatchedMetadata', + 'scannerDisableWatcher', + 'storeCoverWithItem', + 'storeMetadataWithItem', + 'allowIframe', + 'allowedOrigins', + 'backupSchedule', + 'backupsToKeep', + 'maxBackupSize', + 'logLevel', + 'homeBookshelfView', + 'bookshelfView', + 'dateFormat', + 'timeFormat', + 'language', + 'chromecastEnabled', + 'sortingIgnorePrefix' +]) + class ServerSettings { + static patchableSettingsKeys = PATCHABLE_SETTINGS_KEYS constructor(settings) { this.id = 'server-settings' /** @type {string} JWT secret key ONLY used when JWT_SECRET_KEY is not set in ENV */ @@ -341,24 +365,9 @@ class ServerSettings { update(payload) { let hasUpdates = false for (const key in payload) { - if (key === 'authLoginCustomMessage') { - payload[key] = sanitize(payload[key]) - } - if (key === 'sortingPrefixes') { - // Sorting prefixes are updated with the /api/sorting-prefixes endpoint - continue - } else if (key === 'authActiveAuthMethods') { - if (!payload[key]?.length) { - Logger.error(`[ServerSettings] Invalid authActiveAuthMethods`, payload[key]) - continue - } - this.authActiveAuthMethods.sort() - payload[key].sort() - if (payload[key].join() !== this.authActiveAuthMethods.join()) { - this.authActiveAuthMethods = payload[key] - hasUpdates = true - } - } else if (this[key] !== payload[key]) { + if (!PATCHABLE_SETTINGS_KEYS.has(key)) continue + + if (this[key] !== payload[key]) { if (key === 'logLevel') { Logger.setLogLevel(payload[key]) }