/** * Firebase Service * * Servicio principal para la autenticación con Firebase usando Custom Tokens. * Permite que usuarios autenticados con tu backend (Cognito, etc.) accedan * a servicios de Firebase (Firestore, Storage, FCM) de manera segura. */ import { Signal } from '@angular/core'; import { Auth, UserCredential } from '@angular/fire/auth'; import { Observable } from 'rxjs'; import { FirebaseUser, MembershipInfo, OrganizationInfo, SessionState, ValtechFirebaseConfig } from './types'; import * as i0 from "@angular/core"; /** * Servicio de autenticación de Firebase. * * Este servicio NO maneja el login de usuarios directamente. * En su lugar, trabaja con Custom Tokens generados por tu backend. * * @example * ```typescript * // Después de autenticarte con tu backend (ej: Cognito) * @Component({...}) * export class LoginComponent { * private authService = inject(AuthService); // Tu servicio de auth * private firebase = inject(FirebaseService); // Este servicio * * async login(email: string, password: string) { * // 1. Autenticar con tu backend * const response = await this.authService.login(email, password); * * // 2. El backend devuelve un Firebase Custom Token * if (response.firebaseToken) { * await this.firebase.signInWithCustomToken(response.firebaseToken); * } * * // Ahora el usuario puede acceder a Firestore, Storage, etc. * } * * async logout() { * await this.authService.logout(); * await this.firebase.signOut(); * } * } * ``` */ export declare class FirebaseService { private auth; private config; /** Estado interno de la sesión */ private sessionState; /** Estado actual de la sesión como Observable */ readonly state$: Observable; /** Usuario actual de Firebase como Observable */ readonly user$: Observable; /** Indica si el usuario está autenticado en Firebase */ readonly isAuthenticated$: Observable; /** * Signal interna que respalda `firebaseAuthReady`. * `true` cuando hay un `firebase.User` activo y por tanto las reglas de * Firestore evaluarán `request.auth != null` correctamente. */ private readonly _firebaseAuthReady; /** * Indica si la sesión de **Firebase Auth** está establecida y lista para * leer Firestore. * * IMPORTANTE: esto es distinto del JWT del backend. La sesión de Firebase * Auth es una sesión separada que se establece vía `signInWithCustomToken` * (ver `AuthService.signInWithFirebase`). En cold start de PWA, el JWT del * backend puede estar listo varios cientos de ms antes de que Firebase Auth * confirme su `User` — adjuntar un listener de Firestore en esa ventana * produce `permission-denied`. * * Usar este signal (o `whenFirebaseAuthReady()`) como gate antes de * suscribirse a cualquier query/listener de Firestore. * * @example * ```typescript * if (this.firebase.firebaseAuthReady()) { * // seguro leer Firestore * } * ``` */ readonly firebaseAuthReady: Signal; /** * Emite `true` una sola vez en cuanto la sesión de Firebase Auth está lista, * y completa. Si ya está lista, emite inmediatamente. * * Pensado como gate compartido para abrir streams Firestore — espera la * ventana de hidratación de Firebase Auth sin necesidad de retries. */ readonly firebaseAuthReady$: Observable; constructor(auth: Auth, config: ValtechFirebaseConfig); /** * Resuelve en cuanto la sesión de Firebase Auth está lista para leer * Firestore. Si ya está lista, resuelve inmediatamente. * * Útil para gatear la primera suscripción a un listener de Firestore y así * cerrar la ventana de `permission-denied` en cold start. */ whenFirebaseAuthReady(): Promise; /** * Autentica al usuario con un Custom Token generado por el backend. * * @param token - Firebase Custom Token generado por tu backend * @returns UserCredential con la información del usuario * @throws Error si el token es inválido o expiró * * @example * ```typescript * // Después de login exitoso con tu backend * const { firebaseToken } = await backendAuth.login(email, password); * await firebaseService.signInWithCustomToken(firebaseToken); * ``` */ signInWithCustomToken(token: string): Promise; /** * Cierra la sesión de Firebase. * Llamar junto con el logout de tu sistema de autenticación principal. * * @example * ```typescript * async logout() { * await this.backendAuth.logout(); // Tu auth * await this.firebase.signOut(); // Firebase * } * ``` */ signOut(): Promise; /** * Obtiene el usuario actual de Firebase (síncrono). * Retorna null si no hay usuario autenticado. */ get currentUser(): FirebaseUser | null; /** * Obtiene el UID del usuario actual. * Retorna null si no hay usuario autenticado. */ get uid(): string | null; /** * Indica si hay un usuario autenticado actualmente. */ get isAuthenticated(): boolean; /** * Obtiene el ID Token de Firebase para el usuario actual. * Útil para validar el usuario en tu backend. * * @param forceRefresh - Si true, fuerza la renovación del token * @returns ID Token o null si no hay usuario */ getIdToken(forceRefresh?: boolean): Promise; /** * Obtiene los claims personalizados del token del usuario. * Los claims son establecidos por tu backend al crear el Custom Token. * * @param forceRefresh - Si true, fuerza la renovación del token para obtener claims actualizados * @returns Objeto con los claims o vacío si no hay usuario */ getClaims(forceRefresh?: boolean): Promise>; /** * Verifica si el usuario tiene un rol específico. * El rol debe estar definido en los claims del Custom Token. * * @param role - Nombre del rol a verificar * @returns true si el usuario tiene el rol */ hasRole(role: string): Promise; /** * Obtiene las memberships (organizaciones) del usuario. * Cada membership contiene el rol y permisos en esa organización. * * @param forceRefresh - Si true, fuerza la renovación del token * @returns Mapa de orgId → MembershipInfo * * @example * ```typescript * const memberships = await firebaseService.getMemberships(); * // { 'org_abc': { roleId: 'admin', roleName: 'admin', permissions: ['users:*', ...] } } * ``` */ getMemberships(forceRefresh?: boolean): Promise>; /** * Obtiene la organización activa del usuario. * La organización activa se establece al hacer login o al cambiar de org. * * @param forceRefresh - Si true, fuerza la renovación del token * @returns ID de la organización activa o null si no hay ninguna */ getActiveOrg(forceRefresh?: boolean): Promise; /** * Obtiene información de todas las organizaciones del usuario. * * @param forceRefresh - Si true, fuerza la renovación del token * @returns Array con información de cada organización */ getOrganizations(forceRefresh?: boolean): Promise; /** * Obtiene los IDs de todas las organizaciones del usuario. * * @returns Array de IDs de organizaciones */ getOrganizationIds(): Promise; /** * Verifica si el usuario pertenece a una organización. * * @param orgId - ID de la organización * @returns true si el usuario es miembro */ isMemberOf(orgId: string): Promise; /** * Obtiene el rol del usuario en una organización. * * @param orgId - ID de la organización * @returns ID del rol o null si no es miembro */ getRoleInOrg(orgId: string): Promise; /** * Obtiene los permisos del usuario en una organización. * * @param orgId - ID de la organización * @returns Array de permisos en formato 'resource:action' */ getPermissionsInOrg(orgId: string): Promise; /** * Verifica si el usuario tiene un permiso específico en una organización. * Soporta wildcards: 'resource:*' y '*:*' (super admin). * * @param orgId - ID de la organización * @param resource - Recurso a verificar (ej: 'users', 'documents') * @param action - Acción a verificar (ej: 'read', 'write', 'create', 'delete') * @returns true si tiene el permiso * * @example * ```typescript * // Verificar permiso específico * const canReadUsers = await firebaseService.hasPermission('org_abc', 'users', 'read'); * * // Verificar en la organización activa * const orgId = await firebaseService.getActiveOrg(); * const canEdit = await firebaseService.hasPermission(orgId!, 'documents', 'write'); * ``` */ hasPermission(orgId: string, resource: string, action: string): Promise; /** * Verifica si el usuario puede leer un recurso en una organización. * Atajo para hasPermission(orgId, resource, 'read'). */ canRead(orgId: string, resource: string): Promise; /** * Verifica si el usuario puede escribir un recurso en una organización. * Atajo para hasPermission(orgId, resource, 'write'). */ canWrite(orgId: string, resource: string): Promise; /** * Verifica si el usuario puede crear un recurso en una organización. * Atajo para hasPermission(orgId, resource, 'create'). */ canCreate(orgId: string, resource: string): Promise; /** * Verifica si el usuario puede eliminar un recurso en una organización. * Atajo para hasPermission(orgId, resource, 'delete'). */ canDelete(orgId: string, resource: string): Promise; /** * Verifica si el usuario puede administrar un recurso en una organización. * Equivale a tener 'resource:*' o '*:*'. */ canManage(orgId: string, resource: string): Promise; /** * Verifica si el usuario es super admin en una organización. * Super admin tiene el permiso '*:*'. */ isSuperAdmin(orgId: string): Promise; /** * Verifica si el usuario es admin en una organización. */ isAdminInOrg(orgId: string): Promise; /** * Espera a que el estado de autenticación esté determinado. * Útil en guards o al inicializar la app. * * @returns Usuario actual o null */ waitForAuth(): Promise; /** * Obtiene la configuración actual de Firebase. */ getConfig(): ValtechFirebaseConfig; /** * Indica si los emuladores están habilitados. */ isUsingEmulators(): boolean; /** * Mapea un User de Firebase a nuestra interface FirebaseUser */ private mapUser; /** * Convierte errores de Firebase a mensajes en español */ private getErrorMessage; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵprov: i0.ɵɵInjectableDeclaration; }