UNPKG

@spartacus/user

Version:

User feature library for Spartacus

705 lines (693 loc) 84 kB
import * as i3 from '@angular/common'; import { CommonModule } from '@angular/common'; import * as i0 from '@angular/core'; import { Component, ChangeDetectionStrategy, NgModule, Injectable } from '@angular/core'; import * as i5 from '@angular/router'; import { RouterModule } from '@angular/router'; import * as i2$1 from '@spartacus/core'; import { GlobalMessageType, UrlModule, I18nModule, provideDefaultConfig, AuthGuard, OAuthFlow, NotAuthGuard, RoutingService, AuthConfigService, GlobalMessageService, HttpErrorModel, AuthService, AuthRedirectService } from '@spartacus/core'; import * as i2 from '@spartacus/storefront'; import { ICON_TYPE, IconModule, SpinnerModule, CustomFormValidators, FormErrorsModule, sortTitles } from '@spartacus/storefront'; import { BehaviorSubject, Subscription, combineLatest } from 'rxjs'; import { first, tap, map, filter, switchMap } from 'rxjs/operators'; import * as i1 from '@spartacus/user/profile/root'; import { UserPasswordFacade, UserEmailFacade, UserProfileFacade } from '@spartacus/user/profile/root'; import * as i4 from '@angular/forms'; import { FormGroup, FormControl, Validators, ReactiveFormsModule, FormsModule } from '@angular/forms'; class CloseAccountModalComponent { constructor(modalService, authService, globalMessageService, routingService, translationService, userProfile) { this.modalService = modalService; this.authService = authService; this.globalMessageService = globalMessageService; this.routingService = routingService; this.translationService = translationService; this.userProfile = userProfile; this.iconTypes = ICON_TYPE; this.isLoading$ = new BehaviorSubject(false); } ngOnInit() { this.isLoggedIn$ = this.authService.isUserLoggedIn(); } onSuccess() { this.dismissModal(); this.translationService .translate('closeAccount.accountClosedSuccessfully') .pipe(first()) .subscribe((text) => { this.globalMessageService.add(text, GlobalMessageType.MSG_TYPE_CONFIRMATION); }); this.routingService.go({ cxRoute: 'home' }); } onError() { this.dismissModal(); this.translationService .translate('closeAccount.accountClosedFailure') .pipe(first()) .subscribe((text) => { this.globalMessageService.add(text, GlobalMessageType.MSG_TYPE_ERROR); }); } dismissModal(reason) { this.modalService.dismissActiveModal(reason); } closeAccount() { this.isLoading$.next(true); this.userProfile.close().subscribe({ next: () => { this.onSuccess(); this.isLoading$.next(false); }, error: () => { this.onError(); this.isLoading$.next(false); }, }); } } CloseAccountModalComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: CloseAccountModalComponent, deps: [{ token: i2.ModalService }, { token: i2$1.AuthService }, { token: i2$1.GlobalMessageService }, { token: i2$1.RoutingService }, { token: i2$1.TranslationService }, { token: i1.UserProfileFacade }], target: i0.ɵɵFactoryTarget.Component }); CloseAccountModalComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.0.5", type: CloseAccountModalComponent, selector: "cx-close-account-modal", ngImport: i0, template: "<ng-container *ngIf=\"isLoggedIn$ | async\">\n <div class=\"modal-header cx-dialog-header\">\n <h3 class=\"modal-title\">\n {{ 'closeAccount.confirmAccountClosure' | cxTranslate }}\n </h3>\n <button\n type=\"button\"\n class=\"close\"\n [attr.aria-label]=\"'common.close' | cxTranslate\"\n (click)=\"dismissModal()\"\n >\n <span aria-hidden=\"true\">\n <cx-icon [type]=\"iconTypes.CLOSE\"></cx-icon>\n </span>\n </button>\n </div>\n\n <div *ngIf=\"isLoading$ | async; else loaded\">\n <div class=\"cx-spinner\">\n <cx-spinner> </cx-spinner>\n </div>\n </div>\n\n <ng-template #loaded>\n <div class=\"modal-body\">\n <div class=\"cx-row\">\n <p class=\"cx-confirmation\">\n {{ 'closeAccount.confirmAccountClosureMessage' | cxTranslate }}\n </p>\n </div>\n <div class=\"cx-row\">\n <div class=\"cx-btn-group\">\n <button class=\"btn btn-primary\" (click)=\"closeAccount()\">\n {{ 'closeAccount.closeMyAccount' | cxTranslate }}\n </button>\n <button (click)=\"dismissModal()\" class=\"btn btn-block btn-secondary\">\n {{ 'common.cancel' | cxTranslate }}\n </button>\n </div>\n </div>\n </div>\n </ng-template>\n</ng-container>\n", components: [{ type: i2.IconComponent, selector: "cx-icon,[cxIcon]", inputs: ["cxIcon", "type"] }, { type: i2.SpinnerComponent, selector: "cx-spinner" }], directives: [{ type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], pipes: { "async": i3.AsyncPipe, "cxTranslate": i2$1.TranslatePipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: CloseAccountModalComponent, decorators: [{ type: Component, args: [{ selector: 'cx-close-account-modal', templateUrl: './close-account-modal.component.html', changeDetection: ChangeDetectionStrategy.OnPush, }] }], ctorParameters: function () { return [{ type: i2.ModalService }, { type: i2$1.AuthService }, { type: i2$1.GlobalMessageService }, { type: i2$1.RoutingService }, { type: i2$1.TranslationService }, { type: i1.UserProfileFacade }]; } }); class CloseAccountComponent { constructor(modalService) { this.modalService = modalService; } openModal() { this.modal = this.modalService.open(CloseAccountModalComponent, { centered: true, }).componentInstance; } } CloseAccountComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: CloseAccountComponent, deps: [{ token: i2.ModalService }], target: i0.ɵɵFactoryTarget.Component }); CloseAccountComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.0.5", type: CloseAccountComponent, selector: "cx-close-account", ngImport: i0, template: "<div class=\"col-lg-8 col-md-9\">\n <div class=\"row cx-btn-group\">\n <div class=\"col-sm-3\">\n <a\n [routerLink]=\"{ cxRoute: 'home' } | cxUrl\"\n class=\"btn btn-block btn-secondary\"\n >{{ 'common.cancel' | cxTranslate }}</a\n >\n </div>\n <div class=\"col-sm-6\">\n <button class=\"btn btn-primary\" (click)=\"openModal()\">\n {{ 'closeAccount.closeMyAccount' | cxTranslate }}\n </button>\n </div>\n </div>\n</div>\n", directives: [{ type: i5.RouterLinkWithHref, selector: "a[routerLink],area[routerLink]", inputs: ["routerLink", "target", "queryParams", "fragment", "queryParamsHandling", "preserveFragment", "skipLocationChange", "replaceUrl", "state", "relativeTo"] }], pipes: { "cxUrl": i2$1.UrlPipe, "cxTranslate": i2$1.TranslatePipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: CloseAccountComponent, decorators: [{ type: Component, args: [{ selector: 'cx-close-account', templateUrl: './close-account.component.html', changeDetection: ChangeDetectionStrategy.OnPush, }] }], ctorParameters: function () { return [{ type: i2.ModalService }]; } }); class CloseAccountModule { } CloseAccountModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: CloseAccountModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); CloseAccountModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: CloseAccountModule, declarations: [CloseAccountComponent, CloseAccountModalComponent], imports: [CommonModule, RouterModule, UrlModule, I18nModule, IconModule, SpinnerModule] }); CloseAccountModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: CloseAccountModule, providers: [ provideDefaultConfig({ cmsComponents: { CloseAccountComponent: { component: CloseAccountComponent, guards: [AuthGuard], }, }, }), ], imports: [[ CommonModule, RouterModule, UrlModule, I18nModule, IconModule, SpinnerModule, ]] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: CloseAccountModule, decorators: [{ type: NgModule, args: [{ imports: [ CommonModule, RouterModule, UrlModule, I18nModule, IconModule, SpinnerModule, ], providers: [ provideDefaultConfig({ cmsComponents: { CloseAccountComponent: { component: CloseAccountComponent, guards: [AuthGuard], }, }, }), ], declarations: [CloseAccountComponent, CloseAccountModalComponent], }] }] }); class ForgotPasswordComponentService { constructor(userPasswordService, routingService, authConfigService, globalMessage) { this.userPasswordService = userPasswordService; this.routingService = routingService; this.authConfigService = authConfigService; this.globalMessage = globalMessage; this.busy$ = new BehaviorSubject(false); this.isUpdating$ = this.busy$.pipe(tap((state) => (state === true ? this.form.disable() : this.form.enable()))); this.form = new FormGroup({ userEmail: new FormControl('', [ Validators.required, CustomFormValidators.emailValidator, ]), }); } /** * Sends an email to the user to reset the password. * * When the `ResourceOwnerPasswordFlow` is used, the user is routed * to the login page. */ requestEmail() { if (!this.form.valid) { this.form.markAllAsTouched(); return; } this.busy$.next(true); this.userPasswordService .requestForgotPasswordEmail(this.form.value.userEmail) .subscribe({ next: () => this.onSuccess(), error: (error) => this.onError(error), }); } onSuccess() { this.globalMessage.add({ key: 'forgottenPassword.passwordResetEmailSent' }, GlobalMessageType.MSG_TYPE_CONFIRMATION); this.busy$.next(false); this.form.reset(); this.redirect(); } onError(_error) { this.busy$.next(false); } /** * Redirects the user back to the login page. * * This only happens in case of the `ResourceOwnerPasswordFlow` OAuth flow. */ redirect() { if (this.authConfigService.getOAuthFlow() === OAuthFlow.ResourceOwnerPasswordFlow) { this.routingService.go({ cxRoute: 'login' }); } } } ForgotPasswordComponentService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: ForgotPasswordComponentService, deps: [{ token: i1.UserPasswordFacade }, { token: i2$1.RoutingService }, { token: i2$1.AuthConfigService }, { token: i2$1.GlobalMessageService }], target: i0.ɵɵFactoryTarget.Injectable }); ForgotPasswordComponentService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: ForgotPasswordComponentService }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: ForgotPasswordComponentService, decorators: [{ type: Injectable }], ctorParameters: function () { return [{ type: i1.UserPasswordFacade }, { type: i2$1.RoutingService }, { type: i2$1.AuthConfigService }, { type: i2$1.GlobalMessageService }]; } }); class ForgotPasswordComponent { constructor(service) { this.service = service; this.form = this.service.form; this.isUpdating$ = this.service.isUpdating$; } onSubmit() { this.service.requestEmail(); } } ForgotPasswordComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: ForgotPasswordComponent, deps: [{ token: ForgotPasswordComponentService }], target: i0.ɵɵFactoryTarget.Component }); ForgotPasswordComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.0.5", type: ForgotPasswordComponent, selector: "cx-forgot-password", ngImport: i0, template: "<cx-spinner class=\"overlay\" *ngIf=\"isUpdating$ | async\"> </cx-spinner>\n\n<form (ngSubmit)=\"onSubmit()\" [formGroup]=\"form\">\n <label>\n <span class=\"label-content\">{{\n 'forgottenPassword.emailAddress.label' | cxTranslate\n }}</span>\n <input\n aria-required=\"true\"\n type=\"email\"\n class=\"form-control\"\n placeholder=\"{{\n 'forgottenPassword.emailAddress.placeholder' | cxTranslate\n }}\"\n formControlName=\"userEmail\"\n />\n <cx-form-errors\n aria-live=\"assertive\"\n aria-atomic=\"true\"\n [control]=\"form.get('userEmail')\"\n ></cx-form-errors>\n </label>\n\n <a\n class=\"btn btn-block btn-secondary\"\n [routerLink]=\"{ cxRoute: 'login' } | cxUrl\"\n >{{ 'common.cancel' | cxTranslate }}</a\n >\n <button class=\"btn btn-block btn-primary\" [disabled]=\"form.disabled\">\n {{ 'common.submit' | cxTranslate }}\n </button>\n</form>\n", components: [{ type: i2.SpinnerComponent, selector: "cx-spinner" }, { type: i2.FormErrorsComponent, selector: "cx-form-errors", inputs: ["prefix", "translationParams", "control"] }], directives: [{ type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i4.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { type: i4.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i4.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i4.FormControlName, selector: "[formControlName]", inputs: ["disabled", "formControlName", "ngModel"], outputs: ["ngModelChange"] }, { type: i5.RouterLinkWithHref, selector: "a[routerLink],area[routerLink]", inputs: ["routerLink", "target", "queryParams", "fragment", "queryParamsHandling", "preserveFragment", "skipLocationChange", "replaceUrl", "state", "relativeTo"] }], pipes: { "async": i3.AsyncPipe, "cxTranslate": i2$1.TranslatePipe, "cxUrl": i2$1.UrlPipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: ForgotPasswordComponent, decorators: [{ type: Component, args: [{ selector: 'cx-forgot-password', templateUrl: './forgot-password.component.html', changeDetection: ChangeDetectionStrategy.OnPush, }] }], ctorParameters: function () { return [{ type: ForgotPasswordComponentService }]; } }); class ForgotPasswordModule { } ForgotPasswordModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: ForgotPasswordModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); ForgotPasswordModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: ForgotPasswordModule, declarations: [ForgotPasswordComponent], imports: [CommonModule, ReactiveFormsModule, RouterModule, UrlModule, I18nModule, FormErrorsModule, SpinnerModule] }); ForgotPasswordModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: ForgotPasswordModule, providers: [ provideDefaultConfig({ cmsComponents: { ForgotPasswordComponent: { component: ForgotPasswordComponent, guards: [NotAuthGuard], providers: [ { provide: ForgotPasswordComponentService, useClass: ForgotPasswordComponentService, deps: [ UserPasswordFacade, RoutingService, AuthConfigService, GlobalMessageService, ], }, ], }, }, }), ], imports: [[ CommonModule, ReactiveFormsModule, RouterModule, UrlModule, I18nModule, FormErrorsModule, SpinnerModule, ]] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: ForgotPasswordModule, decorators: [{ type: NgModule, args: [{ imports: [ CommonModule, ReactiveFormsModule, RouterModule, UrlModule, I18nModule, FormErrorsModule, SpinnerModule, ], providers: [ provideDefaultConfig({ cmsComponents: { ForgotPasswordComponent: { component: ForgotPasswordComponent, guards: [NotAuthGuard], providers: [ { provide: ForgotPasswordComponentService, useClass: ForgotPasswordComponentService, deps: [ UserPasswordFacade, RoutingService, AuthConfigService, GlobalMessageService, ], }, ], }, }, }), ], declarations: [ForgotPasswordComponent], }] }] }); class RegisterComponent { constructor(userRegister, globalMessageService, fb, router, anonymousConsentsService, anonymousConsentsConfig, authConfigService) { this.userRegister = userRegister; this.globalMessageService = globalMessageService; this.fb = fb; this.router = router; this.anonymousConsentsService = anonymousConsentsService; this.anonymousConsentsConfig = anonymousConsentsConfig; this.authConfigService = authConfigService; this.isLoading$ = new BehaviorSubject(false); this.subscription = new Subscription(); this.registerForm = this.fb.group({ titleCode: [''], firstName: ['', Validators.required], lastName: ['', Validators.required], email: ['', [Validators.required, CustomFormValidators.emailValidator]], password: [ '', [Validators.required, CustomFormValidators.passwordValidator], ], passwordconf: ['', Validators.required], newsletter: new FormControl({ value: false, disabled: this.isConsentRequired(), }), termsandconditions: [false, Validators.requiredTrue], }, { validators: CustomFormValidators.passwordsMustMatch('password', 'passwordconf'), }); } ngOnInit() { var _a, _b, _c; this.titles$ = this.userRegister.getTitles().pipe(map((titles) => { return titles.sort(sortTitles); })); // TODO: Workaround: allow server for decide is titleCode mandatory (if yes, provide personalized message) this.subscription.add(this.globalMessageService .get() .pipe(filter((messages) => !!Object.keys(messages).length)) .subscribe((globalMessageEntities) => { const messages = globalMessageEntities && globalMessageEntities[GlobalMessageType.MSG_TYPE_ERROR]; if (messages && messages.some((message) => message === 'This field is required.')) { this.globalMessageService.remove(GlobalMessageType.MSG_TYPE_ERROR); this.globalMessageService.add({ key: 'register.titleRequired' }, GlobalMessageType.MSG_TYPE_ERROR); } })); const registerConsent = (_c = (_b = (_a = this.anonymousConsentsConfig) === null || _a === void 0 ? void 0 : _a.anonymousConsents) === null || _b === void 0 ? void 0 : _b.registerConsent) !== null && _c !== void 0 ? _c : ''; this.anonymousConsent$ = combineLatest([ this.anonymousConsentsService.getConsent(registerConsent), this.anonymousConsentsService.getTemplate(registerConsent), ]).pipe(map(([consent, template]) => { return { consent, template: (template === null || template === void 0 ? void 0 : template.description) ? template.description : '', }; })); this.subscription.add( // eslint-disable-next-line @typescript-eslint/no-non-null-assertion this.registerForm.get('newsletter').valueChanges.subscribe(() => { this.toggleAnonymousConsent(); })); } submitForm() { if (this.registerForm.valid) { this.registerUser(); } else { this.registerForm.markAllAsTouched(); } } registerUser() { this.isLoading$.next(true); this.userRegister .register(this.collectDataFromRegisterForm(this.registerForm.value)) .subscribe({ next: () => this.onRegisterUserSuccess(), complete: () => this.isLoading$.next(false), }); } titleSelected(title) { this.registerForm['controls'].titleCode.setValue(title.code); } collectDataFromRegisterForm(formData) { const { firstName, lastName, email, password, titleCode } = formData; return { firstName, lastName, uid: email.toLowerCase(), password, titleCode, }; } isConsentGiven(consent) { return this.anonymousConsentsService.isConsentGiven(consent); } isConsentRequired() { var _a, _b, _c, _d; const requiredConsents = (_b = (_a = this.anonymousConsentsConfig) === null || _a === void 0 ? void 0 : _a.anonymousConsents) === null || _b === void 0 ? void 0 : _b.requiredConsents; const registerConsent = (_d = (_c = this.anonymousConsentsConfig) === null || _c === void 0 ? void 0 : _c.anonymousConsents) === null || _d === void 0 ? void 0 : _d.registerConsent; if (requiredConsents && registerConsent) { return requiredConsents.includes(registerConsent); } return false; } onRegisterUserSuccess() { if (this.authConfigService.getOAuthFlow() === OAuthFlow.ResourceOwnerPasswordFlow) { this.router.go('login'); } this.globalMessageService.add({ key: 'register.postRegisterMessage' }, GlobalMessageType.MSG_TYPE_CONFIRMATION); } toggleAnonymousConsent() { var _a, _b; const registerConsent = (_b = (_a = this.anonymousConsentsConfig) === null || _a === void 0 ? void 0 : _a.anonymousConsents) === null || _b === void 0 ? void 0 : _b.registerConsent; if (registerConsent) { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion if (Boolean(this.registerForm.get('newsletter').value)) { this.anonymousConsentsService.giveConsent(registerConsent); } else { this.anonymousConsentsService.withdrawConsent(registerConsent); } } } ngOnDestroy() { this.subscription.unsubscribe(); } } RegisterComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: RegisterComponent, deps: [{ token: i1.UserRegisterFacade }, { token: i2$1.GlobalMessageService }, { token: i4.FormBuilder }, { token: i2$1.RoutingService }, { token: i2$1.AnonymousConsentsService }, { token: i2$1.AnonymousConsentsConfig }, { token: i2$1.AuthConfigService }], target: i0.ɵɵFactoryTarget.Component }); RegisterComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.0.5", type: RegisterComponent, selector: "cx-register", ngImport: i0, template: "<section\n class=\"cx-page-section container\"\n *ngIf=\"!(isLoading$ | async); else loading\"\n>\n <div class=\"row justify-content-center\">\n <div class=\"col-md-6\">\n <div class=\"cx-section\">\n <form (ngSubmit)=\"submitForm()\" [formGroup]=\"registerForm\">\n <div class=\"form-group\">\n <label>\n <span class=\"label-content\">{{\n 'register.title' | cxTranslate\n }}</span>\n <select formControlName=\"titleCode\" class=\"form-control\">\n <option selected value=\"\" disabled>\n {{ 'register.selectTitle' | cxTranslate }}\n </option>\n <option\n *ngFor=\"let title of titles$ | async\"\n [value]=\"title.code\"\n >\n {{ title.name }}\n </option>\n </select>\n </label>\n </div>\n\n <div class=\"form-group\">\n <label>\n <span class=\"label-content\">{{\n 'register.firstName.label' | cxTranslate\n }}</span>\n <input\n aria-required=\"true\"\n class=\"form-control\"\n type=\"text\"\n name=\"firstname\"\n placeholder=\"{{\n 'register.firstName.placeholder' | cxTranslate\n }}\"\n formControlName=\"firstName\"\n />\n <cx-form-errors\n aria-live=\"assertive\"\n aria-atomic=\"true\"\n [control]=\"registerForm.get('firstName')\"\n ></cx-form-errors>\n </label>\n </div>\n\n <div class=\"form-group\">\n <label>\n <span class=\"label-content\">{{\n 'register.lastName.label' | cxTranslate\n }}</span>\n <input\n aria-required=\"true\"\n class=\"form-control\"\n type=\"text\"\n name=\"lastname\"\n placeholder=\"{{\n 'register.lastName.placeholder' | cxTranslate\n }}\"\n formControlName=\"lastName\"\n />\n <cx-form-errors\n aria-live=\"assertive\"\n aria-atomic=\"true\"\n [control]=\"registerForm.get('lastName')\"\n ></cx-form-errors>\n </label>\n </div>\n\n <div class=\"form-group\">\n <label>\n <span class=\"label-content\">{{\n 'register.emailAddress.label' | cxTranslate\n }}</span>\n <input\n aria-required=\"true\"\n class=\"form-control\"\n type=\"email\"\n name=\"email\"\n placeholder=\"{{\n 'register.emailAddress.placeholder' | cxTranslate\n }}\"\n formControlName=\"email\"\n />\n <cx-form-errors\n aria-live=\"assertive\"\n aria-atomic=\"true\"\n [control]=\"registerForm.get('email')\"\n ></cx-form-errors>\n </label>\n </div>\n\n <div class=\"form-group\">\n <label>\n <span class=\"label-content\">{{\n 'register.password.label' | cxTranslate\n }}</span>\n <input\n aria-required=\"true\"\n class=\"form-control\"\n type=\"password\"\n name=\"password\"\n placeholder=\"{{\n 'register.password.placeholder' | cxTranslate\n }}\"\n formControlName=\"password\"\n />\n <cx-form-errors\n aria-live=\"assertive\"\n aria-atomic=\"true\"\n [control]=\"registerForm.get('password')\"\n ></cx-form-errors>\n </label>\n </div>\n\n <div class=\"form-group\">\n <label>\n <span class=\"label-content\">{{\n 'register.confirmPassword.label' | cxTranslate\n }}</span>\n <input\n aria-required=\"true\"\n class=\"form-control\"\n type=\"password\"\n name=\"confirmpassword\"\n placeholder=\"{{\n 'register.confirmPassword.placeholder' | cxTranslate\n }}\"\n formControlName=\"passwordconf\"\n />\n <cx-form-errors\n aria-live=\"assertive\"\n aria-atomic=\"true\"\n [control]=\"registerForm.get('passwordconf')\"\n ></cx-form-errors>\n </label>\n </div>\n\n <div class=\"form-group\">\n <div class=\"form-check\">\n <label *ngIf=\"anonymousConsent$ | async as anonymousConsent\">\n <input\n type=\"checkbox\"\n name=\"newsletter\"\n class=\"form-check-input\"\n formControlName=\"newsletter\"\n [checked]=\"isConsentGiven(anonymousConsent.consent)\"\n />\n <span class=\"form-check-label\">\n {{ anonymousConsent.template }}\n </span>\n </label>\n </div>\n </div>\n\n <div class=\"form-group\">\n <div class=\"form-check\">\n <label>\n <input\n aria-required=\"true\"\n type=\"checkbox\"\n name=\"termsandconditions\"\n formControlName=\"termsandconditions\"\n />\n <span class=\"form-check-label\">\n {{ 'register.confirmThatRead' | cxTranslate }}\n <a\n [routerLink]=\"{ cxRoute: 'termsAndConditions' } | cxUrl\"\n target=\"_blank\"\n >\n {{ 'register.termsAndConditions' | cxTranslate }}\n </a>\n </span>\n <cx-form-errors\n aria-live=\"assertive\"\n aria-atomic=\"true\"\n [control]=\"registerForm.get('termsandconditions')\"\n ></cx-form-errors>\n </label>\n </div>\n </div>\n <button type=\"submit\" class=\"btn btn-block btn-primary\">\n {{ 'register.register' | cxTranslate }}\n </button>\n <a\n class=\"cx-login-link btn-link\"\n [routerLink]=\"{ cxRoute: 'login' } | cxUrl\"\n >{{ 'register.signIn' | cxTranslate }}</a\n >\n </form>\n </div>\n </div>\n </div>\n</section>\n\n<ng-template #loading>\n <div class=\"cx-spinner\"><cx-spinner></cx-spinner></div>\n</ng-template>\n", components: [{ type: i2.FormErrorsComponent, selector: "cx-form-errors", inputs: ["prefix", "translationParams", "control"] }, { type: i2.SpinnerComponent, selector: "cx-spinner" }], directives: [{ type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i4.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { type: i4.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i4.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i4.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i4.FormControlName, selector: "[formControlName]", inputs: ["disabled", "formControlName", "ngModel"], outputs: ["ngModelChange"] }, { type: i4.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { type: i4.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i4.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { type: i5.RouterLinkWithHref, selector: "a[routerLink],area[routerLink]", inputs: ["routerLink", "target", "queryParams", "fragment", "queryParamsHandling", "preserveFragment", "skipLocationChange", "replaceUrl", "state", "relativeTo"] }], pipes: { "async": i3.AsyncPipe, "cxTranslate": i2$1.TranslatePipe, "cxUrl": i2$1.UrlPipe } }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: RegisterComponent, decorators: [{ type: Component, args: [{ selector: 'cx-register', templateUrl: './register.component.html', }] }], ctorParameters: function () { return [{ type: i1.UserRegisterFacade }, { type: i2$1.GlobalMessageService }, { type: i4.FormBuilder }, { type: i2$1.RoutingService }, { type: i2$1.AnonymousConsentsService }, { type: i2$1.AnonymousConsentsConfig }, { type: i2$1.AuthConfigService }]; } }); class RegisterComponentModule { } RegisterComponentModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: RegisterComponentModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); RegisterComponentModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: RegisterComponentModule, declarations: [RegisterComponent], imports: [CommonModule, ReactiveFormsModule, RouterModule, UrlModule, I18nModule, SpinnerModule, FormErrorsModule] }); RegisterComponentModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: RegisterComponentModule, providers: [ provideDefaultConfig({ cmsComponents: { RegisterCustomerComponent: { component: RegisterComponent, guards: [NotAuthGuard], }, }, }), ], imports: [[ CommonModule, ReactiveFormsModule, RouterModule, UrlModule, I18nModule, SpinnerModule, FormErrorsModule, ]] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: RegisterComponentModule, decorators: [{ type: NgModule, args: [{ imports: [ CommonModule, ReactiveFormsModule, RouterModule, UrlModule, I18nModule, SpinnerModule, FormErrorsModule, ], providers: [ provideDefaultConfig({ cmsComponents: { RegisterCustomerComponent: { component: RegisterComponent, guards: [NotAuthGuard], }, }, }), ], declarations: [RegisterComponent], }] }] }); class ResetPasswordComponentService { constructor(userPasswordService, routingService, globalMessage) { this.userPasswordService = userPasswordService; this.routingService = routingService; this.globalMessage = globalMessage; this.busy$ = new BehaviorSubject(false); this.isUpdating$ = this.busy$.pipe(tap((state) => (state === true ? this.form.disable() : this.form.enable()))); this.resetToken$ = this.routingService .getRouterState() .pipe(map((routerState) => routerState.state.queryParams['token'])); this.form = new FormGroup({ password: new FormControl('', [ Validators.required, CustomFormValidators.passwordValidator, ]), passwordConfirm: new FormControl('', Validators.required), }, { validators: CustomFormValidators.passwordsMustMatch('password', 'passwordConfirm'), }); } /** * Resets the password by the given token. * * The token has been provided during the request password flow. * The token is not validated on the client. */ resetPassword(token) { if (!this.form.valid) { this.form.markAllAsTouched(); return; } this.busy$.next(true); const password = this.form.get('password').value; this.userPasswordService.reset(token, password).subscribe({ next: () => this.onSuccess(), error: (error) => this.onError(error), }); } onSuccess() { this.globalMessage.add({ key: 'forgottenPassword.passwordResetSuccess' }, GlobalMessageType.MSG_TYPE_CONFIRMATION); this.busy$.next(false); this.form.reset(); this.redirect(); } onError(error) { var _a; this.busy$.next(false); if (error instanceof HttpErrorModel) { ((_a = error.details) !== null && _a !== void 0 ? _a : []).forEach((err) => { if (err.message) { this.globalMessage.add({ raw: err.message }, GlobalMessageType.MSG_TYPE_ERROR); } }); } } /** * Redirects the user to the login page. */ redirect() { this.routingService.go({ cxRoute: 'login' }); } } ResetPasswordComponentService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: ResetPasswordComponentService, deps: [{ token: i1.UserPasswordFacade }, { token: i2$1.RoutingService }, { token: i2$1.GlobalMessageService }], target: i0.ɵɵFactoryTarget.Injectable }); ResetPasswordComponentService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: ResetPasswordComponentService }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: ResetPasswordComponentService, decorators: [{ type: Injectable }], ctorParameters: function () { return [{ type: i1.UserPasswordFacade }, { type: i2$1.RoutingService }, { type: i2$1.GlobalMessageService }]; } }); class ResetPasswordComponent { constructor(service) { this.service = service; this.form = this.service.form; this.isUpdating$ = this.service.isUpdating$; this.token$ = this.service.resetToken$; } onSubmit(token) { this.service.resetPassword(token); } } ResetPasswordComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: ResetPasswordComponent, deps: [{ token: ResetPasswordComponentService }], target: i0.ɵɵFactoryTarget.Component }); ResetPasswordComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.0.5", type: ResetPasswordComponent, selector: "cx-reset-password", host: { classAttribute: "user-form" }, ngImport: i0, template: "<cx-spinner class=\"overlay\" *ngIf=\"isUpdating$ | async\"> </cx-spinner>\n\n<form\n *ngIf=\"token$ | async as token\"\n (ngSubmit)=\"onSubmit(token)\"\n [formGroup]=\"form\"\n>\n <label>\n <span class=\"label-content\">{{\n 'register.newPassword' | cxTranslate\n }}</span>\n <input\n aria-required=\"true\"\n class=\"form-control\"\n type=\"password\"\n placeholder=\"{{ 'register.password.placeholder' | cxTranslate }}\"\n formControlName=\"password\"\n />\n <cx-form-errors\n aria-live=\"assertive\"\n aria-atomic=\"true\"\n [control]=\"form.get('password')\"\n ></cx-form-errors>\n </label>\n\n <label>\n <span class=\"label-content\">{{\n 'register.passwordMinRequirements' | cxTranslate\n }}</span>\n <input\n aria-required=\"true\"\n class=\"form-control\"\n type=\"password\"\n placeholder=\"{{ 'register.confirmPassword.placeholder' | cxTranslate }}\"\n formControlName=\"passwordConfirm\"\n />\n <cx-form-errors\n aria-live=\"assertive\"\n aria-atomic=\"true\"\n [control]=\"form.get('passwordConfirm')\"\n ></cx-form-errors>\n </label>\n\n <button class=\"btn btn-block btn-primary\" [disabled]=\"form.disabled\">\n {{ 'register.resetPassword' | cxTranslate }}\n </button>\n</form>\n", components: [{ type: i2.SpinnerComponent, selector: "cx-spinner" }, { type: i2.FormErrorsComponent, selector: "cx-form-errors", inputs: ["prefix", "translationParams", "control"] }], directives: [{ type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i4.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { type: i4.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i4.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i4.FormControlName, selector: "[formControlName]", inputs: ["disabled", "formControlName", "ngModel"], outputs: ["ngModelChange"] }], pipes: { "async": i3.AsyncPipe, "cxTranslate": i2$1.TranslatePipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: ResetPasswordComponent, decorators: [{ type: Component, args: [{ selector: 'cx-reset-password', templateUrl: './reset-password.component.html', changeDetection: ChangeDetectionStrategy.OnPush, host: { class: 'user-form' }, }] }], ctorParameters: function () { return [{ type: ResetPasswordComponentService }]; } }); class ResetPasswordModule { } ResetPasswordModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: ResetPasswordModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); ResetPasswordModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: ResetPasswordModule, declarations: [ResetPasswordComponent], imports: [CommonModule, FormsModule, ReactiveFormsModule, RouterModule, I18nModule, FormErrorsModule, SpinnerModule] }); ResetPasswordModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: ResetPasswordModule, providers: [ provideDefaultConfig({ cmsComponents: { ResetPasswordComponent: { component: ResetPasswordComponent, guards: [NotAuthGuard], providers: [ { provide: ResetPasswordComponentService, useClass: ResetPasswordComponentService, deps: [UserPasswordFacade, RoutingService, GlobalMessageService], }, ], }, }, }), ], imports: [[ CommonModule, FormsModule, ReactiveFormsModule, RouterModule, I18nModule, FormErrorsModule, SpinnerModule, ]] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: ResetPasswordModule, decorators: [{ type: NgModule, args: [{ imports: [ CommonModule, FormsModule, ReactiveFormsModule, RouterModule, I18nModule, FormErrorsModule, SpinnerModule, ], providers: [ provideDefaultConfig({ cmsComponents: { ResetPasswordComponent: { component: ResetPasswordComponent, guards: [NotAuthGuard], providers: [ { provide: ResetPasswordComponentService, useClass: ResetPasswordComponentService, deps: [UserPasswordFacade, RoutingService, GlobalMessageService], }, ], }, }, }), ], declarations: [ResetPasswordComponent], }] }] }); class UpdateEmailComponentService { constructor(userEmail, routingService, globalMessageService, authService, authRedirectService) { this.userEmail = userEmail; this.routingService = routingService; this.globalMessageService = globalMessageService; this.authService = authService; this.authRedirectService = authRedirectService; this.busy$ = new BehaviorSubject(false); this.isUpdating$ = this.busy$.pipe(tap((state) => (state === true ? this.form.disable() : this.form.enable()))); this.form = new FormGroup({ email: new FormControl('', [ Validators.required, CustomFormValidators.emailValidator, ]), confirmEmail: new FormControl('', [Validators.required]), password: new FormControl('', [Validators.required]), }, { validators: CustomFormValidators.emailsMustMatch('email', 'confirmEmail'), }); } save() { var _a, _b; if (!this.form.valid) { this.form.markAllAsTouched(); return; } this.busy$.next(true); const newEmail = (_a = this.form.get('confirmEmail')) === null || _a === void 0 ? void 0 : _a.value; const password = (_b = this.form.get('password')) === null || _b === void 0 ? void 0 : _b.value; this.userEmail.update(password, newEmail).subscribe({ next: () => this.onSuccess(newEmail), error: (error) => this.onError(error), }); } /** * Handles successful updating of the user email. */ onSuccess(newUid) { this.globalMessageService.add({ key: 'updateEmailForm.emailUpdateSuccess', params: { newUid }, }, GlobalMessageType.MSG_TYPE_CONFIRM