import { CanActivate, ExecutionContext, ForbiddenException, Injectable } from '@nestjs/common'; import { Reflector } from '@nestjs/core'; import { Request } from 'express'; import { REQUIRED_PERMISSIONS_METADATA, } from '../decorators/require-permissions.decorator'; import { AdminUserRecord } from '../interfaces/admin-records.interface'; import { AdminService } from '../admin.service'; @Injectable() export class PermissionsGuard implements CanActivate { constructor( private readonly reflector: Reflector, private readonly adminService: AdminService, ) {} async canActivate(context: ExecutionContext): Promise { const required = this.reflector.getAllAndOverride( REQUIRED_PERMISSIONS_METADATA, [context.getHandler(), context.getClass()], ) ?? []; if (required.length === 0) { return true; } const request = context .switchToHttp() .getRequest(); const adminUser = request.adminUser; if (!adminUser) { throw new ForbiddenException('No permission'); } if (adminUser.isSuperAdmin) { return true; } const permissions = await this.adminService.getPermissionCodesForAdmin( adminUser.id, ); const allowed = required.every((permission) => permissions.includes(permission), ); if (!allowed) { throw new ForbiddenException('No permission'); } return true; } }