AuthContent se define en libs/shared/domain/src/lib/auth.models.ts. El backend entrega como mínimo el access token, refresh token y duración del token; también se consumen sessionId y mustChangePassword.
La implementación trata el access token como JWT. AuthService.decodeToken() separa el token por puntos y decodifica el payload JSON para recuperar User. Esto sirve para poblar el contexto de frontend; no valida firma ni reemplaza la validación del servidor.
AuthService.handleSuccessfulAuth() mantiene valores en memoria y escribe:
| Clave | Valor |
|---|---|
access_token |
JWT usado como bearer en llamadas protegidas. |
refresh_token |
Token enviado al endpoint de renovación. |
token_expiry |
Tiempo absoluto de expiración calculado como Date.now() + expiresIn. |
user_data |
JSON reducido con identidad, roles y datos de compañía/cliente. |
must_change_password |
Marca local temporal del cambio obligatorio, cuando aplica. |
Además, el servicio guarda un perfil seguro en cookie user_profile (sin tokens) y TokenBridgeService puede publicar un cookie app_data que contiene tokens y estado para sincronización/puente entre partes de la aplicación. El código actual de TokenBridgeService crea esta cookie con secure: false, sin HttpOnly (no configurable desde JavaScript) y SameSite=Lax; no tratarla como almacenamiento protegido.
El login calcula token_expiry sumando directamente expiresIn a Date.now(). La selección de compañía, en cambio, acepta un valor ya absoluto si es mayor a 1e12, y si no lo trata como duración. Por tanto, el contrato de unidades de expiresIn debe coincidir con lo que devuelve el backend; no asumir segundos o milisegundos sin validar ese contrato.
La sesión se considera activa si existe access token y Date.now() es menor que token_expiry - 30 segundos. El margen evita operar con un token próximo a expirar.
tokenInterceptor añade Authorization: Bearer <access_token> a peticiones no públicas.errorInterceptor delega en AuthService.handle401Error() para refrescar y reintentar.refreshToken() envía el refresh token a /simappe-oauth2-server/api/v1/refresh; una respuesta exitosa reemplaza los tokens y agenda la próxima renovación.Los tokens están en localStorage, por lo que cualquier JavaScript que se ejecute en el mismo origen podría leerlos. La cookie app_data también expone tokens a JavaScript. No guardar contraseñas. Mantener HTTPS, controles de XSS y autorización del servidor; evaluar con el equipo de seguridad una alternativa de almacenamiento basada en cookie HttpOnly si el modelo de despliegue la permite.