password_reset_tokens
Tokens single-use de recuperação de senha por e-mail.
Tabela auxiliar do fluxo de recuperação de senha. Um row é inserido em POST /auth/forgot-password (apenas se o e-mail existir) e consumido em POST /auth/reset-password. Após uso, o row não é deletado — used_at é setado, preservando o registro pra auditoria.
Igual ao refresh_tokens, guarda apenas sha256(rawToken). O token raw vai apenas no e-mail enviado ao usuário.
Colunas
| Coluna | Tipo | Nullable | Default |
|---|---|---|---|
| id ● | uuid | NOT NULL | gen_random_uuid() |
| user_id | uuid | NOT NULL | — |
| token_hash | varchar | NOT NULL | — |
| expires_at | timestamp | NOT NULL | — |
| used_at | timestamp | NULL ok | — |
● primary key ◆ unique
Funcionalidade dos campos
id— UUID, PK. Não usado em URLs; apenas referência interna.user_id— FK prausers.idcomON DELETE CASCADE. Apagar conta apaga tokens.token_hash— sha256 hex do raw token (32 bytes). Lookup direto.expires_at—now() + 1 horano momento do insert. Tokens expirados são rejeitados em/auth/reset-password.used_at—NULLenquanto não consumido;now()após reset bem-sucedido. Single-use enforcement:WHERE used_at IS NULLno momento da validação.
Foreign keys
| Coluna(s) | Referência | ON DELETE | ON UPDATE |
|---|---|---|---|
| user_id | users.id | cascade | no action |
Índices
Esta tabela não tem índices customizados.
Não há índice secundário em token_hash. Como tokens válidos por usuário são poucos (TTL 1h, single-use), full scan é barato.
Constraints
PRIMARY KEY (id)
Limpeza
Não há job de limpeza implementado. Tokens expirados/usados ficam até a conta ser deletada (cascade).
Volume baixo: usuário típico chama /forgot-password raramente. Se a tabela crescer (ex: spam de forgot-password), considerar adicionar:
- Cron
DELETE FROM password_reset_tokens WHERE expires_at < now() - INTERVAL '7 days' - Rate limiting em
/auth/forgot-passwordpor e-mail
Padrões de uso
- Insert —
POST /auth/forgot-password(se user existe) - Update
used_at—POST /auth/reset-password(quando consumido) - Delete por user_id — apenas via cascade (delete user)
Tabelas relacionadas
users— pai (cascade)refresh_tokens— tabela irmã com semântica parecida