Update settings PATCH endpoint to only accept a fixed set of general settings (auth settings must go through the auth-settings endpoint)

This commit is contained in:
advplyr committed 2026-09-14 17:21:40 -05:00
1 parent 42bf9512b0
commit 3d62a103ae
2 files changed
+38 -21

No files matched your search

+11 -3
View File
@@ -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()
}
}
+27 -18
View File
@@ -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])
}