@dsivd/prestations-ng 19.1.1 → 19.1.2

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/CHANGELOG.md CHANGED
@@ -6,6 +6,16 @@
6
6
 
7
7
  ---
8
8
 
9
+ ## [19.1.2]
10
+
11
+ ### Fixed
12
+
13
+ - [provide-prestations-ng-core.ts](projects/prestations-ng/src/provide-prestations-ng-core.ts)
14
+ - `providePrestationsNgCore()` registers again the HTTP interceptors lost with `FoehnPageModule` in 19.0.0:
15
+ the `foehn-transmit-waiting-modal` is displayed again during a long transmission, the warning before the
16
+ expiration of the session receives its date again, and a new version of the application deployed meanwhile is
17
+ detected again.
18
+
9
19
  ## [19.1.1]
10
20
 
11
21
  ### Fixed
@@ -13,12 +23,12 @@
13
23
  - [foehn-input-phone.component.ts](projects/prestations-ng/src/foehn-input/foehn-input-phone.component.ts)
14
24
  - fixed help texts to be aligned with ch.vd.cyber.prestationsbe.validation.PhoneNumberValidator (prestations-be)
15
25
  - dictionary keys have changed to be more explicit :
16
- - foehn-input-phone.STANDARD_HELPTEXT_SWISS_FIX_AND_MOBILE
17
- - foehn-input-phone.STANDARD_HELPTEXT_SWISS_FIX_ONLY
18
- - foehn-input-phone.STANDARD_HELPTEXT_SWISS_MOBILE_ONLY
19
- - foehn-input-phone.STANDARD_HELPTEXT_INTERNATIONAL_FIX_AND_MOBILE
20
- - foehn-input-phone.STANDARD_HELPTEXT_INTERNATIONAL_FIX_ONLY
21
- - foehn-input-phone.STANDARD_HELPTEXT_INTERNATIONAL_MOBILE_ONLY
26
+ - foehn-input-phone.STANDARD_HELPTEXT_SWISS_FIX_AND_MOBILE
27
+ - foehn-input-phone.STANDARD_HELPTEXT_SWISS_FIX_ONLY
28
+ - foehn-input-phone.STANDARD_HELPTEXT_SWISS_MOBILE_ONLY
29
+ - foehn-input-phone.STANDARD_HELPTEXT_INTERNATIONAL_FIX_AND_MOBILE
30
+ - foehn-input-phone.STANDARD_HELPTEXT_INTERNATIONAL_FIX_ONLY
31
+ - foehn-input-phone.STANDARD_HELPTEXT_INTERNATIONAL_MOBILE_ONLY
22
32
 
23
33
  ## [19.1.0] - should be aligned with prestations-be 19.1.x
24
34
 
Binary file
@@ -5397,6 +5397,193 @@ class I18nForm {
5397
5397
  }
5398
5398
  }
5399
5399
 
5400
+ const APP_VERSION_HEADER = 'app-version';
5401
+ class AppInfoHeadersInterceptor {
5402
+ constructor() {
5403
+ this.foehnPageService = inject(FoehnPageService);
5404
+ this.errorListenerRegistered = false;
5405
+ // Enregistrer une seule fois
5406
+ if (!this.errorListenerRegistered) {
5407
+ window.addEventListener('error', (event) => {
5408
+ if (event.message?.includes('ChunkLoadError') ||
5409
+ event.message?.includes('Loading chunk')) {
5410
+ this.foehnPageService.setAppVersionMismatch();
5411
+ }
5412
+ });
5413
+ this.errorListenerRegistered = true;
5414
+ }
5415
+ }
5416
+ intercept(request, next) {
5417
+ return next.handle(request).pipe(tap$1((httpEvent) => {
5418
+ if (httpEvent instanceof HttpResponse) {
5419
+ const appVersionInHeader = httpEvent.headers.get(APP_VERSION_HEADER);
5420
+ if (!this.appVersion?.length) {
5421
+ this.appVersion = appVersionInHeader;
5422
+ }
5423
+ else if (appVersionInHeader &&
5424
+ this.appVersion !== appVersionInHeader) {
5425
+ this.foehnPageService.setAppVersionMismatch();
5426
+ }
5427
+ }
5428
+ }));
5429
+ }
5430
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.21", ngImport: i0, type: AppInfoHeadersInterceptor, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
5431
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.21", ngImport: i0, type: AppInfoHeadersInterceptor, providedIn: 'root' }); }
5432
+ }
5433
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.21", ngImport: i0, type: AppInfoHeadersInterceptor, decorators: [{
5434
+ type: Injectable,
5435
+ args: [{
5436
+ providedIn: 'root',
5437
+ }]
5438
+ }], ctorParameters: () => [] });
5439
+ const APP_INFO_HEADERS_INTERCEPTOR_PROVIDER = [
5440
+ {
5441
+ provide: HTTP_INTERCEPTORS,
5442
+ useExisting: AppInfoHeadersInterceptor,
5443
+ multi: true,
5444
+ },
5445
+ ];
5446
+
5447
+ class CurrentSessionExpiration {
5448
+ }
5449
+
5450
+ class IntervalHelper {
5451
+ static accurateInterval(
5452
+ // eslint-disable-next-line
5453
+ callBack, intervalInMilliseconds,
5454
+ // eslint-disable-next-line
5455
+ errorCallBack) {
5456
+ let timeout = null;
5457
+ let nextAt = Date.now() + intervalInMilliseconds;
5458
+ const clear = () => clearTimeout(timeout);
5459
+ const timerHandler = () => {
5460
+ nextAt += intervalInMilliseconds;
5461
+ // Avoid time drift by doing "nextAt - Date.now()"
5462
+ const calculatedTimeout = nextAt - Date.now();
5463
+ // Verify browser tab inactivity
5464
+ if (calculatedTimeout < 0) {
5465
+ if (errorCallBack) {
5466
+ clear();
5467
+ return errorCallBack();
5468
+ }
5469
+ }
5470
+ timeout = setTimeout(timerHandler, Math.max(0, nextAt - Date.now()));
5471
+ callBack();
5472
+ };
5473
+ // Avoid time drift by doing "nextAt - Date.now()"
5474
+ timeout = setTimeout(timerHandler, nextAt - Date.now());
5475
+ return { clear };
5476
+ }
5477
+ }
5478
+
5479
+ class DemandeExpirationService {
5480
+ constructor() {
5481
+ this.PULLING_IN_MILLISECONDS = 1000;
5482
+ this._demandeExpirationDateTimeSubject = new BehaviorSubject(null);
5483
+ this.intervalSubject = new BehaviorSubject(null);
5484
+ }
5485
+ shouldDisplayExpirationTimerMessage() {
5486
+ return combineLatest([
5487
+ this.getDemandeExpirationDateTime(),
5488
+ this.intervalSubject.asObservable(),
5489
+ ]).pipe(map(([value]) => !dayjs().isBefore(value?.expiration)), tap((visible) => {
5490
+ if (visible) {
5491
+ this.clearPulling();
5492
+ }
5493
+ }), shareReplay(1));
5494
+ }
5495
+ setDemandeExpirationDateTime(expiration) {
5496
+ this._demandeExpirationDateTimeSubject.next(expiration);
5497
+ }
5498
+ getDemandeExpirationDateTime() {
5499
+ return this._demandeExpirationDateTimeSubject.asObservable().pipe(filter((value) => !!value && value.expiration?.isValid()), tap((value) => {
5500
+ if (dayjs().isBefore(value.expiration)) {
5501
+ this.startPulling();
5502
+ }
5503
+ }), shareReplay(1));
5504
+ }
5505
+ startPulling() {
5506
+ this.clearPulling();
5507
+ this.interval = IntervalHelper.accurateInterval(() => {
5508
+ this.intervalSubject.next();
5509
+ }, this.PULLING_IN_MILLISECONDS, () => {
5510
+ this.startPulling();
5511
+ });
5512
+ }
5513
+ clearPulling() {
5514
+ this.interval?.clear();
5515
+ }
5516
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.21", ngImport: i0, type: DemandeExpirationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
5517
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.21", ngImport: i0, type: DemandeExpirationService, providedIn: 'root' }); }
5518
+ }
5519
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.21", ngImport: i0, type: DemandeExpirationService, decorators: [{
5520
+ type: Injectable,
5521
+ args: [{
5522
+ providedIn: 'root',
5523
+ }]
5524
+ }] });
5525
+
5526
+ const EXPIRATION_HEADER = 'Sessions-Expirations';
5527
+ class DemandeExpirationInterceptor {
5528
+ constructor() {
5529
+ this.demandeExpirationService = inject(DemandeExpirationService);
5530
+ }
5531
+ intercept(request, next) {
5532
+ return next.handle(request).pipe(tap$1((httpEvent) => {
5533
+ if (httpEvent.type === HttpEventType.Sent) {
5534
+ return;
5535
+ }
5536
+ if (httpEvent instanceof HttpResponse) {
5537
+ if (httpEvent.headers.has(EXPIRATION_HEADER)) {
5538
+ this.manageDemandeExpirationHeader(httpEvent.headers.get(EXPIRATION_HEADER), httpEvent.body);
5539
+ }
5540
+ }
5541
+ }));
5542
+ }
5543
+ manageDemandeExpirationHeader(expirationByDemande, responseBody) {
5544
+ const expirationByDemandeMap = this.getExpirationByDemandeMap(expirationByDemande);
5545
+ const expiration = new CurrentSessionExpiration();
5546
+ const reference = responseBody?.meta?.reference || '';
5547
+ const dateTimeForReference = expirationByDemandeMap.get(reference);
5548
+ const dateTimeForIam = expirationByDemandeMap.get('IAM');
5549
+ if (dateTimeForReference) {
5550
+ expiration.type = 'SESSION-TOKEN';
5551
+ expiration.expiration = dayjs(dateTimeForReference);
5552
+ }
5553
+ else if (dateTimeForIam) {
5554
+ expiration.type = 'IAM';
5555
+ expiration.expiration = dayjs(dateTimeForIam);
5556
+ }
5557
+ if (expiration.expiration?.isValid()) {
5558
+ this.demandeExpirationService.setDemandeExpirationDateTime(expiration);
5559
+ }
5560
+ }
5561
+ getExpirationByDemandeMap(expirationByDemande) {
5562
+ const myMap = new Map();
5563
+ const expirationByDemandesAsArray = expirationByDemande.split(';');
5564
+ expirationByDemandesAsArray.forEach((value) => {
5565
+ const valueAsArray = value.split(',');
5566
+ myMap.set(valueAsArray[0], new Date(valueAsArray[1]));
5567
+ });
5568
+ return myMap;
5569
+ }
5570
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.21", ngImport: i0, type: DemandeExpirationInterceptor, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
5571
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.21", ngImport: i0, type: DemandeExpirationInterceptor, providedIn: 'root' }); }
5572
+ }
5573
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.21", ngImport: i0, type: DemandeExpirationInterceptor, decorators: [{
5574
+ type: Injectable,
5575
+ args: [{
5576
+ providedIn: 'root',
5577
+ }]
5578
+ }] });
5579
+ const DEMANDE_EXPIRATION_INTERCEPTOR_PROVIDER = [
5580
+ {
5581
+ provide: HTTP_INTERCEPTORS,
5582
+ useExisting: DemandeExpirationInterceptor,
5583
+ multi: true,
5584
+ },
5585
+ ];
5586
+
5400
5587
  const OIDC_ENABLED = new InjectionToken('enable.oidc.interceptor', {
5401
5588
  factory: () => false,
5402
5589
  });
@@ -5468,6 +5655,11 @@ function providePrestationsNgCore() {
5468
5655
  useExisting: IamExpiredInterceptorService,
5469
5656
  multi: true,
5470
5657
  },
5658
+ // Formerly provided by FoehnPageModule: the version of the application changed during a deployment,
5659
+ // the expiration of the session and the modal displayed during the transmission
5660
+ APP_INFO_HEADERS_INTERCEPTOR_PROVIDER,
5661
+ DEMANDE_EXPIRATION_INTERCEPTOR_PROVIDER,
5662
+ DEMANDE_TRANSMIT_INTERCEPTOR_PROVIDER,
5471
5663
  {
5472
5664
  provide: ErrorHandler,
5473
5665
  useClass: ChunkLoadErrorHandler,
@@ -7288,82 +7480,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.21", ngImpo
7288
7480
  args: [{ selector: 'foehn-app-version-mis-match-modal', imports: [FoehnModalComponent, AsyncPipe, SdkDictionaryPipe], template: "<foehn-modal\n [id]=\"'foehn-app-version-mismatch-modal'\"\n [modalHeaderText]=\"\n 'foehn-app-version-mismatch-modal.title' | fromDictionary\n \"\n modalSize=\"modal-md\"\n [isModalVisible]=\"isModalVisible | async\"\n [closeable]=\"false\"\n>\n <div\n id=\"foehn-app-version-mismatch-modal-body\"\n [innerHTML]=\"\n 'foehn-app-version-mismatch-modal.content' | fromDictionary\n \"\n ></div>\n\n <div modal-footer class=\"w-100\">\n <div class=\"d-flex\">\n <button\n id=\"saveAndReloadBtn\"\n type=\"button\"\n class=\"btn btn-primary ms-auto\"\n [innerHTML]=\"\n (hasDemandeInProgress\n ? 'foehn-app-version-mismatch-modal.btn.save-and-reload'\n : 'foehn-app-version-mismatch-modal.btn.reload'\n ) | fromDictionary\n \"\n (click)=\"saveAndReload()\"\n ></button>\n </div>\n </div>\n</foehn-modal>\n", styles: [":host ::ng-deep .modal{z-index:10000}\n"] }]
7289
7481
  }], ctorParameters: () => [] });
7290
7482
 
7291
- class IntervalHelper {
7292
- static accurateInterval(
7293
- // eslint-disable-next-line
7294
- callBack, intervalInMilliseconds,
7295
- // eslint-disable-next-line
7296
- errorCallBack) {
7297
- let timeout = null;
7298
- let nextAt = Date.now() + intervalInMilliseconds;
7299
- const clear = () => clearTimeout(timeout);
7300
- const timerHandler = () => {
7301
- nextAt += intervalInMilliseconds;
7302
- // Avoid time drift by doing "nextAt - Date.now()"
7303
- const calculatedTimeout = nextAt - Date.now();
7304
- // Verify browser tab inactivity
7305
- if (calculatedTimeout < 0) {
7306
- if (errorCallBack) {
7307
- clear();
7308
- return errorCallBack();
7309
- }
7310
- }
7311
- timeout = setTimeout(timerHandler, Math.max(0, nextAt - Date.now()));
7312
- callBack();
7313
- };
7314
- // Avoid time drift by doing "nextAt - Date.now()"
7315
- timeout = setTimeout(timerHandler, nextAt - Date.now());
7316
- return { clear };
7317
- }
7318
- }
7319
-
7320
- class DemandeExpirationService {
7321
- constructor() {
7322
- this.PULLING_IN_MILLISECONDS = 1000;
7323
- this._demandeExpirationDateTimeSubject = new BehaviorSubject(null);
7324
- this.intervalSubject = new BehaviorSubject(null);
7325
- }
7326
- shouldDisplayExpirationTimerMessage() {
7327
- return combineLatest([
7328
- this.getDemandeExpirationDateTime(),
7329
- this.intervalSubject.asObservable(),
7330
- ]).pipe(map(([value]) => !dayjs().isBefore(value?.expiration)), tap((visible) => {
7331
- if (visible) {
7332
- this.clearPulling();
7333
- }
7334
- }), shareReplay(1));
7335
- }
7336
- setDemandeExpirationDateTime(expiration) {
7337
- this._demandeExpirationDateTimeSubject.next(expiration);
7338
- }
7339
- getDemandeExpirationDateTime() {
7340
- return this._demandeExpirationDateTimeSubject.asObservable().pipe(filter((value) => !!value && value.expiration?.isValid()), tap((value) => {
7341
- if (dayjs().isBefore(value.expiration)) {
7342
- this.startPulling();
7343
- }
7344
- }), shareReplay(1));
7345
- }
7346
- startPulling() {
7347
- this.clearPulling();
7348
- this.interval = IntervalHelper.accurateInterval(() => {
7349
- this.intervalSubject.next();
7350
- }, this.PULLING_IN_MILLISECONDS, () => {
7351
- this.startPulling();
7352
- });
7353
- }
7354
- clearPulling() {
7355
- this.interval?.clear();
7356
- }
7357
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.21", ngImport: i0, type: DemandeExpirationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
7358
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.21", ngImport: i0, type: DemandeExpirationService, providedIn: 'root' }); }
7359
- }
7360
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.21", ngImport: i0, type: DemandeExpirationService, decorators: [{
7361
- type: Injectable,
7362
- args: [{
7363
- providedIn: 'root',
7364
- }]
7365
- }] });
7366
-
7367
7483
  class FoehnPageExpirationTimerComponent {
7368
7484
  constructor() {
7369
7485
  this.applicationInfoService = inject(ApplicationInfoService);