valtech-components 2.0.828 → 2.0.830
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/app-version/app-version.service.mjs +10 -1
- package/esm2022/lib/services/auth/auth.service.mjs +55 -10
- package/esm2022/lib/version.mjs +2 -2
- package/fesm2022/valtech-components.mjs +64 -10
- package/fesm2022/valtech-components.mjs.map +1 -1
- package/lib/services/auth/auth.service.d.ts +13 -0
- package/lib/version.d.ts +1 -1
- package/package.json +1 -1
|
@@ -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.830';
|
|
57
57
|
|
|
58
58
|
/**
|
|
59
59
|
* Servicio para gestionar presets de componentes.
|
|
@@ -19839,6 +19839,15 @@ class AppVersionService {
|
|
|
19839
19839
|
this.swUpdate.versionUpdates
|
|
19840
19840
|
.pipe(filter$1(evt => evt.type === 'VERSION_READY'), takeUntilDestroyed(this.destroyRef))
|
|
19841
19841
|
.subscribe(() => this.swUpdateReady.set(true));
|
|
19842
|
+
// SW en estado irrecuperable — la caché del service worker se corrompió o
|
|
19843
|
+
// fue parcialmente evictada (común en PWAs standalone de iOS tras deploys
|
|
19844
|
+
// repetidos). La app no puede cargar sus assets → pantalla en blanco.
|
|
19845
|
+
// Recuperación recomendada por Angular: recargar para traer todo fresco
|
|
19846
|
+
// desde la red.
|
|
19847
|
+
this.swUpdate.unrecoverable.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(event => {
|
|
19848
|
+
console.error('[AppVersionService] SW unrecoverable — reloading:', event.reason);
|
|
19849
|
+
this.document.defaultView?.location.reload();
|
|
19850
|
+
});
|
|
19842
19851
|
// Chequeo periódico.
|
|
19843
19852
|
const intervalMs = this.serviceConfig?.checkIntervalMs ?? DEFAULT_APP_VERSION_SERVICE_CONFIG.checkIntervalMs;
|
|
19844
19853
|
interval(intervalMs)
|
|
@@ -24636,14 +24645,34 @@ class AuthService {
|
|
|
24636
24645
|
void this.ensureFirebaseSessionOnBootstrap();
|
|
24637
24646
|
}
|
|
24638
24647
|
else if (storedState.refreshToken) {
|
|
24639
|
-
// 4. Token expirado pero hay refresh token
|
|
24640
|
-
|
|
24641
|
-
|
|
24648
|
+
// 4. Token expirado pero hay refresh token.
|
|
24649
|
+
//
|
|
24650
|
+
// NO bloqueamos el bootstrap esperando la red: un /refresh en una
|
|
24651
|
+
// Lambda fría son 2-5s de pantalla en blanco (Angular no renderiza
|
|
24652
|
+
// nada hasta que el APP_INITIALIZER resuelve).
|
|
24653
|
+
//
|
|
24654
|
+
// Restauración optimista: el access token expiró pero sus claims
|
|
24655
|
+
// (uid/email/roles) siguen decodificables — `parseToken` NO valida
|
|
24656
|
+
// `exp`. Restauramos la sesión desde esos claims para que la app
|
|
24657
|
+
// renderice el shell autenticado de inmediato, y disparamos el
|
|
24658
|
+
// /refresh en segundo plano (fire-and-forget).
|
|
24659
|
+
//
|
|
24660
|
+
// Seguridad de la ventana sub-segundo antes de que el refresh llegue:
|
|
24661
|
+
// cualquier API call sale con el token expirado → 401 → el
|
|
24662
|
+
// authInterceptor refresca + reintenta automáticamente. Si el refresh
|
|
24663
|
+
// de fondo falla → signOut + clearState.
|
|
24664
|
+
console.log('[ValtechAuth] bootstrap — access token expired, refreshing in background');
|
|
24665
|
+
this.stateService.restoreFromStorage(storedState);
|
|
24666
|
+
const expiredClaims = this.tokenService.parseToken(storedState.accessToken);
|
|
24667
|
+
if (expiredClaims) {
|
|
24668
|
+
this.stateService.updateUserInfo(expiredClaims.uid, expiredClaims.email);
|
|
24642
24669
|
}
|
|
24643
|
-
|
|
24670
|
+
// Refresh en segundo plano — NO se hace await: initialize() resuelve ya.
|
|
24671
|
+
firstValueFrom(this.refreshAccessToken()).catch(() => {
|
|
24672
|
+
console.warn('[ValtechAuth] bootstrap — background refresh failed, signing out');
|
|
24644
24673
|
this.signOutFirebase();
|
|
24645
24674
|
this.clearState();
|
|
24646
|
-
}
|
|
24675
|
+
});
|
|
24647
24676
|
}
|
|
24648
24677
|
else {
|
|
24649
24678
|
this.signOutFirebase();
|
|
@@ -25286,8 +25315,15 @@ class AuthService {
|
|
|
25286
25315
|
console.log('[ValtechAuth] Calling signInWithFirebase with token length:', response.firebaseToken.length);
|
|
25287
25316
|
this.signInWithFirebase(response.firebaseToken);
|
|
25288
25317
|
}
|
|
25318
|
+
else if (this.config.enableFirebaseIntegration) {
|
|
25319
|
+
// El login NO trajo firebaseToken (ej. flujo OAuth que lo perdió). En vez
|
|
25320
|
+
// de quedar sin sesión de Firebase, recurrimos al fallback self-healing:
|
|
25321
|
+
// /refresh sí devuelve un firebaseToken confiable.
|
|
25322
|
+
console.log('[FBAuth] login response sin firebaseToken → recurriendo a fallback /refresh');
|
|
25323
|
+
void this.reestablishFirebaseViaRefresh('login-missing-firebase-token');
|
|
25324
|
+
}
|
|
25289
25325
|
else {
|
|
25290
|
-
console.log('[ValtechAuth] Firebase signin skipped -
|
|
25326
|
+
console.log('[ValtechAuth] Firebase signin skipped - integración Firebase desactivada');
|
|
25291
25327
|
}
|
|
25292
25328
|
// Registro automático de dispositivo para push notifications
|
|
25293
25329
|
if (this.config.enableDeviceRegistration) {
|
|
@@ -25438,13 +25474,31 @@ class AuthService {
|
|
|
25438
25474
|
console.log('[FBAuth] bootstrap — Firebase session restored on its own');
|
|
25439
25475
|
return;
|
|
25440
25476
|
}
|
|
25441
|
-
console.log('[FBAuth] bootstrap — session valid but Firebase NOT ready →
|
|
25477
|
+
console.log('[FBAuth] bootstrap — session valid but Firebase NOT ready → recurriendo a fallback');
|
|
25478
|
+
await this.reestablishFirebaseViaRefresh('bootstrap-session-restore');
|
|
25479
|
+
}
|
|
25480
|
+
/**
|
|
25481
|
+
* Fallback self-healing de Firebase Auth. Pide un firebaseToken fresco vía
|
|
25482
|
+
* `/refresh` (que sí lo devuelve de forma confiable) y, en éxito,
|
|
25483
|
+
* `refreshAccessToken()` ya ejecuta `signInWithFirebase()`.
|
|
25484
|
+
*
|
|
25485
|
+
* Se invoca cuando un path de auth dejó la sesión de Firebase sin establecer:
|
|
25486
|
+
* - login OAuth/password que volvió sin `firebaseToken`,
|
|
25487
|
+
* - cold launch de PWA iOS sin persistencia de Firebase.
|
|
25488
|
+
*
|
|
25489
|
+
* `reason` aparece en los logs `[FBAuth] fallback` para poder atestiguar
|
|
25490
|
+
* desde el debug-console qué disparó el fallback.
|
|
25491
|
+
*/
|
|
25492
|
+
async reestablishFirebaseViaRefresh(reason) {
|
|
25493
|
+
if (!this.config.enableFirebaseIntegration || !this.firebaseService)
|
|
25494
|
+
return;
|
|
25495
|
+
console.log(`[FBAuth] fallback — re-estableciendo Firebase vía /refresh (motivo: ${reason})`);
|
|
25442
25496
|
try {
|
|
25443
|
-
// refreshAccessToken() ya llama signInWithFirebase() en éxito.
|
|
25444
25497
|
await firstValueFrom(this.refreshAccessToken());
|
|
25498
|
+
console.log(`[FBAuth] fallback — /refresh OK, Firebase re-establecido (motivo: ${reason})`);
|
|
25445
25499
|
}
|
|
25446
25500
|
catch (e) {
|
|
25447
|
-
console.warn(
|
|
25501
|
+
console.warn(`[FBAuth] fallback — /refresh falló (motivo: ${reason}):`, e);
|
|
25448
25502
|
}
|
|
25449
25503
|
}
|
|
25450
25504
|
// =============================================
|