- packages/database: schema Prisma (users/sessions/roles/permissions/
user_roles/role_permissions/audit_logs/password_reset_tokens), migration
inicial e seed (permissoes+perfis+bootstrap super_admin com senha
aleatoria em FIRST_LOGIN.txt). Decisao de ORM (Prisma) documentada em
docs/ARCHITECTURE.md
- packages/shared: catalogo de permissoes (fonte unica usada por seed e API)
- apps/api: NestJS 11 + Fastify
- autenticacao: Argon2id, access JWT + refresh token opaco com rotacao,
cookies HttpOnly/SameSite=Lax, change/forgot/reset password
- rate limiting progressivo de login via Redis (bloqueio crescente por IP)
- RBAC reforcado no backend (PermissionsGuard), protecao contra
auto-elevacao de privilegio
- auditoria (audit_logs) nas acoes sensiveis, com redacao de segredos
- health checks reais (postgres+redis), swagger desabilitavel, logs
estruturados JSON com request_id de correlacao, filtro global de
excecoes sem vazar erro cru
- infrastructure/docker/api.Dockerfile: build multi-stage do monorepo pnpm
- docker-compose.yml: servico api na rede interna, sem porta publicada
Testado via containers reais: login, /me, refresh, change-password,
rate limit (7 tentativas -> 429), RBAC (nega/permite), bloqueio de
auto-elevacao (403), audit log populado, health checks, lint e testes
unitarios passando.
66 lines
2.4 KiB
TypeScript
66 lines
2.4 KiB
TypeScript
import type { IncomingMessage } from 'node:http';
|
|
import { Module } from '@nestjs/common';
|
|
import { ConfigModule } from '@nestjs/config';
|
|
import { APP_FILTER, APP_GUARD } from '@nestjs/core';
|
|
import { ThrottlerModule, ThrottlerGuard } from '@nestjs/throttler';
|
|
import { LoggerModule } from 'nestjs-pino';
|
|
import { AppController } from './app.controller';
|
|
import { AppService } from './app.service';
|
|
import { PrismaModule } from './prisma/prisma.module';
|
|
import { RedisModule } from './redis/redis.module';
|
|
import { AuditModule } from './audit/audit.module';
|
|
import { AuthModule } from './auth/auth.module';
|
|
import { UsersModule } from './users/users.module';
|
|
import { RolesModule } from './roles/roles.module';
|
|
import { HealthModule } from './health/health.module';
|
|
import { AuthGuard } from './common/guards/auth.guard';
|
|
import { PermissionsGuard } from './common/guards/permissions.guard';
|
|
import { GlobalExceptionFilter } from './common/filters/global-exception.filter';
|
|
|
|
@Module({
|
|
imports: [
|
|
ConfigModule.forRoot({ isGlobal: true }),
|
|
// Logs estruturados JSON com request_id de correlação (agente.md seções
|
|
// 60/61). Nunca loga segredos: senha, tokens, credenciais AMI/ARI/SIP.
|
|
LoggerModule.forRoot({
|
|
pinoHttp: {
|
|
genReqId: (req) => req.id,
|
|
redact: {
|
|
paths: [
|
|
'req.headers.authorization',
|
|
'req.headers.cookie',
|
|
'req.body.password',
|
|
'req.body.currentPassword',
|
|
'req.body.newPassword',
|
|
'res.headers["set-cookie"]',
|
|
],
|
|
censor: '[REDACTED]',
|
|
},
|
|
customProps: (req: IncomingMessage & { id: string }) => ({
|
|
service: 'b2bcall-api',
|
|
requestId: req.id,
|
|
}),
|
|
},
|
|
}),
|
|
// Rate limit global genérico (proteção geral contra abuso). O login tem
|
|
// sua própria proteção progressiva mais rígida (LoginThrottleService).
|
|
ThrottlerModule.forRoot([{ ttl: 60_000, limit: 120 }]),
|
|
PrismaModule,
|
|
RedisModule,
|
|
AuditModule,
|
|
AuthModule,
|
|
UsersModule,
|
|
RolesModule,
|
|
HealthModule,
|
|
],
|
|
controllers: [AppController],
|
|
providers: [
|
|
AppService,
|
|
{ provide: APP_GUARD, useClass: ThrottlerGuard },
|
|
{ provide: APP_GUARD, useClass: AuthGuard },
|
|
{ provide: APP_GUARD, useClass: PermissionsGuard },
|
|
{ provide: APP_FILTER, useClass: GlobalExceptionFilter },
|
|
],
|
|
})
|
|
export class AppModule {}
|