valtech-components 2.0.902 → 2.0.904
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 +61 -25
- package/esm2022/lib/services/auth/device.service.mjs +4 -4
- package/esm2022/lib/services/auth/handoff.service.mjs +3 -3
- package/esm2022/lib/services/auth/notification-action.service.mjs +3 -3
- package/esm2022/lib/services/auth/oauth.service.mjs +7 -7
- package/esm2022/lib/services/auth/session.service.mjs +2 -2
- package/esm2022/lib/services/auth/storage.service.mjs +2 -2
- package/esm2022/lib/services/auth/sync.service.mjs +6 -6
- package/esm2022/lib/services/auth/types.mjs +1 -1
- package/esm2022/lib/version.mjs +2 -2
- package/fesm2022/valtech-components.mjs +80 -46
- package/fesm2022/valtech-components.mjs.map +1 -1
- package/lib/services/auth/auth.service.d.ts +7 -2
- package/lib/services/auth/types.d.ts +7 -0
- package/lib/version.d.ts +1 -1
- package/package.json +1 -1
|
@@ -31,7 +31,7 @@ import { Navigation, Pagination, EffectFade, EffectCube, EffectCoverflow, Effect
|
|
|
31
31
|
import { takeUntilDestroyed, toSignal, toObservable } from '@angular/core/rxjs-interop';
|
|
32
32
|
import { SwUpdate } from '@angular/service-worker';
|
|
33
33
|
import * as i1$5 from '@angular/fire/firestore';
|
|
34
|
-
import { provideFirestore, getFirestore, connectFirestoreEmulator, enableIndexedDbPersistence, doc, getDoc, collection, query as query$1, getDocs, getCountFromServer, limit, docData, collectionData, serverTimestamp, addDoc, setDoc, updateDoc, deleteDoc, writeBatch, arrayUnion, arrayRemove, increment, where, orderBy, startAfter, startAt, endBefore, endAt, Timestamp } from '@angular/fire/firestore';
|
|
34
|
+
import { provideFirestore, getFirestore, connectFirestoreEmulator, enableIndexedDbPersistence, doc, getDoc, collection, query as query$1, getDocs, getCountFromServer, limit, docData, collectionData, serverTimestamp, addDoc, setDoc, updateDoc, deleteDoc, writeBatch, arrayUnion, arrayRemove, increment, where, orderBy, startAfter, startAt, endBefore, endAt, Timestamp, onSnapshot } from '@angular/fire/firestore';
|
|
35
35
|
import { Analytics, logEvent, setUserId, setUserProperties, provideAnalytics, getAnalytics } from '@angular/fire/analytics';
|
|
36
36
|
import { provideFirebaseApp, initializeApp } from '@angular/fire/app';
|
|
37
37
|
import * as i1$6 from '@angular/fire/auth';
|
|
@@ -53,7 +53,7 @@ import 'prismjs/components/prism-json';
|
|
|
53
53
|
* Current version of valtech-components.
|
|
54
54
|
* This is automatically updated during the publish process.
|
|
55
55
|
*/
|
|
56
|
-
const VERSION = '2.0.
|
|
56
|
+
const VERSION = '2.0.904';
|
|
57
57
|
|
|
58
58
|
/**
|
|
59
59
|
* Servicio para gestionar presets de componentes.
|
|
@@ -21912,7 +21912,7 @@ class AuthStorageService {
|
|
|
21912
21912
|
constructor(config, platformId) {
|
|
21913
21913
|
this.config = config;
|
|
21914
21914
|
this.isBrowser = isPlatformBrowser(platformId);
|
|
21915
|
-
const prefix = this.config
|
|
21915
|
+
const prefix = this.config?.storagePrefix || 'valtech_auth_';
|
|
21916
21916
|
this.keys = {
|
|
21917
21917
|
ACCESS_TOKEN: `${prefix}access_token`,
|
|
21918
21918
|
REFRESH_TOKEN: `${prefix}refresh_token`,
|
|
@@ -22092,7 +22092,7 @@ class AuthSyncService {
|
|
|
22092
22092
|
/** Observable de eventos de sincronización */
|
|
22093
22093
|
this.onEvent$ = this.eventSubject.asObservable();
|
|
22094
22094
|
this.isBrowser = isPlatformBrowser(platformId);
|
|
22095
|
-
const prefix = this.config
|
|
22095
|
+
const prefix = this.config?.storagePrefix || 'valtech_auth_';
|
|
22096
22096
|
this.channelName = `${prefix}sync_channel`;
|
|
22097
22097
|
}
|
|
22098
22098
|
/**
|
|
@@ -22100,7 +22100,7 @@ class AuthSyncService {
|
|
|
22100
22100
|
* SSR-noop — sync de pestañas solo aplica en browser.
|
|
22101
22101
|
*/
|
|
22102
22102
|
start() {
|
|
22103
|
-
if (!this.config
|
|
22103
|
+
if (!this.config?.enableTabSync || !this.isBrowser) {
|
|
22104
22104
|
return;
|
|
22105
22105
|
}
|
|
22106
22106
|
// Intentar usar BroadcastChannel API (mejor rendimiento)
|
|
@@ -22129,7 +22129,7 @@ class AuthSyncService {
|
|
|
22129
22129
|
* Envía un evento a otras pestañas.
|
|
22130
22130
|
*/
|
|
22131
22131
|
broadcast(event) {
|
|
22132
|
-
if (!this.config
|
|
22132
|
+
if (!this.config?.enableTabSync || !this.isBrowser) {
|
|
22133
22133
|
return;
|
|
22134
22134
|
}
|
|
22135
22135
|
const fullEvent = {
|
|
@@ -22173,7 +22173,7 @@ class AuthSyncService {
|
|
|
22173
22173
|
* Inicializa fallback con storage events.
|
|
22174
22174
|
*/
|
|
22175
22175
|
initStorageEvents() {
|
|
22176
|
-
const storageKey = `${this.config
|
|
22176
|
+
const storageKey = `${this.config?.storagePrefix}sync_event`;
|
|
22177
22177
|
this.storageListener = (event) => {
|
|
22178
22178
|
if (event.key === storageKey && event.newValue) {
|
|
22179
22179
|
try {
|
|
@@ -22191,7 +22191,7 @@ class AuthSyncService {
|
|
|
22191
22191
|
* Envía evento via localStorage (fallback).
|
|
22192
22192
|
*/
|
|
22193
22193
|
broadcastViaStorage(event) {
|
|
22194
|
-
const storageKey = `${this.config
|
|
22194
|
+
const storageKey = `${this.config?.storagePrefix}sync_event`;
|
|
22195
22195
|
try {
|
|
22196
22196
|
// Escribir y luego limpiar para permitir múltiples eventos del mismo tipo
|
|
22197
22197
|
localStorage.setItem(storageKey, JSON.stringify(event));
|
|
@@ -25273,7 +25273,7 @@ class OAuthService {
|
|
|
25273
25273
|
return new Observable(observer => {
|
|
25274
25274
|
// Construir URL de inicio
|
|
25275
25275
|
const redirectUri = `${window.location.origin}/auth/oauth/callback`;
|
|
25276
|
-
const startUrl = `${this.config
|
|
25276
|
+
const startUrl = `${this.config?.apiUrl}/v2/auth/oauth/${provider}/start?redirect_uri=${encodeURIComponent(redirectUri)}`;
|
|
25277
25277
|
// Abrir popup centrado
|
|
25278
25278
|
const width = 500;
|
|
25279
25279
|
const height = 600;
|
|
@@ -25378,7 +25378,7 @@ class OAuthService {
|
|
|
25378
25378
|
startLinkFlow(provider) {
|
|
25379
25379
|
return new Observable(observer => {
|
|
25380
25380
|
const redirectUri = `${window.location.origin}/auth/oauth/callback`;
|
|
25381
|
-
const startUrl = `${this.config
|
|
25381
|
+
const startUrl = `${this.config?.apiUrl}/v2/auth/oauth/link/${provider}/start?redirect_uri=${encodeURIComponent(redirectUri)}`;
|
|
25382
25382
|
const width = 500;
|
|
25383
25383
|
const height = 600;
|
|
25384
25384
|
const left = window.screenX + (window.outerWidth - width) / 2;
|
|
@@ -25429,7 +25429,7 @@ class OAuthService {
|
|
|
25429
25429
|
*/
|
|
25430
25430
|
getLinkedProviders() {
|
|
25431
25431
|
return this.http
|
|
25432
|
-
.get(`${this.config
|
|
25432
|
+
.get(`${this.config?.apiUrl}/v2/auth/oauth/providers`)
|
|
25433
25433
|
.pipe(catchError(error => throwError(() => ({
|
|
25434
25434
|
code: error.error?.code || 'FETCH_ERROR',
|
|
25435
25435
|
message: error.error?.message || 'Error al obtener proveedores vinculados',
|
|
@@ -25440,7 +25440,7 @@ class OAuthService {
|
|
|
25440
25440
|
*/
|
|
25441
25441
|
unlinkProvider(provider) {
|
|
25442
25442
|
return this.http
|
|
25443
|
-
.post(`${this.config
|
|
25443
|
+
.post(`${this.config?.apiUrl}/v2/auth/oauth/unlink`, { provider })
|
|
25444
25444
|
.pipe(catchError(error => throwError(() => ({
|
|
25445
25445
|
code: error.error?.code || 'UNLINK_ERROR',
|
|
25446
25446
|
message: error.error?.message || 'Error al desvincular proveedor',
|
|
@@ -25451,7 +25451,7 @@ class OAuthService {
|
|
|
25451
25451
|
*/
|
|
25452
25452
|
setPassword(password) {
|
|
25453
25453
|
return this.http
|
|
25454
|
-
.post(`${this.config
|
|
25454
|
+
.post(`${this.config?.apiUrl}/v2/auth/oauth/set-password`, { password })
|
|
25455
25455
|
.pipe(catchError(error => throwError(() => ({
|
|
25456
25456
|
code: error.error?.code || 'SET_PASSWORD_ERROR',
|
|
25457
25457
|
message: error.error?.message || 'Error al establecer contraseña',
|
|
@@ -25462,7 +25462,7 @@ class OAuthService {
|
|
|
25462
25462
|
*/
|
|
25463
25463
|
hasPassword() {
|
|
25464
25464
|
return this.http
|
|
25465
|
-
.get(`${this.config
|
|
25465
|
+
.get(`${this.config?.apiUrl}/v2/auth/oauth/has-password`)
|
|
25466
25466
|
.pipe(catchError(error => throwError(() => ({
|
|
25467
25467
|
code: error.error?.code || 'CHECK_PASSWORD_ERROR',
|
|
25468
25468
|
message: error.error?.message || 'Error al verificar contraseña',
|
|
@@ -25759,7 +25759,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
25759
25759
|
* ```
|
|
25760
25760
|
*/
|
|
25761
25761
|
class AuthService {
|
|
25762
|
-
constructor(config, http, router, stateService, tokenService, storageService, syncService, firebaseService, oauthService, messagingService, i18nService, confirmationService) {
|
|
25762
|
+
constructor(config, http, router, stateService, tokenService, storageService, syncService, firebaseService, oauthService, messagingService, i18nService, confirmationService, firestoreInstance) {
|
|
25763
25763
|
this.config = config;
|
|
25764
25764
|
this.http = http;
|
|
25765
25765
|
this.router = router;
|
|
@@ -25772,9 +25772,11 @@ class AuthService {
|
|
|
25772
25772
|
this.messagingService = messagingService;
|
|
25773
25773
|
this.i18nService = i18nService;
|
|
25774
25774
|
this.confirmationService = confirmationService;
|
|
25775
|
+
this.firestoreInstance = firestoreInstance;
|
|
25775
25776
|
// Timer para refresh proactivo
|
|
25776
25777
|
this.refreshTimerId = null;
|
|
25777
25778
|
this.syncSubscription = null;
|
|
25779
|
+
this.firestoreRBACUnsubscribe = null;
|
|
25778
25780
|
// =============================================
|
|
25779
25781
|
// ESTADO PÚBLICO (Signals readonly)
|
|
25780
25782
|
// =============================================
|
|
@@ -25871,7 +25873,7 @@ class AuthService {
|
|
|
25871
25873
|
}
|
|
25872
25874
|
}
|
|
25873
25875
|
// 5. Iniciar sincronización entre pestañas
|
|
25874
|
-
if (this.config
|
|
25876
|
+
if (this.config?.enableTabSync) {
|
|
25875
25877
|
this.syncService.start();
|
|
25876
25878
|
this.syncSubscription = this.syncService.onEvent$.subscribe(event => this.handleSyncEvent(event));
|
|
25877
25879
|
}
|
|
@@ -25880,6 +25882,7 @@ class AuthService {
|
|
|
25880
25882
|
ngOnDestroy() {
|
|
25881
25883
|
this.stopRefreshTimer();
|
|
25882
25884
|
this.syncSubscription?.unsubscribe();
|
|
25885
|
+
this.teardownFirestoreRBACSync();
|
|
25883
25886
|
}
|
|
25884
25887
|
// =============================================
|
|
25885
25888
|
// AUTENTICACIÓN
|
|
@@ -26103,7 +26106,7 @@ class AuthService {
|
|
|
26103
26106
|
this.stateService.updateRefreshToken(response.refreshToken); // NUEVO: guardar refresh rotado
|
|
26104
26107
|
this.storageService.saveAccessToken(response.accessToken, expiresAt);
|
|
26105
26108
|
this.storageService.saveRefreshToken(response.refreshToken); // NUEVO: persistir refresh rotado
|
|
26106
|
-
if (this.config
|
|
26109
|
+
if (this.config?.enableFirebaseIntegration && response.firebaseToken) {
|
|
26107
26110
|
this.signInWithFirebase(response.firebaseToken);
|
|
26108
26111
|
}
|
|
26109
26112
|
this.startRefreshTimer();
|
|
@@ -26189,7 +26192,7 @@ class AuthService {
|
|
|
26189
26192
|
this.signOutFirebase();
|
|
26190
26193
|
this.clearState();
|
|
26191
26194
|
this.syncService.broadcast({ type: 'LOGOUT' });
|
|
26192
|
-
this.router.navigate([this.config
|
|
26195
|
+
this.router.navigate([this.config?.loginRoute]);
|
|
26193
26196
|
}
|
|
26194
26197
|
// =============================================
|
|
26195
26198
|
// MFA SETUP (usuario autenticado)
|
|
@@ -26404,7 +26407,7 @@ class AuthService {
|
|
|
26404
26407
|
this.signOutFirebase();
|
|
26405
26408
|
this.clearState();
|
|
26406
26409
|
this.syncService.broadcast({ type: 'LOGOUT' });
|
|
26407
|
-
this.router.navigate([this.config
|
|
26410
|
+
this.router.navigate([this.config?.loginRoute]);
|
|
26408
26411
|
}
|
|
26409
26412
|
}), catchError(error => this.handleAuthError(error)));
|
|
26410
26413
|
}
|
|
@@ -26481,11 +26484,11 @@ class AuthService {
|
|
|
26481
26484
|
// PRIVATE METHODS
|
|
26482
26485
|
// =============================================
|
|
26483
26486
|
get baseUrl() {
|
|
26484
|
-
return `${this.config
|
|
26487
|
+
return `${this.config?.apiUrl}${this.config?.authPrefix}`;
|
|
26485
26488
|
}
|
|
26486
26489
|
/** Base for /v2/users endpoints (separate from /v2/auth). */
|
|
26487
26490
|
get usersBaseUrl() {
|
|
26488
|
-
return `${this.config
|
|
26491
|
+
return `${this.config?.apiUrl}/v2/users`;
|
|
26489
26492
|
}
|
|
26490
26493
|
handleSuccessfulAuth(response) {
|
|
26491
26494
|
const expiresAt = Date.now() + response.expiresIn * 1000;
|
|
@@ -26518,18 +26521,18 @@ class AuthService {
|
|
|
26518
26521
|
this.syncService.broadcast({ type: 'LOGIN' });
|
|
26519
26522
|
// Integración con Firebase
|
|
26520
26523
|
console.log('[ValtechAuth] handleSuccessfulAuth - Firebase check:', {
|
|
26521
|
-
enableFirebaseIntegration: this.config
|
|
26524
|
+
enableFirebaseIntegration: this.config?.enableFirebaseIntegration,
|
|
26522
26525
|
hasFirebaseTokenKey: 'firebaseToken' in response,
|
|
26523
26526
|
firebaseTokenValue: !!response.firebaseToken,
|
|
26524
26527
|
firebaseTokenLength: response.firebaseToken?.length || 0,
|
|
26525
26528
|
});
|
|
26526
|
-
if (this.config
|
|
26529
|
+
if (this.config?.enableFirebaseIntegration &&
|
|
26527
26530
|
'firebaseToken' in response &&
|
|
26528
26531
|
response.firebaseToken) {
|
|
26529
26532
|
console.log('[ValtechAuth] Calling signInWithFirebase with token length:', response.firebaseToken.length);
|
|
26530
26533
|
this.signInWithFirebase(response.firebaseToken);
|
|
26531
26534
|
}
|
|
26532
|
-
else if (this.config
|
|
26535
|
+
else if (this.config?.enableFirebaseIntegration) {
|
|
26533
26536
|
// El login NO trajo firebaseToken (ej. flujo OAuth que lo perdió). En vez
|
|
26534
26537
|
// de quedar sin sesión de Firebase, recurrimos al fallback self-healing:
|
|
26535
26538
|
// /refresh sí devuelve un firebaseToken confiable.
|
|
@@ -26540,7 +26543,7 @@ class AuthService {
|
|
|
26540
26543
|
console.log('[ValtechAuth] Firebase signin skipped - integración Firebase desactivada');
|
|
26541
26544
|
}
|
|
26542
26545
|
// Registro automático de dispositivo para push notifications
|
|
26543
|
-
if (this.config
|
|
26546
|
+
if (this.config?.enableDeviceRegistration) {
|
|
26544
26547
|
this.registerDeviceIfNeeded(); // fire-and-forget
|
|
26545
26548
|
}
|
|
26546
26549
|
// Sincronizar idioma del usuario con i18n
|
|
@@ -26552,18 +26555,47 @@ class AuthService {
|
|
|
26552
26555
|
console.log(`[ValtechAuth] Language synced to: ${userLang}`);
|
|
26553
26556
|
}
|
|
26554
26557
|
}
|
|
26558
|
+
// Listener Firestore RBAC — opt-in via enableFirestoreRBAC: true
|
|
26559
|
+
const userId = this.stateService.state().userId;
|
|
26560
|
+
if (userId) {
|
|
26561
|
+
this.setupFirestoreRBACSync(userId);
|
|
26562
|
+
}
|
|
26555
26563
|
}
|
|
26556
26564
|
clearState() {
|
|
26557
26565
|
this.stopRefreshTimer();
|
|
26566
|
+
this.teardownFirestoreRBACSync();
|
|
26558
26567
|
this.stateService.reset();
|
|
26559
26568
|
this.storageService.clear();
|
|
26560
26569
|
}
|
|
26570
|
+
setupFirestoreRBACSync(userId) {
|
|
26571
|
+
if (!this.config?.enableFirestoreRBAC || !this.firestoreInstance)
|
|
26572
|
+
return;
|
|
26573
|
+
this.teardownFirestoreRBACSync();
|
|
26574
|
+
const docRef = doc(this.firestoreInstance, 'users', userId);
|
|
26575
|
+
this.firestoreRBACUnsubscribe = onSnapshot(docRef, snap => {
|
|
26576
|
+
const rbac = snap.data()?.['rbac'];
|
|
26577
|
+
if (!rbac)
|
|
26578
|
+
return;
|
|
26579
|
+
const activeOrg = this.stateService.state().activeOrg;
|
|
26580
|
+
if (rbac['activeOrg'] && rbac['activeOrg'] !== activeOrg)
|
|
26581
|
+
return;
|
|
26582
|
+
const roles = rbac['roles'] ?? [];
|
|
26583
|
+
const permissions = rbac['permissions'] ?? [];
|
|
26584
|
+
this.stateService.updatePermissions(roles, permissions, permissions.includes('*:*'));
|
|
26585
|
+
});
|
|
26586
|
+
}
|
|
26587
|
+
teardownFirestoreRBACSync() {
|
|
26588
|
+
if (this.firestoreRBACUnsubscribe) {
|
|
26589
|
+
this.firestoreRBACUnsubscribe();
|
|
26590
|
+
this.firestoreRBACUnsubscribe = null;
|
|
26591
|
+
}
|
|
26592
|
+
}
|
|
26561
26593
|
startRefreshTimer() {
|
|
26562
26594
|
this.stopRefreshTimer();
|
|
26563
26595
|
const state = this.stateService.state();
|
|
26564
26596
|
if (!state.expiresAt)
|
|
26565
26597
|
return;
|
|
26566
|
-
const refreshBeforeMs = (this.config
|
|
26598
|
+
const refreshBeforeMs = (this.config?.refreshBeforeExpiry || 60) * 1000;
|
|
26567
26599
|
const refreshAt = state.expiresAt - refreshBeforeMs;
|
|
26568
26600
|
const delay = refreshAt - Date.now();
|
|
26569
26601
|
if (delay > 0) {
|
|
@@ -26608,7 +26640,7 @@ class AuthService {
|
|
|
26608
26640
|
case 'LOGOUT':
|
|
26609
26641
|
this.stateService.reset();
|
|
26610
26642
|
this.stopRefreshTimer();
|
|
26611
|
-
this.router.navigate([this.config
|
|
26643
|
+
this.router.navigate([this.config?.loginRoute]);
|
|
26612
26644
|
break;
|
|
26613
26645
|
case 'PERMISSIONS_UPDATE': {
|
|
26614
26646
|
const perms = this.storageService.loadPermissions();
|
|
@@ -26654,7 +26686,7 @@ class AuthService {
|
|
|
26654
26686
|
}
|
|
26655
26687
|
}
|
|
26656
26688
|
async signOutFirebase() {
|
|
26657
|
-
if (!this.config
|
|
26689
|
+
if (!this.config?.enableFirebaseIntegration)
|
|
26658
26690
|
return;
|
|
26659
26691
|
try {
|
|
26660
26692
|
if (this.firebaseService) {
|
|
@@ -26685,7 +26717,7 @@ class AuthService {
|
|
|
26685
26717
|
* Fire-and-forget: se invoca con `void` para no demorar `initialize()`.
|
|
26686
26718
|
*/
|
|
26687
26719
|
async ensureFirebaseSessionOnBootstrap() {
|
|
26688
|
-
if (!this.config
|
|
26720
|
+
if (!this.config?.enableFirebaseIntegration || !this.firebaseService)
|
|
26689
26721
|
return;
|
|
26690
26722
|
// Dar a la persistencia IndexedDB propia de Firebase Auth una oportunidad
|
|
26691
26723
|
// de auto-restaurarse (navegador normal). En una PWA standalone de iOS
|
|
@@ -26711,7 +26743,7 @@ class AuthService {
|
|
|
26711
26743
|
* desde el debug-console qué disparó el fallback.
|
|
26712
26744
|
*/
|
|
26713
26745
|
async reestablishFirebaseViaRefresh(reason) {
|
|
26714
|
-
if (!this.config
|
|
26746
|
+
if (!this.config?.enableFirebaseIntegration || !this.firebaseService)
|
|
26715
26747
|
return;
|
|
26716
26748
|
console.log(`[FBAuth] fallback — re-estableciendo Firebase vía /refresh (motivo: ${reason})`);
|
|
26717
26749
|
try {
|
|
@@ -26784,7 +26816,7 @@ class AuthService {
|
|
|
26784
26816
|
if (token) {
|
|
26785
26817
|
// Eliminar del backend
|
|
26786
26818
|
await firstValueFrom(this.http
|
|
26787
|
-
.request('DELETE', `${this.config
|
|
26819
|
+
.request('DELETE', `${this.config?.apiUrl}/v2/users/me/devices/by-token`, {
|
|
26788
26820
|
body: { token },
|
|
26789
26821
|
})
|
|
26790
26822
|
.pipe(catchError(() => of(null))));
|
|
@@ -26854,7 +26886,7 @@ class AuthService {
|
|
|
26854
26886
|
}
|
|
26855
26887
|
// Registrar en backend
|
|
26856
26888
|
const { platform, browser, os } = this.detectPlatformInfo();
|
|
26857
|
-
const response = await firstValueFrom(this.http.post(`${this.config
|
|
26889
|
+
const response = await firstValueFrom(this.http.post(`${this.config?.apiUrl}/v2/users/me/devices`, {
|
|
26858
26890
|
token,
|
|
26859
26891
|
platform,
|
|
26860
26892
|
browser,
|
|
@@ -26877,7 +26909,7 @@ class AuthService {
|
|
|
26877
26909
|
*/
|
|
26878
26910
|
async registerDeviceIfNeeded() {
|
|
26879
26911
|
// Solo si está habilitado y messaging está disponible
|
|
26880
|
-
if (!this.config
|
|
26912
|
+
if (!this.config?.enableDeviceRegistration || !this.messagingService) {
|
|
26881
26913
|
return false;
|
|
26882
26914
|
}
|
|
26883
26915
|
try {
|
|
@@ -26897,7 +26929,7 @@ class AuthService {
|
|
|
26897
26929
|
}
|
|
26898
26930
|
// Registrar en backend
|
|
26899
26931
|
const { platform, browser, os } = this.detectPlatformInfo();
|
|
26900
|
-
await firstValueFrom(this.http.post(`${this.config
|
|
26932
|
+
await firstValueFrom(this.http.post(`${this.config?.apiUrl}/v2/users/me/devices`, {
|
|
26901
26933
|
token,
|
|
26902
26934
|
platform,
|
|
26903
26935
|
browser,
|
|
@@ -26916,7 +26948,7 @@ class AuthService {
|
|
|
26916
26948
|
* Elimina el dispositivo del backend y borra el token FCM.
|
|
26917
26949
|
*/
|
|
26918
26950
|
async unregisterDevice() {
|
|
26919
|
-
if (!this.config
|
|
26951
|
+
if (!this.config?.enableDeviceRegistration || !this.messagingService) {
|
|
26920
26952
|
return;
|
|
26921
26953
|
}
|
|
26922
26954
|
try {
|
|
@@ -26924,7 +26956,7 @@ class AuthService {
|
|
|
26924
26956
|
if (token) {
|
|
26925
26957
|
// Delete from backend (fire and forget)
|
|
26926
26958
|
this.http
|
|
26927
|
-
.request('DELETE', `${this.config
|
|
26959
|
+
.request('DELETE', `${this.config?.apiUrl}/v2/users/me/devices/by-token`, {
|
|
26928
26960
|
body: { token },
|
|
26929
26961
|
})
|
|
26930
26962
|
.pipe(catchError(() => of(null)))
|
|
@@ -26976,7 +27008,7 @@ class AuthService {
|
|
|
26976
27008
|
}
|
|
26977
27009
|
return { platform: 'web', browser, os };
|
|
26978
27010
|
}
|
|
26979
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AuthService, deps: [{ token: VALTECH_AUTH_CONFIG, optional: true }, { token: i1$8.HttpClient }, { token: i1$1.Router }, { token: AuthStateService }, { token: TokenService }, { token: AuthStorageService }, { token: AuthSyncService }, { token: FirebaseService }, { token: OAuthService }, { token: MessagingService, optional: true }, { token: I18nService, optional: true }, { token: ConfirmationDialogService }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
27011
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AuthService, deps: [{ token: VALTECH_AUTH_CONFIG, optional: true }, { token: i1$8.HttpClient }, { token: i1$1.Router }, { token: AuthStateService }, { token: TokenService }, { token: AuthStorageService }, { token: AuthSyncService }, { token: FirebaseService }, { token: OAuthService }, { token: MessagingService, optional: true }, { token: I18nService, optional: true }, { token: ConfirmationDialogService }, { token: i1$5.Firestore, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
26980
27012
|
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AuthService, providedIn: 'root' }); }
|
|
26981
27013
|
}
|
|
26982
27014
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AuthService, decorators: [{
|
|
@@ -26991,7 +27023,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
26991
27023
|
type: Optional
|
|
26992
27024
|
}] }, { type: I18nService, decorators: [{
|
|
26993
27025
|
type: Optional
|
|
26994
|
-
}] }, { type: ConfirmationDialogService }
|
|
27026
|
+
}] }, { type: ConfirmationDialogService }, { type: i1$5.Firestore, decorators: [{
|
|
27027
|
+
type: Optional
|
|
27028
|
+
}] }] });
|
|
26995
27029
|
|
|
26996
27030
|
addIcons({ checkmarkCircle, closeCircle, alertCircle });
|
|
26997
27031
|
/**
|
|
@@ -30165,7 +30199,7 @@ class DeviceService {
|
|
|
30165
30199
|
this.http = http;
|
|
30166
30200
|
}
|
|
30167
30201
|
get baseUrl() {
|
|
30168
|
-
return `${this.config
|
|
30202
|
+
return `${this.config?.apiUrl}/v2/users/me/devices`;
|
|
30169
30203
|
}
|
|
30170
30204
|
/**
|
|
30171
30205
|
* Lista todos los dispositivos registrados del usuario.
|
|
@@ -30220,7 +30254,7 @@ class DeviceService {
|
|
|
30220
30254
|
* ```
|
|
30221
30255
|
*/
|
|
30222
30256
|
validateAction(token) {
|
|
30223
|
-
return this.http.post(`${this.config
|
|
30257
|
+
return this.http.post(`${this.config?.apiUrl}/v2/actions/validate`, { token });
|
|
30224
30258
|
}
|
|
30225
30259
|
/**
|
|
30226
30260
|
* Ejecuta una acción de dispositivo desde un token de email.
|
|
@@ -30243,7 +30277,7 @@ class DeviceService {
|
|
|
30243
30277
|
*/
|
|
30244
30278
|
executeAction(token) {
|
|
30245
30279
|
// Usa el endpoint unificado de acciones
|
|
30246
|
-
return this.http.post(`${this.config
|
|
30280
|
+
return this.http.post(`${this.config?.apiUrl}/v2/actions/execute`, { token }).pipe(map$1(response => ({
|
|
30247
30281
|
operationId: response.operationId,
|
|
30248
30282
|
success: response.success,
|
|
30249
30283
|
message: response.message,
|
|
@@ -30302,7 +30336,7 @@ class SessionService {
|
|
|
30302
30336
|
this.http = http;
|
|
30303
30337
|
}
|
|
30304
30338
|
get baseUrl() {
|
|
30305
|
-
return `${this.config
|
|
30339
|
+
return `${this.config?.apiUrl}/v2/users/me/sessions`;
|
|
30306
30340
|
}
|
|
30307
30341
|
/**
|
|
30308
30342
|
* Lista todas las sesiones activas del usuario.
|
|
@@ -30625,7 +30659,7 @@ class HandoffService {
|
|
|
30625
30659
|
const tokenParam = options.tokenParam ?? HANDOFF_TOKEN_PARAM;
|
|
30626
30660
|
const routeParam = options.routeParam ?? HANDOFF_ROUTE_PARAM;
|
|
30627
30661
|
const defaultRoute = options.defaultRoute ?? '/';
|
|
30628
|
-
const errorRoute = options.errorRoute ?? this.config
|
|
30662
|
+
const errorRoute = options.errorRoute ?? this.config?.loginRoute ?? '/login';
|
|
30629
30663
|
const params = new URLSearchParams(window.location.search);
|
|
30630
30664
|
const token = params.get(tokenParam);
|
|
30631
30665
|
if (!token) {
|
|
@@ -30655,7 +30689,7 @@ class HandoffService {
|
|
|
30655
30689
|
});
|
|
30656
30690
|
}
|
|
30657
30691
|
get baseUrl() {
|
|
30658
|
-
return `${this.config
|
|
30692
|
+
return `${this.config?.apiUrl}${this.config?.authPrefix}`;
|
|
30659
30693
|
}
|
|
30660
30694
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: HandoffService, deps: [{ token: VALTECH_AUTH_CONFIG, optional: true }, { token: i1$8.HttpClient }, { token: AuthService }, { token: i1$1.Router }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
30661
30695
|
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: HandoffService, providedIn: 'root' }); }
|
|
@@ -30843,7 +30877,7 @@ class NotificationActionService {
|
|
|
30843
30877
|
if (!route) {
|
|
30844
30878
|
return 'no-action-route';
|
|
30845
30879
|
}
|
|
30846
|
-
const currentApp = this.config
|
|
30880
|
+
const currentApp = this.config?.appId;
|
|
30847
30881
|
const targetApp = notif.appId;
|
|
30848
30882
|
// 2) Cross-app: handoff + full redirect
|
|
30849
30883
|
//
|
|
@@ -30853,7 +30887,7 @@ class NotificationActionService {
|
|
|
30853
30887
|
if (targetApp && currentApp && targetApp !== currentApp) {
|
|
30854
30888
|
try {
|
|
30855
30889
|
const resp = await firstValueFrom(this.handoff.createHandoff({ targetAppId: targetApp, route }));
|
|
30856
|
-
const baseUrl = resp.targetBaseUrl ?? this.config
|
|
30890
|
+
const baseUrl = resp.targetBaseUrl ?? this.config?.appUrls?.[targetApp];
|
|
30857
30891
|
if (!baseUrl) {
|
|
30858
30892
|
console.warn(`[NotificationAction] No baseUrl for app '${targetApp}' — backend did not return targetBaseUrl and no appUrls fallback configured`);
|
|
30859
30893
|
return 'cross-app-unconfigured';
|