@flusys/ng-auth 9.2.2 → 9.3.0
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/fesm2022/{flusys-ng-auth-administration-page.component-C9cMjTFU.mjs → flusys-ng-auth-administration-page.component-CxQYkCc1.mjs} +4 -4
- package/fesm2022/{flusys-ng-auth-administration-page.component-C9cMjTFU.mjs.map → flusys-ng-auth-administration-page.component-CxQYkCc1.mjs.map} +1 -1
- package/fesm2022/{flusys-ng-auth-branch-form.component-xttRMwxT.mjs → flusys-ng-auth-branch-form.component-DtoM4SET.mjs} +4 -4
- package/fesm2022/{flusys-ng-auth-branch-form.component-xttRMwxT.mjs.map → flusys-ng-auth-branch-form.component-DtoM4SET.mjs.map} +1 -1
- package/fesm2022/{flusys-ng-auth-branch-list.component-SeGvWdUO.mjs → flusys-ng-auth-branch-list.component-CP9VFx_8.mjs} +4 -4
- package/fesm2022/{flusys-ng-auth-branch-list.component-SeGvWdUO.mjs.map → flusys-ng-auth-branch-list.component-CP9VFx_8.mjs.map} +1 -1
- package/fesm2022/{flusys-ng-auth-company-form.component-BPrFxqto.mjs → flusys-ng-auth-company-form.component-C1HXjgn-.mjs} +4 -4
- package/fesm2022/{flusys-ng-auth-company-form.component-BPrFxqto.mjs.map → flusys-ng-auth-company-form.component-C1HXjgn-.mjs.map} +1 -1
- package/fesm2022/{flusys-ng-auth-company-list.component-jEtVFxYE.mjs → flusys-ng-auth-company-list.component-jkyaG-hS.mjs} +4 -4
- package/fesm2022/{flusys-ng-auth-company-list.component-jEtVFxYE.mjs.map → flusys-ng-auth-company-list.component-jkyaG-hS.mjs.map} +1 -1
- package/fesm2022/{flusys-ng-auth-forgot-password-page.component-JnLtR304.mjs → flusys-ng-auth-forgot-password-page.component-D92hBmWF.mjs} +4 -4
- package/fesm2022/{flusys-ng-auth-forgot-password-page.component-JnLtR304.mjs.map → flusys-ng-auth-forgot-password-page.component-D92hBmWF.mjs.map} +1 -1
- package/fesm2022/{flusys-ng-auth-login-page.component-R8gMWdLZ.mjs → flusys-ng-auth-login-page.component-Bz-bbY3U.mjs} +4 -4
- package/fesm2022/{flusys-ng-auth-login-page.component-R8gMWdLZ.mjs.map → flusys-ng-auth-login-page.component-Bz-bbY3U.mjs.map} +1 -1
- package/fesm2022/{flusys-ng-auth-profile-page.component-Cd4bhDRV.mjs → flusys-ng-auth-profile-page.component-Dg25DA0i.mjs} +4 -4
- package/fesm2022/{flusys-ng-auth-profile-page.component-Cd4bhDRV.mjs.map → flusys-ng-auth-profile-page.component-Dg25DA0i.mjs.map} +1 -1
- package/fesm2022/{flusys-ng-auth-register-page.component-B0me9tCm.mjs → flusys-ng-auth-register-page.component-Cb-ycJHR.mjs} +4 -4
- package/fesm2022/{flusys-ng-auth-register-page.component-B0me9tCm.mjs.map → flusys-ng-auth-register-page.component-Cb-ycJHR.mjs.map} +1 -1
- package/fesm2022/{flusys-ng-auth-reset-password-page.component-DnULwTow.mjs → flusys-ng-auth-reset-password-page.component-C33Lu6ST.mjs} +4 -4
- package/fesm2022/{flusys-ng-auth-reset-password-page.component-DnULwTow.mjs.map → flusys-ng-auth-reset-password-page.component-C33Lu6ST.mjs.map} +1 -1
- package/fesm2022/{flusys-ng-auth-social-callback-page.component-DTrdtpbR.mjs → flusys-ng-auth-social-callback-page.component-CDb3VVWf.mjs} +4 -4
- package/fesm2022/{flusys-ng-auth-social-callback-page.component-DTrdtpbR.mjs.map → flusys-ng-auth-social-callback-page.component-CDb3VVWf.mjs.map} +1 -1
- package/fesm2022/{flusys-ng-auth-social-config-page.component-Ce7yrJtX.mjs → flusys-ng-auth-social-config-page.component-mkFaxN4w.mjs} +4 -4
- package/fesm2022/{flusys-ng-auth-social-config-page.component-Ce7yrJtX.mjs.map → flusys-ng-auth-social-config-page.component-mkFaxN4w.mjs.map} +1 -1
- package/fesm2022/{flusys-ng-auth-user-form.component-cY4cmjV_.mjs → flusys-ng-auth-user-form.component-o0MbxMQn.mjs} +4 -4
- package/fesm2022/{flusys-ng-auth-user-form.component-cY4cmjV_.mjs.map → flusys-ng-auth-user-form.component-o0MbxMQn.mjs.map} +1 -1
- package/fesm2022/{flusys-ng-auth-user-list.component-Dhq8Hygo.mjs → flusys-ng-auth-user-list.component-MHHsLH9r.mjs} +4 -4
- package/fesm2022/{flusys-ng-auth-user-list.component-Dhq8Hygo.mjs.map → flusys-ng-auth-user-list.component-MHHsLH9r.mjs.map} +1 -1
- package/fesm2022/{flusys-ng-auth-verify-email-page.component-C3CLhAip.mjs → flusys-ng-auth-verify-email-page.component-3qcv2X_u.mjs} +4 -4
- package/fesm2022/{flusys-ng-auth-verify-email-page.component-C3CLhAip.mjs.map → flusys-ng-auth-verify-email-page.component-3qcv2X_u.mjs.map} +1 -1
- package/fesm2022/flusys-ng-auth.mjs +87 -87
- package/package.json +5 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flusys-ng-auth-register-page.component-B0me9tCm.mjs","names":[],"sources":["../../../projects/ng-auth/pages/register/register-page.component.ts"],"sourcesContent":["import {\n Component,\n computed,\n DestroyRef,\n effect,\n inject,\n Injector,\n input,\n signal,\n} from '@angular/core';\nimport { takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop';\nimport { NgComponentOutlet, NgTemplateOutlet } from '@angular/common';\nimport { FormsModule } from '@angular/forms';\nimport {\n form,\n FormField,\n minLength,\n required,\n} from '@angular/forms/signals';\nimport { ActivatedRoute, Router, RouterLink } from '@angular/router';\nimport {\n APP_CONFIG,\n getDefaultBranchSlug,\n getDefaultCompanySlug,\n isCompanyFeatureEnabled,\n} from '@flusys/ng-core';\nimport { AppFloatingConfigurator } from '@flusys/ng-layout';\nimport {\n TranslatePipe,\n TranslateService,\n} from '@flusys/ng-shared';\nimport {\n CheckboxComponent,\n FButtonDirective,\n InputTextDirective,\n MessageService,\n PasswordComponent,\n SelectComponent,\n TextareaDirective,\n UiIconComponent,\n} from '@flusys/ng-ui';\nimport { IRegistrationRequest } from '../../interfaces/auth.interface';\nimport {\n AUTH_REGISTRATION_EXTENSION,\n IRegistrationExtraField,\n IRegistrationFieldTemplateContext,\n REGISTRATION_FIELD_CONTEXT,\n} from '../../providers/auth-extension.providers';\nimport { sortByOrder } from '../../providers/extension-order.util';\nimport { AuthApiService } from '../../services/auth-api.service';\nimport { AuthStateService } from '../../services/auth-state.service';\nimport { EmailPolicyService } from '../../services/email-policy.service';\nimport { PasswordPolicyService } from '../../services/password-policy.service';\n\ninterface IUserFormModel {\n name: string;\n email: string;\n password: string;\n confirmPassword: string;\n phone: string;\n}\n\ninterface ICompanyFormModel {\n createNewCompany: boolean;\n companySlug: string;\n branchSlug: string;\n newCompanyName: string;\n newCompanyPhone: string;\n newCompanyAddress: string;\n}\n\n@Component({\n selector: 'lib-register-page',\n imports: [\n CheckboxComponent,\n FButtonDirective,\n InputTextDirective,\n PasswordComponent,\n SelectComponent,\n TextareaDirective,\n UiIconComponent,\n FormsModule,\n NgComponentOutlet,\n NgTemplateOutlet,\n RouterLink,\n FormField,\n AppFloatingConfigurator,\n TranslatePipe,\n ],\n template: `\n <app-floating-configurator />\n <div\n class=\"bg-surface-ground flex items-center justify-center min-h-screen py-8\"\n >\n <div class=\"flex flex-col items-center justify-center\">\n <div\n style=\"border-radius: var(--f-content-border-radius); padding: 0.3rem; background: linear-gradient(180deg, var(--primary-color) 10%, rgba(33, 150, 243, 0) 30%)\"\n >\n <div\n class=\"py-8 px-4 sm:py-10 sm:px-8 md:py-12 md:px-12 w-full sm:w-[650px] max-w-[95vw] sm:max-w-[90vw]\"\n style=\"border-radius: var(--f-content-border-radius); background: var(--f-content-background)\"\n >\n <div class=\"text-center mb-6\">\n <div class=\"text-3xl font-medium mb-4 text-color\">\n {{ 'auth.register.create.account' | translate }}\n </div>\n <span class=\"text-muted-color font-medium\">{{\n 'auth.register.subtitle' | translate\n }}</span>\n </div>\n\n <form (ngSubmit)=\"onSubmit()\">\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4 mb-4\">\n <div>\n <label for=\"name\" class=\"block font-medium mb-2\"\n >{{ 'auth.register.full.name' | translate }} *</label\n >\n <input\n fInputText\n id=\"name\"\n [formField]=\"userForm.name\"\n [placeholder]=\"'auth.register.name.placeholder' | translate\"\n class=\"w-full\"\n autocomplete=\"name\"\n />\n </div>\n\n <div>\n <label for=\"phone\" class=\"block font-medium mb-2\">{{\n 'auth.phone.label' | translate\n }}</label>\n <input\n fInputText\n id=\"phone\"\n [formField]=\"userForm.phone\"\n [placeholder]=\"'auth.phone.placeholder' | translate\"\n class=\"w-full\"\n autocomplete=\"tel\"\n />\n </div>\n </div>\n\n <div class=\"mb-4\">\n <label for=\"email\" class=\"block font-medium mb-2\"\n >{{ 'auth.email.label' | translate }} *</label\n >\n <input\n fInputText\n id=\"email\"\n type=\"email\"\n [formField]=\"userForm.email\"\n [placeholder]=\"'auth.email.placeholder' | translate\"\n class=\"w-full\"\n autocomplete=\"email\"\n />\n @if (emailValidationError()) {\n <small class=\"text-danger block mt-1\">{{\n emailValidationError()\n }}</small>\n }\n </div>\n\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4 mb-4\">\n <div>\n <label for=\"password\" class=\"block font-medium mb-2\"\n >{{ 'auth.password.label' | translate }} *</label\n >\n <f-password\n [inputId]=\"'password'\"\n [formField]=\"userForm.password\"\n [placeholder]=\"\n 'shared.min.characters'\n | translate: { count: passwordPolicy.minLength }\n \"\n class=\"w-full\"\n autocomplete=\"new-password\"\n />\n @if (passwordValidationError()) {\n <small class=\"text-danger block mt-1\">{{\n passwordValidationError()\n }}</small>\n }\n </div>\n\n <div>\n <label for=\"confirmPassword\" class=\"block font-medium mb-2\"\n >{{ 'auth.register.confirm.password' | translate }} *</label\n >\n <f-password\n [inputId]=\"'confirmPassword'\"\n [formField]=\"userForm.confirmPassword\"\n [placeholder]=\"\n 'auth.register.confirm.password.placeholder' | translate\n \"\n class=\"w-full\"\n autocomplete=\"new-password\"\n />\n @if (!passwordsMatch() && userFormModel().confirmPassword) {\n <small class=\"text-danger block mt-2\">{{\n 'auth.register.passwords.do.not.match' | translate\n }}</small>\n }\n </div>\n </div>\n\n @if (extraFields().length > 0) {\n <div class=\"border-t border-surface pt-4 mt-4 mb-4\">\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n @for (field of extraFields(); track field.key) {\n <div [class]=\"field.containerClass ?? ''\">\n <label [for]=\"field.key\" class=\"block font-medium mb-2\">\n {{ field.labelKey | translate: null : field.label\n }}{{ field.required ? ' *' : '' }}\n </label>\n @if (field.component) {\n <ng-container\n [ngComponentOutlet]=\"field.component\"\n [ngComponentOutletInjector]=\"getFieldInjector(field)\"\n ></ng-container>\n } @else if (field.template) {\n <ng-container\n [ngTemplateOutlet]=\"field.template\"\n [ngTemplateOutletContext]=\"\n getFieldTemplateContext(field)\n \"\n ></ng-container>\n } @else {\n @switch (field.type) {\n @case ('text') {\n <input\n fInputText\n [id]=\"field.key\"\n [placeholder]=\"\n field.placeholderKey\n | translate: null : field.placeholder ?? ''\n \"\n [value]=\"\n extraFieldsModel()[field.key] ??\n field.defaultValue ??\n ''\n \"\n (input)=\"\n updateExtraField(\n field.key,\n $any($event.target).value\n )\n \"\n class=\"w-full\"\n />\n }\n @case ('number') {\n <input\n fInputText\n type=\"number\"\n [id]=\"field.key\"\n [placeholder]=\"\n field.placeholderKey\n | translate: null : field.placeholder ?? ''\n \"\n [value]=\"\n extraFieldsModel()[field.key] ??\n field.defaultValue ??\n ''\n \"\n (input)=\"\n updateExtraField(\n field.key,\n $any($event.target).valueAsNumber\n )\n \"\n class=\"w-full\"\n />\n }\n @case ('textarea') {\n <textarea\n fTextarea\n [id]=\"field.key\"\n [placeholder]=\"\n field.placeholderKey\n | translate: null : field.placeholder ?? ''\n \"\n [value]=\"\n extraFieldsModel()[field.key] ??\n field.defaultValue ??\n ''\n \"\n (input)=\"\n updateExtraField(\n field.key,\n $any($event.target).value\n )\n \"\n class=\"w-full\"\n rows=\"3\"\n ></textarea>\n }\n @case ('select') {\n <f-select\n [id]=\"field.key\"\n class=\"w-full\"\n [options]=\"field.options ?? []\"\n optionValue=\"value\"\n [ngModel]=\"\n extraFieldsModel()[field.key] ??\n field.defaultValue ??\n ''\n \"\n [ngModelOptions]=\"{ standalone: true }\"\n (ngModelChange)=\"\n updateExtraField(field.key, $event)\n \"\n [placeholder]=\"\n field.placeholderKey\n | translate\n : null\n : field.placeholder ??\n ('shared.select' | translate)\n \"\n >\n <ng-template #item let-opt>{{\n opt.labelKey | translate: null : opt.label\n }}</ng-template>\n <ng-template #selectedItem let-opt>{{\n opt.labelKey | translate: null : opt.label\n }}</ng-template>\n </f-select>\n }\n @case ('checkbox') {\n <f-checkbox\n [inputId]=\"field.key\"\n [checked]=\"\n $any(\n extraFieldsModel()[field.key] ??\n field.defaultValue ??\n false\n )\n \"\n (onChange)=\"\n updateExtraField(field.key, $event.checked)\n \"\n [label]=\"\n field.placeholderKey\n | translate\n : null\n : field.placeholder ??\n (field.labelKey\n | translate: null : field.label)\n \"\n />\n }\n @case ('date') {\n <input\n fInputText\n type=\"date\"\n [id]=\"field.key\"\n [value]=\"\n extraFieldsModel()[field.key] ??\n field.defaultValue ??\n ''\n \"\n (input)=\"\n updateExtraField(\n field.key,\n $any($event.target).value\n )\n \"\n class=\"w-full\"\n />\n }\n }\n }\n </div>\n }\n </div>\n @if (extraFieldsValidationError()) {\n <small class=\"text-danger block mt-2\">{{\n extraFieldsValidationError()\n }}</small>\n }\n </div>\n }\n\n @if (companyFeatureEnabled()) {\n <div class=\"border-t border-surface pt-6 mt-6\">\n <div class=\"text-center mb-6\">\n <div class=\"text-2xl font-medium mb-2 text-color\">\n {{ 'auth.register.company.details' | translate }}\n </div>\n <span class=\"text-muted-color font-medium\">\n @if (hasDefaultCompany()) {\n {{ 'auth.register.join.default.company' | translate }}\n } @else {\n {{ 'auth.register.join.or.create.company' | translate }}\n }\n </span>\n </div>\n\n @if (!hasDefaultCompany()) {\n <div class=\"mb-4\">\n <f-checkbox\n [formField]=\"companyForm.createNewCompany\"\n [label]=\"'auth.register.create.new.company' | translate\"\n (onChange)=\"onCreateCompanyToggle($event.checked)\"\n />\n </div>\n }\n\n @if (!companyFormModel().createNewCompany) {\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4 mb-4\">\n <div>\n <label\n for=\"companySlug\"\n class=\"block font-medium mb-2\"\n >{{ 'auth.register.company.code' | translate }}</label\n >\n @if (hasDefaultCompany()) {\n <input\n fInputText\n id=\"companySlug\"\n [value]=\"defaultCompanySlug()\"\n class=\"w-full bg-(--f-form-field-filled-background)\"\n readonly\n />\n <small class=\"text-muted-color\">{{\n 'auth.register.preconfigured.company' | translate\n }}</small>\n } @else {\n <input\n fInputText\n id=\"companySlug\"\n [formField]=\"companyForm.companySlug\"\n [placeholder]=\"\n 'auth.register.company.code.placeholder'\n | translate\n \"\n class=\"w-full\"\n />\n <small class=\"text-muted-color\">{{\n 'auth.register.enter.company.code' | translate\n }}</small>\n }\n </div>\n\n <div>\n <label\n for=\"branchSlug\"\n class=\"block font-medium mb-2\"\n >{{ 'auth.register.branch.code' | translate }}</label\n >\n @if (hasDefaultBranch()) {\n <input\n fInputText\n id=\"branchSlug\"\n [value]=\"defaultBranchSlug()\"\n class=\"w-full bg-(--f-form-field-filled-background)\"\n readonly\n />\n <small class=\"text-muted-color\">{{\n 'auth.register.preconfigured.branch' | translate\n }}</small>\n } @else {\n <input\n fInputText\n id=\"branchSlug\"\n [formField]=\"companyForm.branchSlug\"\n [placeholder]=\"\n 'auth.register.branch.code.placeholder'\n | translate\n \"\n class=\"w-full\"\n />\n }\n </div>\n </div>\n } @else {\n <div class=\"mb-4\">\n <label for=\"newCompanyName\" class=\"block font-medium mb-2\"\n >{{ 'auth.register.company.name' | translate }} *</label\n >\n <input\n fInputText\n id=\"newCompanyName\"\n [formField]=\"companyForm.newCompanyName\"\n [placeholder]=\"\n 'auth.register.company.name.placeholder' | translate\n \"\n class=\"w-full\"\n />\n </div>\n\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4 mb-4\">\n <div>\n <label\n for=\"newCompanyPhone\"\n class=\"block font-medium mb-2\"\n >{{ 'auth.phone.label' | translate }}</label\n >\n <input\n fInputText\n id=\"newCompanyPhone\"\n [formField]=\"companyForm.newCompanyPhone\"\n [placeholder]=\"'auth.phone.placeholder' | translate\"\n class=\"w-full\"\n />\n </div>\n\n <div>\n <label\n for=\"newCompanyAddress\"\n class=\"block font-medium mb-2\"\n >{{ 'auth.address.label' | translate }}</label\n >\n <input\n fInputText\n id=\"newCompanyAddress\"\n [formField]=\"companyForm.newCompanyAddress\"\n [placeholder]=\"'auth.address.placeholder' | translate\"\n class=\"w-full\"\n />\n </div>\n </div>\n }\n </div>\n }\n\n <button\n fButton\n class=\"w-full mt-4\"\n type=\"submit\"\n [disabled]=\"!isFormValid() || isLoading()\"\n >\n @if (isLoading()) {\n <ui-icon pButtonIcon name=\"spinner\" [spin]=\"true\"></ui-icon>\n }\n <span pButtonLabel>{{\n 'auth.register.create.account' | translate\n }}</span>\n </button>\n\n <div class=\"flex items-center justify-center mt-4 gap-2\">\n <span class=\"font-medium\">{{\n 'auth.register.already.have.account' | translate\n }}</span>\n <a\n routerLink=\"/auth/login\"\n class=\"font-semibold text-primary cursor-pointer\"\n >\n {{ 'auth.login.sign.in' | translate }}\n </a>\n </div>\n </form>\n </div>\n </div>\n </div>\n </div>\n `,\n})\nexport class RegisterPageComponent {\n private readonly destroyRef = inject(DestroyRef);\n private readonly appConfig = inject(APP_CONFIG);\n private readonly messageService = inject(MessageService);\n private readonly authApi = inject(AuthApiService);\n private readonly authState = inject(AuthStateService);\n private readonly route = inject(ActivatedRoute);\n private readonly router = inject(Router);\n\n private readonly emailPolicy = inject(EmailPolicyService);\n protected readonly passwordPolicy = inject(PasswordPolicyService);\n private readonly registrationExtension = inject(AUTH_REGISTRATION_EXTENSION, {\n optional: true,\n });\n private readonly translateAdapter = inject(TranslateService, {\n optional: true,\n });\n\n private translate(\n key: string,\n vars?: Record<string, unknown>,\n ): string {\n return this.translateAdapter?.translate(key, vars) ?? key;\n }\n\n private readonly queryParamMap = toSignal(this.route.queryParamMap);\n private companySlugInitialized = false;\n\n readonly returnUrl = input<string>('');\n readonly isLoading = signal(false);\n readonly companyFeatureEnabled = computed(() =>\n isCompanyFeatureEnabled(this.appConfig),\n );\n readonly defaultCompanySlug = computed(() =>\n getDefaultCompanySlug(this.appConfig),\n );\n readonly defaultBranchSlug = computed(() =>\n getDefaultBranchSlug(this.appConfig),\n );\n readonly hasDefaultCompany = computed(() => !!this.defaultCompanySlug());\n readonly hasDefaultBranch = computed(() => !!this.defaultBranchSlug());\n\n readonly extraFields = computed<IRegistrationExtraField[]>(() => {\n if (!this.registrationExtension) return [];\n return sortByOrder(this.registrationExtension.getExtraFields());\n });\n\n readonly extraFieldsModel = signal<Record<string, unknown>>(\n this.extraFields().reduce<Record<string, unknown>>((acc, field) => {\n if (field.defaultValue !== undefined) {\n acc[field.key] = field.defaultValue;\n }\n return acc;\n }, {}),\n );\n\n readonly userFormModel = signal<IUserFormModel>({\n name: '',\n email: '',\n password: '',\n confirmPassword: '',\n phone: '',\n });\n readonly userForm = form(this.userFormModel, (f) => {\n required(f.name, {\n message: this.translate('shared.name.required'),\n });\n minLength(f.name, 2, {\n message: this.translate('auth.validation.name.min.length', { min: 2 }),\n });\n required(f.email, {\n message: this.translate('auth.validation.email.required'),\n });\n required(f.password, {\n message: this.translate('auth.validation.password.required'),\n });\n required(f.confirmPassword, {\n message: this.translate('auth.validation.confirm.password.required'),\n });\n });\n\n readonly companyFormModel = signal<ICompanyFormModel>({\n createNewCompany: false,\n companySlug: '',\n branchSlug: '',\n newCompanyName: '',\n newCompanyPhone: '',\n newCompanyAddress: '',\n });\n readonly companyForm = form(this.companyFormModel);\n\n readonly emailValidationError = computed(() =>\n this.emailPolicy.validate(this.userFormModel().email),\n );\n\n readonly passwordValidationError = computed(() =>\n this.passwordPolicy.validate(this.userFormModel().password),\n );\n\n readonly extraFieldsValidationError = computed(() => {\n if (!this.registrationExtension?.validateExtraFields) return null;\n return this.registrationExtension.validateExtraFields(\n this.extraFieldsModel(),\n );\n });\n\n readonly passwordsMatch = computed(() => {\n const model = this.userFormModel();\n return model.password === model.confirmPassword;\n });\n\n readonly isFormValid = computed(() => {\n const userModel = this.userFormModel();\n const emailError = this.emailValidationError();\n const passwordError = this.passwordValidationError();\n const extraFieldsError = this.extraFieldsValidationError();\n\n const userValid =\n userModel.name.trim().length >= 2 &&\n userModel.email.includes('@') &&\n !emailError &&\n userModel.password.length > 0 &&\n !passwordError &&\n userModel.confirmPassword.length > 0 &&\n this.passwordsMatch() &&\n !extraFieldsError;\n\n const extraFieldsValid = this.validateRequiredExtraFields();\n\n if (!isCompanyFeatureEnabled(this.appConfig))\n return userValid && extraFieldsValid;\n\n const companyModel = this.companyFormModel();\n if (companyModel.createNewCompany) {\n return (\n userValid &&\n extraFieldsValid &&\n companyModel.newCompanyName.trim().length > 0\n );\n }\n return userValid && extraFieldsValid;\n });\n\n private validateRequiredExtraFields(): boolean {\n const fields = this.extraFields();\n const values = this.extraFieldsModel();\n\n for (const field of fields) {\n if (field.required) {\n const value = values[field.key];\n if (value === undefined || value === null || value === '') {\n return false;\n }\n }\n }\n return true;\n }\n\n updateExtraField(key: string, value: unknown): void {\n this.extraFieldsModel.update((model) => ({ ...model, [key]: value }));\n }\n\n getFieldTemplateContext(\n field: IRegistrationExtraField,\n ): IRegistrationFieldTemplateContext {\n return {\n field,\n value: this.extraFieldsModel()[field.key] ?? field.defaultValue,\n updateValue: (value: unknown) => this.updateExtraField(field.key, value),\n };\n }\n\n private readonly parentInjector = inject(Injector);\n\n private readonly fieldInjectors = new Map<\n string,\n { injector: Injector; setField: (field: IRegistrationExtraField) => void }\n >();\n\n getFieldInjector(field: IRegistrationExtraField): Injector {\n const cached = this.fieldInjectors.get(field.key);\n if (cached) {\n cached.setField(field);\n return cached.injector;\n }\n\n let currentField = field;\n const extraFieldsModel = this.extraFieldsModel;\n const context: IRegistrationFieldTemplateContext = {\n get field() {\n return currentField;\n },\n get value() {\n return extraFieldsModel()[currentField.key] ?? currentField.defaultValue;\n },\n updateValue: (value: unknown) =>\n this.updateExtraField(currentField.key, value),\n };\n\n const injector = Injector.create({\n providers: [{ provide: REGISTRATION_FIELD_CONTEXT, useValue: context }],\n parent: field.injector ?? this.parentInjector,\n });\n this.fieldInjectors.set(field.key, {\n injector,\n setField: (next) => (currentField = next),\n });\n return injector;\n }\n\n constructor() {\n effect(() => {\n const params = this.queryParamMap();\n if (!params || this.companySlugInitialized) return;\n\n this.companySlugInitialized = true;\n\n const configCompanySlug = this.defaultCompanySlug();\n const configBranchSlug = this.defaultBranchSlug();\n const queryCompanySlug = params.get('companySlug');\n\n const companySlug = configCompanySlug || queryCompanySlug || '';\n const branchSlug = configBranchSlug || '';\n\n if (companySlug || branchSlug) {\n this.companyFormModel.update((model) => ({\n ...model,\n companySlug,\n branchSlug,\n }));\n }\n });\n }\n\n onCreateCompanyToggle(createNew: boolean): void {\n if (createNew) {\n this.companyFormModel.update((model) => ({\n ...model,\n createNewCompany: true,\n companySlug: '',\n branchSlug: '',\n }));\n } else {\n this.companyFormModel.update((model) => ({\n ...model,\n createNewCompany: false,\n newCompanyName: '',\n newCompanyPhone: '',\n newCompanyAddress: '',\n }));\n }\n }\n\n onSubmit(): void {\n if (!this.isFormValid()) {\n this.messageService.add({\n severity: 'error',\n summary: this.translate('shared.validation.error'),\n detail: this.translate('shared.fill.required.fields'),\n });\n return;\n }\n\n this.isLoading.set(true);\n\n const userModel = this.userFormModel();\n const companyModel = this.companyFormModel();\n\n let registrationData: Record<string, unknown> = {\n name: userModel.name,\n email: userModel.email,\n password: userModel.password,\n phone: userModel.phone || undefined,\n };\n\n const extraFieldsData = this.extraFieldsModel();\n if (Object.keys(extraFieldsData).length > 0) {\n registrationData['additionalFields'] = extraFieldsData;\n }\n\n if (this.registrationExtension?.transformRegistrationData) {\n registrationData =\n this.registrationExtension.transformRegistrationData(registrationData);\n }\n\n if (isCompanyFeatureEnabled(this.appConfig)) {\n if (companyModel.createNewCompany) {\n registrationData['newCompanyName'] =\n companyModel.newCompanyName || undefined;\n registrationData['newCompanyPhone'] =\n companyModel.newCompanyPhone || undefined;\n registrationData['newCompanyAddress'] =\n companyModel.newCompanyAddress || undefined;\n } else {\n registrationData['companySlug'] = companyModel.companySlug || undefined;\n registrationData['branchSlug'] = companyModel.branchSlug || undefined;\n }\n }\n\n this.authApi\n .register(registrationData as unknown as IRegistrationRequest)\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe({\n next: (response) => {\n this.isLoading.set(false);\n const data = response.data;\n if (!data) return;\n\n if (data.requiresEmailVerification) {\n this.messageService.add({\n severity: 'success',\n summary: this.translate('shared.success'),\n detail: response.messageKey\n ? this.translate(response.messageKey, response.messageVariables)\n : response.message,\n life: 5000,\n });\n this.router.navigate(['/auth/login']);\n return;\n }\n\n if (data.accessToken) {\n this.authState.setLoginState({\n accessToken: data.accessToken,\n user: data.user,\n company: data.company,\n branch: data.branch,\n });\n this.messageService.add({\n severity: 'success',\n summary: this.translate('shared.success'),\n detail: response.messageKey\n ? this.translate(response.messageKey, response.messageVariables)\n : response.message,\n });\n this.authState.navigateAfterLogin(this.returnUrl());\n }\n },\n error: () => {\n this.isLoading.set(false);\n },\n });\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"flusys-ng-auth-register-page.component-Cb-ycJHR.mjs","names":[],"sources":["../../../projects/ng-auth/pages/register/register-page.component.ts"],"sourcesContent":["import {\n Component,\n computed,\n DestroyRef,\n effect,\n inject,\n Injector,\n input,\n signal,\n} from '@angular/core';\nimport { takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop';\nimport { NgComponentOutlet, NgTemplateOutlet } from '@angular/common';\nimport { FormsModule } from '@angular/forms';\nimport {\n form,\n FormField,\n minLength,\n required,\n} from '@angular/forms/signals';\nimport { ActivatedRoute, Router, RouterLink } from '@angular/router';\nimport {\n APP_CONFIG,\n getDefaultBranchSlug,\n getDefaultCompanySlug,\n isCompanyFeatureEnabled,\n} from '@flusys/ng-core';\nimport { AppFloatingConfigurator } from '@flusys/ng-layout';\nimport {\n TranslatePipe,\n TranslateService,\n} from '@flusys/ng-shared';\nimport {\n CheckboxComponent,\n FButtonDirective,\n InputTextDirective,\n MessageService,\n PasswordComponent,\n SelectComponent,\n TextareaDirective,\n UiIconComponent,\n} from '@flusys/ng-ui';\nimport { IRegistrationRequest } from '../../interfaces/auth.interface';\nimport {\n AUTH_REGISTRATION_EXTENSION,\n IRegistrationExtraField,\n IRegistrationFieldTemplateContext,\n REGISTRATION_FIELD_CONTEXT,\n} from '../../providers/auth-extension.providers';\nimport { sortByOrder } from '../../providers/extension-order.util';\nimport { AuthApiService } from '../../services/auth-api.service';\nimport { AuthStateService } from '../../services/auth-state.service';\nimport { EmailPolicyService } from '../../services/email-policy.service';\nimport { PasswordPolicyService } from '../../services/password-policy.service';\n\ninterface IUserFormModel {\n name: string;\n email: string;\n password: string;\n confirmPassword: string;\n phone: string;\n}\n\ninterface ICompanyFormModel {\n createNewCompany: boolean;\n companySlug: string;\n branchSlug: string;\n newCompanyName: string;\n newCompanyPhone: string;\n newCompanyAddress: string;\n}\n\n@Component({\n selector: 'lib-register-page',\n imports: [\n CheckboxComponent,\n FButtonDirective,\n InputTextDirective,\n PasswordComponent,\n SelectComponent,\n TextareaDirective,\n UiIconComponent,\n FormsModule,\n NgComponentOutlet,\n NgTemplateOutlet,\n RouterLink,\n FormField,\n AppFloatingConfigurator,\n TranslatePipe,\n ],\n template: `\n <app-floating-configurator />\n <div\n class=\"bg-surface-ground flex items-center justify-center min-h-screen py-8\"\n >\n <div class=\"flex flex-col items-center justify-center\">\n <div\n style=\"border-radius: var(--f-content-border-radius); padding: 0.3rem; background: linear-gradient(180deg, var(--primary-color) 10%, rgba(33, 150, 243, 0) 30%)\"\n >\n <div\n class=\"py-8 px-4 sm:py-10 sm:px-8 md:py-12 md:px-12 w-full sm:w-[650px] max-w-[95vw] sm:max-w-[90vw]\"\n style=\"border-radius: var(--f-content-border-radius); background: var(--f-content-background)\"\n >\n <div class=\"text-center mb-6\">\n <div class=\"text-3xl font-medium mb-4 text-color\">\n {{ 'auth.register.create.account' | translate }}\n </div>\n <span class=\"text-muted-color font-medium\">{{\n 'auth.register.subtitle' | translate\n }}</span>\n </div>\n\n <form (ngSubmit)=\"onSubmit()\">\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4 mb-4\">\n <div>\n <label for=\"name\" class=\"block font-medium mb-2\"\n >{{ 'auth.register.full.name' | translate }} *</label\n >\n <input\n fInputText\n id=\"name\"\n [formField]=\"userForm.name\"\n [placeholder]=\"'auth.register.name.placeholder' | translate\"\n class=\"w-full\"\n autocomplete=\"name\"\n />\n </div>\n\n <div>\n <label for=\"phone\" class=\"block font-medium mb-2\">{{\n 'auth.phone.label' | translate\n }}</label>\n <input\n fInputText\n id=\"phone\"\n [formField]=\"userForm.phone\"\n [placeholder]=\"'auth.phone.placeholder' | translate\"\n class=\"w-full\"\n autocomplete=\"tel\"\n />\n </div>\n </div>\n\n <div class=\"mb-4\">\n <label for=\"email\" class=\"block font-medium mb-2\"\n >{{ 'auth.email.label' | translate }} *</label\n >\n <input\n fInputText\n id=\"email\"\n type=\"email\"\n [formField]=\"userForm.email\"\n [placeholder]=\"'auth.email.placeholder' | translate\"\n class=\"w-full\"\n autocomplete=\"email\"\n />\n @if (emailValidationError()) {\n <small class=\"text-danger block mt-1\">{{\n emailValidationError()\n }}</small>\n }\n </div>\n\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4 mb-4\">\n <div>\n <label for=\"password\" class=\"block font-medium mb-2\"\n >{{ 'auth.password.label' | translate }} *</label\n >\n <f-password\n [inputId]=\"'password'\"\n [formField]=\"userForm.password\"\n [placeholder]=\"\n 'shared.min.characters'\n | translate: { count: passwordPolicy.minLength }\n \"\n class=\"w-full\"\n autocomplete=\"new-password\"\n />\n @if (passwordValidationError()) {\n <small class=\"text-danger block mt-1\">{{\n passwordValidationError()\n }}</small>\n }\n </div>\n\n <div>\n <label for=\"confirmPassword\" class=\"block font-medium mb-2\"\n >{{ 'auth.register.confirm.password' | translate }} *</label\n >\n <f-password\n [inputId]=\"'confirmPassword'\"\n [formField]=\"userForm.confirmPassword\"\n [placeholder]=\"\n 'auth.register.confirm.password.placeholder' | translate\n \"\n class=\"w-full\"\n autocomplete=\"new-password\"\n />\n @if (!passwordsMatch() && userFormModel().confirmPassword) {\n <small class=\"text-danger block mt-2\">{{\n 'auth.register.passwords.do.not.match' | translate\n }}</small>\n }\n </div>\n </div>\n\n @if (extraFields().length > 0) {\n <div class=\"border-t border-surface pt-4 mt-4 mb-4\">\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n @for (field of extraFields(); track field.key) {\n <div [class]=\"field.containerClass ?? ''\">\n <label [for]=\"field.key\" class=\"block font-medium mb-2\">\n {{ field.labelKey | translate: null : field.label\n }}{{ field.required ? ' *' : '' }}\n </label>\n @if (field.component) {\n <ng-container\n [ngComponentOutlet]=\"field.component\"\n [ngComponentOutletInjector]=\"getFieldInjector(field)\"\n ></ng-container>\n } @else if (field.template) {\n <ng-container\n [ngTemplateOutlet]=\"field.template\"\n [ngTemplateOutletContext]=\"\n getFieldTemplateContext(field)\n \"\n ></ng-container>\n } @else {\n @switch (field.type) {\n @case ('text') {\n <input\n fInputText\n [id]=\"field.key\"\n [placeholder]=\"\n field.placeholderKey\n | translate: null : field.placeholder ?? ''\n \"\n [value]=\"\n extraFieldsModel()[field.key] ??\n field.defaultValue ??\n ''\n \"\n (input)=\"\n updateExtraField(\n field.key,\n $any($event.target).value\n )\n \"\n class=\"w-full\"\n />\n }\n @case ('number') {\n <input\n fInputText\n type=\"number\"\n [id]=\"field.key\"\n [placeholder]=\"\n field.placeholderKey\n | translate: null : field.placeholder ?? ''\n \"\n [value]=\"\n extraFieldsModel()[field.key] ??\n field.defaultValue ??\n ''\n \"\n (input)=\"\n updateExtraField(\n field.key,\n $any($event.target).valueAsNumber\n )\n \"\n class=\"w-full\"\n />\n }\n @case ('textarea') {\n <textarea\n fTextarea\n [id]=\"field.key\"\n [placeholder]=\"\n field.placeholderKey\n | translate: null : field.placeholder ?? ''\n \"\n [value]=\"\n extraFieldsModel()[field.key] ??\n field.defaultValue ??\n ''\n \"\n (input)=\"\n updateExtraField(\n field.key,\n $any($event.target).value\n )\n \"\n class=\"w-full\"\n rows=\"3\"\n ></textarea>\n }\n @case ('select') {\n <f-select\n [id]=\"field.key\"\n class=\"w-full\"\n [options]=\"field.options ?? []\"\n optionValue=\"value\"\n [ngModel]=\"\n extraFieldsModel()[field.key] ??\n field.defaultValue ??\n ''\n \"\n [ngModelOptions]=\"{ standalone: true }\"\n (ngModelChange)=\"\n updateExtraField(field.key, $event)\n \"\n [placeholder]=\"\n field.placeholderKey\n | translate\n : null\n : field.placeholder ??\n ('shared.select' | translate)\n \"\n >\n <ng-template #item let-opt>{{\n opt.labelKey | translate: null : opt.label\n }}</ng-template>\n <ng-template #selectedItem let-opt>{{\n opt.labelKey | translate: null : opt.label\n }}</ng-template>\n </f-select>\n }\n @case ('checkbox') {\n <f-checkbox\n [inputId]=\"field.key\"\n [checked]=\"\n $any(\n extraFieldsModel()[field.key] ??\n field.defaultValue ??\n false\n )\n \"\n (onChange)=\"\n updateExtraField(field.key, $event.checked)\n \"\n [label]=\"\n field.placeholderKey\n | translate\n : null\n : field.placeholder ??\n (field.labelKey\n | translate: null : field.label)\n \"\n />\n }\n @case ('date') {\n <input\n fInputText\n type=\"date\"\n [id]=\"field.key\"\n [value]=\"\n extraFieldsModel()[field.key] ??\n field.defaultValue ??\n ''\n \"\n (input)=\"\n updateExtraField(\n field.key,\n $any($event.target).value\n )\n \"\n class=\"w-full\"\n />\n }\n }\n }\n </div>\n }\n </div>\n @if (extraFieldsValidationError()) {\n <small class=\"text-danger block mt-2\">{{\n extraFieldsValidationError()\n }}</small>\n }\n </div>\n }\n\n @if (companyFeatureEnabled()) {\n <div class=\"border-t border-surface pt-6 mt-6\">\n <div class=\"text-center mb-6\">\n <div class=\"text-2xl font-medium mb-2 text-color\">\n {{ 'auth.register.company.details' | translate }}\n </div>\n <span class=\"text-muted-color font-medium\">\n @if (hasDefaultCompany()) {\n {{ 'auth.register.join.default.company' | translate }}\n } @else {\n {{ 'auth.register.join.or.create.company' | translate }}\n }\n </span>\n </div>\n\n @if (!hasDefaultCompany()) {\n <div class=\"mb-4\">\n <f-checkbox\n [formField]=\"companyForm.createNewCompany\"\n [label]=\"'auth.register.create.new.company' | translate\"\n (onChange)=\"onCreateCompanyToggle($event.checked)\"\n />\n </div>\n }\n\n @if (!companyFormModel().createNewCompany) {\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4 mb-4\">\n <div>\n <label\n for=\"companySlug\"\n class=\"block font-medium mb-2\"\n >{{ 'auth.register.company.code' | translate }}</label\n >\n @if (hasDefaultCompany()) {\n <input\n fInputText\n id=\"companySlug\"\n [value]=\"defaultCompanySlug()\"\n class=\"w-full bg-(--f-form-field-filled-background)\"\n readonly\n />\n <small class=\"text-muted-color\">{{\n 'auth.register.preconfigured.company' | translate\n }}</small>\n } @else {\n <input\n fInputText\n id=\"companySlug\"\n [formField]=\"companyForm.companySlug\"\n [placeholder]=\"\n 'auth.register.company.code.placeholder'\n | translate\n \"\n class=\"w-full\"\n />\n <small class=\"text-muted-color\">{{\n 'auth.register.enter.company.code' | translate\n }}</small>\n }\n </div>\n\n <div>\n <label\n for=\"branchSlug\"\n class=\"block font-medium mb-2\"\n >{{ 'auth.register.branch.code' | translate }}</label\n >\n @if (hasDefaultBranch()) {\n <input\n fInputText\n id=\"branchSlug\"\n [value]=\"defaultBranchSlug()\"\n class=\"w-full bg-(--f-form-field-filled-background)\"\n readonly\n />\n <small class=\"text-muted-color\">{{\n 'auth.register.preconfigured.branch' | translate\n }}</small>\n } @else {\n <input\n fInputText\n id=\"branchSlug\"\n [formField]=\"companyForm.branchSlug\"\n [placeholder]=\"\n 'auth.register.branch.code.placeholder'\n | translate\n \"\n class=\"w-full\"\n />\n }\n </div>\n </div>\n } @else {\n <div class=\"mb-4\">\n <label for=\"newCompanyName\" class=\"block font-medium mb-2\"\n >{{ 'auth.register.company.name' | translate }} *</label\n >\n <input\n fInputText\n id=\"newCompanyName\"\n [formField]=\"companyForm.newCompanyName\"\n [placeholder]=\"\n 'auth.register.company.name.placeholder' | translate\n \"\n class=\"w-full\"\n />\n </div>\n\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4 mb-4\">\n <div>\n <label\n for=\"newCompanyPhone\"\n class=\"block font-medium mb-2\"\n >{{ 'auth.phone.label' | translate }}</label\n >\n <input\n fInputText\n id=\"newCompanyPhone\"\n [formField]=\"companyForm.newCompanyPhone\"\n [placeholder]=\"'auth.phone.placeholder' | translate\"\n class=\"w-full\"\n />\n </div>\n\n <div>\n <label\n for=\"newCompanyAddress\"\n class=\"block font-medium mb-2\"\n >{{ 'auth.address.label' | translate }}</label\n >\n <input\n fInputText\n id=\"newCompanyAddress\"\n [formField]=\"companyForm.newCompanyAddress\"\n [placeholder]=\"'auth.address.placeholder' | translate\"\n class=\"w-full\"\n />\n </div>\n </div>\n }\n </div>\n }\n\n <button\n fButton\n class=\"w-full mt-4\"\n type=\"submit\"\n [disabled]=\"!isFormValid() || isLoading()\"\n >\n @if (isLoading()) {\n <ui-icon pButtonIcon name=\"spinner\" [spin]=\"true\"></ui-icon>\n }\n <span pButtonLabel>{{\n 'auth.register.create.account' | translate\n }}</span>\n </button>\n\n <div class=\"flex items-center justify-center mt-4 gap-2\">\n <span class=\"font-medium\">{{\n 'auth.register.already.have.account' | translate\n }}</span>\n <a\n routerLink=\"/auth/login\"\n class=\"font-semibold text-primary cursor-pointer\"\n >\n {{ 'auth.login.sign.in' | translate }}\n </a>\n </div>\n </form>\n </div>\n </div>\n </div>\n </div>\n `,\n})\nexport class RegisterPageComponent {\n private readonly destroyRef = inject(DestroyRef);\n private readonly appConfig = inject(APP_CONFIG);\n private readonly messageService = inject(MessageService);\n private readonly authApi = inject(AuthApiService);\n private readonly authState = inject(AuthStateService);\n private readonly route = inject(ActivatedRoute);\n private readonly router = inject(Router);\n\n private readonly emailPolicy = inject(EmailPolicyService);\n protected readonly passwordPolicy = inject(PasswordPolicyService);\n private readonly registrationExtension = inject(AUTH_REGISTRATION_EXTENSION, {\n optional: true,\n });\n private readonly translateAdapter = inject(TranslateService, {\n optional: true,\n });\n\n private translate(\n key: string,\n vars?: Record<string, unknown>,\n ): string {\n return this.translateAdapter?.translate(key, vars) ?? key;\n }\n\n private readonly queryParamMap = toSignal(this.route.queryParamMap);\n private companySlugInitialized = false;\n\n readonly returnUrl = input<string>('');\n readonly isLoading = signal(false);\n readonly companyFeatureEnabled = computed(() =>\n isCompanyFeatureEnabled(this.appConfig),\n );\n readonly defaultCompanySlug = computed(() =>\n getDefaultCompanySlug(this.appConfig),\n );\n readonly defaultBranchSlug = computed(() =>\n getDefaultBranchSlug(this.appConfig),\n );\n readonly hasDefaultCompany = computed(() => !!this.defaultCompanySlug());\n readonly hasDefaultBranch = computed(() => !!this.defaultBranchSlug());\n\n readonly extraFields = computed<IRegistrationExtraField[]>(() => {\n if (!this.registrationExtension) return [];\n return sortByOrder(this.registrationExtension.getExtraFields());\n });\n\n readonly extraFieldsModel = signal<Record<string, unknown>>(\n this.extraFields().reduce<Record<string, unknown>>((acc, field) => {\n if (field.defaultValue !== undefined) {\n acc[field.key] = field.defaultValue;\n }\n return acc;\n }, {}),\n );\n\n readonly userFormModel = signal<IUserFormModel>({\n name: '',\n email: '',\n password: '',\n confirmPassword: '',\n phone: '',\n });\n readonly userForm = form(this.userFormModel, (f) => {\n required(f.name, {\n message: this.translate('shared.name.required'),\n });\n minLength(f.name, 2, {\n message: this.translate('auth.validation.name.min.length', { min: 2 }),\n });\n required(f.email, {\n message: this.translate('auth.validation.email.required'),\n });\n required(f.password, {\n message: this.translate('auth.validation.password.required'),\n });\n required(f.confirmPassword, {\n message: this.translate('auth.validation.confirm.password.required'),\n });\n });\n\n readonly companyFormModel = signal<ICompanyFormModel>({\n createNewCompany: false,\n companySlug: '',\n branchSlug: '',\n newCompanyName: '',\n newCompanyPhone: '',\n newCompanyAddress: '',\n });\n readonly companyForm = form(this.companyFormModel);\n\n readonly emailValidationError = computed(() =>\n this.emailPolicy.validate(this.userFormModel().email),\n );\n\n readonly passwordValidationError = computed(() =>\n this.passwordPolicy.validate(this.userFormModel().password),\n );\n\n readonly extraFieldsValidationError = computed(() => {\n if (!this.registrationExtension?.validateExtraFields) return null;\n return this.registrationExtension.validateExtraFields(\n this.extraFieldsModel(),\n );\n });\n\n readonly passwordsMatch = computed(() => {\n const model = this.userFormModel();\n return model.password === model.confirmPassword;\n });\n\n readonly isFormValid = computed(() => {\n const userModel = this.userFormModel();\n const emailError = this.emailValidationError();\n const passwordError = this.passwordValidationError();\n const extraFieldsError = this.extraFieldsValidationError();\n\n const userValid =\n userModel.name.trim().length >= 2 &&\n userModel.email.includes('@') &&\n !emailError &&\n userModel.password.length > 0 &&\n !passwordError &&\n userModel.confirmPassword.length > 0 &&\n this.passwordsMatch() &&\n !extraFieldsError;\n\n const extraFieldsValid = this.validateRequiredExtraFields();\n\n if (!isCompanyFeatureEnabled(this.appConfig))\n return userValid && extraFieldsValid;\n\n const companyModel = this.companyFormModel();\n if (companyModel.createNewCompany) {\n return (\n userValid &&\n extraFieldsValid &&\n companyModel.newCompanyName.trim().length > 0\n );\n }\n return userValid && extraFieldsValid;\n });\n\n private validateRequiredExtraFields(): boolean {\n const fields = this.extraFields();\n const values = this.extraFieldsModel();\n\n for (const field of fields) {\n if (field.required) {\n const value = values[field.key];\n if (value === undefined || value === null || value === '') {\n return false;\n }\n }\n }\n return true;\n }\n\n updateExtraField(key: string, value: unknown): void {\n this.extraFieldsModel.update((model) => ({ ...model, [key]: value }));\n }\n\n getFieldTemplateContext(\n field: IRegistrationExtraField,\n ): IRegistrationFieldTemplateContext {\n return {\n field,\n value: this.extraFieldsModel()[field.key] ?? field.defaultValue,\n updateValue: (value: unknown) => this.updateExtraField(field.key, value),\n };\n }\n\n private readonly parentInjector = inject(Injector);\n\n private readonly fieldInjectors = new Map<\n string,\n { injector: Injector; setField: (field: IRegistrationExtraField) => void }\n >();\n\n getFieldInjector(field: IRegistrationExtraField): Injector {\n const cached = this.fieldInjectors.get(field.key);\n if (cached) {\n cached.setField(field);\n return cached.injector;\n }\n\n let currentField = field;\n const extraFieldsModel = this.extraFieldsModel;\n const context: IRegistrationFieldTemplateContext = {\n get field() {\n return currentField;\n },\n get value() {\n return extraFieldsModel()[currentField.key] ?? currentField.defaultValue;\n },\n updateValue: (value: unknown) =>\n this.updateExtraField(currentField.key, value),\n };\n\n const injector = Injector.create({\n providers: [{ provide: REGISTRATION_FIELD_CONTEXT, useValue: context }],\n parent: field.injector ?? this.parentInjector,\n });\n this.fieldInjectors.set(field.key, {\n injector,\n setField: (next) => (currentField = next),\n });\n return injector;\n }\n\n constructor() {\n effect(() => {\n const params = this.queryParamMap();\n if (!params || this.companySlugInitialized) return;\n\n this.companySlugInitialized = true;\n\n const configCompanySlug = this.defaultCompanySlug();\n const configBranchSlug = this.defaultBranchSlug();\n const queryCompanySlug = params.get('companySlug');\n\n const companySlug = configCompanySlug || queryCompanySlug || '';\n const branchSlug = configBranchSlug || '';\n\n if (companySlug || branchSlug) {\n this.companyFormModel.update((model) => ({\n ...model,\n companySlug,\n branchSlug,\n }));\n }\n });\n }\n\n onCreateCompanyToggle(createNew: boolean): void {\n if (createNew) {\n this.companyFormModel.update((model) => ({\n ...model,\n createNewCompany: true,\n companySlug: '',\n branchSlug: '',\n }));\n } else {\n this.companyFormModel.update((model) => ({\n ...model,\n createNewCompany: false,\n newCompanyName: '',\n newCompanyPhone: '',\n newCompanyAddress: '',\n }));\n }\n }\n\n onSubmit(): void {\n if (!this.isFormValid()) {\n this.messageService.add({\n severity: 'error',\n summary: this.translate('shared.validation.error'),\n detail: this.translate('shared.fill.required.fields'),\n });\n return;\n }\n\n this.isLoading.set(true);\n\n const userModel = this.userFormModel();\n const companyModel = this.companyFormModel();\n\n let registrationData: Record<string, unknown> = {\n name: userModel.name,\n email: userModel.email,\n password: userModel.password,\n phone: userModel.phone || undefined,\n };\n\n const extraFieldsData = this.extraFieldsModel();\n if (Object.keys(extraFieldsData).length > 0) {\n registrationData['additionalFields'] = extraFieldsData;\n }\n\n if (this.registrationExtension?.transformRegistrationData) {\n registrationData =\n this.registrationExtension.transformRegistrationData(registrationData);\n }\n\n if (isCompanyFeatureEnabled(this.appConfig)) {\n if (companyModel.createNewCompany) {\n registrationData['newCompanyName'] =\n companyModel.newCompanyName || undefined;\n registrationData['newCompanyPhone'] =\n companyModel.newCompanyPhone || undefined;\n registrationData['newCompanyAddress'] =\n companyModel.newCompanyAddress || undefined;\n } else {\n registrationData['companySlug'] = companyModel.companySlug || undefined;\n registrationData['branchSlug'] = companyModel.branchSlug || undefined;\n }\n }\n\n this.authApi\n .register(registrationData as unknown as IRegistrationRequest)\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe({\n next: (response) => {\n this.isLoading.set(false);\n const data = response.data;\n if (!data) return;\n\n if (data.requiresEmailVerification) {\n this.messageService.add({\n severity: 'success',\n summary: this.translate('shared.success'),\n detail: response.messageKey\n ? this.translate(response.messageKey, response.messageVariables)\n : response.message,\n life: 5000,\n });\n this.router.navigate(['/auth/login']);\n return;\n }\n\n if (data.accessToken) {\n this.authState.setLoginState({\n accessToken: data.accessToken,\n user: data.user,\n company: data.company,\n branch: data.branch,\n });\n this.messageService.add({\n severity: 'success',\n summary: this.translate('shared.success'),\n detail: response.messageKey\n ? this.translate(response.messageKey, response.messageVariables)\n : response.message,\n });\n this.authState.navigateAfterLogin(this.returnUrl());\n }\n },\n error: () => {\n this.isLoading.set(false);\n },\n });\n }\n}\n"],"mappings":"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"}
|
|
@@ -79,7 +79,7 @@ var ResetPasswordPageComponent = class ResetPasswordPageComponent {
|
|
|
79
79
|
}
|
|
80
80
|
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
81
81
|
minVersion: "12.0.0",
|
|
82
|
-
version: "22.2.
|
|
82
|
+
version: "22.2.3",
|
|
83
83
|
ngImport: i0,
|
|
84
84
|
type: ResetPasswordPageComponent,
|
|
85
85
|
deps: [],
|
|
@@ -87,7 +87,7 @@ var ResetPasswordPageComponent = class ResetPasswordPageComponent {
|
|
|
87
87
|
});
|
|
88
88
|
static ɵcmp = i0.ɵɵngDeclareComponent({
|
|
89
89
|
minVersion: "17.0.0",
|
|
90
|
-
version: "22.2.
|
|
90
|
+
version: "22.2.3",
|
|
91
91
|
type: ResetPasswordPageComponent,
|
|
92
92
|
isStandalone: true,
|
|
93
93
|
selector: "lib-reset-password-page",
|
|
@@ -357,7 +357,7 @@ var ResetPasswordPageComponent = class ResetPasswordPageComponent {
|
|
|
357
357
|
};
|
|
358
358
|
i0.ɵɵngDeclareClassMetadata({
|
|
359
359
|
minVersion: "12.0.0",
|
|
360
|
-
version: "22.2.
|
|
360
|
+
version: "22.2.3",
|
|
361
361
|
ngImport: i0,
|
|
362
362
|
type: ResetPasswordPageComponent,
|
|
363
363
|
decorators: [{
|
|
@@ -535,4 +535,4 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
535
535
|
});
|
|
536
536
|
export { ResetPasswordPageComponent };
|
|
537
537
|
|
|
538
|
-
//# sourceMappingURL=flusys-ng-auth-reset-password-page.component-
|
|
538
|
+
//# sourceMappingURL=flusys-ng-auth-reset-password-page.component-C33Lu6ST.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flusys-ng-auth-reset-password-page.component-DnULwTow.mjs","names":[],"sources":["../../../projects/ng-auth/pages/reset-password/reset-password-page.component.ts"],"sourcesContent":["import {\n Component,\n computed,\n DestroyRef,\n effect,\n inject,\n signal,\n} from '@angular/core';\nimport { takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop';\nimport { form, FormField, required } from '@angular/forms/signals';\nimport { ActivatedRoute, RouterLink } from '@angular/router';\nimport { AppFloatingConfigurator } from '@flusys/ng-layout';\nimport { FButtonDirective, MessageService, PasswordComponent, UiIconComponent } from '@flusys/ng-ui';\nimport {\n TranslatePipe,\n TranslateService,\n} from '@flusys/ng-shared';\nimport { finalize } from 'rxjs';\nimport { AuthApiService } from '../../services/auth-api.service';\nimport { PasswordPolicyService } from '../../services/password-policy.service';\n\ninterface IResetPasswordFormModel {\n newPassword: string;\n confirmPassword: string;\n}\n\ntype PageState = 'form' | 'success' | 'invalid-token';\n\n@Component({\n selector: 'lib-reset-password-page',\n imports: [\n RouterLink,\n FButtonDirective,\n PasswordComponent,\n UiIconComponent,\n FormField,\n AppFloatingConfigurator,\n TranslatePipe,\n ],\n template: `\n <app-floating-configurator />\n <div\n class=\"bg-surface-ground flex items-center justify-center min-h-screen\"\n >\n <div\n class=\"flex flex-col items-center justify-center w-full max-w-[32rem] px-4\"\n >\n <div\n class=\"w-full\"\n style=\"border-radius: var(--f-content-border-radius); padding: 0.3rem; background: linear-gradient(180deg, var(--primary-color) 10%, rgba(33, 150, 243, 0) 30%)\"\n >\n <div\n class=\"w-full py-8 px-4 sm:py-12 sm:px-8 md:py-16 md:px-12\"\n style=\"border-radius: var(--f-content-border-radius); background: var(--f-content-background)\"\n >\n @switch (pageState()) {\n @case ('form') {\n <div class=\"text-center mb-8\">\n <div class=\"text-3xl font-medium mb-4 text-color\">\n {{ 'auth.reset.password.title' | translate }}\n </div>\n <span class=\"text-muted-color font-medium\">\n {{ 'auth.reset.password.subtitle' | translate }}\n </span>\n </div>\n\n <form (submit)=\"onSubmit($event)\">\n <label\n for=\"newPassword\"\n class=\"block text-lg font-medium mb-2 text-color\"\n >\n {{ 'auth.reset.password.new.password' | translate }}\n </label>\n <div class=\"mb-4\">\n <f-password\n [inputId]=\"'newPassword'\"\n [placeholder]=\"\n 'auth.reset.password.new.password.placeholder' | translate\n \"\n class=\"w-full\"\n [formField]=\"resetForm.newPassword\"\n autocomplete=\"new-password\"\n />\n @if (passwordValidationError()) {\n <small class=\"text-danger block mt-1\">{{\n passwordValidationError()\n }}</small>\n }\n </div>\n\n <label\n for=\"confirmPassword\"\n class=\"block text-lg font-medium mb-2 text-color\"\n >\n {{ 'auth.reset.password.confirm.password' | translate }}\n </label>\n <f-password\n [inputId]=\"'confirmPassword'\"\n [placeholder]=\"\n 'auth.reset.password.confirm.password.placeholder'\n | translate\n \"\n class=\"w-full mb-2\"\n [formField]=\"resetForm.confirmPassword\"\n autocomplete=\"new-password\"\n />\n\n @if (passwordMismatch()) {\n <small class=\"text-danger block mb-4\">{{\n 'auth.register.passwords.do.not.match' | translate\n }}</small>\n }\n\n <button\n fButton\n class=\"w-full mt-4 mb-4\"\n type=\"submit\"\n [disabled]=\"!canSubmit() || isLoading()\"\n >\n @if (isLoading()) {\n <ui-icon pButtonIcon name=\"spinner\" [spin]=\"true\"></ui-icon>\n }\n <span pButtonLabel>{{ 'auth.reset.password.reset.password' | translate }}</span>\n </button>\n\n <div class=\"flex items-center justify-center gap-2\">\n <a\n routerLink=\"/auth/login\"\n class=\"font-semibold text-primary cursor-pointer\"\n >\n {{ 'auth.login.back.to.sign.in' | translate }}\n </a>\n </div>\n </form>\n }\n\n @case ('success') {\n <div class=\"text-center\">\n <div class=\"flex justify-center mb-6\">\n <ui-icon name=\"check-circle\" class=\"text-6xl text-success\"></ui-icon>\n </div>\n <div class=\"text-3xl font-medium mb-4 text-color\">\n {{ 'auth.reset.password.success' | translate }}\n </div>\n <p class=\"text-muted-color font-medium mb-6\">\n {{ 'auth.reset.password.success.message' | translate }}\n </p>\n <a routerLink=\"/auth/login\">\n <button\n fButton\n class=\"w-full\"\n >\n <span pButtonLabel>{{ 'auth.login.sign.in' | translate }}</span>\n </button>\n </a>\n </div>\n }\n\n @case ('invalid-token') {\n <div class=\"text-center\">\n <div class=\"flex justify-center mb-6\">\n <ui-icon name=\"times-circle\" class=\"text-6xl text-danger\"></ui-icon>\n </div>\n <div class=\"text-3xl font-medium mb-4 text-color\">\n {{ 'auth.reset.password.invalid.link' | translate }}\n </div>\n <p class=\"text-muted-color font-medium mb-6\">\n {{ 'auth.reset.password.invalid.link.message' | translate }}\n </p>\n <a routerLink=\"/auth/forgot-password\">\n <button\n fButton\n class=\"w-full mb-4\"\n >\n <span pButtonLabel>{{\n 'auth.reset.password.request.new.link' | translate\n }}</span>\n </button>\n </a>\n <div class=\"mt-4\">\n <a\n routerLink=\"/auth/login\"\n class=\"font-semibold text-primary cursor-pointer\"\n >\n {{ 'auth.login.back.to.sign.in' | translate }}\n </a>\n </div>\n </div>\n }\n }\n </div>\n </div>\n </div>\n </div>\n `,\n})\nexport class ResetPasswordPageComponent {\n private readonly destroyRef = inject(DestroyRef);\n private readonly route = inject(ActivatedRoute);\n private readonly messageService = inject(MessageService);\n private readonly authApi = inject(AuthApiService);\n private readonly passwordPolicy = inject(PasswordPolicyService);\n private readonly translateAdapter = inject(TranslateService, {\n optional: true,\n });\n\n private translate(\n key: string,\n vars?: Record<string, unknown>,\n ): string {\n return this.translateAdapter?.translate(key, vars) ?? key;\n }\n\n private readonly queryParams = toSignal(this.route.queryParams);\n private tokenInitialized = false;\n\n private token = '';\n readonly isLoading = signal(false);\n readonly pageState = signal<PageState>('form');\n readonly formModel = signal<IResetPasswordFormModel>({\n newPassword: '',\n confirmPassword: '',\n });\n readonly resetForm = form(this.formModel, (f) => {\n required(f.newPassword, {\n message: this.translate('auth.validation.password.required'),\n });\n required(f.confirmPassword, {\n message: this.translate('auth.validation.confirm.password.required'),\n });\n });\n readonly passwordMismatch = computed(() => {\n const model = this.formModel();\n return (\n model.confirmPassword.length > 0 &&\n model.newPassword !== model.confirmPassword\n );\n });\n readonly passwordValidationError = computed(() =>\n this.passwordPolicy.validate(this.formModel().newPassword),\n );\n readonly canSubmit = computed(\n () =>\n this.resetForm().valid() &&\n !this.passwordValidationError() &&\n !this.passwordMismatch(),\n );\n\n constructor() {\n effect(() => {\n const params = this.queryParams();\n if (!params || this.tokenInitialized) return;\n\n this.tokenInitialized = true;\n this.token = params['token'] || '';\n if (!this.token) {\n this.pageState.set('invalid-token');\n }\n });\n }\n\n onSubmit(event: Event): void {\n event.preventDefault();\n\n if (!this.canSubmit()) {\n this.messageService.add({\n severity: 'error',\n summary: this.translate('shared.validation.error'),\n detail: this.translate('shared.fill.required.fields'),\n });\n return;\n }\n\n this.isLoading.set(true);\n const newPassword = this.formModel().newPassword;\n\n this.authApi\n .resetPassword(this.token, newPassword)\n .pipe(\n takeUntilDestroyed(this.destroyRef),\n finalize(() => this.isLoading.set(false)),\n )\n .subscribe({\n next: (response) => {\n this.messageService.add({\n severity: 'success',\n summary: this.translate('shared.success'),\n detail: response?.messageKey\n ? this.translate(response.messageKey, response.messageVariables)\n : response?.message,\n });\n this.pageState.set('success');\n },\n error: (error) => {\n const messageKey: string = error.error?.messageKey || '';\n const invalidTokenKeys = [\n 'auth.password.reset.token.expired',\n 'auth.password.reset.token.used',\n 'email.verification.token.invalid',\n ];\n if (invalidTokenKeys.includes(messageKey)) {\n this.pageState.set('invalid-token');\n }\n // Other errors handled by global interceptor\n },\n });\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"flusys-ng-auth-reset-password-page.component-C33Lu6ST.mjs","names":[],"sources":["../../../projects/ng-auth/pages/reset-password/reset-password-page.component.ts"],"sourcesContent":["import {\n Component,\n computed,\n DestroyRef,\n effect,\n inject,\n signal,\n} from '@angular/core';\nimport { takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop';\nimport { form, FormField, required } from '@angular/forms/signals';\nimport { ActivatedRoute, RouterLink } from '@angular/router';\nimport { AppFloatingConfigurator } from '@flusys/ng-layout';\nimport { FButtonDirective, MessageService, PasswordComponent, UiIconComponent } from '@flusys/ng-ui';\nimport {\n TranslatePipe,\n TranslateService,\n} from '@flusys/ng-shared';\nimport { finalize } from 'rxjs';\nimport { AuthApiService } from '../../services/auth-api.service';\nimport { PasswordPolicyService } from '../../services/password-policy.service';\n\ninterface IResetPasswordFormModel {\n newPassword: string;\n confirmPassword: string;\n}\n\ntype PageState = 'form' | 'success' | 'invalid-token';\n\n@Component({\n selector: 'lib-reset-password-page',\n imports: [\n RouterLink,\n FButtonDirective,\n PasswordComponent,\n UiIconComponent,\n FormField,\n AppFloatingConfigurator,\n TranslatePipe,\n ],\n template: `\n <app-floating-configurator />\n <div\n class=\"bg-surface-ground flex items-center justify-center min-h-screen\"\n >\n <div\n class=\"flex flex-col items-center justify-center w-full max-w-[32rem] px-4\"\n >\n <div\n class=\"w-full\"\n style=\"border-radius: var(--f-content-border-radius); padding: 0.3rem; background: linear-gradient(180deg, var(--primary-color) 10%, rgba(33, 150, 243, 0) 30%)\"\n >\n <div\n class=\"w-full py-8 px-4 sm:py-12 sm:px-8 md:py-16 md:px-12\"\n style=\"border-radius: var(--f-content-border-radius); background: var(--f-content-background)\"\n >\n @switch (pageState()) {\n @case ('form') {\n <div class=\"text-center mb-8\">\n <div class=\"text-3xl font-medium mb-4 text-color\">\n {{ 'auth.reset.password.title' | translate }}\n </div>\n <span class=\"text-muted-color font-medium\">\n {{ 'auth.reset.password.subtitle' | translate }}\n </span>\n </div>\n\n <form (submit)=\"onSubmit($event)\">\n <label\n for=\"newPassword\"\n class=\"block text-lg font-medium mb-2 text-color\"\n >\n {{ 'auth.reset.password.new.password' | translate }}\n </label>\n <div class=\"mb-4\">\n <f-password\n [inputId]=\"'newPassword'\"\n [placeholder]=\"\n 'auth.reset.password.new.password.placeholder' | translate\n \"\n class=\"w-full\"\n [formField]=\"resetForm.newPassword\"\n autocomplete=\"new-password\"\n />\n @if (passwordValidationError()) {\n <small class=\"text-danger block mt-1\">{{\n passwordValidationError()\n }}</small>\n }\n </div>\n\n <label\n for=\"confirmPassword\"\n class=\"block text-lg font-medium mb-2 text-color\"\n >\n {{ 'auth.reset.password.confirm.password' | translate }}\n </label>\n <f-password\n [inputId]=\"'confirmPassword'\"\n [placeholder]=\"\n 'auth.reset.password.confirm.password.placeholder'\n | translate\n \"\n class=\"w-full mb-2\"\n [formField]=\"resetForm.confirmPassword\"\n autocomplete=\"new-password\"\n />\n\n @if (passwordMismatch()) {\n <small class=\"text-danger block mb-4\">{{\n 'auth.register.passwords.do.not.match' | translate\n }}</small>\n }\n\n <button\n fButton\n class=\"w-full mt-4 mb-4\"\n type=\"submit\"\n [disabled]=\"!canSubmit() || isLoading()\"\n >\n @if (isLoading()) {\n <ui-icon pButtonIcon name=\"spinner\" [spin]=\"true\"></ui-icon>\n }\n <span pButtonLabel>{{ 'auth.reset.password.reset.password' | translate }}</span>\n </button>\n\n <div class=\"flex items-center justify-center gap-2\">\n <a\n routerLink=\"/auth/login\"\n class=\"font-semibold text-primary cursor-pointer\"\n >\n {{ 'auth.login.back.to.sign.in' | translate }}\n </a>\n </div>\n </form>\n }\n\n @case ('success') {\n <div class=\"text-center\">\n <div class=\"flex justify-center mb-6\">\n <ui-icon name=\"check-circle\" class=\"text-6xl text-success\"></ui-icon>\n </div>\n <div class=\"text-3xl font-medium mb-4 text-color\">\n {{ 'auth.reset.password.success' | translate }}\n </div>\n <p class=\"text-muted-color font-medium mb-6\">\n {{ 'auth.reset.password.success.message' | translate }}\n </p>\n <a routerLink=\"/auth/login\">\n <button\n fButton\n class=\"w-full\"\n >\n <span pButtonLabel>{{ 'auth.login.sign.in' | translate }}</span>\n </button>\n </a>\n </div>\n }\n\n @case ('invalid-token') {\n <div class=\"text-center\">\n <div class=\"flex justify-center mb-6\">\n <ui-icon name=\"times-circle\" class=\"text-6xl text-danger\"></ui-icon>\n </div>\n <div class=\"text-3xl font-medium mb-4 text-color\">\n {{ 'auth.reset.password.invalid.link' | translate }}\n </div>\n <p class=\"text-muted-color font-medium mb-6\">\n {{ 'auth.reset.password.invalid.link.message' | translate }}\n </p>\n <a routerLink=\"/auth/forgot-password\">\n <button\n fButton\n class=\"w-full mb-4\"\n >\n <span pButtonLabel>{{\n 'auth.reset.password.request.new.link' | translate\n }}</span>\n </button>\n </a>\n <div class=\"mt-4\">\n <a\n routerLink=\"/auth/login\"\n class=\"font-semibold text-primary cursor-pointer\"\n >\n {{ 'auth.login.back.to.sign.in' | translate }}\n </a>\n </div>\n </div>\n }\n }\n </div>\n </div>\n </div>\n </div>\n `,\n})\nexport class ResetPasswordPageComponent {\n private readonly destroyRef = inject(DestroyRef);\n private readonly route = inject(ActivatedRoute);\n private readonly messageService = inject(MessageService);\n private readonly authApi = inject(AuthApiService);\n private readonly passwordPolicy = inject(PasswordPolicyService);\n private readonly translateAdapter = inject(TranslateService, {\n optional: true,\n });\n\n private translate(\n key: string,\n vars?: Record<string, unknown>,\n ): string {\n return this.translateAdapter?.translate(key, vars) ?? key;\n }\n\n private readonly queryParams = toSignal(this.route.queryParams);\n private tokenInitialized = false;\n\n private token = '';\n readonly isLoading = signal(false);\n readonly pageState = signal<PageState>('form');\n readonly formModel = signal<IResetPasswordFormModel>({\n newPassword: '',\n confirmPassword: '',\n });\n readonly resetForm = form(this.formModel, (f) => {\n required(f.newPassword, {\n message: this.translate('auth.validation.password.required'),\n });\n required(f.confirmPassword, {\n message: this.translate('auth.validation.confirm.password.required'),\n });\n });\n readonly passwordMismatch = computed(() => {\n const model = this.formModel();\n return (\n model.confirmPassword.length > 0 &&\n model.newPassword !== model.confirmPassword\n );\n });\n readonly passwordValidationError = computed(() =>\n this.passwordPolicy.validate(this.formModel().newPassword),\n );\n readonly canSubmit = computed(\n () =>\n this.resetForm().valid() &&\n !this.passwordValidationError() &&\n !this.passwordMismatch(),\n );\n\n constructor() {\n effect(() => {\n const params = this.queryParams();\n if (!params || this.tokenInitialized) return;\n\n this.tokenInitialized = true;\n this.token = params['token'] || '';\n if (!this.token) {\n this.pageState.set('invalid-token');\n }\n });\n }\n\n onSubmit(event: Event): void {\n event.preventDefault();\n\n if (!this.canSubmit()) {\n this.messageService.add({\n severity: 'error',\n summary: this.translate('shared.validation.error'),\n detail: this.translate('shared.fill.required.fields'),\n });\n return;\n }\n\n this.isLoading.set(true);\n const newPassword = this.formModel().newPassword;\n\n this.authApi\n .resetPassword(this.token, newPassword)\n .pipe(\n takeUntilDestroyed(this.destroyRef),\n finalize(() => this.isLoading.set(false)),\n )\n .subscribe({\n next: (response) => {\n this.messageService.add({\n severity: 'success',\n summary: this.translate('shared.success'),\n detail: response?.messageKey\n ? this.translate(response.messageKey, response.messageVariables)\n : response?.message,\n });\n this.pageState.set('success');\n },\n error: (error) => {\n const messageKey: string = error.error?.messageKey || '';\n const invalidTokenKeys = [\n 'auth.password.reset.token.expired',\n 'auth.password.reset.token.used',\n 'email.verification.token.invalid',\n ];\n if (invalidTokenKeys.includes(messageKey)) {\n this.pageState.set('invalid-token');\n }\n // Other errors handled by global interceptor\n },\n });\n }\n}\n"],"mappings":"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"}
|
|
@@ -87,7 +87,7 @@ var SocialCallbackPageComponent = class SocialCallbackPageComponent {
|
|
|
87
87
|
}
|
|
88
88
|
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
89
89
|
minVersion: "12.0.0",
|
|
90
|
-
version: "22.2.
|
|
90
|
+
version: "22.2.3",
|
|
91
91
|
ngImport: i0,
|
|
92
92
|
type: SocialCallbackPageComponent,
|
|
93
93
|
deps: [],
|
|
@@ -95,7 +95,7 @@ var SocialCallbackPageComponent = class SocialCallbackPageComponent {
|
|
|
95
95
|
});
|
|
96
96
|
static ɵcmp = i0.ɵɵngDeclareComponent({
|
|
97
97
|
minVersion: "17.0.0",
|
|
98
|
-
version: "22.2.
|
|
98
|
+
version: "22.2.3",
|
|
99
99
|
type: SocialCallbackPageComponent,
|
|
100
100
|
isStandalone: true,
|
|
101
101
|
selector: "lib-social-callback-page",
|
|
@@ -175,7 +175,7 @@ var SocialCallbackPageComponent = class SocialCallbackPageComponent {
|
|
|
175
175
|
};
|
|
176
176
|
i0.ɵɵngDeclareClassMetadata({
|
|
177
177
|
minVersion: "12.0.0",
|
|
178
|
-
version: "22.2.
|
|
178
|
+
version: "22.2.3",
|
|
179
179
|
ngImport: i0,
|
|
180
180
|
type: SocialCallbackPageComponent,
|
|
181
181
|
decorators: [{
|
|
@@ -216,4 +216,4 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
216
216
|
});
|
|
217
217
|
export { SocialCallbackPageComponent };
|
|
218
218
|
|
|
219
|
-
//# sourceMappingURL=flusys-ng-auth-social-callback-page.component-
|
|
219
|
+
//# sourceMappingURL=flusys-ng-auth-social-callback-page.component-CDb3VVWf.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flusys-ng-auth-social-callback-page.component-
|
|
1
|
+
{"version":3,"file":"flusys-ng-auth-social-callback-page.component-CDb3VVWf.mjs","names":[],"sources":["../../../projects/ng-auth/pages/social-callback/social-callback-page.component.ts"],"sourcesContent":["import { Component, computed, DestroyRef, inject, signal } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { ActivatedRoute, Router } from '@angular/router';\nimport { AppFloatingConfigurator } from '@flusys/ng-layout';\nimport { PlatformService, TranslatePipe, TranslateService } from '@flusys/ng-shared';\nimport { FButtonDirective, MessageService, UiIconComponent } from '@flusys/ng-ui';\nimport {\n isCompanySelectionResponse,\n isLoginResponse,\n} from '../../interfaces/auth.interface';\nimport { AuthStateService } from '../../services/auth-state.service';\nimport { SocialAuthApiService } from '../../services/social-auth-api.service';\n\n@Component({\n selector: 'lib-social-callback-page',\n imports: [FButtonDirective, UiIconComponent, TranslatePipe, AppFloatingConfigurator],\n template: `\n <app-floating-configurator />\n <div class=\"bg-surface-ground flex items-center justify-center min-h-screen\">\n <div class=\"flex flex-col items-center gap-4 text-center px-4\">\n @if (errorDetail()) {\n <ui-icon name=\"exclamation-circle\" class=\"text-6xl text-danger\"></ui-icon>\n <div class=\"text-2xl font-medium text-color\">\n {{ 'auth.social.failed' | translate }}\n </div>\n <p class=\"text-muted-color font-medium\">{{ errorDetail() }}</p>\n <button fButton severity=\"secondary\" [outlined]=\"true\" (click)=\"backToLogin()\">\n <span>{{ 'auth.login.back.to.sign.in' | translate }}</span>\n </button>\n } @else {\n <ui-icon name=\"spinner\" [spin]=\"true\" class=\"text-5xl text-primary\"></ui-icon>\n <div class=\"text-2xl font-medium text-color\">\n {{ 'auth.social.signing.in' | translate }}\n </div>\n }\n </div>\n </div>\n `,\n})\nexport class SocialCallbackPageComponent {\n private readonly destroyRef = inject(DestroyRef);\n private readonly route = inject(ActivatedRoute);\n private readonly router = inject(Router);\n private readonly platform = inject(PlatformService);\n private readonly socialApi = inject(SocialAuthApiService);\n private readonly authState = inject(AuthStateService);\n private readonly messageService = inject(MessageService);\n private readonly translateAdapter = inject(TranslateService, {\n optional: true,\n });\n\n private readonly _error = signal<\n { key: string; vars?: Record<string, string | number> } | { raw: string } | null\n >(null);\n readonly errorDetail = computed(() => {\n const error = this._error();\n if (!error) return null;\n return 'key' in error ? this.translate(error.key, error.vars) : error.raw;\n });\n\n constructor() {\n if (this.platform.isServer) return;\n this.exchangeCode();\n }\n\n backToLogin(): void {\n this.router.navigate(['/auth/login']);\n }\n\n private exchangeCode(): void {\n const params = this.route.snapshot.queryParamMap;\n\n const providerError = params.get('error_description') ?? params.get('error');\n if (providerError) {\n this._error.set({ raw: providerError });\n return;\n }\n\n const code = params.get('code');\n const state = params.get('state');\n\n if (!code || !state) {\n this._error.set({ key: 'auth.social.state.invalid' });\n return;\n }\n\n this.socialApi\n .callback({ code, state, redirectUri: this.socialApi.redirectUri })\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe({\n next: (response) => {\n if (!response.data) {\n this._error.set({ key: 'auth.social.failed' });\n return;\n }\n\n if (isCompanySelectionResponse(response)) {\n this.authState.setSelectionState(response.data);\n this.router.navigate(['/auth/login']);\n return;\n }\n\n if (isLoginResponse(response)) {\n this.authState.setLoginState(response.data);\n this.messageService.add({\n severity: 'success',\n summary: this.translate('shared.success'),\n detail: response.messageKey\n ? this.translate(response.messageKey, response.messageVariables)\n : (response.message ?? this.translate('auth.login.success')),\n });\n this.authState.navigateAfterLogin(this.returnUrl());\n return;\n }\n\n this._error.set({ key: 'auth.social.failed' });\n },\n error: (error) => {\n const messageKey = error?.error?.messageKey;\n if (messageKey) {\n this._error.set({ key: messageKey, vars: error?.error?.messageVariables });\n } else if (error?.error?.message) {\n this._error.set({ raw: error.error.message });\n } else {\n this._error.set({ key: 'auth.social.failed' });\n }\n },\n });\n }\n\n private returnUrl(): string {\n return this.socialApi.consumeReturnUrl();\n }\n\n private translate(\n key: string,\n vars?: Record<string, unknown>,\n ): string {\n return this.translateAdapter?.translate(key, vars) ?? key;\n }\n}\n"],"mappings":";;;;;;;;AAuCA,IAAa,8BAAb,MAAa,4BAA2B;CACrB,aAAa,OAAO,UAAU;CAC9B,QAAQ,OAAO,cAAc;CAC7B,SAAS,OAAO,MAAM;CACtB,WAAW,OAAO,eAAe;CACjC,YAAY,OAAO,oBAAoB;CACvC,YAAY,OAAO,gBAAgB;CACnC,iBAAiB,OAAO,cAAc;CACtC,mBAAmB,OAAO,kBAAkB,EAC3D,UAAU,KACX,CAAA;CAEgB,SAAS,OAExB,MAAK,GAAA,YAAA,CAAA,EAAA,WAAA,SAAA,CAAA,+BAAA,CAAA,CAAA;CACE,cAAc,eAAc;EACnC,MAAM,QAAQ,KAAK,OAAM;EACzB,IAAI,CAAC,OAAO,OAAO;EACnB,OAAO,SAAS,QAAQ,KAAK,UAAU,MAAM,KAAK,MAAM,IAAI,IAAI,MAAM;CACxE,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,cAAA,CAAA,+BAAA,CAAA,CAAA;CAEF,cAAA;EACE,IAAI,KAAK,SAAS,UAAU;EAC5B,KAAK,aAAY;CACnB;CAEA,cAAW;EACT,KAAK,OAAO,SAAS,CAAC,aAAa,CAAC;CACtC;CAEQ,eAAY;EAClB,MAAM,SAAS,KAAK,MAAM,SAAS;EAEnC,MAAM,gBAAgB,OAAO,IAAI,mBAAmB,KAAK,OAAO,IAAI,OAAO;EAC3E,IAAI,eAAe;GACjB,KAAK,OAAO,IAAI,EAAE,KAAK,cAAa,CAAE;GACtC;EACF;EAEA,MAAM,OAAO,OAAO,IAAI,MAAM;EAC9B,MAAM,QAAQ,OAAO,IAAI,OAAO;EAEhC,IAAI,CAAC,QAAQ,CAAC,OAAO;GACnB,KAAK,OAAO,IAAI,EAAE,KAAK,4BAA2B,CAAE;GACpD;EACF;EAEA,KAAK,UACF,SAAS;GAAE;GAAM;GAAO,aAAa,KAAK,UAAU;EAAW,CAAE,CAAC,CAClE,KAAK,mBAAmB,KAAK,UAAU,CAAC,CAAC,CACzC,UAAU;GACT,OAAO,aAAY;IACjB,IAAI,CAAC,SAAS,MAAM;KAClB,KAAK,OAAO,IAAI,EAAE,KAAK,qBAAoB,CAAE;KAC7C;IACF;IAEA,IAAI,2BAA2B,QAAQ,GAAG;KACxC,KAAK,UAAU,kBAAkB,SAAS,IAAI;KAC9C,KAAK,OAAO,SAAS,CAAC,aAAa,CAAC;KACpC;IACF;IAEA,IAAI,gBAAgB,QAAQ,GAAG;KAC7B,KAAK,UAAU,cAAc,SAAS,IAAI;KAC1C,KAAK,eAAe,IAAI;MACtB,UAAU;MACV,SAAS,KAAK,UAAU,gBAAgB;MACxC,QAAQ,SAAS,aACb,KAAK,UAAU,SAAS,YAAY,SAAS,gBAAgB,IAC5D,SAAS,WAAW,KAAK,UAAU,oBAAoB;KAC7D,CAAA;KACD,KAAK,UAAU,mBAAmB,KAAK,UAAS,CAAE;KAClD;IACF;IAEA,KAAK,OAAO,IAAI,EAAE,KAAK,qBAAoB,CAAE;GAC/C;GACA,QAAQ,UAAS;IACf,MAAM,aAAa,OAAO,OAAO;IACjC,IAAI,YACF,KAAK,OAAO,IAAI;KAAE,KAAK;KAAY,MAAM,OAAO,OAAO;IAAgB,CAAE;SACpE,IAAI,OAAO,OAAO,SACvB,KAAK,OAAO,IAAI,EAAE,KAAK,MAAM,MAAM,QAAO,CAAE;SAE5C,KAAK,OAAO,IAAI,EAAE,KAAK,qBAAoB,CAAE;GAEjD;EACD,CAAA;CACL;CAEQ,YAAS;EACf,OAAO,KAAK,UAAU,iBAAgB;CACxC;CAEQ,UACN,KACA,MAA8B;EAE9B,OAAO,KAAK,kBAAkB,UAAU,KAAK,IAAI,KAAK;CACxD;CApGW,OAAA,OAAA,GAAA,mBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAA2B,MAAA,CAAA;EAAA,QAAA,GAAA,gBAAA;CAAA,CAAA;CAA3B,OAAA,OAAA,GAAA,qBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,MAAA;EAA2B,cAAA;EAAA,UAAA;EAAA,UAAA;EAAA,UAvB5B;;;;;;;;;;;;;;;;;;;;;;EAqBT,UAAA;EAAA,cAAA;GAAA;IAAA,MAAA;IAAA,MAtBS;IAAgB,UAAA;IAAA,QAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;IAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MAAE;IAAe,UAAA;IAAA,QAAA;KAAA;KAAA;KAAA;KAAA;KAAA;IAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MAAiB;IAAuB,UAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MAAtC;IAAa,MAAA;GAAA;EAAA;CAAA,CAAA;;AAwB/C,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAA2B,YAAA,CAAA;EA1BvC,MAAA;EAAU,MAAA,CAAA;GACT,UAAU;GACV,SAAS;IAAC;IAAkB;IAAiB;IAAe;GAAuB;GACnF,UAAU;;;;;;;;;;;;;;;;;;;;;;EAsBX,CAAA"}
|
|
@@ -74,7 +74,7 @@ var SocialConfigPageComponent = class SocialConfigPageComponent {
|
|
|
74
74
|
}
|
|
75
75
|
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
76
76
|
minVersion: "12.0.0",
|
|
77
|
-
version: "22.2.
|
|
77
|
+
version: "22.2.3",
|
|
78
78
|
ngImport: i0,
|
|
79
79
|
type: SocialConfigPageComponent,
|
|
80
80
|
deps: [],
|
|
@@ -82,7 +82,7 @@ var SocialConfigPageComponent = class SocialConfigPageComponent {
|
|
|
82
82
|
});
|
|
83
83
|
static ɵcmp = i0.ɵɵngDeclareComponent({
|
|
84
84
|
minVersion: "17.0.0",
|
|
85
|
-
version: "22.2.
|
|
85
|
+
version: "22.2.3",
|
|
86
86
|
type: SocialConfigPageComponent,
|
|
87
87
|
isStandalone: true,
|
|
88
88
|
selector: "lib-social-config-page",
|
|
@@ -342,7 +342,7 @@ var SocialConfigPageComponent = class SocialConfigPageComponent {
|
|
|
342
342
|
};
|
|
343
343
|
i0.ɵɵngDeclareClassMetadata({
|
|
344
344
|
minVersion: "12.0.0",
|
|
345
|
-
version: "22.2.
|
|
345
|
+
version: "22.2.3",
|
|
346
346
|
ngImport: i0,
|
|
347
347
|
type: SocialConfigPageComponent,
|
|
348
348
|
decorators: [{
|
|
@@ -536,4 +536,4 @@ function toUpdateDto(form) {
|
|
|
536
536
|
}
|
|
537
537
|
export { SocialConfigPageComponent };
|
|
538
538
|
|
|
539
|
-
//# sourceMappingURL=flusys-ng-auth-social-config-page.component-
|
|
539
|
+
//# sourceMappingURL=flusys-ng-auth-social-config-page.component-mkFaxN4w.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flusys-ng-auth-social-config-page.component-Ce7yrJtX.mjs","names":[],"sources":["../../../projects/ng-auth/pages/social-config/social-config-page.component.ts"],"sourcesContent":["import { Component, inject, signal } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport {\n TranslatePipe,\n TranslateService,\n} from '@flusys/ng-shared';\nimport {\n FButtonDirective,\n InputTextDirective,\n MessageService,\n PasswordComponent,\n ToggleSwitchComponent,\n UiIconComponent,\n} from '@flusys/ng-ui';\nimport {\n SOCIAL_PROVIDERS,\n SocialProviderEnum,\n} from '../../enums/social-provider.enum';\nimport {\n ICreateSocialAuthConfigDto,\n ISocialAuthConfig,\n IUpdateSocialAuthConfigDto,\n} from '../../interfaces/social-auth.interface';\nimport { SocialAuthApiService } from '../../services/social-auth-api.service';\nimport { SocialAuthConfigApiService } from '../../services/social-auth-config-api.service';\n\ninterface IProviderFormModel {\n provider: SocialProviderEnum;\n id: string | null;\n isEnabled: boolean;\n clientId: string;\n /** A newly typed secret to save. Left blank keeps the previously stored one. */\n clientSecret: string;\n hasClientSecret: boolean;\n tenantId: string;\n scopes: string;\n}\n\nconst TENANT_PROVIDER = SocialProviderEnum.MICROSOFT;\n\n@Component({\n selector: 'lib-social-config-page',\n imports: [\n FButtonDirective,\n InputTextDirective,\n PasswordComponent,\n ToggleSwitchComponent,\n UiIconComponent,\n FormsModule,\n TranslatePipe,\n ],\n template: `\n <div class=\"card\">\n <div class=\"flex flex-col sm:flex-row justify-between items-start sm:items-center gap-3 mb-4\">\n <div>\n <h3 class=\"text-lg sm:text-xl font-semibold m-0\">\n {{ 'social.config.title' | translate }}\n </h3>\n <p class=\"text-sm text-muted-color mt-1\">\n {{ 'social.config.subtitle' | translate }}\n </p>\n </div>\n <button fButton (click)=\"onSave()\" [disabled]=\"isSaving()\" [loading]=\"isSaving()\">\n @if (!isSaving()) {\n <ui-icon pButtonIcon name=\"save\"></ui-icon>\n }\n <span pButtonLabel>{{ 'shared.save' | translate }}</span>\n </button>\n </div>\n\n <p class=\"text-sm text-muted-color mb-4\">\n {{ 'social.config.redirect.uri' | translate }}:\n <code class=\"text-color\">{{ redirectUri }}</code>\n </p>\n\n @if (isLoading()) {\n <div class=\"flex justify-center py-8\">\n <ui-icon name=\"spinner\" [spin]=\"true\" class=\"text-3xl text-primary\"></ui-icon>\n </div>\n } @else {\n <div class=\"flex flex-col gap-4\">\n @for (form of forms(); track form.provider) {\n <div class=\"border border-surface rounded p-4\">\n <div class=\"flex items-center justify-between gap-3\">\n <div>\n <div class=\"font-semibold\">\n {{ 'auth.social.provider.' + form.provider | translate }}\n </div>\n <div class=\"text-sm text-muted-color\">\n {{ 'social.config.provider.hint.' + form.provider | translate }}\n </div>\n </div>\n <f-toggleswitch\n [ngModel]=\"form.isEnabled\"\n (ngModelChange)=\"updateField(form.provider, 'isEnabled', $event)\"\n />\n </div>\n\n @if (form.isEnabled) {\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4 mt-4 pt-4 border-t border-surface\">\n <div class=\"field\">\n <label [for]=\"form.provider + '-client-id'\" class=\"block font-medium mb-2\">\n {{ 'social.config.client.id' | translate }} *\n </label>\n <input\n fInputText\n [id]=\"form.provider + '-client-id'\"\n class=\"w-full\"\n [ngModel]=\"form.clientId\"\n (ngModelChange)=\"updateField(form.provider, 'clientId', $event)\"\n />\n </div>\n\n <div class=\"field\">\n <label [for]=\"form.provider + '-client-secret'\" class=\"block font-medium mb-2\">\n {{ 'social.config.client.secret' | translate }}\n @if (!form.hasClientSecret) {\n *\n }\n </label>\n <f-password\n [inputId]=\"form.provider + '-client-secret'\"\n styleClass=\"w-full\"\n [placeholder]=\"\n form.hasClientSecret\n ? ('social.config.client.secret.unchanged' | translate)\n : ''\n \"\n [ngModel]=\"form.clientSecret\"\n (ngModelChange)=\"updateField(form.provider, 'clientSecret', $event)\"\n />\n </div>\n\n @if (form.provider === tenantProvider) {\n <div class=\"field\">\n <label [for]=\"form.provider + '-tenant'\" class=\"block font-medium mb-2\">\n {{ 'social.config.tenant.id' | translate }}\n </label>\n <input\n fInputText\n [id]=\"form.provider + '-tenant'\"\n class=\"w-full\"\n [placeholder]=\"'social.config.tenant.id.example' | translate\"\n [ngModel]=\"form.tenantId\"\n (ngModelChange)=\"updateField(form.provider, 'tenantId', $event)\"\n />\n </div>\n }\n\n <div class=\"field\">\n <label [for]=\"form.provider + '-scopes'\" class=\"block font-medium mb-2\">\n {{ 'social.config.scopes' | translate }}\n </label>\n <input\n fInputText\n [id]=\"form.provider + '-scopes'\"\n class=\"w-full\"\n [placeholder]=\"'social.config.scopes.placeholder' | translate\"\n [ngModel]=\"form.scopes\"\n (ngModelChange)=\"updateField(form.provider, 'scopes', $event)\"\n />\n </div>\n\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n `,\n})\nexport class SocialConfigPageComponent {\n private readonly configService = inject(SocialAuthConfigApiService);\n private readonly socialApi = inject(SocialAuthApiService);\n private readonly messageService = inject(MessageService);\n private readonly translateAdapter = inject(TranslateService, {\n optional: true,\n });\n\n readonly tenantProvider = TENANT_PROVIDER;\n\n private readonly _forms = signal<IProviderFormModel[]>(\n SOCIAL_PROVIDERS.map(emptyForm),\n );\n readonly forms = this._forms.asReadonly();\n\n private readonly _isLoading = signal(true);\n readonly isLoading = this._isLoading.asReadonly();\n\n private readonly _isSaving = signal(false);\n readonly isSaving = this._isSaving.asReadonly();\n\n readonly redirectUri = this.socialApi.redirectUri;\n\n constructor() {\n void this.loadConfigs();\n }\n\n updateField<K extends keyof IProviderFormModel>(\n provider: SocialProviderEnum,\n field: K,\n value: IProviderFormModel[K],\n ): void {\n this._forms.update((forms) =>\n forms.map((form) =>\n form.provider === provider ? { ...form, [field]: value } : form,\n ),\n );\n }\n\n async onSave(): Promise<void> {\n const invalid = this._forms().find(\n (form) =>\n form.isEnabled &&\n (!form.clientId.trim() || (!form.hasClientSecret && !form.clientSecret.trim())),\n );\n\n if (invalid) {\n this.messageService.add({\n severity: 'warn',\n summary: this.translate('shared.validation'),\n detail: this.translate('social.config.credentials.required', {\n provider: this.translate(`auth.social.provider.${invalid.provider}`),\n }),\n });\n return;\n }\n\n this._isSaving.set(true);\n try {\n const pending = this._forms().filter((form) => form.id || form.isEnabled);\n await this.configService.bulkUpsert(\n pending.filter((form) => !form.id).map(toCreateDto),\n pending.filter((form) => form.id).map(toUpdateDto),\n );\n\n this.messageService.add({\n severity: 'success',\n summary: this.translate('shared.success'),\n detail: this.translate('social.config.save.success'),\n });\n await this.loadConfigs();\n } catch {\n // Error toast handled by global interceptor\n } finally {\n this._isSaving.set(false);\n }\n }\n\n private async loadConfigs(): Promise<void> {\n this._isLoading.set(true);\n try {\n const response = await this.configService.getAll({\n pagination: { currentPage: 0, pageSize: SOCIAL_PROVIDERS.length },\n filter: {},\n select: [],\n sort: {},\n });\n this._forms.set(mergeConfigs(response.data ?? []));\n } catch {\n // Error toast handled by global interceptor\n } finally {\n this._isLoading.set(false);\n }\n }\n\n private translate(\n key: string,\n vars?: Record<string, string | number>,\n ): string {\n return this.translateAdapter?.translate(key, vars) ?? key;\n }\n}\n\nfunction emptyForm(provider: SocialProviderEnum): IProviderFormModel {\n return {\n provider,\n id: null,\n isEnabled: false,\n clientId: '',\n clientSecret: '',\n hasClientSecret: false,\n tenantId: '',\n scopes: '',\n };\n}\n\nfunction mergeConfigs(configs: ISocialAuthConfig[]): IProviderFormModel[] {\n return SOCIAL_PROVIDERS.map((provider) => {\n const config = configs.find((entry) => entry.provider === provider);\n if (!config) return emptyForm(provider);\n\n return {\n provider,\n id: config.id,\n isEnabled: config.isEnabled,\n clientId: config.clientId ?? '',\n clientSecret: '',\n hasClientSecret: config.hasClientSecret,\n tenantId: (config.extraConfig?.['tenantId'] as string) ?? '',\n scopes: (config.scopes ?? []).join(', '),\n };\n });\n}\n\n/** clientSecret is omitted here; callers decide whether to include a newly typed value. */\nfunction toBaseDto(form: IProviderFormModel): Omit<ICreateSocialAuthConfigDto, 'clientSecret'> {\n const scopes = form.scopes\n .split(',')\n .map((scope) => scope.trim())\n .filter(Boolean);\n\n return {\n provider: form.provider,\n isEnabled: form.isEnabled,\n clientId: form.clientId.trim(),\n ...(scopes.length ? { scopes } : {}),\n ...(form.provider === TENANT_PROVIDER && form.tenantId.trim()\n ? { extraConfig: { tenantId: form.tenantId.trim() } }\n : {}),\n };\n}\n\nfunction toCreateDto(form: IProviderFormModel): ICreateSocialAuthConfigDto {\n return { ...toBaseDto(form), clientSecret: form.clientSecret.trim() };\n}\n\nfunction toUpdateDto(form: IProviderFormModel): IUpdateSocialAuthConfigDto {\n const trimmedSecret = form.clientSecret.trim();\n return {\n id: form.id!,\n ...toBaseDto(form),\n // Blank means \"keep the previously stored secret\" - never overwrite it with an empty value.\n ...(trimmedSecret ? { clientSecret: trimmedSecret } : {}),\n };\n}\n"],"mappings":";;;;;;;AAsCA,MAAM,kBAAkB,mBAAmB;AAsI3C,IAAa,4BAAb,MAAa,0BAAyB;CACnB,gBAAgB,OAAO,0BAA0B;CACjD,YAAY,OAAO,oBAAoB;CACvC,iBAAiB,OAAO,cAAc;CACtC,mBAAmB,OAAO,kBAAkB,EAC3D,UAAU,KACX,CAAA;CAEQ,iBAAiB;CAET,SAAS,OACxB,iBAAiB,IAAI,SAAS,GAC/B,GAAA,YAAA,CAAA,EAAA,WAAA,SAAA,CAAA,+BAAA,CAAA,CAAA;CACQ,QAAQ,KAAK,OAAO,WAAU;CAEtB,aAAa,OAAO,MAAK,GAAA,YAAA,CAAA,EAAA,WAAA,aAAA,CAAA,+BAAA,CAAA,CAAA;CACjC,YAAY,KAAK,WAAW,WAAU;CAE9B,YAAY,OAAO,OAAM,GAAA,YAAA,CAAA,EAAA,WAAA,YAAA,CAAA,+BAAA,CAAA,CAAA;CACjC,WAAW,KAAK,UAAU,WAAU;CAEpC,cAAc,KAAK,UAAU;CAEtC,cAAA;EACE,AAAK,KAAK,YAAW;CACvB;CAEA,YACE,UACA,OACA,OAA4B;EAE5B,KAAK,OAAO,QAAQ,UAClB,MAAM,KAAK,SACT,KAAK,aAAa,WAAW;GAAE,GAAG;IAAO,QAAQ;EAAK,IAAK,IAAI,CAChE;CAEL;CAEA,MAAM,SAAM;EACV,MAAM,UAAU,KAAK,OAAM,CAAE,CAAC,MAC3B,SACC,KAAK,cACJ,CAAC,KAAK,SAAS,KAAI,KAAO,CAAC,KAAK,mBAAmB,CAAC,KAAK,aAAa,KAAI,EAAI;EAGnF,IAAI,SAAS;GACX,KAAK,eAAe,IAAI;IACtB,UAAU;IACV,SAAS,KAAK,UAAU,mBAAmB;IAC3C,QAAQ,KAAK,UAAU,sCAAsC,EAC3D,UAAU,KAAK,UAAU,wBAAwB,QAAQ,UAAU,EACpE,CAAA;GACF,CAAA;GACD;EACF;EAEA,KAAK,UAAU,IAAI,IAAI;EACvB,IAAI;GACF,MAAM,UAAU,KAAK,OAAM,CAAE,CAAC,QAAQ,SAAS,KAAK,MAAM,KAAK,SAAS;GACxE,MAAM,KAAK,cAAc,WACvB,QAAQ,QAAQ,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,WAAW,GAClD,QAAQ,QAAQ,SAAS,KAAK,EAAE,CAAC,CAAC,IAAI,WAAW,CAAC;GAGpD,KAAK,eAAe,IAAI;IACtB,UAAU;IACV,SAAS,KAAK,UAAU,gBAAgB;IACxC,QAAQ,KAAK,UAAU,4BAA4B;GACpD,CAAA;GACD,MAAM,KAAK,YAAW;EACxB,QAAQ,CAER,UAAU;GACR,KAAK,UAAU,IAAI,KAAK;EAC1B;CACF;CAEQ,MAAM,cAAW;EACvB,KAAK,WAAW,IAAI,IAAI;EACxB,IAAI;GACF,MAAM,WAAW,MAAM,KAAK,cAAc,OAAO;IAC/C,YAAY;KAAE,aAAa;KAAG,UAAU,iBAAiB;IAAM;IAC/D,QAAQ,CAAA;IACR,QAAQ,CAAA;IACR,MAAM,CAAA;GACP,CAAA;GACD,KAAK,OAAO,IAAI,aAAa,SAAS,QAAQ,CAAA,CAAE,CAAC;EACnD,QAAQ,CAER,UAAU;GACR,KAAK,WAAW,IAAI,KAAK;EAC3B;CACF;CAEQ,UACN,KACA,MAAsC;EAEtC,OAAO,KAAK,kBAAkB,UAAU,KAAK,IAAI,KAAK;CACxD;CApGW,OAAA,OAAA,GAAA,mBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAAyB,MAAA,CAAA;EAAA,QAAA,GAAA,gBAAA;CAAA,CAAA;CAAzB,OAAA,OAAA,GAAA,qBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,MAAA;EAAyB,cAAA;EAAA,UAAA;EAAA,UAAA;EAAA,UAzH1B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuHT,UAAA;EAAA,cAAA;GAAA;IAAA,MAAA;IAAA,MA/HC;IAAgB,UAAA;IAAA,QAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;IAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MAChB;IAAkB,UAAA;IAAA,QAAA;KAAA;KAAA;KAAA;KAAA;KAAA;IAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MAClB;IAAiB,UAAA;IAAA,QAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;IAAA;IAAA,SAAA,CAAA,UAAA,SAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MACjB;IAAqB,UAAA;IAAA,QAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;IAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MACrB;IAAe,UAAA;IAAA,QAAA;KAAA;KAAA;KAAA;KAAA;KAAA;IAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MACf;GAAW;GAAA;IAAA,MAAA;IAAA,MAAA,GAAA;IAAA,UAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MAAA,GAAA;IAAA,UAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MAAA,GAAA;IAAA,UAAA;IAAA,QAAA;KAAA;KAAA;KAAA;KAAA;IAAA;IAAA,SAAA,CAAA,eAAA;IAAA,UAAA,CAAA,SAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MACX;IAAa,MAAA;GAAA;EAAA;CAAA,CAAA;;AA2HJ,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAyB,YAAA,CAAA;EApIrC,MAAA;EAAU,MAAA,CAAA;GACT,UAAU;GACV,SAAS;IACP;IACA;IACA;IACA;IACA;IACA;IACA;GACD;GACD,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAwHX,CAAA;;;;AAwGD,SAAS,UAAU,UAA4B;CAC7C,OAAO;EACL;EACA,IAAI;EACJ,WAAW;EACX,UAAU;EACV,cAAc;EACd,iBAAiB;EACjB,UAAU;EACV,QAAQ;CACT;AACH;AAEA,SAAS,aAAa,SAA4B;CAChD,OAAO,iBAAiB,KAAK,aAAY;EACvC,MAAM,SAAS,QAAQ,MAAM,UAAU,MAAM,aAAa,QAAQ;EAClE,IAAI,CAAC,QAAQ,OAAO,UAAU,QAAQ;EAEtC,OAAO;GACL;GACA,IAAI,OAAO;GACX,WAAW,OAAO;GAClB,UAAU,OAAO,YAAY;GAC7B,cAAc;GACd,iBAAiB,OAAO;GACxB,UAAW,OAAO,cAAc,eAA0B;GAC1D,SAAS,OAAO,UAAU,CAAA,EAAA,CAAI,KAAK,IAAI;EACxC;CACH,CAAC;AACH;AAGA,SAAS,UAAU,MAAwB;CACzC,MAAM,SAAS,KAAK,OACjB,MAAM,GAAG,CAAC,CACV,KAAK,UAAU,MAAM,KAAI,CAAE,CAAC,CAC5B,OAAO,OAAO;CAEjB,OAAO;EACL,UAAU,KAAK;EACf,WAAW,KAAK;EAChB,UAAU,KAAK,SAAS,KAAI;EAC5B,GAAI,OAAO,SAAS,EAAE,OAAM,IAAK,CAAA;EACjC,GAAI,KAAK,aAAa,mBAAmB,KAAK,SAAS,KAAI,IACvD,EAAE,aAAa,EAAE,UAAU,KAAK,SAAS,KAAI,EAAE,EAAE,IACjD,CAAA;CACL;AACH;AAEA,SAAS,YAAY,MAAwB;CAC3C,OAAO;EAAE,GAAG,UAAU,IAAI;EAAG,cAAc,KAAK,aAAa,KAAI;CAAE;AACrE;AAEA,SAAS,YAAY,MAAwB;CAC3C,MAAM,gBAAgB,KAAK,aAAa,KAAI;CAC5C,OAAO;EACL,IAAI,KAAK;EACT,GAAG,UAAU,IAAI;EAEjB,GAAI,gBAAgB,EAAE,cAAc,cAAa,IAAK,CAAA;CACvD;AACH"}
|
|
1
|
+
{"version":3,"file":"flusys-ng-auth-social-config-page.component-mkFaxN4w.mjs","names":[],"sources":["../../../projects/ng-auth/pages/social-config/social-config-page.component.ts"],"sourcesContent":["import { Component, inject, signal } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport {\n TranslatePipe,\n TranslateService,\n} from '@flusys/ng-shared';\nimport {\n FButtonDirective,\n InputTextDirective,\n MessageService,\n PasswordComponent,\n ToggleSwitchComponent,\n UiIconComponent,\n} from '@flusys/ng-ui';\nimport {\n SOCIAL_PROVIDERS,\n SocialProviderEnum,\n} from '../../enums/social-provider.enum';\nimport {\n ICreateSocialAuthConfigDto,\n ISocialAuthConfig,\n IUpdateSocialAuthConfigDto,\n} from '../../interfaces/social-auth.interface';\nimport { SocialAuthApiService } from '../../services/social-auth-api.service';\nimport { SocialAuthConfigApiService } from '../../services/social-auth-config-api.service';\n\ninterface IProviderFormModel {\n provider: SocialProviderEnum;\n id: string | null;\n isEnabled: boolean;\n clientId: string;\n /** A newly typed secret to save. Left blank keeps the previously stored one. */\n clientSecret: string;\n hasClientSecret: boolean;\n tenantId: string;\n scopes: string;\n}\n\nconst TENANT_PROVIDER = SocialProviderEnum.MICROSOFT;\n\n@Component({\n selector: 'lib-social-config-page',\n imports: [\n FButtonDirective,\n InputTextDirective,\n PasswordComponent,\n ToggleSwitchComponent,\n UiIconComponent,\n FormsModule,\n TranslatePipe,\n ],\n template: `\n <div class=\"card\">\n <div class=\"flex flex-col sm:flex-row justify-between items-start sm:items-center gap-3 mb-4\">\n <div>\n <h3 class=\"text-lg sm:text-xl font-semibold m-0\">\n {{ 'social.config.title' | translate }}\n </h3>\n <p class=\"text-sm text-muted-color mt-1\">\n {{ 'social.config.subtitle' | translate }}\n </p>\n </div>\n <button fButton (click)=\"onSave()\" [disabled]=\"isSaving()\" [loading]=\"isSaving()\">\n @if (!isSaving()) {\n <ui-icon pButtonIcon name=\"save\"></ui-icon>\n }\n <span pButtonLabel>{{ 'shared.save' | translate }}</span>\n </button>\n </div>\n\n <p class=\"text-sm text-muted-color mb-4\">\n {{ 'social.config.redirect.uri' | translate }}:\n <code class=\"text-color\">{{ redirectUri }}</code>\n </p>\n\n @if (isLoading()) {\n <div class=\"flex justify-center py-8\">\n <ui-icon name=\"spinner\" [spin]=\"true\" class=\"text-3xl text-primary\"></ui-icon>\n </div>\n } @else {\n <div class=\"flex flex-col gap-4\">\n @for (form of forms(); track form.provider) {\n <div class=\"border border-surface rounded p-4\">\n <div class=\"flex items-center justify-between gap-3\">\n <div>\n <div class=\"font-semibold\">\n {{ 'auth.social.provider.' + form.provider | translate }}\n </div>\n <div class=\"text-sm text-muted-color\">\n {{ 'social.config.provider.hint.' + form.provider | translate }}\n </div>\n </div>\n <f-toggleswitch\n [ngModel]=\"form.isEnabled\"\n (ngModelChange)=\"updateField(form.provider, 'isEnabled', $event)\"\n />\n </div>\n\n @if (form.isEnabled) {\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4 mt-4 pt-4 border-t border-surface\">\n <div class=\"field\">\n <label [for]=\"form.provider + '-client-id'\" class=\"block font-medium mb-2\">\n {{ 'social.config.client.id' | translate }} *\n </label>\n <input\n fInputText\n [id]=\"form.provider + '-client-id'\"\n class=\"w-full\"\n [ngModel]=\"form.clientId\"\n (ngModelChange)=\"updateField(form.provider, 'clientId', $event)\"\n />\n </div>\n\n <div class=\"field\">\n <label [for]=\"form.provider + '-client-secret'\" class=\"block font-medium mb-2\">\n {{ 'social.config.client.secret' | translate }}\n @if (!form.hasClientSecret) {\n *\n }\n </label>\n <f-password\n [inputId]=\"form.provider + '-client-secret'\"\n styleClass=\"w-full\"\n [placeholder]=\"\n form.hasClientSecret\n ? ('social.config.client.secret.unchanged' | translate)\n : ''\n \"\n [ngModel]=\"form.clientSecret\"\n (ngModelChange)=\"updateField(form.provider, 'clientSecret', $event)\"\n />\n </div>\n\n @if (form.provider === tenantProvider) {\n <div class=\"field\">\n <label [for]=\"form.provider + '-tenant'\" class=\"block font-medium mb-2\">\n {{ 'social.config.tenant.id' | translate }}\n </label>\n <input\n fInputText\n [id]=\"form.provider + '-tenant'\"\n class=\"w-full\"\n [placeholder]=\"'social.config.tenant.id.example' | translate\"\n [ngModel]=\"form.tenantId\"\n (ngModelChange)=\"updateField(form.provider, 'tenantId', $event)\"\n />\n </div>\n }\n\n <div class=\"field\">\n <label [for]=\"form.provider + '-scopes'\" class=\"block font-medium mb-2\">\n {{ 'social.config.scopes' | translate }}\n </label>\n <input\n fInputText\n [id]=\"form.provider + '-scopes'\"\n class=\"w-full\"\n [placeholder]=\"'social.config.scopes.placeholder' | translate\"\n [ngModel]=\"form.scopes\"\n (ngModelChange)=\"updateField(form.provider, 'scopes', $event)\"\n />\n </div>\n\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n `,\n})\nexport class SocialConfigPageComponent {\n private readonly configService = inject(SocialAuthConfigApiService);\n private readonly socialApi = inject(SocialAuthApiService);\n private readonly messageService = inject(MessageService);\n private readonly translateAdapter = inject(TranslateService, {\n optional: true,\n });\n\n readonly tenantProvider = TENANT_PROVIDER;\n\n private readonly _forms = signal<IProviderFormModel[]>(\n SOCIAL_PROVIDERS.map(emptyForm),\n );\n readonly forms = this._forms.asReadonly();\n\n private readonly _isLoading = signal(true);\n readonly isLoading = this._isLoading.asReadonly();\n\n private readonly _isSaving = signal(false);\n readonly isSaving = this._isSaving.asReadonly();\n\n readonly redirectUri = this.socialApi.redirectUri;\n\n constructor() {\n void this.loadConfigs();\n }\n\n updateField<K extends keyof IProviderFormModel>(\n provider: SocialProviderEnum,\n field: K,\n value: IProviderFormModel[K],\n ): void {\n this._forms.update((forms) =>\n forms.map((form) =>\n form.provider === provider ? { ...form, [field]: value } : form,\n ),\n );\n }\n\n async onSave(): Promise<void> {\n const invalid = this._forms().find(\n (form) =>\n form.isEnabled &&\n (!form.clientId.trim() || (!form.hasClientSecret && !form.clientSecret.trim())),\n );\n\n if (invalid) {\n this.messageService.add({\n severity: 'warn',\n summary: this.translate('shared.validation'),\n detail: this.translate('social.config.credentials.required', {\n provider: this.translate(`auth.social.provider.${invalid.provider}`),\n }),\n });\n return;\n }\n\n this._isSaving.set(true);\n try {\n const pending = this._forms().filter((form) => form.id || form.isEnabled);\n await this.configService.bulkUpsert(\n pending.filter((form) => !form.id).map(toCreateDto),\n pending.filter((form) => form.id).map(toUpdateDto),\n );\n\n this.messageService.add({\n severity: 'success',\n summary: this.translate('shared.success'),\n detail: this.translate('social.config.save.success'),\n });\n await this.loadConfigs();\n } catch {\n // Error toast handled by global interceptor\n } finally {\n this._isSaving.set(false);\n }\n }\n\n private async loadConfigs(): Promise<void> {\n this._isLoading.set(true);\n try {\n const response = await this.configService.getAll({\n pagination: { currentPage: 0, pageSize: SOCIAL_PROVIDERS.length },\n filter: {},\n select: [],\n sort: {},\n });\n this._forms.set(mergeConfigs(response.data ?? []));\n } catch {\n // Error toast handled by global interceptor\n } finally {\n this._isLoading.set(false);\n }\n }\n\n private translate(\n key: string,\n vars?: Record<string, string | number>,\n ): string {\n return this.translateAdapter?.translate(key, vars) ?? key;\n }\n}\n\nfunction emptyForm(provider: SocialProviderEnum): IProviderFormModel {\n return {\n provider,\n id: null,\n isEnabled: false,\n clientId: '',\n clientSecret: '',\n hasClientSecret: false,\n tenantId: '',\n scopes: '',\n };\n}\n\nfunction mergeConfigs(configs: ISocialAuthConfig[]): IProviderFormModel[] {\n return SOCIAL_PROVIDERS.map((provider) => {\n const config = configs.find((entry) => entry.provider === provider);\n if (!config) return emptyForm(provider);\n\n return {\n provider,\n id: config.id,\n isEnabled: config.isEnabled,\n clientId: config.clientId ?? '',\n clientSecret: '',\n hasClientSecret: config.hasClientSecret,\n tenantId: (config.extraConfig?.['tenantId'] as string) ?? '',\n scopes: (config.scopes ?? []).join(', '),\n };\n });\n}\n\n/** clientSecret is omitted here; callers decide whether to include a newly typed value. */\nfunction toBaseDto(form: IProviderFormModel): Omit<ICreateSocialAuthConfigDto, 'clientSecret'> {\n const scopes = form.scopes\n .split(',')\n .map((scope) => scope.trim())\n .filter(Boolean);\n\n return {\n provider: form.provider,\n isEnabled: form.isEnabled,\n clientId: form.clientId.trim(),\n ...(scopes.length ? { scopes } : {}),\n ...(form.provider === TENANT_PROVIDER && form.tenantId.trim()\n ? { extraConfig: { tenantId: form.tenantId.trim() } }\n : {}),\n };\n}\n\nfunction toCreateDto(form: IProviderFormModel): ICreateSocialAuthConfigDto {\n return { ...toBaseDto(form), clientSecret: form.clientSecret.trim() };\n}\n\nfunction toUpdateDto(form: IProviderFormModel): IUpdateSocialAuthConfigDto {\n const trimmedSecret = form.clientSecret.trim();\n return {\n id: form.id!,\n ...toBaseDto(form),\n // Blank means \"keep the previously stored secret\" - never overwrite it with an empty value.\n ...(trimmedSecret ? { clientSecret: trimmedSecret } : {}),\n };\n}\n"],"mappings":"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"}
|
|
@@ -254,7 +254,7 @@ var UserFormComponent = class UserFormComponent {
|
|
|
254
254
|
}
|
|
255
255
|
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
256
256
|
minVersion: "12.0.0",
|
|
257
|
-
version: "22.2.
|
|
257
|
+
version: "22.2.3",
|
|
258
258
|
ngImport: i0,
|
|
259
259
|
type: UserFormComponent,
|
|
260
260
|
deps: [],
|
|
@@ -262,7 +262,7 @@ var UserFormComponent = class UserFormComponent {
|
|
|
262
262
|
});
|
|
263
263
|
static ɵcmp = i0.ɵɵngDeclareComponent({
|
|
264
264
|
minVersion: "17.0.0",
|
|
265
|
-
version: "22.2.
|
|
265
|
+
version: "22.2.3",
|
|
266
266
|
type: UserFormComponent,
|
|
267
267
|
isStandalone: true,
|
|
268
268
|
selector: "lib-user-form",
|
|
@@ -842,7 +842,7 @@ var UserFormComponent = class UserFormComponent {
|
|
|
842
842
|
};
|
|
843
843
|
i0.ɵɵngDeclareClassMetadata({
|
|
844
844
|
minVersion: "12.0.0",
|
|
845
|
-
version: "22.2.
|
|
845
|
+
version: "22.2.3",
|
|
846
846
|
ngImport: i0,
|
|
847
847
|
type: UserFormComponent,
|
|
848
848
|
decorators: [{
|
|
@@ -1168,4 +1168,4 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
1168
1168
|
});
|
|
1169
1169
|
export { UserFormComponent };
|
|
1170
1170
|
|
|
1171
|
-
//# sourceMappingURL=flusys-ng-auth-user-form.component-
|
|
1171
|
+
//# sourceMappingURL=flusys-ng-auth-user-form.component-o0MbxMQn.mjs.map
|