chore: import DH V2 D5.6.4 production baseline

This commit is contained in:
DH V2
2026-09-05 10:12:35 -03:00
commit 82213e72f5
757 changed files with 84218 additions and 0 deletions
@@ -0,0 +1,59 @@
import {
CanActivate,
ExecutionContext,
ForbiddenException,
Injectable,
UnauthorizedException,
} from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { IS_PUBLIC_KEY } from '../../auth/decorators/public.decorator';
import type { RequestWithContext } from '../../common/http/request-context';
import { REQUIRED_PERMISSIONS_KEY } from '../decorators/require-permissions.decorator';
@Injectable()
export class PermissionsGuard implements CanActivate {
constructor(private readonly reflector: Reflector) {}
canActivate(context: ExecutionContext): boolean {
const isPublic = this.reflector.getAllAndOverride<boolean>(IS_PUBLIC_KEY, [
context.getHandler(),
context.getClass(),
]);
if (isPublic) return true;
const required =
this.reflector.getAllAndMerge<string[]>(REQUIRED_PERMISSIONS_KEY, [
context.getHandler(),
context.getClass(),
]) ?? [];
const uniqueRequired = [...new Set(required)];
if (uniqueRequired.length === 0) return true;
const request = context.switchToHttp().getRequest<RequestWithContext>();
if (!request.auth) {
throw new UnauthorizedException({
code: 'UNAUTHORIZED',
message: 'Autenticación requerida',
});
}
if (request.auth.mustChangePassword) {
throw new ForbiddenException({
code: 'PASSWORD_CHANGE_REQUIRED',
message: 'Debe cambiar la contraseña temporal antes de continuar',
});
}
const granted = new Set(request.auth.permissions);
const missing = uniqueRequired.filter((permission) => !granted.has(permission));
if (missing.length > 0) {
throw new ForbiddenException({
code: 'FORBIDDEN',
message: 'Permisos insuficientes',
});
}
return true;
}
}