ML Engine Updates: - Updated BTCUSD with Polygon API data (2024-2025): 215,699 new records - Re-trained all ML models: Attention (R²: 0.223), Base, Metamodel (87.3% confidence) - Backtest results: +176.71R profit with aggressive_filter strategy Documentation Consolidation: - Created docs/99-analisis/_MAP.md index with 13 new analysis documents - Consolidated inventories: removed duplicates from orchestration/inventarios/ - Updated ML_INVENTORY.yml with BTCUSD metrics and training results - Added execution reports: FASE11-BTCUSD, correction issues, alignment validation Architecture & Integration: - Updated all module documentation with NEXUS v3.4 frontmatter - Fixed _MAP.md indexes across all folders - Updated orchestration plans and traces Files: 229 changed, 5064 insertions(+), 1872 deletions(-) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
304 lines
11 KiB
Markdown
304 lines
11 KiB
Markdown
---
|
|
id: "RF-AUTH-001"
|
|
title: "OAuth Multi-proveedor"
|
|
type: "Requirement"
|
|
status: "Done"
|
|
priority: "Alta"
|
|
module: "auth"
|
|
epic: "OQI-001"
|
|
version: "1.0"
|
|
created_date: "2025-12-05"
|
|
updated_date: "2026-01-04"
|
|
---
|
|
|
|
# RF-AUTH-001: OAuth Multi-proveedor
|
|
|
|
**Version:** 1.0.0
|
|
**Fecha:** 2025-12-05
|
|
**Estado:** ✅ Implementado
|
|
**Prioridad:** P0 (Crítica)
|
|
**Épica:** [OQI-001](../_MAP.md)
|
|
|
|
---
|
|
|
|
## Descripción
|
|
|
|
El sistema debe permitir a los usuarios autenticarse mediante proveedores OAuth 2.0 externos, facilitando el registro y login sin necesidad de crear credenciales específicas para la plataforma.
|
|
|
|
---
|
|
|
|
## Objetivo de Negocio
|
|
|
|
- Reducir fricción en el registro (aumentar conversión)
|
|
- Mejorar seguridad delegando auth a proveedores confiables
|
|
- Obtener datos de perfil verificados automáticamente
|
|
|
|
---
|
|
|
|
## Proveedores Requeridos
|
|
|
|
| Proveedor | Prioridad | Mercado Objetivo |
|
|
|-----------|-----------|------------------|
|
|
| Google | P0 | Global, mayor adopción |
|
|
| Facebook | P0 | LATAM, social heavy |
|
|
| X/Twitter | P1 | Traders, crypto community |
|
|
| Apple | P1 | Usuarios iOS premium |
|
|
| GitHub | P2 | Desarrolladores, técnicos |
|
|
|
|
---
|
|
|
|
## Requisitos Funcionales
|
|
|
|
### RF-AUTH-001.1: Flujo OAuth Standard
|
|
|
|
**DEBE:**
|
|
1. Generar URL de autorización con parámetros correctos
|
|
2. Manejar callback con código de autorización
|
|
3. Intercambiar código por access/refresh tokens
|
|
4. Obtener información del perfil del usuario
|
|
5. Crear o vincular cuenta en el sistema
|
|
|
|
### RF-AUTH-001.2: Vinculación de Cuentas
|
|
|
|
**DEBE:**
|
|
1. Permitir vincular múltiples proveedores a una cuenta
|
|
2. Detectar si el email ya existe en el sistema
|
|
3. Ofrecer vincular cuentas con mismo email
|
|
4. Mantener al menos un método de autenticación activo
|
|
|
|
### RF-AUTH-001.3: Desvinculación
|
|
|
|
**DEBE:**
|
|
1. Permitir desvincular proveedores OAuth
|
|
2. Requerir al menos un método de auth activo
|
|
3. Confirmar acción antes de desvincular
|
|
|
|
---
|
|
|
|
## Datos Requeridos por Proveedor
|
|
|
|
| Campo | Google | Facebook | X/Twitter | Apple | GitHub |
|
|
|-------|--------|----------|-----------|-------|--------|
|
|
| provider_user_id | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
| email | ✅ | ✅ | ❌* | ✅ | ✅ |
|
|
| name | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
| picture | ✅ | ✅ | ✅ | ❌ | ✅ |
|
|
| verified_email | ✅ | ✅ | ❌ | ✅ | ✅ |
|
|
|
|
*X/Twitter requiere scope adicional para email
|
|
|
|
---
|
|
|
|
## Scopes Requeridos
|
|
|
|
```yaml
|
|
google:
|
|
- profile
|
|
- email
|
|
|
|
facebook:
|
|
- email
|
|
- public_profile
|
|
|
|
twitter:
|
|
- tweet.read
|
|
- users.read
|
|
- offline.access
|
|
|
|
apple:
|
|
- name
|
|
- email
|
|
|
|
github:
|
|
- read:user
|
|
- user:email
|
|
```
|
|
|
|
---
|
|
|
|
## Flujo de Autorización
|
|
|
|
```
|
|
┌────────────┐ ┌────────────┐ ┌────────────┐ ┌────────────┐
|
|
│ Usuario │ │ Frontend │ │ Backend │ │ Provider │
|
|
└─────┬──────┘ └─────┬──────┘ └─────┬──────┘ └─────┬──────┘
|
|
│ │ │ │
|
|
│ Click "Login │ │ │
|
|
│ with Google" │ │ │
|
|
│─────────────────▶│ │ │
|
|
│ │ │ │
|
|
│ │ GET /auth/oauth/ │ │
|
|
│ │ google/url │ │
|
|
│ │─────────────────▶│ │
|
|
│ │ │ │
|
|
│ │ │ Generate │
|
|
│ │ │ state, nonce │
|
|
│ │ │ │
|
|
│ │◀─────────────────│ │
|
|
│ │ { auth_url } │ │
|
|
│ │ │ │
|
|
│◀─────────────────│ │ │
|
|
│ Redirect to │ │ │
|
|
│ auth_url │ │ │
|
|
│ │ │ │
|
|
│─────────────────────────────────────────────────────▶│
|
|
│ │ │ User authorizes │
|
|
│ │ │ │
|
|
│◀─────────────────────────────────────────────────────│
|
|
│ Redirect to │ │ code, state │
|
|
│ callback │ │ │
|
|
│ │ │ │
|
|
│─────────────────▶│ │ │
|
|
│ /callback?code= │ │ │
|
|
│ │ │ │
|
|
│ │ POST /auth/oauth/│ │
|
|
│ │ google │ │
|
|
│ │ { code, state } │ │
|
|
│ │─────────────────▶│ │
|
|
│ │ │ │
|
|
│ │ │─────────────────▶│
|
|
│ │ │ Exchange code │
|
|
│ │ │ for tokens │
|
|
│ │ │ │
|
|
│ │ │◀─────────────────│
|
|
│ │ │ access_token, │
|
|
│ │ │ user_info │
|
|
│ │ │ │
|
|
│ │ │ Find/Create user │
|
|
│ │ │ Generate JWT │
|
|
│ │ │ │
|
|
│ │◀─────────────────│ │
|
|
│ │ { access_token, │ │
|
|
│ │ refresh_token, │ │
|
|
│ │ user } │ │
|
|
│ │ │ │
|
|
│◀─────────────────│ │ │
|
|
│ Login success │ │ │
|
|
│ │ │ │
|
|
```
|
|
|
|
---
|
|
|
|
## Reglas de Negocio
|
|
|
|
### RN-001: Email Existente
|
|
|
|
Si el email del proveedor OAuth ya existe en el sistema:
|
|
1. Si el usuario está logueado → Vincular proveedor a cuenta existente
|
|
2. Si no está logueado → Crear sesión con cuenta existente
|
|
3. Registrar el nuevo proveedor OAuth en la cuenta
|
|
|
|
### RN-002: Cuenta Nueva
|
|
|
|
Si el email no existe:
|
|
1. Crear nuevo usuario con datos del proveedor
|
|
2. Marcar email como verificado (confiamos en el proveedor)
|
|
3. Asignar rol por defecto (`investor`)
|
|
4. Generar tokens JWT
|
|
|
|
### RN-003: Sin Email
|
|
|
|
Si el proveedor no proporciona email (X/Twitter sin scope):
|
|
1. Permitir registro/login
|
|
2. Solicitar email posteriormente para funciones críticas
|
|
3. Marcar cuenta como `email_required`
|
|
|
|
---
|
|
|
|
## Manejo de Errores
|
|
|
|
| Error | Código | Mensaje Usuario |
|
|
|-------|--------|-----------------|
|
|
| Invalid state | 400 | Sesión expirada, intenta de nuevo |
|
|
| Code expired | 400 | Autorización expirada, intenta de nuevo |
|
|
| Provider error | 502 | Error con {provider}, intenta más tarde |
|
|
| Account suspended | 403 | Cuenta suspendida en {provider} |
|
|
| Email conflict | 409 | Este email ya está registrado |
|
|
|
|
---
|
|
|
|
## Seguridad
|
|
|
|
### Tokens del Proveedor
|
|
|
|
- Encriptar access_token y refresh_token en DB
|
|
- No exponer tokens del proveedor al frontend
|
|
- Usar tokens solo para refresh de datos si es necesario
|
|
|
|
### State Parameter
|
|
|
|
- Generar state único por solicitud
|
|
- Almacenar en Redis con TTL de 10 minutos
|
|
- Validar state en callback
|
|
- Invalidar state después de uso
|
|
|
|
### PKCE (Proof Key for Code Exchange)
|
|
|
|
Implementar PKCE para proveedores que lo soporten:
|
|
- Google ✅
|
|
- Apple ✅
|
|
- GitHub (no requerido)
|
|
- Facebook (no requerido)
|
|
- X/Twitter (OAuth 2.0 con PKCE) ✅
|
|
|
|
---
|
|
|
|
## Configuración Requerida
|
|
|
|
```env
|
|
# Google OAuth
|
|
GOOGLE_CLIENT_ID=xxx.apps.googleusercontent.com
|
|
GOOGLE_CLIENT_SECRET=xxx
|
|
|
|
# Facebook OAuth
|
|
FACEBOOK_APP_ID=xxx
|
|
FACEBOOK_APP_SECRET=xxx
|
|
|
|
# X/Twitter OAuth
|
|
TWITTER_CLIENT_ID=xxx
|
|
TWITTER_CLIENT_SECRET=xxx
|
|
|
|
# Apple OAuth
|
|
APPLE_CLIENT_ID=com.trading.auth
|
|
APPLE_TEAM_ID=xxx
|
|
APPLE_KEY_ID=xxx
|
|
APPLE_PRIVATE_KEY=xxx
|
|
|
|
# GitHub OAuth
|
|
GITHUB_CLIENT_ID=xxx
|
|
GITHUB_CLIENT_SECRET=xxx
|
|
|
|
# Callback URLs
|
|
OAUTH_CALLBACK_URL=https://api.trading.com/auth/oauth/callback
|
|
FRONTEND_URL=https://app.trading.com
|
|
```
|
|
|
|
---
|
|
|
|
## Criterios de Aceptación
|
|
|
|
- [ ] Usuario puede iniciar sesión con Google
|
|
- [ ] Usuario puede iniciar sesión con Facebook
|
|
- [ ] Usuario puede iniciar sesión con X/Twitter
|
|
- [ ] Usuario puede iniciar sesión con Apple
|
|
- [ ] Usuario puede iniciar sesión con GitHub
|
|
- [ ] Usuario puede vincular múltiples proveedores
|
|
- [ ] Usuario puede desvincular proveedores (con restricción)
|
|
- [ ] Emails existentes se detectan correctamente
|
|
- [ ] State parameter se valida correctamente
|
|
- [ ] Tokens del proveedor se almacenan encriptados
|
|
|
|
---
|
|
|
|
## Especificación Técnica Relacionada
|
|
|
|
- [ET-AUTH-001: OAuth Providers](../especificaciones/ET-AUTH-001-oauth.md)
|
|
|
|
## Historias de Usuario Relacionadas
|
|
|
|
- [US-AUTH-003: Login con Google](../historias-usuario/US-AUTH-003-oauth-google.md)
|
|
- [US-AUTH-004: Login con Facebook](../historias-usuario/US-AUTH-004-oauth-facebook.md)
|
|
- [US-AUTH-005: Login con X/Twitter](../historias-usuario/US-AUTH-005-oauth-twitter.md)
|
|
- [US-AUTH-006: Login con Apple](../historias-usuario/US-AUTH-006-oauth-apple.md)
|
|
- [US-AUTH-007: Login con GitHub](../historias-usuario/US-AUTH-007-oauth-github.md)
|