@spartacus/user
Version:
User feature library for Spartacus
705 lines (693 loc) • 84 kB
JavaScript
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