import { NgZone } from '@angular/core'; import { Observable } from 'rxjs'; import { ValtechAuthConfig, OAuthProvider, OAuthResult, LinkedProvider, HasPasswordResponse } from './types'; import { HttpClient } from '@angular/common/http'; import * as i0 from "@angular/core"; /** * Servicio de OAuth para login social. * * Implementa flujo OAuth server-side con popup: * 1. Frontend abre popup hacia backend * 2. Backend redirige a provider (Google, Apple, Microsoft) * 3. Usuario autoriza * 4. Backend intercambia code, genera JWT, redirige con tokens * 5. Popup envía tokens a ventana padre via postMessage * * @example * ```typescript * import { OAuthService, AuthService } from 'valtech-components'; * * @Component({...}) * export class LoginComponent { * private oauth = inject(OAuthService); * private auth = inject(AuthService); * * async loginWithGoogle() { * this.oauth.startFlow('google').subscribe({ * next: (result) => { * // Tokens recibidos, guardar en auth state * this.auth.handleOAuthSuccess(result); * this.router.navigate(['/']); * }, * error: (error) => { * console.error('OAuth failed:', error); * } * }); * } * } * ``` */ export declare class OAuthService { private config; private http; private ngZone; private popup; private messageHandler; private checkClosedInterval; /** * Nonce del flujo OAuth en curso (M-07). Vive SOLO en memoria — un XSS no lo * puede leer de localStorage/sessionStorage. Viaja al backend (client_nonce), * vuelve en el callback, y se verifica acá → rechaza un oauth_callback_data * forjado por XSS. */ private expectedNonce; constructor(config: ValtechAuthConfig | null, http: HttpClient, ngZone: NgZone); /** * Inicia flujo OAuth en popup. * Retorna Observable que emite cuando el usuario completa el flujo. * * @param provider - Proveedor OAuth ('google', 'apple', 'microsoft') * @returns Observable que emite OAuthResult o error */ startFlow(provider: OAuthProvider): Observable; /** * Inicia flujo de linking para vincular un proveedor adicional. * Requiere que el usuario esté autenticado. * * @param provider - Proveedor OAuth a vincular * @returns Observable que emite cuando se completa el linking */ startLinkFlow(provider: OAuthProvider): Observable; /** * Obtiene los proveedores OAuth vinculados al usuario. */ getLinkedProviders(): Observable; /** * Desvincula un proveedor OAuth. */ unlinkProvider(provider: OAuthProvider): Observable<{ success: boolean; }>; /** * Establece contraseña para usuarios que solo tienen OAuth. */ setPassword(password: string): Observable<{ success: boolean; }>; /** * Verifica si el usuario tiene contraseña establecida. */ hasPassword(): Observable; /** * Revisa localStorage por datos de callback OAuth (fallback para COOP). * Solo acepta datos recientes (últimos 30 segundos). */ private checkLocalStorageFallback; /** * Limpia datos de fallback de localStorage. */ private clearLocalStorageFallback; /** * Limpia recursos del popup. */ private cleanup; /** * Genera un nonce aleatorio (CSPRNG) url-safe para el flujo OAuth (M-07). */ private generateNonce; /** * Verifica que el callback traiga el nonce del flujo actual (M-07). * * Estricto: si el opener generó un nonce (siempre, en clientes nuevos) exige * que el callback lo traiga y coincida. Un payload forjado en localStorage por * XSS no conoce el nonce (vive solo en memoria) → se rechaza. * * ⚠️ Requiere que el backend ya eche `client_nonce` en el callback. Deploy: * backend ANTES que el frontend, si no este check rechaza callbacks legítimos * (sin nonce) durante la ventana de transición. */ private isNonceValid; /** * Valida la forma del payload del callback (M-07): debe ser un error o tokens * como objeto. Bloquea inyecciones malformadas (primitivos, shapes basura). */ private isCallbackShapeValid; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵprov: i0.ɵɵInjectableDeclaration; }