import { CanActivate, ExecutionContext, ForbiddenException, Injectable, } from '@nestjs/common'; import { Reflector } from '@nestjs/core'; import { Role } from '../generated/prisma/enums.js'; import { ROLES_KEY } from './roles.decorator.js'; import { MESSAGES } from '../common/messages.js'; /** * 角色守卫:读取 @Roles 元数据并校验当前登录角色是否可访问。 */ @Injectable() export class RolesGuard implements CanActivate { constructor(private readonly reflector: Reflector) {} /** * 守卫入口:认证后执行授权校验。 */ canActivate(context: ExecutionContext): boolean { const requiredRoles = this.reflector.getAllAndOverride(ROLES_KEY, [ context.getHandler(), context.getClass(), ]); if (!requiredRoles || requiredRoles.length === 0) { return true; } const request = context.switchToHttp().getRequest<{ actor?: { role?: Role } }>(); const actorRole = request.actor?.role; if (!actorRole || !requiredRoles.includes(actorRole)) { throw new ForbiddenException(MESSAGES.DEFAULT_FORBIDDEN); } return true; } }