feat(club-004): club recovery: recovery codes and device reassignment
This commit is contained in:
34
work/artifacts/CLUB-004/architect.md
Normal file
34
work/artifacts/CLUB-004/architect.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Architect — CLUB-004
|
||||
|
||||
## Objetivo
|
||||
Permitir que un socio anónimo recupere su membresía en un dispositivo nuevo usando códigos de recuperación.
|
||||
|
||||
## Diseño
|
||||
|
||||
### Flujo
|
||||
1. **Alta**: al unirse al Club se generan 3 códigos (mostrados una sola vez).
|
||||
2. **Generar más**: `POST /club/recovery-codes/generate` (autenticado con device token o cuenta).
|
||||
3. **Listar**: `GET /club/recovery-codes` devuelve códigos activos (fingerprints, nunca plaintext).
|
||||
4. **Recuperar**: `POST /club/recover` acepta `{ code, newDeviceToken }` → consume código + vincula nuevo dispositivo.
|
||||
|
||||
### Formato de código
|
||||
`XXXX-XXXX-XXXX-XXXX-XXXX-XXXX` (6 grupos de 4 chars alfanuméricos, sin I,O,0,1 para legibilidad).
|
||||
~44 bits de entropía (~10⁹⁶ combinaciones).
|
||||
|
||||
### Almacenamiento
|
||||
- `code_hash = SHA-256(plaintext)` — para verificación
|
||||
- `code_fingerprint = SHA-256(UPPER(plaintext))[0:16]` — para lookups rápidos y dedup
|
||||
- `expires_at = now() + 30 días`
|
||||
- `used_at = NULL` initially
|
||||
|
||||
### Seguridad
|
||||
- Código hasheado, nunca se guarda plaintext
|
||||
- `FOR UPDATE` en la misma transacción para evitar race conditions
|
||||
- Valida que no esté usado ni caducado antes de vincular
|
||||
|
||||
### Endpoints nuevos
|
||||
| Método | Ruta | Auth | Descripción |
|
||||
|--------|------|------|-------------|
|
||||
| POST | `/club/recovery-codes/generate` | device token o sesión | Generar códigos |
|
||||
| GET | `/club/recovery-codes` | device token o sesión | Listar códigos activos |
|
||||
| POST | `/club/recover` | ninguno (código + token) | Recuperar con código |
|
||||
Reference in New Issue
Block a user