@dsivd/prestations-ng 18.2.4 → 18.3.0-beta.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 +7 -0
- package/dsivd-prestations-ng-18.3.0-beta.2.tgz +0 -0
- package/fesm2022/dsivd-prestations-ng.mjs +49 -21
- package/fesm2022/dsivd-prestations-ng.mjs.map +1 -1
- package/gesdem/gesdem-error-handler.service.d.ts +1 -1
- package/gesdem-action-recovery/gesdem-action-recovery-login/gesdem-action-recovery-login.component.d.ts +9 -4
- package/package.json +1 -1
- package/dsivd-prestations-ng-18.2.4.tgz +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,13 @@
|
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
+
## [18.3.0] - should be aligned with prestations-be 18.3.x
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- [gesdem-action-recovery-login.component.ts](projects/prestations-ng/src/gesdem-action-recovery/gesdem-action-recovery-login/gesdem-action-recovery-login.component.ts)
|
|
14
|
+
- Display a countdown to get a new OTP during action recovery (to handle backend rate limiter)
|
|
15
|
+
|
|
9
16
|
## [18.2.4]
|
|
10
17
|
|
|
11
18
|
### Fixed
|
|
Binary file
|
|
@@ -2,8 +2,8 @@ import * as i0 from '@angular/core';
|
|
|
2
2
|
import { Optional, Inject, Injectable, EventEmitter, Input, HostBinding, Output, forwardRef, ViewChildren, ViewChild, Directive, Pipe, Component, ContentChildren, HostListener, NgModule, inject, TemplateRef, ContentChild } from '@angular/core';
|
|
3
3
|
import * as i1$1 from '@angular/router';
|
|
4
4
|
import { ActivatedRoute, NavigationStart, RouterModule, NavigationEnd, RouterLink } from '@angular/router';
|
|
5
|
-
import { of, Subject, BehaviorSubject, combineLatest, throwError, switchMap as switchMap$1, forkJoin, tap as tap$1, concat, toArray, EMPTY, startWith, filter as filter$1, merge, withLatestFrom, debounceTime as debounceTime$1, map as map$1 } from 'rxjs';
|
|
6
|
-
import { map, shareReplay, filter, tap, debounceTime, catchError, switchMap, first, throttleTime, mergeMap, share, finalize, distinctUntilChanged } from 'rxjs/operators';
|
|
5
|
+
import { of, Subject, BehaviorSubject, combineLatest, throwError, switchMap as switchMap$1, forkJoin, tap as tap$1, concat, toArray, EMPTY, startWith, filter as filter$1, merge, interval, withLatestFrom, debounceTime as debounceTime$1, map as map$1 } from 'rxjs';
|
|
6
|
+
import { map, shareReplay, filter, tap, debounceTime, catchError, switchMap, first, throttleTime, mergeMap, share, finalize, take, distinctUntilChanged } from 'rxjs/operators';
|
|
7
7
|
import * as i1 from '@angular/common/http';
|
|
8
8
|
import { HttpStatusCode, HttpResponseBase, HttpErrorResponse, HttpParams, HttpEventType, HttpResponse, HTTP_INTERCEPTORS, provideHttpClient, withInterceptorsFromDi, HttpClient } from '@angular/common/http';
|
|
9
9
|
import * as i3 from '@angular/forms';
|
|
@@ -1253,6 +1253,10 @@ const DEFAULT_DICTIONARY = {
|
|
|
1253
1253
|
'gesdem-confirmation.resume-my-demand.label': 'Vous pouvez reprendre votre demande en cliquant sur le lien ci-dessous',
|
|
1254
1254
|
'gesdem-confirmation.resume-my-demand.button': 'Reprendre ma demande',
|
|
1255
1255
|
'gesdem.download-pdf.button.title': 'Télécharger le PDF',
|
|
1256
|
+
'gesdem-action-recovery-login.request-now-code.label': 'Pour obtenir un nouveau code, vous devez recliquer sur le ' +
|
|
1257
|
+
'<a href="{redirectTarget}">lien</a> de reprise de la demande.\n',
|
|
1258
|
+
'gesdem-action-recovery-login.rate-limited.label': "Merci d'attendre {rateLimitCounter} seconde{plural} " +
|
|
1259
|
+
'pour demander un nouveau code.',
|
|
1256
1260
|
'gesdem-action-recovery-login.save.label': 'Les données de votre demande enregistrée le {date} ont été chargées.',
|
|
1257
1261
|
'gesdem-action-recovery-login.invalid-otp.label': "Le mot de passe saisi n'est pas valide",
|
|
1258
1262
|
'gesdem-action-recovery-login.password-generation-failed.label': 'Impossible de générer un mot de passe, veuillez réessayer plus tard.',
|
|
@@ -1409,7 +1413,7 @@ const DEFAULT_DICTIONARY = {
|
|
|
1409
1413
|
'gesdem-error.title.error': 'Erreur rencontrée',
|
|
1410
1414
|
'gesdem-error.title.recovery': 'Reprise de la demande',
|
|
1411
1415
|
'gesdem-error.text.wrong-etape-requested': 'La demande {reference} ne peut plus être modifiée via ce formulaire',
|
|
1412
|
-
'gesdem-error.text.demande-not-found': '
|
|
1416
|
+
'gesdem-error.text.demande-not-found': 'Les conditions préalables pour la reprise de cette demande ne sont pas remplies',
|
|
1413
1417
|
'gesdem-error.text.has-reference': 'Vous pouvez essayer de reprendre votre demande en cliquant sur le lien ci-dessous',
|
|
1414
1418
|
'gesdem-error.link.has-reference': 'Reprendre ma demande',
|
|
1415
1419
|
'gesdem-error.text.has-no-reference': 'Vous pouvez recommencer une demande en cliquant sur le lien ci-dessous',
|
|
@@ -1966,7 +1970,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImpo
|
|
|
1966
1970
|
const SESSION_EXPIRED = 'SESSION_EXPIRED';
|
|
1967
1971
|
const DEMANDE_SHOULD_EXIST = 'DEMANDE_SHOULD_EXIST';
|
|
1968
1972
|
const WRONG_ETAPE_REQUESTED = 'WRONG_ETAPE_REQUESTED';
|
|
1969
|
-
const
|
|
1973
|
+
const OBJECT_NOT_FOUND = 'OBJECT_NOT_FOUND';
|
|
1970
1974
|
class GesdemErrorHandlerService {
|
|
1971
1975
|
constructor(growlService, router, iamExpiredInterceptorService) {
|
|
1972
1976
|
this.growlService = growlService;
|
|
@@ -5667,12 +5671,12 @@ class GesdemActionRecoveryLoginComponent {
|
|
|
5667
5671
|
this.router = router;
|
|
5668
5672
|
this.route = route;
|
|
5669
5673
|
this.eventsLoggerService = eventsLoggerService;
|
|
5670
|
-
this.
|
|
5671
|
-
this.
|
|
5674
|
+
this.demandeNotFound = false;
|
|
5675
|
+
this.rateLimited = false;
|
|
5676
|
+
this.rateLimitCounter = 0;
|
|
5672
5677
|
}
|
|
5673
5678
|
ngOnInit() {
|
|
5674
5679
|
this.otpRecipient = null;
|
|
5675
|
-
this.missingRecoveryInfos = false;
|
|
5676
5680
|
this.applicationInfoService.currentEtapeInfo
|
|
5677
5681
|
.pipe(tap(currentEtape => {
|
|
5678
5682
|
if (currentEtape.reprisePossible) {
|
|
@@ -5698,6 +5702,9 @@ class GesdemActionRecoveryLoginComponent {
|
|
|
5698
5702
|
// eslint-disable-next-line rxjs-angular/prefer-async-pipe
|
|
5699
5703
|
.subscribe();
|
|
5700
5704
|
}
|
|
5705
|
+
ngOnDestroy() {
|
|
5706
|
+
this.rateLimitCounterSub?.unsubscribe();
|
|
5707
|
+
}
|
|
5701
5708
|
validateOtp() {
|
|
5702
5709
|
this.eventsLoggerService.addEvent(SdkEventType.RECOVERY_LOGIN_STARTED);
|
|
5703
5710
|
if (!this.route.snapshot.queryParams.reCaptchaByPassUUID &&
|
|
@@ -5763,35 +5770,56 @@ class GesdemActionRecoveryLoginComponent {
|
|
|
5763
5770
|
}
|
|
5764
5771
|
});
|
|
5765
5772
|
}
|
|
5773
|
+
getPluralMarker(count) {
|
|
5774
|
+
return this.dictionaryService.getPluralMarkerSync(count);
|
|
5775
|
+
}
|
|
5766
5776
|
startRecovery() {
|
|
5777
|
+
this.rateLimited = false;
|
|
5778
|
+
this.demandeNotFound = false;
|
|
5767
5779
|
this.recoveryService
|
|
5768
5780
|
.startRecovery(this.reference)
|
|
5769
5781
|
.pipe(catchError((response) => {
|
|
5770
5782
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5771
5783
|
const { error, status } = response;
|
|
5772
|
-
this.
|
|
5784
|
+
this.rateLimited = status === 429;
|
|
5785
|
+
if (this.rateLimited) {
|
|
5786
|
+
this.startRateLimitCounter();
|
|
5787
|
+
return EMPTY;
|
|
5788
|
+
}
|
|
5789
|
+
this.demandeNotFound =
|
|
5773
5790
|
status === 404 &&
|
|
5774
5791
|
error &&
|
|
5775
|
-
JSON.parse(error).code ===
|
|
5776
|
-
this.
|
|
5777
|
-
|
|
5778
|
-
error &&
|
|
5779
|
-
JSON.parse(error).code === 'ACTION_ALREADY_TRANSFERRED';
|
|
5780
|
-
if (!this.missingRecoveryInfos &&
|
|
5781
|
-
!this.alreadyTransferred) {
|
|
5782
|
-
this.growlService.addWithType(GrowlType.DANGER, this.dictionaryService.getKeySync('gesdem-action-recovery-login.password-generation-failed.label'));
|
|
5792
|
+
JSON.parse(error).code === OBJECT_NOT_FOUND;
|
|
5793
|
+
if (this.demandeNotFound) {
|
|
5794
|
+
return EMPTY;
|
|
5783
5795
|
}
|
|
5796
|
+
this.growlService.addWithType(GrowlType.DANGER, this.dictionaryService.getKeySync('gesdem-action-recovery-login.password-generation-failed.label'));
|
|
5784
5797
|
return throwError(() => true);
|
|
5785
5798
|
}))
|
|
5786
5799
|
// eslint-disable-next-line rxjs-angular/prefer-async-pipe
|
|
5787
|
-
.subscribe(otpRecipient =>
|
|
5800
|
+
.subscribe(otpRecipient => {
|
|
5801
|
+
this.otpRecipient = otpRecipient;
|
|
5802
|
+
this.startRateLimitCounter();
|
|
5803
|
+
});
|
|
5804
|
+
}
|
|
5805
|
+
startRateLimitCounter() {
|
|
5806
|
+
this.rateLimitCounter = 30;
|
|
5807
|
+
const rateLimitCounterSub = interval(1000)
|
|
5808
|
+
.pipe(take(30))
|
|
5809
|
+
// eslint-disable-next-line rxjs-angular/prefer-async-pipe
|
|
5810
|
+
.subscribe(() => {
|
|
5811
|
+
this.rateLimitCounter--;
|
|
5812
|
+
if (this.rateLimitCounter === 0) {
|
|
5813
|
+
rateLimitCounterSub?.unsubscribe();
|
|
5814
|
+
}
|
|
5815
|
+
});
|
|
5788
5816
|
}
|
|
5789
5817
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: GesdemActionRecoveryLoginComponent, deps: [{ token: GesdemActionRecoveryService }, { token: GrowlBrokerService }, { token: FoehnConfirmModalService }, { token: ValidationHandlerService }, { token: ApplicationInfoService }, { token: GesdemHandlerService }, { token: SdkDictionaryService }, { token: i1$1.Router }, { token: i1$1.ActivatedRoute }, { token: SdkEventsLoggerService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
5790
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
5818
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.17", type: GesdemActionRecoveryLoginComponent, isStandalone: false, selector: "gesdem-action-recovery-login", inputs: { reference: "reference", redirectTarget: "redirectTarget" }, viewQueries: [{ propertyName: "loginForm", first: true, predicate: FoehnFormComponent, descendants: true }, { propertyName: "recaptchaComponent", first: true, predicate: SdkRecaptchaComponent, descendants: true }], ngImport: i0, template: "<div class=\"container mt-5\">\n <div\n class=\"alert alert-danger\"\n *ngIf=\"demandeNotFound\"\n [innerHTML]=\"'gesdem-error.text.demande-not-found' | fromDictionary\"\n ></div>\n\n <div class=\"alert alert-danger\" *ngIf=\"rateLimited\">\n @if (rateLimitCounter > 0) {\n <span\n [innerHTML]=\"\n 'gesdem-action-recovery-login.rate-limited.label'\n | fromDictionary\n : {\n rateLimitCounter:\n rateLimitCounter?.toString(),\n plural: getPluralMarker(rateLimitCounter)\n }\n \"\n ></span>\n } @else {\n <span\n [innerHTML]=\"\n 'gesdem-action-recovery-login.request-now-code.label'\n | fromDictionary: { redirectTarget: redirectTarget }\n \"\n ></span>\n }\n </div>\n\n <foehn-form [shouldDisplayAlertSummary]=\"false\" *ngIf=\"otpRecipient\">\n <div class=\"row\">\n <div class=\"col-md-8\">\n <foehn-input-text\n [label]=\"\n 'Veuillez saisir le code envoy\u00E9 par SMS au num\u00E9ro ' +\n otpRecipient\n \"\n [(model)]=\"otp\"\n name=\"otp\"\n [required]=\"true\"\n ></foehn-input-text>\n </div>\n </div>\n\n <div class=\"row\">\n <div class=\"col-md-8\">\n @if (rateLimitCounter > 0) {\n <span\n [innerHTML]=\"\n 'gesdem-action-recovery-login.rate-limited.label'\n | fromDictionary\n : {\n rateLimitCounter:\n rateLimitCounter?.toString(),\n plural: getPluralMarker(\n rateLimitCounter\n )\n }\n \"\n ></span>\n } @else {\n <span\n [innerHTML]=\"\n 'gesdem-action-recovery-login.request-now-code.label'\n | fromDictionary\n : { redirectTarget: redirectTarget }\n \"\n ></span>\n }\n </div>\n </div>\n\n <br />\n\n <div class=\"row\">\n <div class=\"col-md-8\">\n <captcha></captcha>\n\n <button\n id=\"nextButton\"\n type=\"submit\"\n class=\"btn btn-dark float-end\"\n (click)=\"validateOtp()\"\n >\n Suivant\n </button>\n </div>\n </div>\n </foehn-form>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: FoehnInputTextComponent, selector: "foehn-input-text", inputs: ["numberOnly"] }, { kind: "component", type: FoehnFormComponent, selector: "foehn-form", inputs: ["shouldDisplayAlertSummary"] }, { kind: "component", type: SdkRecaptchaComponent, selector: "captcha" }, { kind: "pipe", type: SdkDictionaryPipe, name: "fromDictionary" }] }); }
|
|
5791
5819
|
}
|
|
5792
5820
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: GesdemActionRecoveryLoginComponent, decorators: [{
|
|
5793
5821
|
type: Component,
|
|
5794
|
-
args: [{ selector: 'gesdem-action-recovery-login', standalone: false, template: "<div class=\"container mt-5\">\n <div
|
|
5822
|
+
args: [{ selector: 'gesdem-action-recovery-login', standalone: false, template: "<div class=\"container mt-5\">\n <div\n class=\"alert alert-danger\"\n *ngIf=\"demandeNotFound\"\n [innerHTML]=\"'gesdem-error.text.demande-not-found' | fromDictionary\"\n ></div>\n\n <div class=\"alert alert-danger\" *ngIf=\"rateLimited\">\n @if (rateLimitCounter > 0) {\n <span\n [innerHTML]=\"\n 'gesdem-action-recovery-login.rate-limited.label'\n | fromDictionary\n : {\n rateLimitCounter:\n rateLimitCounter?.toString(),\n plural: getPluralMarker(rateLimitCounter)\n }\n \"\n ></span>\n } @else {\n <span\n [innerHTML]=\"\n 'gesdem-action-recovery-login.request-now-code.label'\n | fromDictionary: { redirectTarget: redirectTarget }\n \"\n ></span>\n }\n </div>\n\n <foehn-form [shouldDisplayAlertSummary]=\"false\" *ngIf=\"otpRecipient\">\n <div class=\"row\">\n <div class=\"col-md-8\">\n <foehn-input-text\n [label]=\"\n 'Veuillez saisir le code envoy\u00E9 par SMS au num\u00E9ro ' +\n otpRecipient\n \"\n [(model)]=\"otp\"\n name=\"otp\"\n [required]=\"true\"\n ></foehn-input-text>\n </div>\n </div>\n\n <div class=\"row\">\n <div class=\"col-md-8\">\n @if (rateLimitCounter > 0) {\n <span\n [innerHTML]=\"\n 'gesdem-action-recovery-login.rate-limited.label'\n | fromDictionary\n : {\n rateLimitCounter:\n rateLimitCounter?.toString(),\n plural: getPluralMarker(\n rateLimitCounter\n )\n }\n \"\n ></span>\n } @else {\n <span\n [innerHTML]=\"\n 'gesdem-action-recovery-login.request-now-code.label'\n | fromDictionary\n : { redirectTarget: redirectTarget }\n \"\n ></span>\n }\n </div>\n </div>\n\n <br />\n\n <div class=\"row\">\n <div class=\"col-md-8\">\n <captcha></captcha>\n\n <button\n id=\"nextButton\"\n type=\"submit\"\n class=\"btn btn-dark float-end\"\n (click)=\"validateOtp()\"\n >\n Suivant\n </button>\n </div>\n </div>\n </foehn-form>\n</div>\n" }]
|
|
5795
5823
|
}], ctorParameters: () => [{ type: GesdemActionRecoveryService }, { type: GrowlBrokerService }, { type: FoehnConfirmModalService }, { type: ValidationHandlerService }, { type: ApplicationInfoService }, { type: GesdemHandlerService }, { type: SdkDictionaryService }, { type: i1$1.Router }, { type: i1$1.ActivatedRoute }, { type: SdkEventsLoggerService }], propDecorators: { reference: [{
|
|
5796
5824
|
type: Input
|
|
5797
5825
|
}], redirectTarget: [{
|
|
@@ -5839,18 +5867,18 @@ class GesdemErrorComponent {
|
|
|
5839
5867
|
}
|
|
5840
5868
|
}
|
|
5841
5869
|
ngOnInit() {
|
|
5870
|
+
const errorCode = this.activatedRoute.snapshot.queryParamMap.get('errorCode');
|
|
5842
5871
|
if (this.reference) {
|
|
5843
5872
|
const firstPage = this.getFirstPage();
|
|
5844
5873
|
if (this.gesdemService.prefix) {
|
|
5845
5874
|
this.link += `${this.gesdemService.prefix}/`;
|
|
5846
5875
|
}
|
|
5847
5876
|
this.link += `${this.reference}/${firstPage.path}`;
|
|
5848
|
-
const errorCode = this.activatedRoute.snapshot.queryParamMap.get('errorCode');
|
|
5849
5877
|
this.hasSessionExpired = errorCode === SESSION_EXPIRED;
|
|
5850
5878
|
this.demandeShouldExist = errorCode === DEMANDE_SHOULD_EXIST;
|
|
5851
5879
|
this.wrongEtapeRequested = errorCode === WRONG_ETAPE_REQUESTED;
|
|
5852
|
-
this.demandeNotFound = errorCode === DEMANDE_NOT_FOUND;
|
|
5853
5880
|
}
|
|
5881
|
+
this.demandeNotFound = errorCode === OBJECT_NOT_FOUND;
|
|
5854
5882
|
// The error might have been caused by an issue with the prestation that has been identified
|
|
5855
5883
|
// whilst the user is using the prestation. This ensures that if any alert is added by the
|
|
5856
5884
|
// administrator, the user will at least see them if an error is shown.
|