Skip to content

Uma API de comunicação com um Chat em tempo real usando um sistema WebSocket de baixa latencia e alta disponibilidade

Notifications You must be signed in to change notification settings

EdnaldoLuiz/devchat-api

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

DevChat-Api

🗺️ Diagramas

🔒🔑 Arquitetura de Autenticação de Usuários

Este diagrama mostra, de forma clara e enxuta, todo o fluxo de autenticação do sistema:

  • Registro de novos usuários com senha criptografada
  • Login por credenciais e via OAuth2 (GitHub/Google)
  • Recuperação de senha (esqueci senha + redefinição) sem expor existência de conta
  • Logout via blacklist de token
  • Acesso a rotas protegidas validando JWT e blacklist
--- config: theme: redux-dark-color --- sequenceDiagram autonumber participant FE as Front-end participant API as REST API participant DB as MySQL participant REDIS as Redis (Blacklist) participant SES as Serviço de Email participant OAUTH as OAuth2 Provider %% 1) REGISTRO rect rgba(0, 0, 255, 0.1) FE->>API: POST /auth/register {email, senha, confirmação, nome, termos} API->>DB: cria usuário com senha criptografada DB-->>API: usuário criado (id) API-->API: gera JWT + Refresh API-->>FE: 201 Created {access, refresh} end %% 2) LOGIN POR CREDENCIAIS rect rgba(0, 128, 0, 0.1) FE->>API: POST /auth/login {email, senha} API->>DB: busca usuário por email e compare hash alt credenciais válidas API-->API: gera JWT + Refresh API-->>FE: 200 OK {access, refresh} else inválido API-->>FE: 401 Unauthorized {"Email ou senha inválidos"} end end %% 3) LOGIN VIA OAUTH2 rect rgba(0, 128, 128, 0.1) FE->>OAUTH: redirect para login externo OAUTH-->>FE: Callback OAuth2 com ccódigo FE->>API: GET /auth/oauth2/success?code=… API-->API: troca código por userInfo API->>DB: busca ou cria usuário via provider API-->API: gera JWT API-->>FE: 200 OK {access} end %% 4) ESQUECI SENHA → RESET rect rgba(255, 165, 0, 0.1) FE->>API: POST /auth/forgot-password?email=… API->>DB: tenta buscar usuário por email alt email cadastrado API-->API: cria token (UUID + hash) e persiste API-->API: monta link de reset API->>SES: envia email com link else não cadastrado Note right of API: ignora e retorna mesma resposta end API-->>FE: 200 OK {"Confira seu email para instruções"} end rect rgba(255, 140, 0, 0.1) FE->>API: POST /auth/reset-password {key, token, novaSenha} API->>DB: busca token de reset por key alt token válido e não expirado API-->API: atualiza senha (hash) e marca token usado API-->>FE: 200 OK {"Senha redefinida com sucesso"} else inválido ou expirado API-->>FE: 400 Bad Request {"Token inválido ou expirado"} end end %% 5) LOGOUT rect rgba(220, 20, 60, 0.1) FE->>API: POST /auth/logout (Bearer JWT) API-->API: extrai jti + exp do token API->>REDIS: adiciona jti na blacklist até expirar REDIS-->>API: OK API-->>FE: 200 OK {"Logout realizado"} end %% 6) ACESSO A RECURSOS PROTEGIDOS rect rgba(128, 0, 128, 0.1) FE->>API: GET /api/recurso (Bearer JWT) API-->API: JwtAuthFilter intercepta API->>REDIS: verifica se jti está blacklist alt token válido e não blacklist API-->>FE: 200 OK {dados…} else inválido ou blacklist API-->>FE: 401 Unauthorized {"Token inválido ou expirado"} end end 
Loading

🔒🔑 Arquitetura E2EE (Signal)

Este diagrama ilustra o fluxo completo de comunicação fim-a-fim criptografada implementado na nossa API usando o protocolo Signal:

  • Mostra como o cliente gera e publica chaves na primeira inicialização (ou quando o storage local é perdido).
  • Descreve o handshake de sessão entre usuários, com fetch seguro de bundles.
  • Explica o envio de mensagens cifradas via WebSocket, totalmente opacas ao servidor.
  • Detalha como o backend monitora pre-keys e signedPreKeys, enviando alertas automáticos para reposição ou rotação.
  • Representa a segurança baseada em IndexedDB local com trust-on-first-use.

--- config: theme: redux-dark-color --- sequenceDiagram autonumber participant FE_A as Frontend A participant SC_A as SignalClient A participant WS as WebSocket Broker participant API as REST API participant FE_B as Frontend B participant SC_B as SignalClient B rect rgba(0, 0, 255, 0.1) FE_A->>SC_A: bootstrap() alt Primeiro login OU IndexedDB limpo/perdido SC_A->>API: POST /signal/keys/save API-->>SC_A: 201 Created else Já tem chaves locais SC_A-->SC_A: Load keys from IndexedDB end end rect rgba(0, 100, 0, 0.1) FE_A->>SC_A: ensureSession(B) SC_A->>API: GET /signal/keys/fetch/{B} API-->>SC_A: {identity_B, SPK_B, PK₁} SC_A-->SC_A: SessionBuilder.processPreKey() end rect rgba(128, 0, 128, 0.1) FE_A->>SC_A: encrypt("Olá") SC_A->>WS: SEND /chat (ciphertext, type=WHISPER) WS->>FE_B: MESSAGE (ciphertext) FE_B->>SC_B: decrypt() SC_B-->FE_B: "Olá" end rect rgba(255, 165, 0, 0.1) Note over API: Monitor de PreKeys API->>WS: toUser(B) {type: LOW_PREKEY, remaining:18} WS->>FE_B: evento LOW_PREKEY FE_B->>SC_B: replenishBundle() (+100 PK) SC_B->>API: POST /signal/keys/save (novos PKs) API-->>SC_B: 201 Created end rect rgba(220, 20, 60, 0.1) Note over API: Scheduler detecta SPK expirada API->>WS: toUser(B) {type: SPK_EXPIRED} WS->>FE_B: evento SPK_EXPIRED FE_B->>SC_B: rotateSignedPreKey() SC_B->>API: POST /signal/keys/rotate-spk (nova SPK₁) API-->>SC_B: 200 OK end Note over FE_A,FE_B: 🛡️ Próxima mensagem usa SPK₁ de B 
Loading

🖥️ Tech Stack

👨‍💻 Technologies

MySQL Hibernate Spring Boot Java Redis JWT WebSocket
🔖 8.1.0 🔖 6.3 🔖 3.3.2 🔖 17 🔖 7.4.2 🔖 0.12.6 🔖 3.4.2

🛠️ Development Tools

IntelliJ IDEA DataGrip Postman Docker Maven GitHub Actions
🔖 2024.3.2 🔖 2024.3 🔖 11.32.1 🔖 27.5.1 🔖 3.9.6 🔖 -

☁️ Cloud Services

AWS S3 AWS SES AWS CloudWatch

🧪 Testing & QA

Swagger Cucumber JUnit ArchUnit TestContainers
🔖 2.8.5 🔖 7.21.1 🔖 5 🔖 1.4.0 🔖 1.20.4

About

Uma API de comunicação com um Chat em tempo real usando um sistema WebSocket de baixa latencia e alta disponibilidade

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published