diff --git a/server/src/config/services.ts b/server/src/config/services.ts index aef32440f..6b91bcf63 100644 --- a/server/src/config/services.ts +++ b/server/src/config/services.ts @@ -74,6 +74,7 @@ import { MongoUsersRepository, MongoInvitesRepository, MongoRecoveryTokensRepository, + MongoSettingsRepository, IMonitorsRepository, IChecksRepository, IMonitorStatsRepository, @@ -81,6 +82,7 @@ import { IUsersRepository, IInvitesRepository, IRecoveryTokensRepository, + ISettingsRepository, } from "@/repositories/index.js"; export type InitializedSerivces = { @@ -113,6 +115,7 @@ export type InitializedSerivces = { usersRepository: IUsersRepository; invitesRepository: IInvitesRepository; recoveryTokensRepository: IRecoveryTokensRepository; + settingsRepository: ISettingsRepository; }; export const initializeServices = async ({ @@ -167,6 +170,7 @@ export const initializeServices = async ({ const usersRepository = new MongoUsersRepository(); const invitesRepository = new MongoInvitesRepository(); const recoveryTokensRepository = new MongoRecoveryTokensRepository(); + const settingsRepository = new MongoSettingsRepository(); const networkService = new NetworkService({ axios, @@ -240,7 +244,6 @@ export const initializeServices = async ({ // Business services const userService = new UserService({ crypto, - db, emailService, settingsService, logger, @@ -252,6 +255,7 @@ export const initializeServices = async ({ usersRepository, invitesRepository, recoveryTokensRepository, + settingsRepository, }); const diagnosticService = new DiagnosticService(); @@ -313,6 +317,7 @@ export const initializeServices = async ({ usersRepository, invitesRepository, recoveryTokensRepository, + settingsRepository, }; Object.values(services).forEach((service) => { diff --git a/server/src/db/models/AppSettings.ts b/server/src/db/models/AppSettings.ts index 22d1369e5..9eeaa640a 100644 --- a/server/src/db/models/AppSettings.ts +++ b/server/src/db/models/AppSettings.ts @@ -21,6 +21,7 @@ const AppSettingsSchema = new Schema( { checkTTL: { type: Number, default: 30 }, language: { type: String, default: "gb" }, + jwtSecret: { type: String }, pagespeedApiKey: { type: String }, systemEmailHost: { type: String }, systemEmailPort: { type: Number }, diff --git a/server/src/repositories/settings/MongoSettingsRepository.ts b/server/src/repositories/settings/MongoSettingsRepository.ts index f4d71d56e..2cc700525 100644 --- a/server/src/repositories/settings/MongoSettingsRepository.ts +++ b/server/src/repositories/settings/MongoSettingsRepository.ts @@ -2,7 +2,6 @@ import mongoose from "mongoose"; import { ISettingsRepository } from "@/repositories/settings/ISettingsRepository.js"; import type { Settings } from "@/types/index.js"; import { AppSettingsModel, type AppSettingsDocument } from "@/db/models/AppSettings.js"; -import { AppError } from "@/utils/AppError.js"; class MongoSettingsRepository implements ISettingsRepository { private toStringId = (value?: mongoose.Types.ObjectId | string | null): string => { @@ -24,6 +23,7 @@ class MongoSettingsRepository implements ISettingsRepository { id: this.toStringId(doc._id), checkTTL: doc.checkTTL, language: doc.language, + jwtSecret: doc.jwtSecret ?? undefined, pagespeedApiKey: doc.pagespeedApiKey ?? undefined, systemEmailHost: doc.systemEmailHost ?? undefined, systemEmailPort: doc.systemEmailPort ?? undefined, @@ -63,11 +63,13 @@ class MongoSettingsRepository implements ISettingsRepository { upsert: true, }); - const currentSettings = await AppSettingsModel.findOne().select("-__v -_id -createdAt -updatedAt -singleton").lean(); - if (!currentSettings) { - throw new AppError({ message: "Settings not found after update", status: 500 }); - } - return this.toEntity(currentSettings); + const updatedSettings = await AppSettingsModel.findOneAndUpdate({}, update, { + upsert: true, + new: true, + projection: "-__v -_id -createdAt -updatedAt -singleton", + }); + + return this.toEntity(updatedSettings); }; } diff --git a/server/src/service/business/userService.ts b/server/src/service/business/userService.ts index 7d9e5811e..5f73508dd 100644 --- a/server/src/service/business/userService.ts +++ b/server/src/service/business/userService.ts @@ -1,4 +1,4 @@ -import { IInvitesRepository, IMonitorsRepository, IRecoveryTokensRepository, IUsersRepository } from "@/repositories/index.js"; +import { IInvitesRepository, IMonitorsRepository, IRecoveryTokensRepository, IUsersRepository, ISettingsRepository } from "@/repositories/index.js"; import Team from "@/db/models/Team.js"; import type { User } from "@/types/index.js"; import bcrypt from "bcryptjs"; @@ -9,7 +9,6 @@ const SERVICE_NAME = "userService"; class UserService { static SERVICE_NAME = SERVICE_NAME; - private db: any; private emailService: any; private settingsService: any; private logger: any; @@ -22,10 +21,10 @@ class UserService { private usersRepository: IUsersRepository; private invitesRepository: IInvitesRepository; private recoveryTokensRepository: IRecoveryTokensRepository; + private settingsRepository: ISettingsRepository; constructor({ crypto, - db, emailService, settingsService, logger, @@ -37,9 +36,9 @@ class UserService { usersRepository, invitesRepository, recoveryTokensRepository, + settingsRepository, }: { crypto: any; - db: any; emailService: any; settingsService: any; logger: any; @@ -51,8 +50,8 @@ class UserService { usersRepository: IUsersRepository; invitesRepository: IInvitesRepository; recoveryTokensRepository: IRecoveryTokensRepository; + settingsRepository: ISettingsRepository; }) { - this.db = db; this.emailService = emailService; this.settingsService = settingsService; this.logger = logger; @@ -65,6 +64,7 @@ class UserService { this.usersRepository = usersRepository; this.invitesRepository = invitesRepository; this.recoveryTokensRepository = recoveryTokensRepository; + this.settingsRepository = settingsRepository; } get serviceName() { @@ -89,7 +89,7 @@ class UserService { } else { // This is the first account, create JWT secret to use if one is not supplied by env const jwtSecret = this.crypto.randomBytes(64).toString("hex"); - await this.db.settingsModule.updateAppSettings({ jwtSecret }); + await this.settingsRepository.update({ jwtSecret }); // Create a new team const team = new Team({ email: user.email, diff --git a/server/src/types/settings.ts b/server/src/types/settings.ts index 78284a451..108cdcb72 100644 --- a/server/src/types/settings.ts +++ b/server/src/types/settings.ts @@ -9,6 +9,7 @@ export interface Settings { id: string; checkTTL: number; language: string; + jwtSecret?: string; pagespeedApiKey?: string; systemEmailHost?: string; systemEmailPort?: number;