From 7aa9038a61350708364b4aade0d7c4bafd6a1a90 Mon Sep 17 00:00:00 2001 From: Julian Krauser Date: Sun, 20 Apr 2025 16:15:27 +0200 Subject: [PATCH] provide setting endbpoints --- package-lock.json | 18 ++++++ package.json | 2 + .../setting}/settingCommand.ts | 0 .../setting}/settingCommandHandler.ts | 8 +-- src/controller/admin/management/setting.ts | 60 +++++++++++++++++++ src/helpers/settingsHelper.ts | 9 ++- src/routes/admin/index.ts | 2 + src/routes/admin/management/setting.ts | 31 ++++++++++ src/routes/public.ts | 6 +- .../{ => management}/settingService.ts | 8 +-- src/type/permissionTypes.ts | 6 +- 11 files changed, 137 insertions(+), 13 deletions(-) rename src/command/{ => management/setting}/settingCommand.ts (100%) rename src/command/{ => management/setting}/settingCommandHandler.ts (85%) create mode 100644 src/controller/admin/management/setting.ts create mode 100644 src/routes/admin/management/setting.ts rename src/service/{ => management}/settingService.ts (82%) diff --git a/package-lock.json b/package-lock.json index a7c3021..6d738ff 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,6 +20,7 @@ "ics": "^3.8.1", "ip": "^2.0.1", "jsonwebtoken": "^9.0.2", + "lodash.clonedeep": "^4.5.0", "lodash.uniqby": "^4.7.0", "moment": "^2.30.1", "morgan": "^1.10.0", @@ -45,6 +46,7 @@ "@types/express": "^5.0.1", "@types/ip": "^1.1.3", "@types/jsonwebtoken": "^9.0.6", + "@types/lodash.clonedeep": "^4.5.9", "@types/lodash.uniqby": "^4.7.9", "@types/morgan": "^1.9.9", "@types/ms": "^2.1.0", @@ -462,6 +464,16 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/lodash.clonedeep": { + "version": "4.5.9", + "resolved": "https://registry.npmjs.org/@types/lodash.clonedeep/-/lodash.clonedeep-4.5.9.tgz", + "integrity": "sha512-19429mWC+FyaAhOLzsS8kZUsI+/GmBAQ0HFiCPsKGU+7pBXOQWhyrY6xNNDwUSX8SMZMJvuFVMF9O5dQOlQK9Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/lodash": "*" + } + }, "node_modules/@types/lodash.uniqby": { "version": "4.7.9", "resolved": "https://registry.npmjs.org/@types/lodash.uniqby/-/lodash.uniqby-4.7.9.tgz", @@ -2770,6 +2782,12 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "license": "MIT" }, + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==", + "license": "MIT" + }, "node_modules/lodash.includes": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", diff --git a/package.json b/package.json index 9f7d24c..0483b20 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,7 @@ "ics": "^3.8.1", "ip": "^2.0.1", "jsonwebtoken": "^9.0.2", + "lodash.clonedeep": "^4.5.0", "lodash.uniqby": "^4.7.0", "moment": "^2.30.1", "morgan": "^1.10.0", @@ -61,6 +62,7 @@ "@types/express": "^5.0.1", "@types/ip": "^1.1.3", "@types/jsonwebtoken": "^9.0.6", + "@types/lodash.clonedeep": "^4.5.9", "@types/lodash.uniqby": "^4.7.9", "@types/morgan": "^1.9.9", "@types/ms": "^2.1.0", diff --git a/src/command/settingCommand.ts b/src/command/management/setting/settingCommand.ts similarity index 100% rename from src/command/settingCommand.ts rename to src/command/management/setting/settingCommand.ts diff --git a/src/command/settingCommandHandler.ts b/src/command/management/setting/settingCommandHandler.ts similarity index 85% rename from src/command/settingCommandHandler.ts rename to src/command/management/setting/settingCommandHandler.ts index 148bdef..a6bde0f 100644 --- a/src/command/settingCommandHandler.ts +++ b/src/command/management/setting/settingCommandHandler.ts @@ -1,7 +1,7 @@ -import { dataSource } from "../data-source"; -import { setting } from "../entity/setting"; -import DatabaseActionException from "../exceptions/databaseActionException"; -import { StringHelper } from "../helpers/stringHelper"; +import { dataSource } from "../../../data-source"; +import { setting } from "../../../entity/setting"; +import DatabaseActionException from "../../../exceptions/databaseActionException"; +import { StringHelper } from "../../../helpers/stringHelper"; import { CreateOrUpdateSettingCommand, DeleteSettingCommand } from "./settingCommand"; export default abstract class SettingCommandHandler { diff --git a/src/controller/admin/management/setting.ts b/src/controller/admin/management/setting.ts new file mode 100644 index 0000000..84a302f --- /dev/null +++ b/src/controller/admin/management/setting.ts @@ -0,0 +1,60 @@ +import { Request, Response } from "express"; +import SettingHelper from "../../../helpers/settingsHelper"; +import { SettingString } from "../../../type/settingTypes"; + +/** + * @description get All settings + * @param req {Request} Express req object + * @param res {Response} Express res object + * @returns {Promise<*>} + */ +export async function getSettings(req: Request, res: Response): Promise { + res.json(SettingHelper.getAllSettings()); +} + +/** + * @description get setting + * @param req {Request} Express req object + * @param res {Response} Express res object + * @returns {Promise<*>} + */ +export async function getSetting(req: Request, res: Response): Promise { + let setting = req.params.setting as SettingString; + + let value = SettingHelper.getSetting(setting); + + if (setting == "mail.password") { + value = undefined; + } + + res.send(value); +} + +/** + * @description set setting + * @param req {Request} Express req object + * @param res {Response} Express res object + * @returns {Promise<*>} + */ +export async function setSetting(req: Request, res: Response): Promise { + let setting = req.body.setting as SettingString; + let value = req.body.value as string; + + SettingHelper.setSetting(setting, value); + + res.sendStatus(204); +} + +/** + * @description reset setting + * @param req {Request} Express req object + * @param res {Response} Express res object + * @returns {Promise<*>} + */ +export async function resetSetting(req: Request, res: Response): Promise { + let setting = req.params.setting as SettingString; + + SettingHelper.resetSetting(setting); + + res.sendStatus(204); +} diff --git a/src/helpers/settingsHelper.ts b/src/helpers/settingsHelper.ts index 35ce974..8418cab 100644 --- a/src/helpers/settingsHelper.ts +++ b/src/helpers/settingsHelper.ts @@ -1,7 +1,7 @@ import { SettingString, settingsType, SettingTopic, SettingTypeAtom, SettingValueMapping } from "../type/settingTypes"; import { CodingHelper } from "./codingHelper"; -import SettingCommandHandler from "../command/settingCommandHandler"; -import SettingService from "../service/settingService"; +import SettingCommandHandler from "../command/management/setting/settingCommandHandler"; +import SettingService from "../service/management/settingService"; import { APPLICATION_SECRET } from "../env.defaults"; import { BooleanConverter, @@ -12,6 +12,7 @@ import { TypeConverter, UrlConverter, } from "./convertHelper"; +import cloneDeep from "lodash.clonedeep"; export default abstract class SettingHelper { private static settings: { [key in SettingString]?: string } = {}; @@ -28,6 +29,10 @@ export default abstract class SettingHelper { ms: new MsConverter(), }; + public static getAllSettings() { + return cloneDeep(this.settings); + } + /** * Returns the value of a setting with the correct type based on the key * @param key The key of the setting diff --git a/src/routes/admin/index.ts b/src/routes/admin/index.ts index c2bab0f..5c3444b 100644 --- a/src/routes/admin/index.ts +++ b/src/routes/admin/index.ts @@ -26,6 +26,7 @@ import user from "./management/user"; import invite from "./management/invite"; import api from "./management/webapi"; import backup from "./management/backup"; +import setting from "./management/setting"; var router = express.Router({ mergeParams: true }); @@ -159,5 +160,6 @@ router.use( PermissionHelper.passCheckMiddleware("read", "management", "backup"), backup ); +router.use("/setting", PermissionHelper.passCheckMiddleware("read", "management", "setting"), setting); export default router; diff --git a/src/routes/admin/management/setting.ts b/src/routes/admin/management/setting.ts new file mode 100644 index 0000000..e0ffe14 --- /dev/null +++ b/src/routes/admin/management/setting.ts @@ -0,0 +1,31 @@ +import express, { Request, Response } from "express"; +import PermissionHelper from "../../../helpers/permissionHelper"; +import { getSetting, getSettings, resetSetting, setSetting } from "../../../controller/admin/management/setting"; + +var router = express.Router({ mergeParams: true }); + +router.get("/", async (req: Request, res: Response) => { + await getSettings(req, res); +}); + +router.get("/:setting", async (req: Request, res: Response) => { + await getSetting(req, res); +}); + +router.put( + "/", + PermissionHelper.passCheckMiddleware("create", "management", "setting"), + async (req: Request, res: Response) => { + await setSetting(req, res); + } +); + +router.delete( + "/:setting", + PermissionHelper.passCheckMiddleware("delete", "management", "setting"), + async (req: Request, res: Response) => { + await resetSetting(req, res); + } +); + +export default router; diff --git a/src/routes/public.ts b/src/routes/public.ts index 56b4784..49ec98a 100644 --- a/src/routes/public.ts +++ b/src/routes/public.ts @@ -1,5 +1,5 @@ import express from "express"; -import { getCalendarItemsByTypes } from "../controller/publicController"; +import { getApplicationConfig, getCalendarItemsByTypes } from "../controller/publicController"; var router = express.Router({ mergeParams: true }); @@ -7,4 +7,8 @@ router.get("/calendar", async (req, res) => { await getCalendarItemsByTypes(req, res); }); +router.get("/configuration", async (req, res) => { + await getApplicationConfig(req, res); +}); + export default router; diff --git a/src/service/settingService.ts b/src/service/management/settingService.ts similarity index 82% rename from src/service/settingService.ts rename to src/service/management/settingService.ts index d5f7701..1860065 100644 --- a/src/service/settingService.ts +++ b/src/service/management/settingService.ts @@ -1,7 +1,7 @@ -import { dataSource } from "../data-source"; -import { setting } from "../entity/setting"; -import InternalException from "../exceptions/internalException"; -import { SettingString } from "../type/settingTypes"; +import { dataSource } from "../../data-source"; +import { setting } from "../../entity/setting"; +import InternalException from "../../exceptions/internalException"; +import { SettingString } from "../../type/settingTypes"; export default abstract class SettingService { /** diff --git a/src/type/permissionTypes.ts b/src/type/permissionTypes.ts index 1061d49..c3babac 100644 --- a/src/type/permissionTypes.ts +++ b/src/type/permissionTypes.ts @@ -21,7 +21,8 @@ export type PermissionModule = | "query_store" | "template" | "template_usage" - | "backup"; + | "backup" + | "setting"; export type PermissionType = "read" | "create" | "update" | "delete"; @@ -78,6 +79,7 @@ export const permissionModules: Array = [ "template", "template_usage", "backup", + "setting", ]; export const permissionTypes: Array = ["read", "create", "update", "delete"]; export const sectionsAndModules: SectionsAndModulesObject = { @@ -95,6 +97,6 @@ export const sectionsAndModules: SectionsAndModulesObject = { "template_usage", "newsletter_config", ], - management: ["user", "role", "webapi", "backup"], + management: ["user", "role", "webapi", "backup", "setting"], additional: [], };