Skip to content

Autenticação e Autorização

Fluxo de autenticação OAuth e controle de acesso.


Fluxo OAuth

IMPORTANTE: A URL OAuth é construída no frontend, não no backend.

┌────────┐     ┌─────────┐     ┌──────────┐     ┌────────┐
│Frontend│     │ Backend │     │ Provider │     │Database│
└───┬────┘     └────┬────┘     └────┬─────┘     └───┬────┘
    │               │               │               │
    │ Frontend constrói URL OAuth   │               │
    │═══════════════════════════════►               │
    │      Popup abre Provider      │               │
    │               │               │               │
    │◄══════════════════════════════│               │
    │      Callback com code        │               │
    │               │               │               │
    │ POST /auth/social             │               │
    │   { provider, code }          │               │
    │──────────────►│               │               │
    │               │ Exchange code │               │
    │               │──────────────►│               │
    │               │◄─ Token ──────│               │
    │               │ Get profile   │               │
    │               │──────────────►│               │
    │               │◄─ Profile ────│               │
    │               │               │               │
    │               │ Upsert user   │               │
    │               │──────────────────────────────►│
    │               │◄──────────────────────────────│
    │               │               │               │
    │◄─ { user, token, companies,   │               │
    │     action, needsProfileCompletion }          │
    │               │               │               │

Endpoints de Autenticação

EndpointMétodoDescrição
/auth/socialPOSTAutentica com código OAuth
/auth/complete-profilePOSTCompleta dados do perfil
/auth/create-companyPOSTCria nova empresa
/auth/meGETDados do usuário autenticado
/auth/companiesGETLista empresas do usuário
/auth/logoutPOSTRealiza logout

Response do /auth/social

typescript
{
  user: User,
  token: string,
  companies: Company[],
  action: 'login' | 'register',
  needsProfileCompletion: boolean
}

JWT Payload

typescript
interface IJwtPayload {
  sub: string;           // User ID
  sid?: string;          // App device-session id (somente tokens do app mobile)
  email: string;
  name: string;
  iat: number;
  exp: number;
}

Guards

JwtAuthGuard

Valida token JWT em todas as rotas (aplicado globalmente). Quando o payload tem o claim sid (tokens do app mobile), o JwtStrategy também valida a sessão de dispositivo: se a linha em app_device_sessions não existe ou está revogada (revokedAt), recusa com 401 "Dispositivo desconectado". Tokens web não têm sid e seguem o fluxo normal. É o que permite ao painel desconectar um aparelho de verdade (revogação que invalida o token na próxima requisição). Endpoints e tabela em api/app-devices.md.

CompanyGuard

Valida o header x-company-id e verifica se o usuário tem acesso à empresa.

SigningJwtGuard

Guard separado do JwtAuthGuard, aplicado apenas em /signing/:token. Extrai o JWT da URL (não do header Authorization), valida:

  • Assinatura e expiração com authConfig.jwt.secret (HS256).
  • Claim type === "signing": recusa JWTs de outros tipos (login, reset, convite).
  • contract.status: recusa signing em contratos COMPLETED / FINISHED / OVERDUE / ACTIVE.

Injeta SigningContext { contractId, signerId } no request.signing, consumido via @GetSigningContext(). As rotas sob /signing/:token usam @Public() + @SkipCompany() para bypass dos guards padrão.


JWT Payload de assinatura

typescript
interface SigningTokenPayload {
  contractId: string;
  signerId: string;
  type: 'signing';
  iat: number;
  exp: number;
}

Decorators

DecoratorUso
@Public()Marca rota como pública (sem autenticação)
@SkipCompany()Pula validação de empresa
@CurrentUser()Extrai dados do usuário autenticado
@CurrentCompany()Extrai dados da empresa do contexto

Header x-company-id

Todas as rotas que requerem contexto de empresa devem enviar:

x-company-id: <uuid-da-empresa>

O guard valida:

  1. Presença do header
  2. Usuário tem acesso à empresa (borrower, provider ou user)

Documento atualizado em Janeiro 2026