# US-AUTH-006: OAuth Apple Sign In

**Version:** 1.0.0
**Fecha:** 2025-12-05
**Estado:** Pendiente
**Story Points:** 3
**Prioridad:** P1 (Alta)
**Épica:** [OQI-001](../_MAP.md)

---

## Historia de Usuario

**Como** visitante o usuario de OrbiQuant
**Quiero** poder registrarme e iniciar sesión usando Apple Sign In
**Para** tener un acceso seguro y privado sin compartir mi email real

---

## Criterios de Aceptación

### AC-001: Botón de Apple visible

**Dado** que estoy en la página de registro o login
**Cuando** veo las opciones de autenticación
**Entonces** debería ver un botón "Continuar con Apple"
**Y** debería seguir las guías de diseño de Apple (botón negro con logo)

### AC-002: Flujo de OAuth

**Dado** que hago click en "Continuar con Apple"
**Cuando** se abre la ventana de Apple
**Entonces** debería:
1. Ver la pantalla de autorización de Apple
2. Poder elegir compartir mi email real o ocultarlo
3. Poder usar Touch ID / Face ID si está disponible
4. Poder autorizar con mi Apple ID

### AC-003: Opción de ocultar email

**Dado** que estoy en la pantalla de Apple Sign In
**Cuando** elijo ocultar mi email
**Entonces** Apple debería generar un email relay privado
**Y** ese email debería funcionar para comunicaciones

### AC-004: Primer registro exitoso

**Dado** que es mi primera vez usando Apple Sign In
**Cuando** autorizo los permisos
**Entonces** debería:
1. Crear mi cuenta automáticamente
2. Recibir un JWT token
3. Ser redirigido al dashboard
4. Ver mi nombre de Apple (si lo compartí)
5. Email verificado automáticamente

### AC-005: Login existente

**Dado** que ya tengo una cuenta vinculada con Apple
**Cuando** uso "Continuar con Apple"
**Entonces** debería:
1. Iniciar sesión automáticamente
2. Usar Touch ID / Face ID si está configurado
3. Ser redirigido al dashboard

### AC-006: Email relay de Apple

**Dado** que usé la opción de ocultar mi email
**Cuando** la aplicación envía emails
**Entonces** debería enviarlos al email relay de Apple
**Y** Apple debería reenviarlos a mi email real
**Y** debería poder responder a través del relay

### AC-007: Datos mínimos recibidos

**Dado** que autorizo Apple Sign In
**Cuando** completo el flujo
**Entonces** la app debería recibir:
- `user_id` único de Apple
- Email (real o relay)
- Nombre (opcional, solo primera vez)
**Y** NO debería recibir otra información personal

### AC-008: Revocación de acceso

**Dado** que revoco el acceso desde configuración de Apple
**Cuando** intento hacer login nuevamente
**Entonces** debería ver un error de autorización
**Y** debería poder re-autorizar la aplicación

---

## Mockup

```
┌─────────────────────────────────────────────────────────────┐
│                                                             │
│              🌟 Bienvenido a OrbiQuant                     │
│                                                             │
│  ┌─────────────────────────────────────────────────────┐   │
│  │               📧 Email                               │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  ┌─────────────────────────────────────────────────────┐   │
│  │          🔴 Continuar con Google                     │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  ┌─────────────────────────────────────────────────────┐   │
│  │           Continuar con Apple                       │   │
│  └─────────────────────────────────────────────────────┘   │
│  (Botón negro con logo de Apple blanco)                    │
│                                                             │
│  [Facebook]  [Twitter/X]  [GitHub]                         │
│                                                             │
└─────────────────────────────────────────────────────────────┘

Ventana de Apple Sign In:
┌─────────────────────────────────────────────────────────────┐
│  appleid.apple.com                                     ✕    │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│                                                      │
│                                                             │
│  "OrbiQuant" desea usar tu Apple ID para iniciar sesión    │
│                                                             │
│  ┌─────────────────────────────────────────────────────┐   │
│  │ Nombre                                               │   │
│  │ ○ Compartir mi nombre                               │   │
│  │ ○ No compartir                                       │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  ┌─────────────────────────────────────────────────────┐   │
│  │ Email                                                │   │
│  │ ○ Compartir mi email (juan@icloud.com)              │   │
│  │ ● Ocultar mi email                                   │   │
│  │   (se usará: xyz123@privaterelay.appleid.com)        │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  Tu información será compartida según las políticas de     │
│  privacidad de OrbiQuant.                                  │
│                                                             │
│  ┌─────────────────────────────────────────────────────┐   │
│  │          Continuar con Touch ID                      │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  Cancelar                                                   │
│                                                             │
└─────────────────────────────────────────────────────────────┘
```

---

## Tareas Técnicas

### Database (DB)

- [ ] Agregar campos a tabla `users`:
  ```sql
  ALTER TABLE users ADD COLUMN apple_id VARCHAR(255) UNIQUE;
  ALTER TABLE users ADD COLUMN is_private_email BOOLEAN DEFAULT false;
  ```
- [ ] Usar tabla `oauth_connections` existente
- [ ] Índice en `apple_id`

### Backend (BE)

- [ ] Configurar Apple Developer Account
- [ ] Crear App ID y Service ID
- [ ] Generar y configurar private key (.p8)
- [ ] Endpoint `GET /api/v1/auth/apple`
  - Redirige a Apple Sign In
- [ ] Endpoint `POST /api/v1/auth/apple/callback`
  - Recibe ID Token (JWT)
  - Valida firma del token con Apple public key
  - Decodifica user info
  - Maneja primera autorización (recibe nombre)
  - Crea o actualiza usuario
  - Genera JWT token
- [ ] Service `AppleOAuthService`
  - `getAuthorizationUrl()`
  - `validateIdToken()`
  - `decodeUserInfo()`
  - `linkAccount()`
- [ ] Librería: `apple-signin-auth` o similar
- [ ] Tests unitarios (8 casos)
- [ ] Tests de integración con mock

### Frontend (FE)

- [ ] Botón "Sign in with Apple" (siguiendo guías de Apple)
- [ ] Manejo de popup/redirect OAuth
- [ ] Recepción de callback
- [ ] Almacenamiento de token JWT
- [ ] Estado de loading
- [ ] Manejo de errores
- [ ] Tests con React Testing Library

### Testing (QA)

- [ ] E2E: Registro con Apple (email real)
- [ ] E2E: Registro con Apple (email oculto)
- [ ] E2E: Login existente
- [ ] E2E: Revocación y re-autorización
- [ ] Test de validación de ID Token
- [ ] Test de seguridad: Firma del token
- [ ] Test de seguridad: CSRF protection
- [ ] Mock de Apple ID Token

---

## Dependencias

- **Bloqueantes:**
  - Apple Developer Account ($99/año)
  - Dominio verificado en Apple
  - Configuración de Service ID
  - Private key (.p8) generada
  - SSL/HTTPS en producción

- **Deseables:**
  - US-AUTH-003: Consistencia con otros OAuth

---

## Definition of Ready (DoR)

- [ ] Apple Developer Account activa
- [ ] Service ID configurado
- [ ] Private key generada y segura
- [ ] Mockups aprobados siguiendo Apple HIG
- [ ] API contract definido
- [ ] Dominio verificado en Apple

---

## Definition of Done (DoD)

- [ ] Código implementado y revisado
- [ ] Tests unitarios con 80%+ cobertura
- [ ] Tests de integración pasando
- [ ] Tests E2E implementados
- [ ] Botón cumple con Apple guidelines
- [ ] Validación de ID Token implementada
- [ ] Manejo de email relay funcional
- [ ] Documentación actualizada
- [ ] Logs implementados
- [ ] QA aprobado en staging
- [ ] Deploy a producción exitoso

---

## Notas Técnicas

### Apple Sign In Flow

1. Frontend redirige a `/api/v1/auth/apple`
2. Backend redirige a Apple con:
   - `client_id` (Service ID)
   - `redirect_uri`
   - `response_type=code id_token`
   - `response_mode=form_post`
   - `scope=name email`
   - `state` (CSRF token)
3. Usuario autoriza en Apple
4. Apple envía POST a `redirect_uri` con:
   - `id_token` (JWT firmado)
   - `code` (authorization code)
   - `user` (solo primera vez, contiene nombre)
5. Backend valida ID Token con Apple public key
6. Backend decodifica user info
7. Backend crea/actualiza usuario
8. Backend genera JWT y redirige a frontend

### Apple ID Token Structure

```json
{
  "iss": "https://appleid.apple.com",
  "aud": "com.orbiquant.service",
  "exp": 1234567890,
  "iat": 1234567890,
  "sub": "001234.abc123...", // Apple User ID
  "email": "xyz@privaterelay.appleid.com",
  "email_verified": true,
  "is_private_email": true,
  "nonce_supported": true
}
```

### Environment Variables

```env
APPLE_SERVICE_ID=com.orbiquant.service
APPLE_TEAM_ID=ABC123XYZ
APPLE_KEY_ID=KEY123
APPLE_PRIVATE_KEY_PATH=/path/to/AuthKey_KEY123.p8
APPLE_CALLBACK_URL=https://orbiquant.com/api/v1/auth/apple/callback
```

### Consideraciones Especiales de Apple

- Apple solo envía nombre en la primera autorización
- Email relay de Apple es permanente por app
- ID Token está firmado con RS256
- Requiere validar firma con Apple public keys
- Response mode debe ser `form_post` (no query params)
- Requiere HTTPS estricto
- No hay refresh tokens en el flujo web

### Security Considerations

- Validar firma del ID Token con Apple public key
- Verificar `aud` claim coincide con Service ID
- Validar `iss` es `https://appleid.apple.com`
- Verificar `exp` no está expirado
- Validar `state` parameter (CSRF)
- Guardar nombre solo en primera autorización
- Logs de autenticación

### Apple Design Guidelines

- Usar botón oficial "Sign in with Apple"
- Color negro en tema claro, blanco en tema oscuro
- Logo de Apple siempre visible
- Texto específico según contexto
- Mismo tamaño que otros botones OAuth

---

## Requerimientos Relacionados

- [RF-AUTH-003: OAuth Social](../requerimientos/RF-AUTH-003-oauth.md)

## Especificaciones Relacionadas

- [ET-AUTH-002: JWT Tokens](../especificaciones/ET-AUTH-002-jwt.md)
- [ET-AUTH-004: OAuth Integration](../especificaciones/ET-AUTH-004-oauth.md)
