--- id: "README" title: "Fundamentos y Autenticación" type: "Documentation" project: "trading-platform" version: "1.0.0" updated_date: "2026-01-04" --- # OQI-001: Fundamentos y Autenticación ## Resumen Ejecutivo La épica OQI-001 establece los fundamentos técnicos del proyecto Trading Platform, incluyendo un sistema de autenticación robusto y flexible que soporta múltiples métodos de acceso para maximizar la conversión de usuarios. --- ## Objetivo Implementar un sistema de autenticación multi-proveedor que permita a los usuarios: 1. Registrarse e iniciar sesión de la forma más conveniente 2. Mantener sus cuentas seguras con 2FA 3. Vincular múltiples métodos de autenticación a una sola cuenta --- ## Alcance ### Incluido | Feature | Descripción | |---------|-------------| | OAuth 2.0 | Google, Facebook, X, Apple, GitHub | | Email/Password | Registro tradicional con verificación | | Phone Auth | SMS y WhatsApp OTP via Twilio | | 2FA | TOTP (Google Authenticator) + backup codes | | JWT | Access tokens (15min) + refresh tokens (7d) | | Sessions | Gestión de dispositivos y sesiones | | RBAC | Roles: investor, trader, student, admin | ### Excluido | Feature | Razón | Fase | |---------|-------|------| | SSO Enterprise | Complejidad | Q3 2025 | | Biometrics | Requiere mobile | Q2 2025 | | Hardware Keys | Nicho pequeño | Backlog | --- ## Arquitectura ``` ┌─────────────────────────────────────────────────────────────────┐ │ FRONTEND │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │ Login │ │ Register │ │ Callback │ │ │ │ Page │ │ Page │ │ Page │ │ │ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │ └─────────┼────────────────┼────────────────┼─────────────────────┘ │ │ │ └────────────────┼────────────────┘ │ HTTPS ▼ ┌─────────────────────────────────────────────────────────────────┐ │ BACKEND API │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ AUTH CONTROLLER │ │ │ │ POST /auth/register POST /auth/login │ │ │ │ POST /auth/oauth/:provider POST /auth/phone/send │ │ │ │ POST /auth/2fa/setup POST /auth/refresh │ │ │ └─────────────────────────────────────────────────────────┘ │ │ │ │ │ ┌───────────┐ ┌───────────┐ ┌───────────┐ ┌───────────┐ │ │ │ OAuth │ │ Token │ │ Phone │ │ 2FA │ │ │ │ Service │ │ Service │ │ Service │ │ Service │ │ │ └─────┬─────┘ └─────┬─────┘ └─────┬─────┘ └─────┬─────┘ │ └────────┼──────────────┼──────────────┼──────────────┼───────────┘ │ │ │ │ ▼ ▼ ▼ ▼ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ OAuth │ │ PostgreSQL │ │ Twilio │ │ Redis │ │ Providers │ │ (users) │ │ SMS/WA │ │ (sessions) │ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ ``` --- ## Flujos Principales ### 1. Registro con Email ``` Usuario Frontend Backend DB │ │ │ │ │─── Completa form ───────▶│ │ │ │ │─── POST /auth/register ─▶│ │ │ │ │─── INSERT user ───────▶│ │ │ │◀── user_id ────────────│ │ │ │─── Send email ─────────│ │ │◀── 201 + message ────────│ │ │◀── "Verifica email" ─────│ │ │ │ │ │ │ │─── Click link email ────────────────────────────────▶ │ │ │ │─── UPDATE verified ───▶│ │◀── Redirect to login ───────────────────────────────│ │ ``` ### 2. Login OAuth (Google) ``` Usuario Frontend Backend Google │ │ │ │ │─── Click "Google" ──────▶│ │ │ │ │─── GET /auth/oauth/google/url ─▶│ │ │ │◀── auth_url ─────────────│ │ │◀── Redirect to Google ───│ │ │ │ │ │ │ │─── Autoriza en Google ──────────────────────────────────────────────────────▶│ │◀── Redirect con code ───────────────────────────────────────────────────────│ │ │ │ │ │─── /callback?code=xxx ──▶│ │ │ │ │─── POST /auth/oauth/google ─▶│ │ │ │ │─── Exchange code ─────▶│ │ │ │◀── user_info ─────────│ │ │ │─── Find/Create user ──│ │ │◀── JWT tokens ───────────│ │ │◀── Logged in ────────────│ │ │ ``` ### 3. Login con 2FA ``` Usuario Frontend Backend Redis │ │ │ │ │─── Login email/pass ────▶│ │ │ │ │─── POST /auth/login ────▶│ │ │ │◀── 200 + requires_2fa ───│ │ │◀── Show 2FA input ───────│ │ │ │ │ │ │ │─── Ingresa código ──────▶│ │ │ │ │─── POST /auth/2fa/verify ▶│ │ │ │ │─── Validate TOTP ─────▶│ │ │◀── JWT tokens ───────────│ │ │◀── Logged in ────────────│ │ │ ``` --- ## Modelo de Datos ### Tablas Principales ```sql -- Usuarios CREATE TABLE users ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), email VARCHAR(255) UNIQUE, password_hash VARCHAR(255), phone VARCHAR(20) UNIQUE, first_name VARCHAR(100), last_name VARCHAR(100), role user_role_enum DEFAULT 'investor', status user_status_enum DEFAULT 'pending_verification', email_verified BOOLEAN DEFAULT FALSE, phone_verified BOOLEAN DEFAULT FALSE, two_factor_enabled BOOLEAN DEFAULT FALSE, two_factor_secret VARCHAR(255), created_at TIMESTAMPTZ DEFAULT NOW(), updated_at TIMESTAMPTZ DEFAULT NOW() ); -- Cuentas OAuth vinculadas CREATE TABLE oauth_accounts ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), user_id UUID REFERENCES users(id), provider auth_provider_enum NOT NULL, provider_user_id VARCHAR(255) NOT NULL, email VARCHAR(255), access_token TEXT, refresh_token TEXT, expires_at TIMESTAMPTZ, UNIQUE(provider, provider_user_id) ); -- Sesiones activas CREATE TABLE sessions ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), user_id UUID REFERENCES users(id), token_hash VARCHAR(255) NOT NULL, device_info JSONB, ip_address INET, expires_at TIMESTAMPTZ NOT NULL, last_activity TIMESTAMPTZ DEFAULT NOW(), is_active BOOLEAN DEFAULT TRUE ); ``` --- ## API Endpoints ### Autenticación Base | Method | Endpoint | Descripción | |--------|----------|-------------| | POST | `/auth/register` | Registro con email | | POST | `/auth/login` | Login con email/password | | POST | `/auth/logout` | Cerrar sesión | | POST | `/auth/refresh` | Renovar access token | | GET | `/auth/me` | Usuario actual | ### OAuth | Method | Endpoint | Descripción | |--------|----------|-------------| | GET | `/auth/oauth/:provider/url` | Obtener URL de autorización | | POST | `/auth/oauth/:provider` | Intercambiar código por tokens | | DELETE | `/auth/oauth/:provider` | Desvincular proveedor | ### Teléfono | Method | Endpoint | Descripción | |--------|----------|-------------| | POST | `/auth/phone/send` | Enviar OTP (SMS/WhatsApp) | | POST | `/auth/phone/verify` | Verificar OTP | ### 2FA | Method | Endpoint | Descripción | |--------|----------|-------------| | POST | `/auth/2fa/setup` | Generar secreto TOTP | | POST | `/auth/2fa/enable` | Activar 2FA | | POST | `/auth/2fa/verify` | Verificar código 2FA | | POST | `/auth/2fa/disable` | Desactivar 2FA | | GET | `/auth/2fa/backup-codes` | Obtener backup codes | ### Recuperación | Method | Endpoint | Descripción | |--------|----------|-------------| | POST | `/auth/forgot-password` | Solicitar reset | | POST | `/auth/reset-password` | Cambiar contraseña | | POST | `/auth/verify-email` | Verificar email | | POST | `/auth/resend-verification` | Reenviar verificación | --- ## Seguridad ### Rate Limiting | Endpoint | Límite | Ventana | |----------|--------|---------| | `/auth/login` | 5 | 15 min | | `/auth/register` | 3 | 1 hora | | `/auth/phone/send` | 3 | 15 min | | `/auth/forgot-password` | 3 | 1 hora | | General API | 100 | 1 min | ### Tokens JWT ```typescript // Access Token (15 min) { "sub": "user_uuid", "email": "user@example.com", "role": "investor", "iat": 1701792000, "exp": 1701792900 } // Refresh Token (7 días) { "sub": "user_uuid", "type": "refresh", "jti": "unique_token_id", "iat": 1701792000, "exp": 1702396800 } ``` ### Password Policy - Mínimo 8 caracteres - Al menos 1 mayúscula - Al menos 1 número - Al menos 1 carácter especial - No puede ser igual al email --- ## Entregables | Entregable | Ruta | Estado | |------------|------|--------| | Schema DB | `apps/database/schemas/01_public_schema.sql` | ✅ | | Schema OAuth | `apps/database/schemas/01b_oauth_providers.sql` | ✅ | | Token Service | `apps/backend/src/modules/auth/services/token.service.ts` | ✅ | | OAuth Service | `apps/backend/src/modules/auth/services/oauth.service.ts` | ✅ | | Phone Service | `apps/backend/src/modules/auth/services/phone.service.ts` | ✅ | | 2FA Service | `apps/backend/src/modules/auth/services/twofa.service.ts` | ✅ | | Auth Controller | `apps/backend/src/modules/auth/controllers/auth.controller.ts` | ✅ | | Auth Routes | `apps/backend/src/modules/auth/auth.routes.ts` | ✅ | | Login Page | `apps/frontend/src/modules/auth/pages/Login.tsx` | ✅ | | Register Page | `apps/frontend/src/modules/auth/pages/Register.tsx` | ✅ | | OAuth Callback | `apps/frontend/src/modules/auth/pages/AuthCallback.tsx` | ✅ | --- ## Referencias - [_MAP de la Épica](./_MAP.md) - [Requerimientos](./requerimientos/) - [Especificaciones](./especificaciones/) - [Historias de Usuario](./historias-usuario/)