From 991dcdbe3ae3ecd8111f5242465bb4e3e10ea913 Mon Sep 17 00:00:00 2001 From: timothycarambat Date: Fri, 29 Mar 2024 10:49:03 -0700 Subject: [PATCH 1/4] Patch ability to update multi-user-flag once set --- server/endpoints/system.js | 8 ++--- server/models/systemSettings.js | 53 ++++++++++++++++++++++----------- server/models/telemetry.js | 2 +- 3 files changed, 40 insertions(+), 23 deletions(-) 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..001f58f490 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, value]) => { + 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. + _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; }, From 9f317f4f885e8b172497d1dcc746a8a714be30ab Mon Sep 17 00:00:00 2001 From: timothycarambat Date: Fri, 29 Mar 2024 10:51:10 -0700 Subject: [PATCH 2/4] update logo funciton to safeupdate --- server/endpoints/system.js | 2 +- server/models/systemSettings.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/server/endpoints/system.js b/server/endpoints/system.js index 9012768100..9902a47fc9 100644 --- a/server/endpoints/system.js +++ b/server/endpoints/system.js @@ -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 001f58f490..832ab597b2 100644 --- a/server/models/systemSettings.js +++ b/server/models/systemSettings.js @@ -295,7 +295,7 @@ const SystemSettings = { this.supportedFields.includes(key) ); - Object.entries(updates).forEach(([key, value]) => { + Object.entries(updates).forEach(([key]) => { if (validFields.includes(key)) return; delete updates[key]; }); From b4a164bb9f29052cde26d062991e62d15bce2e80 Mon Sep 17 00:00:00 2001 From: timothycarambat Date: Fri, 29 Mar 2024 10:52:58 -0700 Subject: [PATCH 3/4] update logo funciton to safeupdate --- server/endpoints/system.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/endpoints/system.js b/server/endpoints/system.js index 9902a47fc9..466a38f7fc 100644 --- a/server/endpoints/system.js +++ b/server/endpoints/system.js @@ -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, }); From 77cdf44778ad28e33ac1dbd294ff60b5b1a6a10d Mon Sep 17 00:00:00 2001 From: timothycarambat Date: Fri, 29 Mar 2024 10:55:50 -0700 Subject: [PATCH 4/4] update logo funciton to safeupdate --- server/endpoints/system.js | 2 +- server/models/systemSettings.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/server/endpoints/system.js b/server/endpoints/system.js index 466a38f7fc..9012768100 100644 --- a/server/endpoints/system.js +++ b/server/endpoints/system.js @@ -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, }); diff --git a/server/models/systemSettings.js b/server/models/systemSettings.js index 832ab597b2..e4c0f94996 100644 --- a/server/models/systemSettings.js +++ b/server/models/systemSettings.js @@ -305,7 +305,7 @@ const SystemSettings = { // Explicit update of settings + key validations. // Only use this method when directly setting a key value - // that takes no user input. + // that takes no user input for the keys being modified. _updateSettings: async function (updates = {}) { try { const updatePromises = Object.keys(updates).map((key) => {