valtech-components 2.0.498 → 2.0.500
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm2022/lib/services/auth/auth.service.mjs +103 -6
- package/esm2022/lib/services/auth/index.mjs +4 -1
- package/esm2022/lib/services/auth/oauth-callback.component.mjs +141 -0
- package/esm2022/lib/services/auth/oauth.service.mjs +250 -0
- package/esm2022/lib/services/auth/types.mjs +1 -1
- package/esm2022/lib/services/firebase/analytics-error-handler.mjs +141 -0
- package/esm2022/lib/services/firebase/analytics-router-tracker.mjs +99 -0
- package/esm2022/lib/services/firebase/analytics.service.mjs +597 -0
- package/esm2022/lib/services/firebase/config.mjs +21 -2
- package/esm2022/lib/services/firebase/index.mjs +6 -1
- package/fesm2022/valtech-components.mjs +1331 -7
- package/fesm2022/valtech-components.mjs.map +1 -1
- package/lib/services/auth/auth.service.d.ts +56 -3
- package/lib/services/auth/index.d.ts +2 -0
- package/lib/services/auth/oauth-callback.component.d.ts +34 -0
- package/lib/services/auth/oauth.service.d.ts +90 -0
- package/lib/services/auth/types.d.ts +69 -0
- package/lib/services/firebase/analytics-error-handler.d.ts +54 -0
- package/lib/services/firebase/analytics-router-tracker.d.ts +51 -0
- package/lib/services/firebase/analytics.service.d.ts +256 -0
- package/lib/services/firebase/index.d.ts +4 -0
- package/package.json +1 -1
|
@@ -6,7 +6,8 @@ import { AuthStateService } from './auth-state.service';
|
|
|
6
6
|
import { TokenService } from './token.service';
|
|
7
7
|
import { AuthStorageService } from './storage.service';
|
|
8
8
|
import { AuthSyncService } from './sync.service';
|
|
9
|
-
import { SigninRequest, SigninResponse, SignupRequest, SignupResponse, VerifyEmailRequest, VerifyEmailResponse, ResendCodeRequest, ResendCodeResponse, MFAVerifyResponse, RefreshResponse, GetPermissionsResponse, GetProfileResponse, UpdateProfileRequest, UpdateProfileResponse, MFASetupResponse, MFAConfirmResponse, MFADisableResponse, ForgotPasswordRequest, ForgotPasswordResponse, ResetPasswordRequest, ResetPasswordResponse, SwitchOrgResponse, MFAMethod, AuthError, ValtechAuthConfig, EnableNotificationsResult, NotificationPermissionState, RegisterDeviceResult, TOTPSetupResponse, TOTPVerifySetupResponse, TOTPDisableResponse, RegenerateBackupCodesResponse, BackupCodesCountResponse } from './types';
|
|
9
|
+
import { SigninRequest, SigninResponse, SignupRequest, SignupResponse, VerifyEmailRequest, VerifyEmailResponse, ResendCodeRequest, ResendCodeResponse, MFAVerifyResponse, RefreshResponse, GetPermissionsResponse, GetProfileResponse, UpdateProfileRequest, UpdateProfileResponse, MFASetupResponse, MFAConfirmResponse, MFADisableResponse, ForgotPasswordRequest, ForgotPasswordResponse, ResetPasswordRequest, ResetPasswordResponse, SwitchOrgResponse, MFAMethod, AuthError, ValtechAuthConfig, EnableNotificationsResult, NotificationPermissionState, RegisterDeviceResult, TOTPSetupResponse, TOTPVerifySetupResponse, TOTPDisableResponse, RegenerateBackupCodesResponse, BackupCodesCountResponse, OAuthProvider, LinkedProvider, HasPasswordResponse } from './types';
|
|
10
|
+
import { OAuthService } from './oauth.service';
|
|
10
11
|
import { FirebaseService, MessagingService } from '../firebase';
|
|
11
12
|
import { I18nService } from '../i18n';
|
|
12
13
|
import * as i0 from "@angular/core";
|
|
@@ -41,11 +42,12 @@ export declare class AuthService implements OnDestroy {
|
|
|
41
42
|
private storageService;
|
|
42
43
|
private syncService;
|
|
43
44
|
private firebaseService;
|
|
45
|
+
private oauthService;
|
|
44
46
|
private messagingService;
|
|
45
47
|
private i18nService;
|
|
46
48
|
private refreshTimerId;
|
|
47
49
|
private syncSubscription;
|
|
48
|
-
constructor(config: ValtechAuthConfig, http: HttpClient, router: Router, stateService: AuthStateService, tokenService: TokenService, storageService: AuthStorageService, syncService: AuthSyncService, firebaseService: FirebaseService, messagingService: MessagingService | null, i18nService: I18nService | null);
|
|
50
|
+
constructor(config: ValtechAuthConfig, http: HttpClient, router: Router, stateService: AuthStateService, tokenService: TokenService, storageService: AuthStorageService, syncService: AuthSyncService, firebaseService: FirebaseService, oauthService: OAuthService, messagingService: MessagingService | null, i18nService: I18nService | null);
|
|
49
51
|
/** Estado completo de autenticación */
|
|
50
52
|
readonly state: import("@angular/core").Signal<import("./types").AuthState>;
|
|
51
53
|
/** Usuario está autenticado */
|
|
@@ -77,6 +79,57 @@ export declare class AuthService implements OnDestroy {
|
|
|
77
79
|
* Detecta automáticamente la plataforma para identificar dispositivos nuevos.
|
|
78
80
|
*/
|
|
79
81
|
signin(request: SigninRequest): Observable<SigninResponse>;
|
|
82
|
+
/**
|
|
83
|
+
* Inicia sesión con OAuth (Google, Apple, Microsoft).
|
|
84
|
+
* Abre un popup para el flujo de autenticación.
|
|
85
|
+
*
|
|
86
|
+
* @param provider - Proveedor OAuth ('google', 'apple', 'microsoft')
|
|
87
|
+
* @returns Observable que emite SigninResponse cuando se completa
|
|
88
|
+
*
|
|
89
|
+
* @example
|
|
90
|
+
* ```typescript
|
|
91
|
+
* this.auth.signinWithOAuth('google').subscribe({
|
|
92
|
+
* next: () => this.router.navigate(['/']),
|
|
93
|
+
* error: (err) => console.error('OAuth failed:', err)
|
|
94
|
+
* });
|
|
95
|
+
* ```
|
|
96
|
+
*/
|
|
97
|
+
signinWithOAuth(provider: OAuthProvider): Observable<SigninResponse>;
|
|
98
|
+
/**
|
|
99
|
+
* Vincula un proveedor OAuth adicional a la cuenta actual.
|
|
100
|
+
* Requiere que el usuario esté autenticado.
|
|
101
|
+
*
|
|
102
|
+
* @param provider - Proveedor OAuth a vincular
|
|
103
|
+
*/
|
|
104
|
+
linkOAuthProvider(provider: OAuthProvider): Observable<{
|
|
105
|
+
success: boolean;
|
|
106
|
+
}>;
|
|
107
|
+
/**
|
|
108
|
+
* Obtiene los proveedores OAuth vinculados al usuario.
|
|
109
|
+
*/
|
|
110
|
+
getLinkedProviders(): Observable<LinkedProvider[]>;
|
|
111
|
+
/**
|
|
112
|
+
* Desvincula un proveedor OAuth de la cuenta.
|
|
113
|
+
*
|
|
114
|
+
* @param provider - Proveedor a desvincular
|
|
115
|
+
*/
|
|
116
|
+
unlinkOAuthProvider(provider: OAuthProvider): Observable<{
|
|
117
|
+
success: boolean;
|
|
118
|
+
}>;
|
|
119
|
+
/**
|
|
120
|
+
* Establece contraseña para usuarios que solo tienen OAuth.
|
|
121
|
+
* Permite que usuarios OAuth-only puedan también usar email/password.
|
|
122
|
+
*
|
|
123
|
+
* @param password - Nueva contraseña
|
|
124
|
+
*/
|
|
125
|
+
setPasswordForOAuthUser(password: string): Observable<{
|
|
126
|
+
success: boolean;
|
|
127
|
+
}>;
|
|
128
|
+
/**
|
|
129
|
+
* Verifica si el usuario tiene contraseña establecida.
|
|
130
|
+
* Útil para mostrar/ocultar opciones de cambio de contraseña.
|
|
131
|
+
*/
|
|
132
|
+
checkHasPassword(): Observable<HasPasswordResponse>;
|
|
80
133
|
/**
|
|
81
134
|
* Registra un nuevo usuario.
|
|
82
135
|
* El usuario queda en estado PENDING hasta verificar su email.
|
|
@@ -277,6 +330,6 @@ export declare class AuthService implements OnDestroy {
|
|
|
277
330
|
* Detecta información de la plataforma del dispositivo.
|
|
278
331
|
*/
|
|
279
332
|
private detectPlatformInfo;
|
|
280
|
-
static ɵfac: i0.ɵɵFactoryDeclaration<AuthService, [null, null, null, null, null, null, null, null, { optional: true; }, { optional: true; }]>;
|
|
333
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<AuthService, [null, null, null, null, null, null, null, null, null, { optional: true; }, { optional: true; }]>;
|
|
281
334
|
static ɵprov: i0.ɵɵInjectableDeclaration<AuthService>;
|
|
282
335
|
}
|
|
@@ -79,3 +79,5 @@ export { AuthStorageService } from './storage.service';
|
|
|
79
79
|
export { AuthSyncService } from './sync.service';
|
|
80
80
|
export { DeviceService } from './device.service';
|
|
81
81
|
export { SessionService } from './session.service';
|
|
82
|
+
export { OAuthService } from './oauth.service';
|
|
83
|
+
export { OAuthCallbackComponent } from './oauth-callback.component';
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { OnInit } from '@angular/core';
|
|
2
|
+
import * as i0 from "@angular/core";
|
|
3
|
+
/**
|
|
4
|
+
* Componente de callback para OAuth.
|
|
5
|
+
*
|
|
6
|
+
* Este componente procesa la respuesta del servidor OAuth y envía
|
|
7
|
+
* los tokens a la ventana padre via postMessage.
|
|
8
|
+
*
|
|
9
|
+
* Debe agregarse a las rutas de la aplicación:
|
|
10
|
+
* ```typescript
|
|
11
|
+
* // app.routes.ts
|
|
12
|
+
* import { OAuthCallbackComponent } from 'valtech-components';
|
|
13
|
+
*
|
|
14
|
+
* export const routes: Routes = [
|
|
15
|
+
* { path: 'auth/oauth/callback', component: OAuthCallbackComponent },
|
|
16
|
+
* // ... otras rutas
|
|
17
|
+
* ];
|
|
18
|
+
* ```
|
|
19
|
+
*
|
|
20
|
+
* El backend redirige a esta ruta con los tokens en query params:
|
|
21
|
+
* `/auth/oauth/callback?access_token=xxx&refresh_token=xxx&expires_in=900`
|
|
22
|
+
*
|
|
23
|
+
* O con error:
|
|
24
|
+
* `/auth/oauth/callback?error=INVALID_CODE&error_description=...`
|
|
25
|
+
*/
|
|
26
|
+
export declare class OAuthCallbackComponent implements OnInit {
|
|
27
|
+
message: string;
|
|
28
|
+
ngOnInit(): void;
|
|
29
|
+
private processCallback;
|
|
30
|
+
private sendToParent;
|
|
31
|
+
private closeAfterDelay;
|
|
32
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<OAuthCallbackComponent, never>;
|
|
33
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<OAuthCallbackComponent, "val-oauth-callback", never, {}, {}, never, never, true, never>;
|
|
34
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { NgZone } from '@angular/core';
|
|
2
|
+
import { Observable } from 'rxjs';
|
|
3
|
+
import { ValtechAuthConfig, OAuthProvider, OAuthResult, LinkedProvider, HasPasswordResponse } from './types';
|
|
4
|
+
import { HttpClient } from '@angular/common/http';
|
|
5
|
+
import * as i0 from "@angular/core";
|
|
6
|
+
/**
|
|
7
|
+
* Servicio de OAuth para login social.
|
|
8
|
+
*
|
|
9
|
+
* Implementa flujo OAuth server-side con popup:
|
|
10
|
+
* 1. Frontend abre popup hacia backend
|
|
11
|
+
* 2. Backend redirige a provider (Google, Apple, Microsoft)
|
|
12
|
+
* 3. Usuario autoriza
|
|
13
|
+
* 4. Backend intercambia code, genera JWT, redirige con tokens
|
|
14
|
+
* 5. Popup envía tokens a ventana padre via postMessage
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```typescript
|
|
18
|
+
* import { OAuthService, AuthService } from 'valtech-components';
|
|
19
|
+
*
|
|
20
|
+
* @Component({...})
|
|
21
|
+
* export class LoginComponent {
|
|
22
|
+
* private oauth = inject(OAuthService);
|
|
23
|
+
* private auth = inject(AuthService);
|
|
24
|
+
*
|
|
25
|
+
* async loginWithGoogle() {
|
|
26
|
+
* this.oauth.startFlow('google').subscribe({
|
|
27
|
+
* next: (result) => {
|
|
28
|
+
* // Tokens recibidos, guardar en auth state
|
|
29
|
+
* this.auth.handleOAuthSuccess(result);
|
|
30
|
+
* this.router.navigate(['/']);
|
|
31
|
+
* },
|
|
32
|
+
* error: (error) => {
|
|
33
|
+
* console.error('OAuth failed:', error);
|
|
34
|
+
* }
|
|
35
|
+
* });
|
|
36
|
+
* }
|
|
37
|
+
* }
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
export declare class OAuthService {
|
|
41
|
+
private config;
|
|
42
|
+
private http;
|
|
43
|
+
private ngZone;
|
|
44
|
+
private popup;
|
|
45
|
+
private messageHandler;
|
|
46
|
+
private checkClosedInterval;
|
|
47
|
+
constructor(config: ValtechAuthConfig, http: HttpClient, ngZone: NgZone);
|
|
48
|
+
/**
|
|
49
|
+
* Inicia flujo OAuth en popup.
|
|
50
|
+
* Retorna Observable que emite cuando el usuario completa el flujo.
|
|
51
|
+
*
|
|
52
|
+
* @param provider - Proveedor OAuth ('google', 'apple', 'microsoft')
|
|
53
|
+
* @returns Observable que emite OAuthResult o error
|
|
54
|
+
*/
|
|
55
|
+
startFlow(provider: OAuthProvider): Observable<OAuthResult>;
|
|
56
|
+
/**
|
|
57
|
+
* Inicia flujo de linking para vincular un proveedor adicional.
|
|
58
|
+
* Requiere que el usuario esté autenticado.
|
|
59
|
+
*
|
|
60
|
+
* @param provider - Proveedor OAuth a vincular
|
|
61
|
+
* @returns Observable que emite cuando se completa el linking
|
|
62
|
+
*/
|
|
63
|
+
startLinkFlow(provider: OAuthProvider): Observable<OAuthResult>;
|
|
64
|
+
/**
|
|
65
|
+
* Obtiene los proveedores OAuth vinculados al usuario.
|
|
66
|
+
*/
|
|
67
|
+
getLinkedProviders(): Observable<LinkedProvider[]>;
|
|
68
|
+
/**
|
|
69
|
+
* Desvincula un proveedor OAuth.
|
|
70
|
+
*/
|
|
71
|
+
unlinkProvider(provider: OAuthProvider): Observable<{
|
|
72
|
+
success: boolean;
|
|
73
|
+
}>;
|
|
74
|
+
/**
|
|
75
|
+
* Establece contraseña para usuarios que solo tienen OAuth.
|
|
76
|
+
*/
|
|
77
|
+
setPassword(password: string): Observable<{
|
|
78
|
+
success: boolean;
|
|
79
|
+
}>;
|
|
80
|
+
/**
|
|
81
|
+
* Verifica si el usuario tiene contraseña establecida.
|
|
82
|
+
*/
|
|
83
|
+
hasPassword(): Observable<HasPasswordResponse>;
|
|
84
|
+
/**
|
|
85
|
+
* Limpia recursos del popup.
|
|
86
|
+
*/
|
|
87
|
+
private cleanup;
|
|
88
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<OAuthService, never>;
|
|
89
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<OAuthService>;
|
|
90
|
+
}
|
|
@@ -664,3 +664,72 @@ export interface ValidateActionResponse {
|
|
|
664
664
|
/** Mensaje de error (si valid=false) */
|
|
665
665
|
message?: string;
|
|
666
666
|
}
|
|
667
|
+
/**
|
|
668
|
+
* Proveedores OAuth soportados.
|
|
669
|
+
*/
|
|
670
|
+
export type OAuthProvider = 'google' | 'apple' | 'microsoft';
|
|
671
|
+
/**
|
|
672
|
+
* Resultado exitoso de flujo OAuth.
|
|
673
|
+
*/
|
|
674
|
+
export interface OAuthResult {
|
|
675
|
+
/** Token de acceso JWT */
|
|
676
|
+
accessToken: string;
|
|
677
|
+
/** Token de refresco */
|
|
678
|
+
refreshToken: string;
|
|
679
|
+
/** Token de Firebase (si está habilitado) */
|
|
680
|
+
firebaseToken?: string;
|
|
681
|
+
/** Tiempo de expiración en segundos */
|
|
682
|
+
expiresIn: number;
|
|
683
|
+
/** Roles del usuario */
|
|
684
|
+
roles?: string[];
|
|
685
|
+
/** Permisos del usuario */
|
|
686
|
+
permissions?: string[];
|
|
687
|
+
/** Indica si es un usuario nuevo (recién creado) */
|
|
688
|
+
isNewUser?: boolean;
|
|
689
|
+
/** Indica si la cuenta fue vinculada a usuario existente */
|
|
690
|
+
linked?: boolean;
|
|
691
|
+
}
|
|
692
|
+
/**
|
|
693
|
+
* Error de OAuth.
|
|
694
|
+
*/
|
|
695
|
+
export interface OAuthError {
|
|
696
|
+
/** Código de error */
|
|
697
|
+
code: string;
|
|
698
|
+
/** Mensaje descriptivo */
|
|
699
|
+
message: string;
|
|
700
|
+
}
|
|
701
|
+
/**
|
|
702
|
+
* Datos enviados desde popup callback via postMessage.
|
|
703
|
+
*/
|
|
704
|
+
export interface OAuthCallbackData {
|
|
705
|
+
/** Tipo de mensaje */
|
|
706
|
+
type: 'oauth-callback';
|
|
707
|
+
/** Tokens (si éxito) */
|
|
708
|
+
tokens?: OAuthResult;
|
|
709
|
+
/** Error (si falló) */
|
|
710
|
+
error?: OAuthError;
|
|
711
|
+
}
|
|
712
|
+
/**
|
|
713
|
+
* Proveedor OAuth vinculado al usuario.
|
|
714
|
+
*/
|
|
715
|
+
export interface LinkedProvider {
|
|
716
|
+
/** Nombre del proveedor */
|
|
717
|
+
provider: OAuthProvider;
|
|
718
|
+
/** Email asociado al proveedor */
|
|
719
|
+
email: string;
|
|
720
|
+
/** Nombre del usuario en el proveedor */
|
|
721
|
+
name?: string;
|
|
722
|
+
/** URL de imagen de perfil */
|
|
723
|
+
picture?: string;
|
|
724
|
+
/** Fecha de vinculación */
|
|
725
|
+
linkedAt: string;
|
|
726
|
+
/** Última vez que se usó para login */
|
|
727
|
+
lastUsedAt?: string;
|
|
728
|
+
}
|
|
729
|
+
/**
|
|
730
|
+
* Response de verificar si tiene contraseña.
|
|
731
|
+
*/
|
|
732
|
+
export interface HasPasswordResponse {
|
|
733
|
+
operationId: string;
|
|
734
|
+
hasPassword: boolean;
|
|
735
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Analytics Error Handler
|
|
3
|
+
*
|
|
4
|
+
* ErrorHandler personalizado que envía errores no capturados a Firebase Analytics.
|
|
5
|
+
* Se activa si enableErrorTracking=true en analyticsConfig.
|
|
6
|
+
*/
|
|
7
|
+
import { ErrorHandler } from '@angular/core';
|
|
8
|
+
import * as i0 from "@angular/core";
|
|
9
|
+
/**
|
|
10
|
+
* ErrorHandler que trackea errores en Firebase Analytics.
|
|
11
|
+
*
|
|
12
|
+
* Captura errores no manejados de la aplicación y los envía a GA4
|
|
13
|
+
* como eventos 'error_occurred'. También delega al ErrorHandler
|
|
14
|
+
* default para mantener el comportamiento de console.error.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```typescript
|
|
18
|
+
* // Se activa automáticamente si enableErrorTracking=true
|
|
19
|
+
* provideValtechFirebase({
|
|
20
|
+
* firebase: environment.firebase,
|
|
21
|
+
* enableAnalytics: true,
|
|
22
|
+
* analyticsConfig: {
|
|
23
|
+
* enableErrorTracking: true,
|
|
24
|
+
* },
|
|
25
|
+
* });
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export declare class AnalyticsErrorHandler implements ErrorHandler {
|
|
29
|
+
private readonly analytics;
|
|
30
|
+
private readonly defaultHandler;
|
|
31
|
+
/**
|
|
32
|
+
* Maneja un error no capturado.
|
|
33
|
+
* Envía el error a Analytics y luego al handler default.
|
|
34
|
+
*/
|
|
35
|
+
handleError(error: unknown): void;
|
|
36
|
+
/**
|
|
37
|
+
* Trackea el error en Analytics
|
|
38
|
+
*/
|
|
39
|
+
private trackError;
|
|
40
|
+
/**
|
|
41
|
+
* Extrae información útil del error
|
|
42
|
+
*/
|
|
43
|
+
private extractErrorInfo;
|
|
44
|
+
/**
|
|
45
|
+
* Verifica si es un PromiseRejectionEvent
|
|
46
|
+
*/
|
|
47
|
+
private isPromiseRejection;
|
|
48
|
+
/**
|
|
49
|
+
* Obtiene la URL actual de forma segura
|
|
50
|
+
*/
|
|
51
|
+
private getCurrentUrl;
|
|
52
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<AnalyticsErrorHandler, never>;
|
|
53
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<AnalyticsErrorHandler>;
|
|
54
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { ValtechFirebaseConfig } from './types';
|
|
2
|
+
import * as i0 from "@angular/core";
|
|
3
|
+
/**
|
|
4
|
+
* Tracker automático de page views via Router.
|
|
5
|
+
*
|
|
6
|
+
* Este servicio escucha eventos de navegación del Router y registra
|
|
7
|
+
* page views automáticamente en Firebase Analytics.
|
|
8
|
+
*
|
|
9
|
+
* Se excluyen rutas configuradas en `analyticsConfig.excludeRoutes`.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* // Se activa automáticamente si enablePageViewTracking=true
|
|
14
|
+
* provideValtechFirebase({
|
|
15
|
+
* firebase: environment.firebase,
|
|
16
|
+
* enableAnalytics: true,
|
|
17
|
+
* analyticsConfig: {
|
|
18
|
+
* enablePageViewTracking: true,
|
|
19
|
+
* excludeRoutes: ['/admin/*', '/debug/*'],
|
|
20
|
+
* },
|
|
21
|
+
* });
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export declare class AnalyticsRouterTracker {
|
|
25
|
+
private config;
|
|
26
|
+
private readonly analytics;
|
|
27
|
+
private readonly router;
|
|
28
|
+
private readonly destroyRef;
|
|
29
|
+
private readonly excludePatterns;
|
|
30
|
+
private readonly enabled;
|
|
31
|
+
constructor(config: ValtechFirebaseConfig);
|
|
32
|
+
/**
|
|
33
|
+
* Inicia el tracking de navegación
|
|
34
|
+
*/
|
|
35
|
+
private startTracking;
|
|
36
|
+
/**
|
|
37
|
+
* Compila patrones de exclusión a RegExp
|
|
38
|
+
*/
|
|
39
|
+
private compileExcludePatterns;
|
|
40
|
+
/**
|
|
41
|
+
* Verifica si una URL debe ser excluida del tracking
|
|
42
|
+
*/
|
|
43
|
+
private isExcluded;
|
|
44
|
+
/**
|
|
45
|
+
* Registra un page view manualmente.
|
|
46
|
+
* Útil para casos donde necesitas trackear manualmente.
|
|
47
|
+
*/
|
|
48
|
+
trackPageView(path: string, title?: string): void;
|
|
49
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<AnalyticsRouterTracker, never>;
|
|
50
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<AnalyticsRouterTracker>;
|
|
51
|
+
}
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Analytics Service (Firebase GA4)
|
|
3
|
+
*
|
|
4
|
+
* Servicio para tracking de eventos, page views y errores con Firebase Analytics.
|
|
5
|
+
* Integra con el sistema de auth para user properties y respeta consent mode GDPR.
|
|
6
|
+
*/
|
|
7
|
+
import { Injector } from '@angular/core';
|
|
8
|
+
import { ValtechFirebaseConfig } from './types';
|
|
9
|
+
import { AnalyticsDebugEvent, AnalyticsEventName, AnalyticsEventParams, AnalyticsItem, ConsentSettings, ConsentState, UserProperties } from './analytics-types';
|
|
10
|
+
import * as i0 from "@angular/core";
|
|
11
|
+
/**
|
|
12
|
+
* Servicio de Firebase Analytics (GA4).
|
|
13
|
+
*
|
|
14
|
+
* Proporciona tracking de eventos, page views, errores y métricas de performance.
|
|
15
|
+
* Soporta GDPR Consent Mode y modo debug para desarrollo.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```typescript
|
|
19
|
+
* @Component({...})
|
|
20
|
+
* export class ProductComponent {
|
|
21
|
+
* private analytics = inject(AnalyticsService);
|
|
22
|
+
*
|
|
23
|
+
* onPurchase(product: Product) {
|
|
24
|
+
* this.analytics.logEvent('purchase', {
|
|
25
|
+
* transaction_id: order.id,
|
|
26
|
+
* value: order.total,
|
|
27
|
+
* currency: 'EUR'
|
|
28
|
+
* });
|
|
29
|
+
* }
|
|
30
|
+
* }
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export declare class AnalyticsService {
|
|
34
|
+
private injector;
|
|
35
|
+
private config;
|
|
36
|
+
private platformId;
|
|
37
|
+
private readonly _consentState;
|
|
38
|
+
private readonly _isDebugMode;
|
|
39
|
+
private readonly _debugHistory;
|
|
40
|
+
/** Estado de consentimiento actual (readonly) */
|
|
41
|
+
readonly consentState: import("@angular/core").Signal<ConsentState>;
|
|
42
|
+
/** Indica si está en modo debug */
|
|
43
|
+
readonly isDebugMode: import("@angular/core").Signal<boolean>;
|
|
44
|
+
/** Indica si analytics está habilitado y funcionando */
|
|
45
|
+
readonly isEnabled: import("@angular/core").Signal<boolean>;
|
|
46
|
+
private readonly analyticsConfig;
|
|
47
|
+
private readonly consentStorageKey;
|
|
48
|
+
private readonly eventPrefix;
|
|
49
|
+
private readonly samplingRate;
|
|
50
|
+
constructor(injector: Injector, config: ValtechFirebaseConfig, platformId: Object);
|
|
51
|
+
/**
|
|
52
|
+
* Inicializa el servicio de analytics
|
|
53
|
+
*/
|
|
54
|
+
private initializeAnalytics;
|
|
55
|
+
/**
|
|
56
|
+
* Obtiene la instancia de Analytics de forma perezosa.
|
|
57
|
+
* Esto evita el error de APP_INITIALIZER de AngularFire.
|
|
58
|
+
*/
|
|
59
|
+
private getAnalyticsInstance;
|
|
60
|
+
/**
|
|
61
|
+
* Verifica si Analytics está soportado
|
|
62
|
+
*/
|
|
63
|
+
private isAnalyticsSupported;
|
|
64
|
+
/**
|
|
65
|
+
* Verifica si debe enviar el evento (sampling)
|
|
66
|
+
*/
|
|
67
|
+
private shouldSample;
|
|
68
|
+
/**
|
|
69
|
+
* Registra un page view.
|
|
70
|
+
* Normalmente se usa automáticamente via AnalyticsRouterTracker.
|
|
71
|
+
*
|
|
72
|
+
* @param pagePath - Ruta de la página (ej: '/products/123')
|
|
73
|
+
* @param pageTitle - Título de la página (opcional)
|
|
74
|
+
*/
|
|
75
|
+
logPageView(pagePath: string, pageTitle?: string): void;
|
|
76
|
+
/**
|
|
77
|
+
* Registra un screen view (para apps tipo SPA).
|
|
78
|
+
*
|
|
79
|
+
* @param screenName - Nombre del screen
|
|
80
|
+
* @param screenClass - Clase del screen (opcional)
|
|
81
|
+
*/
|
|
82
|
+
logScreenView(screenName: string, screenClass?: string): void;
|
|
83
|
+
/**
|
|
84
|
+
* Registra un evento tipado GA4.
|
|
85
|
+
*
|
|
86
|
+
* @param eventName - Nombre del evento (tipado)
|
|
87
|
+
* @param params - Parámetros del evento (tipados según el nombre)
|
|
88
|
+
*
|
|
89
|
+
* @example
|
|
90
|
+
* ```typescript
|
|
91
|
+
* // Evento tipado con autocompletado
|
|
92
|
+
* analytics.logEvent('add_to_cart', {
|
|
93
|
+
* item_id: '123',
|
|
94
|
+
* item_name: 'Producto',
|
|
95
|
+
* value: 99.99,
|
|
96
|
+
* currency: 'EUR'
|
|
97
|
+
* });
|
|
98
|
+
* ```
|
|
99
|
+
*/
|
|
100
|
+
logEvent<T extends AnalyticsEventName>(eventName: T, params?: AnalyticsEventParams[T]): void;
|
|
101
|
+
/**
|
|
102
|
+
* Registra un evento custom con parámetros libres.
|
|
103
|
+
* Usar cuando el evento no está en el catálogo tipado.
|
|
104
|
+
*
|
|
105
|
+
* @param eventName - Nombre del evento custom
|
|
106
|
+
* @param params - Parámetros libres
|
|
107
|
+
*/
|
|
108
|
+
logCustomEvent(eventName: string, params?: Record<string, unknown>): void;
|
|
109
|
+
/**
|
|
110
|
+
* Lógica común para enviar eventos
|
|
111
|
+
*/
|
|
112
|
+
private trackEvent;
|
|
113
|
+
/**
|
|
114
|
+
* Registra vista de item
|
|
115
|
+
*/
|
|
116
|
+
logViewItem(item: AnalyticsItem): void;
|
|
117
|
+
/**
|
|
118
|
+
* Registra agregar al carrito
|
|
119
|
+
*/
|
|
120
|
+
logAddToCart(item: AnalyticsItem, quantity?: number): void;
|
|
121
|
+
/**
|
|
122
|
+
* Registra inicio de checkout
|
|
123
|
+
*/
|
|
124
|
+
logBeginCheckout(items: AnalyticsItem[], value: number, currency?: string): void;
|
|
125
|
+
/**
|
|
126
|
+
* Registra compra completada
|
|
127
|
+
*/
|
|
128
|
+
logPurchase(transactionId: string, items: AnalyticsItem[], value: number, currency?: string): void;
|
|
129
|
+
/**
|
|
130
|
+
* Setea el userId para asociar eventos con el usuario.
|
|
131
|
+
* Llamado automáticamente si enableAuthIntegration=true.
|
|
132
|
+
*
|
|
133
|
+
* @param userId - ID del usuario o null para limpiar
|
|
134
|
+
*/
|
|
135
|
+
setUserId(userId: string | null): void;
|
|
136
|
+
/**
|
|
137
|
+
* Setea propiedades del usuario para segmentación.
|
|
138
|
+
*
|
|
139
|
+
* @param properties - Propiedades key-value
|
|
140
|
+
*
|
|
141
|
+
* @example
|
|
142
|
+
* ```typescript
|
|
143
|
+
* analytics.setUserProperties({
|
|
144
|
+
* subscription_tier: 'premium',
|
|
145
|
+
* preferred_language: 'es'
|
|
146
|
+
* });
|
|
147
|
+
* ```
|
|
148
|
+
*/
|
|
149
|
+
setUserProperties(properties: UserProperties | Record<string, string | number | boolean>): void;
|
|
150
|
+
/**
|
|
151
|
+
* Setea la organización activa (multi-tenant).
|
|
152
|
+
* Llamado automáticamente si enableAuthIntegration=true.
|
|
153
|
+
*
|
|
154
|
+
* @param orgId - ID de la organización o null
|
|
155
|
+
*/
|
|
156
|
+
setActiveOrganization(orgId: string | null): void;
|
|
157
|
+
/**
|
|
158
|
+
* Registra un error para tracking.
|
|
159
|
+
* Integra automáticamente con Angular ErrorHandler si enableErrorTracking=true.
|
|
160
|
+
*
|
|
161
|
+
* @param error - Error o mensaje de error
|
|
162
|
+
* @param context - Contexto adicional
|
|
163
|
+
*
|
|
164
|
+
* @example
|
|
165
|
+
* ```typescript
|
|
166
|
+
* try {
|
|
167
|
+
* await riskyOperation();
|
|
168
|
+
* } catch (error) {
|
|
169
|
+
* analytics.logError(error, { context: 'checkout_flow' });
|
|
170
|
+
* }
|
|
171
|
+
* ```
|
|
172
|
+
*/
|
|
173
|
+
logError(error: Error | string, context?: Record<string, string>): void;
|
|
174
|
+
/**
|
|
175
|
+
* Registra un error fatal (crash-level).
|
|
176
|
+
*/
|
|
177
|
+
logFatalError(error: Error, context?: Record<string, string>): void;
|
|
178
|
+
/**
|
|
179
|
+
* Actualiza el estado de consentimiento del usuario.
|
|
180
|
+
* Afecta qué datos se recolectan y envían.
|
|
181
|
+
*
|
|
182
|
+
* @param consent - Settings de consentimiento
|
|
183
|
+
*
|
|
184
|
+
* @example
|
|
185
|
+
* ```typescript
|
|
186
|
+
* // Usuario acepta todo
|
|
187
|
+
* analytics.updateConsent({ analytics: true, advertising: true });
|
|
188
|
+
*
|
|
189
|
+
* // Usuario rechaza publicidad
|
|
190
|
+
* analytics.updateConsent({ analytics: true, advertising: false });
|
|
191
|
+
* ```
|
|
192
|
+
*/
|
|
193
|
+
updateConsent(consent: ConsentSettings): void;
|
|
194
|
+
/**
|
|
195
|
+
* Deniega todo consentimiento.
|
|
196
|
+
*/
|
|
197
|
+
denyAllConsent(): void;
|
|
198
|
+
/**
|
|
199
|
+
* Acepta todo consentimiento.
|
|
200
|
+
*/
|
|
201
|
+
grantAllConsent(): void;
|
|
202
|
+
/**
|
|
203
|
+
* Obtiene el estado actual de consentimiento.
|
|
204
|
+
*/
|
|
205
|
+
getConsentState(): ConsentState;
|
|
206
|
+
/**
|
|
207
|
+
* Aplica consent settings a gtag (GA4 Consent Mode v2)
|
|
208
|
+
*/
|
|
209
|
+
private applyConsentToGtag;
|
|
210
|
+
/**
|
|
211
|
+
* Carga consent desde localStorage
|
|
212
|
+
*/
|
|
213
|
+
private loadConsentFromStorage;
|
|
214
|
+
/**
|
|
215
|
+
* Guarda consent en localStorage
|
|
216
|
+
*/
|
|
217
|
+
private saveConsentToStorage;
|
|
218
|
+
/**
|
|
219
|
+
* Registra una métrica de timing/performance.
|
|
220
|
+
*
|
|
221
|
+
* @param name - Nombre de la métrica
|
|
222
|
+
* @param valueMs - Valor en milisegundos
|
|
223
|
+
* @param params - Parámetros adicionales
|
|
224
|
+
*
|
|
225
|
+
* @example
|
|
226
|
+
* ```typescript
|
|
227
|
+
* const start = performance.now();
|
|
228
|
+
* await loadData();
|
|
229
|
+
* analytics.logTiming('data_load', performance.now() - start, {
|
|
230
|
+
* category: 'api',
|
|
231
|
+
* endpoint: '/products'
|
|
232
|
+
* });
|
|
233
|
+
* ```
|
|
234
|
+
*/
|
|
235
|
+
logTiming(name: string, valueMs: number, params?: Record<string, string>): void;
|
|
236
|
+
/**
|
|
237
|
+
* Habilita/deshabilita modo debug.
|
|
238
|
+
* En debug: logea a consola, no envía a Firebase.
|
|
239
|
+
*/
|
|
240
|
+
setDebugMode(enabled: boolean): void;
|
|
241
|
+
/**
|
|
242
|
+
* Obtiene historial de eventos (solo en debug mode).
|
|
243
|
+
* Útil para testing y desarrollo.
|
|
244
|
+
*/
|
|
245
|
+
getDebugHistory(): AnalyticsDebugEvent[];
|
|
246
|
+
/**
|
|
247
|
+
* Limpia historial de debug.
|
|
248
|
+
*/
|
|
249
|
+
clearDebugHistory(): void;
|
|
250
|
+
/**
|
|
251
|
+
* Agrega evento al historial de debug
|
|
252
|
+
*/
|
|
253
|
+
private addToDebugHistory;
|
|
254
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<AnalyticsService, never>;
|
|
255
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<AnalyticsService>;
|
|
256
|
+
}
|
|
@@ -38,3 +38,7 @@ export { buildPath, extractPathParams, getCollectionPath, getDocumentId, isColle
|
|
|
38
38
|
export { StorageService } from './storage.service';
|
|
39
39
|
export { MessagingService } from './messaging.service';
|
|
40
40
|
export { NotificationDocument, NotificationsService } from './notifications.service';
|
|
41
|
+
export { AnalyticsService } from './analytics.service';
|
|
42
|
+
export { AnalyticsRouterTracker } from './analytics-router-tracker';
|
|
43
|
+
export { AnalyticsErrorHandler } from './analytics-error-handler';
|
|
44
|
+
export * from './analytics-types';
|