RF04: Usuario inicia sesión con iCloud
Descripción
Como usuario de iOS, quiero iniciar sesión con mi Apple ID (Sign in with Apple) para acceder a Finnova de forma rápida y privada.
Sign in with Apple solo autentica la identidad: la app obtiene un Identity Token firmado por Apple, el backend lo verifica contra https://appleid.apple.com/auth/keys y emite sus propios tokens de Finnova. Su inclusión es obligatoria por la App Store Review Guideline 4.8 al ofrecer también login con Google. Toda la integración está definida en Login con Apple.
| Campo | Valor |
|---|---|
| Módulo | Auth Module |
| Actor | Usuario de iOS (registrado o nuevo) |
| Endpoint | POST /auth/apple |
| Precondiciones | Dispositivo iOS 13+; la app obtuvo un Identity Token |
| Prioridad | Alta (MVP — requisito de App Store) |
| Etapa | MVP |
| Requisitos relacionados | RF01, RF02, RF03 |
Reglas de negocio
- RN-04.1 — El backend verifica el Identity Token (firma,
issuer,audience= Bundle ID, expiración) conjose. Nunca confía en datos del cliente sin validar. - RN-04.2 — El usuario se identifica por
apple_sub, no por email. - RN-04.3 — Apple solo entrega nombre y email en el primer login: deben persistirse en ese momento o se pierden.
- RN-04.4 — Si el email es un alias
@privaterelay.appleid.com(Hide My Email), se trata como cuenta nueva: no se vincula automáticamente por email. - RN-04.5 — A partir de la verificación, el flujo de sesión es idéntico al de RF02.
Validaciones de entrada
| Campo | Reglas | Mensaje de error |
|---|---|---|
identity_token | Obligatorio. JWT verificable contra Apple. | "No se pudo iniciar sesión con Apple. Intenta de nuevo." |
full_name | Opcional (solo llega en el 1er login). | — |
email | Opcional (solo llega en el 1er login). | — |
deviceInfo | Obligatorio. | — |
Criterios de aceptación
Escenario 1: Primer login con Apple — cuenta nueva
Dado que mi apple_sub no existe en Finnova,
Cuando la app envía un Identity Token válido junto con full_name y email,
Entonces el sistema crea una cuenta nueva con apple_sub, nombre y email persistidos,
Y me autentica con 201 Created.
Escenario 2: Login posterior — usuario existente
Dado que ya tengo cuenta con apple_sub registrado,
Cuando envío un Identity Token válido (sin nombre ni email, porque Apple no los reenvía),
Entonces el sistema me identifica por apple_sub y crea una sesión con 200 OK,
Y conserva el nombre y email guardados en el primer login.
Escenario 3: Hide My Email (alias privado)
Dado que uso "Ocultar mi correo" y Apple entrega un alias @privaterelay.appleid.com,
Cuando el apple_sub es nuevo,
Entonces el sistema crea una cuenta nueva sin intentar vincular por ese alias.
Escenario 4: Token inválido o de otra app (seguridad)
Dado que llega un Identity Token expirado, con firma inválida o audience distinto al Bundle ID,
Cuando el backend lo verifica,
Entonces responde 401 Unauthorized y no crea usuario ni sesión.
Escenario 5: Plataforma no iOS
Dado que el usuario está en Android, Cuando se renderiza la pantalla de login, Entonces el botón "Continuar con Apple" se oculta (o usa el flujo web si está configurado).
Criterios no funcionales
- El backend valida contra las claves públicas (JWKS) de Apple, cacheadas.
- Comunicación sobre TLS 1.2+.
- El Identity Token no se persiste ni se registra en logs.