diff --git a/server/endpoints/system.js b/server/endpoints/system.js index 3c8cf6bc9d..9012768100 100644 --- a/server/endpoints/system.js +++ b/server/endpoints/system.js @@ -400,7 +400,7 @@ function systemEndpoints(app) { password, role: ROLES.admin, }); - await SystemSettings.updateSettings({ + await SystemSettings._updateSettings({ multi_user_mode: true, users_can_delete_workspaces: false, limit_user_messages: false, @@ -422,7 +422,7 @@ function systemEndpoints(app) { response.status(200).json({ success: !!user, error }); } catch (e) { await User.delete({}); - await SystemSettings.updateSettings({ + await SystemSettings._updateSettings({ multi_user_mode: false, }); @@ -623,7 +623,7 @@ function systemEndpoints(app) { const existingLogoFilename = await SystemSettings.currentLogoFilename(); await removeCustomLogo(existingLogoFilename); - const { success, error } = await SystemSettings.updateSettings({ + const { success, error } = await SystemSettings._updateSettings({ logo_filename: newFilename, }); @@ -657,7 +657,7 @@ function systemEndpoints(app) { try { const currentLogoFilename = await SystemSettings.currentLogoFilename(); await removeCustomLogo(currentLogoFilename); - const { success, error } = await SystemSettings.updateSettings({ + const { success, error } = await SystemSettings._updateSettings({ logo_filename: LOGO_FILENAME, }); diff --git a/server/models/systemSettings.js b/server/models/systemSettings.js index f27434ca95..e4c0f94996 100644 --- a/server/models/systemSettings.js +++ b/server/models/systemSettings.js @@ -5,8 +5,8 @@ process.env.NODE_ENV === "development" const prisma = require("../utils/prisma"); const SystemSettings = { + protectedFields: ["multi_user_mode"], supportedFields: [ - "multi_user_mode", "users_can_delete_workspaces", "limit_user_messages", "message_limit", @@ -287,26 +287,43 @@ const SystemSettings = { } }, + // Can take generic keys and will pre-filter invalid keys + // from the set before sending to the explicit update function + // that will then enforce validations as well. updateSettings: async function (updates = {}) { + const validFields = Object.keys(updates).filter((key) => + this.supportedFields.includes(key) + ); + + Object.entries(updates).forEach(([key]) => { + if (validFields.includes(key)) return; + delete updates[key]; + }); + + return this._updateSettings(updates); + }, + + // Explicit update of settings + key validations. + // Only use this method when directly setting a key value + // that takes no user input for the keys being modified. + _updateSettings: async function (updates = {}) { try { - const updatePromises = Object.keys(updates) - .filter((key) => this.supportedFields.includes(key)) - .map((key) => { - const validatedValue = this.validations.hasOwnProperty(key) - ? this.validations[key](updates[key]) - : updates[key]; - - return prisma.system_settings.upsert({ - where: { label: key }, - update: { - value: validatedValue === null ? null : String(validatedValue), - }, - create: { - label: key, - value: validatedValue === null ? null : String(validatedValue), - }, - }); + const updatePromises = Object.keys(updates).map((key) => { + const validatedValue = this.validations.hasOwnProperty(key) + ? this.validations[key](updates[key]) + : updates[key]; + + return prisma.system_settings.upsert({ + where: { label: key }, + update: { + value: validatedValue === null ? null : String(validatedValue), + }, + create: { + label: key, + value: validatedValue === null ? null : String(validatedValue), + }, }); + }); await Promise.all(updatePromises); return { success: true, error: null }; diff --git a/server/models/telemetry.js b/server/models/telemetry.js index 7c27aa69ce..ac82d56f40 100644 --- a/server/models/telemetry.js +++ b/server/models/telemetry.js @@ -67,7 +67,7 @@ const Telemetry = { setUid: async function () { const newId = v4(); - await SystemSettings.updateSettings({ [this.label]: newId }); + await SystemSettings._updateSettings({ [this.label]: newId }); return newId; },