import { Request } from 'express'; import { CustomDecorator } from '@nestjs/common'; import { PermissionsObjectPermission } from './permissions.enum'; import { RequestUser } from './user.decorator'; export const AUTH_FUNCTION_KEY = '__AUTH_FUNCTION__'; export type AuthenticationFunction = (req: Request, user: any) => boolean; // implementation copied from SetMetadata, but tweaked to get existing values // of the metadataKey and accumulate it with the new metadataValue function SetMultipleMetadata(metadataKey, metadataValue): CustomDecorator { const decoratorFactory = (target, key, descriptor) => { // .start: tweak // descriptor?.value = function decorator; target = class decorator const accumulatedVal = Reflect.getMetadata(metadataKey, descriptor?.value ?? target) ?? []; accumulatedVal.push(metadataValue); // .end: tweak if (descriptor) { Reflect.defineMetadata(metadataKey, accumulatedVal, descriptor.value); return descriptor; } Reflect.defineMetadata(metadataKey, accumulatedVal, target); return target; }; decoratorFactory.KEY = metadataKey; return decoratorFactory as any; } export function RequireAllPermissions( ...permissions: PermissionsObjectPermission[] ) { return SetMultipleMetadata(AUTH_FUNCTION_KEY, (req, user: RequestUser) => permissions.every(({ seqid }) => user.permissions.includes(seqid)), ); } export function RequireSomePermission( ...permissions: PermissionsObjectPermission[] ) { return SetMultipleMetadata(AUTH_FUNCTION_KEY, (req, user: RequestUser) => permissions.some(({ seqid }) => user.permissions.includes(seqid)), ); } export function AuthenticateCondition(func: AuthenticationFunction) { return SetMultipleMetadata(AUTH_FUNCTION_KEY, func); } export function Authenticated() { return SetMultipleMetadata(AUTH_FUNCTION_KEY, () => true); }