import { CanActivate, ExecutionContext, ForbiddenException, Injectable } from "@nestjs/common"; import { Reflector } from "@nestjs/core"; import type { Request } from "express"; import { REQUIRE_PERMISSION_KEY, type RequiredPermission } from "./decorators/require-permission.decorator.js"; import { hasPermission } from "./permissions.js"; /** * Runs after JwtAuthGuard (which populates request.edenUser). Endpoints * without @RequirePermission are left alone — authentication only. */ @Injectable() export class PermissionGuard implements CanActivate { constructor(private readonly reflector: Reflector) {} canActivate(context: ExecutionContext): boolean { const required = this.reflector.get( REQUIRE_PERMISSION_KEY, context.getHandler(), ); if (!required) return true; const request = context.switchToHttp().getRequest(); const user = request.edenUser; if (!user) { throw new ForbiddenException("Autenticação necessária"); } if (!hasPermission(user.permissions, required.resource, required.action)) { throw new ForbiddenException( `Sem permissão para '${required.action}' em '${required.resource}'`, ); } return true; } }