AuthManager
AuthManager es el broker del SDK responsable de autenticar al usuario contra el
broker remoto, registrar el dispositivo, persistir el token de sesión y los headers
HMAC de CouchDB, y mantener el aislamiento multi-tenant del dispositivo. Es el primer
eslabón del arranque del SDK: sin un token válido en localStorage no hay sincronización.
Forma parte del conjunto de brokers del SDK y se apoya en la infraestructura descrita en plataforma e infraestructura.
Responsabilidades
Sección titulada «Responsabilidades»- Autenticación de usuario (
login,loginWithGoogle,registerUser,createUser). - Persistencia y renovación de tokens (
saveToken,getToken,refreshAuthentication). - Registro y estado del dispositivo (
registerDevice,updateDeviceStatus,updateDeviceInfo). - Cierre de sesión y limpieza del estado local (
logout,signOut). - Lectura de roles y verificación de permisos desde el JWT (
getCurrentRoles,hasPermission). - Hooks de ciclo de vida para que el SDK reaccione a login, refresh y logout.
Modelo de tokens y storage
Sección titulada «Modelo de tokens y storage»Todo el estado de sesión se guarda en window.localStorage bajo el prefijo
tablesProxyToken (expuesto como AuthManager.tokenPrefix):
| Clave | Contenido |
|---|---|
tablesProxyToken-Auth | JWT de acceso |
tablesProxyToken-Refresh | refresh token |
tablesProxyToken-expiresAt-Auth | timestamp de expiración del JWT (ms) |
X-Couchdb-Headers-Remote | headers HMAC para CouchDB remoto |
X-Couchdb-Headers-Local | headers HMAC para CouchDB local |
El JWT codifica companyId, userId y los roles. AuthManager lo decodifica con
jwtDecode para resolver la compañía y el usuario actuales sin llamadas extra al servidor.
Flujo de login
Sección titulada «Flujo de login»-
El cliente llama
login(credentials)conusername,password; el SDK adjuntadeviceInfoy hacePOST /auth. -
Si la respuesta no es
200, se devuelve{ success: false, error }sin tocar el estado local. -
En éxito se ejecuta
_cleanupBeforeLogin(): corre los handlers de signOut y destruye todas las PouchDB locales trackeadas (destroyAllLocalDatabases). Esto es deliberadamente agresivo para impedir que datos de un tenant anterior contaminen al nuevo usuario. -
Se persisten los headers de CouchDB (
RemoteyLocal) y los tokens (AuthconexpiresIn,RefreshconrefreshExpiresIn). -
Se ejecutan los handlers de login (
_runLoginHandlers) para invalidar caches dependientes del usuario (permisos, preferencias).
loginWithGoogle(credential) sigue exactamente la misma lógica contra POST /auth/google.
Relación con el handshake de init del SDK
Sección titulada «Relación con el handshake de init del SDK»AuthManager produce los insumos que el resto del arranque consume:
- El token habilita las llamadas HTTP autenticadas y el proxy de CouchDB.
- Los headers HMAC (
X-Couchdb-Headers-*) autorizan la replicación. registerDevice()hacePOST /auth/connecty, si el servidor devuelvedeviceId, actualizadeviceInfo.id. Requiere token previo; si no hay, retorna error.
El handshake de inicialización (sdk:init → ready) que coordina el ruteo de base de
datos vive en el SyncManager y en tables-socket, y se apoya
en la sesión que AuthManager dejó establecida. Ver sincronización
para el detalle del flujo realtime.
Hooks de ciclo de vida
Sección titulada «Hooks de ciclo de vida»Tres registradores permiten al SDK enganchar lógica sin acoplar AuthManager a otros
módulos. Los handlers corren en secuencia y cada error queda aislado (no aborta el resto):
authManager.registerOnLogin(async () => { /* invalidar caches de usuario */ });authManager.registerOnTokenRefresh(async () => { /* revalidar roles/permisos */ });authManager.registerOnSignOut(async () => { /* destruir PouchDB local, reset singleton */ });- onLogin: tras un login exitoso, una vez persistido el token.
- onTokenRefresh: tras un refresh exitoso (el backend podría re-emitir roles distintos).
- onSignOut: durante el logout, después de notificar al servidor y antes de limpiar el
estado local. También se dispara al detectar cambio de
companyIden login o refresh.
Renovación de token
Sección titulada «Renovación de token»refreshAuthentication() hace POST a proxyRoutes.refreshToken con el refresh token
y reescribe Auth y Refresh. Si detecta que el companyId del nuevo token difiere del
anterior, fuerza el cleanup completo (_cleanupBeforeLogin) igual que en login; si el
tenant no cambia, no toca la base de datos local para no perder datos offline.
getToken() es el accessor canónico: si isTokenExpired() es true, intenta refrescar;
si el refresh falla, llama logout() y devuelve null. Usa un margen de seguridad de
1 minuto, replicado en isAboutToExpire().
Logout y limpieza
Sección titulada «Logout y limpieza»logout() y signOut() delegan en _clearAllAuth(), que:
-
Notifica al servidor con
POST /auth/logout(solo si hay token), enviandodeviceId. -
Ejecuta los handlers de signOut antes de limpiar tokens, porque alguno puede necesitar el token aún válido (por ejemplo, confirmar la replicación final).
-
Limpia el estado en memoria (
token,lastCredentials,currentCompany). -
Borra de
localStoragelos tokensAuthyRefreshy los headersX-Couchdb-Headers-Remote/X-Couchdb-Headers-Local.
API pública (selección)
Sección titulada «API pública (selección)»| Método | Descripción |
|---|---|
login(credentials) | Autentica vía POST /auth; persiste token y headers HMAC. |
loginWithGoogle(credential) | Autentica con Google vía POST /auth/google. |
registerUser(credentials) | Registra usuario vía POST /auth/register. |
createUser(credentials) | Crea usuario vía POST /register-user. |
logout() / signOut() | Cierra sesión y limpia todo el estado local. |
getToken() | Devuelve el JWT vigente; refresca si está expirado. |
getRefreshToken() | Lee el refresh token desde localStorage. |
refreshAuthentication() | Renueva el JWT con el refresh token. |
isTokenExpired() / isAboutToExpire() | Estado de vigencia del JWT (margen 1 min). |
checkIfLoggedIn() | true si existe token Auth en localStorage. |
getCurrentUser() | JWT decodificado del usuario autenticado. |
getCurrentCompany() | Compañía actual (cacheada; resuelve companyId del JWT). |
getCurrentRoles() | Roles extraídos del JWT ([] si no hay token). |
hasPermission(action) | Verificación asíncrona de permiso por roles. |
requirePermission(action) | Verificación sincrónica; lanza si no autoriza. |
registerDevice() | Registra el dispositivo vía POST /auth/connect. |
updateDeviceStatus({ isOnline }) | Actualiza estado del dispositivo vía PUT /auth/status. |
updateDeviceInfo(partial) | Mergea cambios en deviceInfo en memoria. |
addDevice / deleteDevice / getDevices | Gestión de dispositivos del usuario. |
getCompanies / getCompany / updateCompany / deleteCompany | Gestión de compañías. |
updateUser / deleteUser / listUsers / getMyUser | Gestión de usuarios. |
updatePaymentReference(companyId, saleId, data) | Actualiza la referencia de un pago. |
Páginas relacionadas
Sección titulada «Páginas relacionadas»- Brokers del SDK — visión general de AuthManager, SyncManager, NetworkMonitor y TablesBroker.
- Plataforma e infraestructura — broker remoto, CouchDB y proxy HMAC.