diff --git a/src/helpers/jwtHelper.ts b/src/helpers/jwtHelper.ts index c16f2a2..5708ab8 100644 --- a/src/helpers/jwtHelper.ts +++ b/src/helpers/jwtHelper.ts @@ -58,7 +58,10 @@ export abstract class JWTHelper { let rolePermissions = userRoles.length != 0 ? await RolePermissionService.getByRoles(userRoles.map((e) => e.id)) : []; let rolePermissionStrings = rolePermissions.map((e) => e.permission); - let permissionObject = PermissionHelper.convertToObject([...userPermissionStrings, ...rolePermissionStrings]); + let permissionObject = PermissionHelper.convertToObject( + [...userPermissionStrings, ...rolePermissionStrings], + isOwner + ); let jwtData: JWTToken = { userId: id, diff --git a/src/helpers/permissionHelper.ts b/src/helpers/permissionHelper.ts index 86b27e2..6a83f92 100644 --- a/src/helpers/permissionHelper.ts +++ b/src/helpers/permissionHelper.ts @@ -4,9 +4,11 @@ import { permissionModules, PermissionObject, PermissionSection, + permissionSections, PermissionString, PermissionType, permissionTypes, + sectionsAndModules, } from "../type/permissionTypes"; import ForbiddenRequestException from "../exceptions/forbiddenRequestException"; @@ -17,8 +19,8 @@ export default class PermissionHelper { section: PermissionSection, module?: PermissionModule ) { - if (type == "admin") return permissions?.admin ?? false; - if (permissions?.admin) return true; + if (type == "admin") return permissions?.admin ?? permissions?.adminByOwner ?? false; + if (permissions?.admin || permissions?.adminByOwner) return true; if ( (!module && permissions[section] != undefined && @@ -50,8 +52,8 @@ export default class PermissionHelper { type: PermissionType | "admin", section: PermissionSection ): boolean { - if (type == "admin") return permissions?.admin ?? false; - if (permissions?.admin) return true; + if (type == "admin") return permissions?.admin ?? permissions?.adminByOwner ?? false; + if (permissions?.admin || permissions?.adminByOwner) return true; if ( permissions[section]?.all == "*" || permissions[section]?.all?.includes(type) || @@ -73,6 +75,11 @@ export default class PermissionHelper { }, false); } + static canValue(permissions: PermissionObject, key: string, emptyIfAdmin: boolean = false): string { + if (emptyIfAdmin && (permissions.admin || permissions.adminByOwner)) return ""; + return permissions?.additional?.[key] ?? ""; + } + static passCheckMiddleware( requiredPermissions: PermissionType | "admin", section: PermissionSection, @@ -159,14 +166,28 @@ export default class PermissionHelper { }; } - static convertToObject(permissions: Array): PermissionObject { - if (permissions.includes("*")) { + static convertToObject(permissions: Array, isOwner: boolean = false): PermissionObject { + let isAdmin = permissions.includes("*"); + + let additional: { [key: string]: string } = {}; + let additionalPermissions = permissions.map((e) => e.split(".")).filter((e) => e[0] == "additional") as Array< + ["additional", string, string] + >; + for (let split of additionalPermissions) { + let module = sectionsAndModules.additional.find((a) => a.key == split[1]); + if (!isAdmin || (isAdmin && !module.emptyIfAdmin)) additional[split[1]] = split[2]; + } + + if (isAdmin) { return { admin: true, + adminByOwner: isOwner, + ...(Object.keys(additional).length > 0 && { additional }), }; } + let output: PermissionObject = {}; - let splitPermissions = permissions.map((e) => e.split(".")) as Array< + let splitPermissions = permissions.map((e) => e.split(".")).filter((e) => e[0] != "additional") as Array< [PermissionSection, PermissionModule | PermissionType | "*", PermissionType | "*"] >; for (let split of splitPermissions) { @@ -208,15 +229,31 @@ export default class PermissionHelper { } } } - return output; + + return { + adminByOwner: isOwner, + ...output, + ...(Object.keys(additional).length > 0 && { additional }), + }; } static convertToStringArray(permissions: PermissionObject): Array { - if (permissions?.admin) { - return ["*"]; + let isAdmin = permissions?.admin; + + let additional: Array = []; + let additionalPermissions = Object.entries(permissions?.additional ?? {}); + for (let add of additionalPermissions) { + additional.push(`additional.${add[0]}.${add[1]}`); } + + if (isAdmin) { + return ["*", ...additional]; + } + let output: Array = []; - let sections = Object.keys(permissions) as Array; + let sections = Object.keys(permissions).filter((m: PermissionSection) => + permissionSections.includes(m) + ) as Array; for (let section of sections) { if (permissions[section].all) { let types = permissions[section].all; @@ -242,7 +279,8 @@ export default class PermissionHelper { } } } - return output; + + return [...output, ...additional]; } static getWhatToAdd(before: Array, after: Array): Array { diff --git a/src/type/permissionTypes.ts b/src/type/permissionTypes.ts index e9ed138..1061d49 100644 --- a/src/type/permissionTypes.ts +++ b/src/type/permissionTypes.ts @@ -30,6 +30,7 @@ export type PermissionString = | `${PermissionSection}.${PermissionModule}.*` // für alle Berechtigungen in einem Modul | `${PermissionSection}.${PermissionType}` // für spezifische Berechtigungen in einem Abschnitt | `${PermissionSection}.*` // für alle Berechtigungen in einem Abschnitt + | `additional.${string}.${string}` // additional | "*"; // für Admin export type PermissionObject = { @@ -38,10 +39,20 @@ export type PermissionObject = { } & { all?: Array | "*" }; } & { admin?: boolean; + adminByOwner?: boolean; +} & { + additional?: { [key: string]: string }; }; export type SectionsAndModulesObject = { [section in PermissionSection]: Array; +} & { + additional?: Array<{ + key: string; + name: string; + type: "number" | "string"; + emptyIfAdmin: boolean; + }>; }; export const permissionSections: Array = ["club", "configuration", "management"]; @@ -85,4 +96,5 @@ export const sectionsAndModules: SectionsAndModulesObject = { "newsletter_config", ], management: ["user", "role", "webapi", "backup"], + additional: [], };