feat(signatures): UI completa do módulo + rate limiting em rotas públicas
Fecha as duas pendências da leva anterior (módulo de Assinatura Eletrônica): tela de backoffice para gerenciar envelopes (criação, envio, cancelamento, checkpoint/finalização, auditoria) e as duas páginas públicas (/assinar/:token, /verificar/:verificationId). Backend: novos endpoints de streaming de PDF (documento congelado e PDF final consolidado, autenticados e via token público) que faltavam para a UI funcionar — o signatário não tinha como ver o próprio documento antes de confirmar leitura. Rate limiting (guard próprio, em memória, chaves por IP e por token) em todas as rotas sem sessão: auth (login/mfa/forgot-password/reset-password/refresh/logout) e todo o fluxo público de assinatura/verificação. Suíte: 77/77 verdes. pnpm turbo run typecheck build: 28/28. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -12,6 +12,16 @@ import { ResetPasswordDto } from "./dto/reset-password.dto.js";
|
||||
import { JwtAuthGuard } from "./jwt-auth.guard.js";
|
||||
import { CurrentUser } from "./decorators/current-user.decorator.js";
|
||||
import type { EdenAuthenticatedUser } from "./jwt-auth.guard.js";
|
||||
import { RateLimitGuard } from "../common/rate-limit/rate-limit.guard.js";
|
||||
import { RateLimit } from "../common/rate-limit/rate-limit.decorator.js";
|
||||
import {
|
||||
AUTH_FORGOT_PASSWORD_RULE,
|
||||
AUTH_LOGIN_RULE,
|
||||
AUTH_MFA_CHALLENGE_RULE,
|
||||
AUTH_LOGOUT_RULE,
|
||||
AUTH_REFRESH_RULE,
|
||||
AUTH_RESET_PASSWORD_RULE,
|
||||
} from "../common/rate-limit/rate-limit-rules.js";
|
||||
|
||||
function requestContext(req: Request) {
|
||||
return {
|
||||
@@ -22,6 +32,7 @@ function requestContext(req: Request) {
|
||||
|
||||
@ApiTags("auth")
|
||||
@Controller("v1/auth")
|
||||
@UseGuards(RateLimitGuard)
|
||||
export class AuthController {
|
||||
constructor(
|
||||
private readonly auth: AuthService,
|
||||
@@ -30,12 +41,14 @@ export class AuthController {
|
||||
|
||||
@Post("login")
|
||||
@HttpCode(200)
|
||||
@RateLimit(AUTH_LOGIN_RULE)
|
||||
async login(@Body() dto: LoginDto, @Req() req: Request) {
|
||||
return this.auth.login(dto.email, dto.password, dto.applicationKey, requestContext(req));
|
||||
}
|
||||
|
||||
@Post("mfa/challenge")
|
||||
@HttpCode(200)
|
||||
@RateLimit(AUTH_MFA_CHALLENGE_RULE)
|
||||
async mfaChallenge(@Body() dto: MfaChallengeDto, @Req() req: Request) {
|
||||
return this.auth.completeMfaLogin(dto.mfaChallenge, dto.code, requestContext(req));
|
||||
}
|
||||
@@ -65,6 +78,7 @@ export class AuthController {
|
||||
|
||||
@Post("forgot-password")
|
||||
@HttpCode(200)
|
||||
@RateLimit(AUTH_FORGOT_PASSWORD_RULE)
|
||||
async forgotPassword(@Body() dto: ForgotPasswordDto, @Req() req: Request) {
|
||||
await this.auth.forgotPassword(dto.email, requestContext(req));
|
||||
// Always the same response regardless of whether the email is
|
||||
@@ -74,18 +88,21 @@ export class AuthController {
|
||||
|
||||
@Post("reset-password")
|
||||
@HttpCode(204)
|
||||
@RateLimit(AUTH_RESET_PASSWORD_RULE)
|
||||
async resetPassword(@Body() dto: ResetPasswordDto, @Req() req: Request) {
|
||||
await this.auth.resetPassword(dto.token, dto.newPassword, requestContext(req));
|
||||
}
|
||||
|
||||
@Post("refresh")
|
||||
@HttpCode(200)
|
||||
@RateLimit(AUTH_REFRESH_RULE)
|
||||
async refresh(@Body() dto: RefreshDto, @Req() req: Request) {
|
||||
return this.auth.refresh(dto.refreshToken, requestContext(req));
|
||||
}
|
||||
|
||||
@Post("logout")
|
||||
@HttpCode(204)
|
||||
@RateLimit(AUTH_LOGOUT_RULE)
|
||||
async logout(@Body() dto: RefreshDto, @Req() req: Request) {
|
||||
await this.auth.logout(dto.refreshToken, requestContext(req));
|
||||
}
|
||||
|
||||
@@ -8,8 +8,10 @@ import { JwtAuthGuard } from "./jwt-auth.guard.js";
|
||||
import { PermissionGuard } from "./permission.guard.js";
|
||||
import { SuperAdminGuard } from "./super-admin.guard.js";
|
||||
import { FieldEncryptionService } from "../crypto/field-encryption.service.js";
|
||||
import { RateLimitModule } from "../common/rate-limit/rate-limit.module.js";
|
||||
|
||||
@Module({
|
||||
imports: [RateLimitModule],
|
||||
controllers: [AuthController],
|
||||
providers: [
|
||||
AuthService,
|
||||
|
||||
Reference in New Issue
Block a user