@newheap/platform-common 1.3.1 → 1.4.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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"newheap-platform-common-two-factor.mjs","sources":["../../../projects/nh-common/two-factor/src/lib/i18n/nh-two-factor-translations.ts","../../../projects/nh-common/two-factor/src/lib/nh-two-factor-errors.ts","../../../projects/nh-common/two-factor/src/lib/challenge/nh-two-factor-challenge.component.ts","../../../projects/nh-common/two-factor/src/lib/challenge/nh-two-factor-challenge.component.html","../../../projects/nh-common/two-factor/src/lib/recovery-codes/nh-two-factor-recovery-codes.component.ts","../../../projects/nh-common/two-factor/src/lib/recovery-codes/nh-two-factor-recovery-codes.component.html","../../../projects/nh-common/two-factor/src/lib/enrollment/nh-two-factor-enrollment.component.ts","../../../projects/nh-common/two-factor/src/lib/enrollment/nh-two-factor-enrollment.component.html","../../../projects/nh-common/two-factor/src/lib/settings/nh-two-factor-settings.component.ts","../../../projects/nh-common/two-factor/src/lib/settings/nh-two-factor-settings.component.html","../../../projects/nh-common/two-factor/src/lib/passkey-login/nh-passkey-login-button.component.ts","../../../projects/nh-common/two-factor/src/lib/passkey-login/nh-passkey-login-button.component.html","../../../projects/nh-common/two-factor/src/lib/provide-nh-two-factor.ts","../../../projects/nh-common/two-factor/src/public-api.ts","../../../projects/nh-common/two-factor/src/newheap-platform-common-two-factor.ts"],"sourcesContent":["import {DestroyRef, inject, Injectable} from '@angular/core';\nimport {TranslateService, TranslationObject} from '@ngx-translate/core';\nimport {merge} from 'rxjs';\nimport en from './en.json';\nimport nl from './nl.json';\n\n/** The entry point's own translation bundles, keyed by language. All keys live under `nh-two-factor.`. */\nexport const NH_TWO_FACTOR_TRANSLATIONS: Readonly<Record<'en' | 'nl', TranslationObject>> = {en, nl};\n\ntype TranslationTree = { [key: string]: unknown };\n\nconst rootKey = 'nh-two-factor';\n\nfunction isTree(value: unknown): value is TranslationTree {\n return !!value && typeof value === 'object' && !Array.isArray(value);\n}\n\n/** Deep merge where values of `override` win. */\nfunction mergeTrees(base: TranslationTree, override: TranslationTree): TranslationTree {\n const result: TranslationTree = {...base};\n for (const [key, value] of Object.entries(override)) {\n const current = result[key];\n result[key] = isTree(current) && isTree(value) ? mergeTrees(current, value) : value;\n }\n return result;\n}\n\nfunction hasAllKeys(bundle: TranslationTree, candidate: unknown): boolean {\n if (!isTree(candidate)) {\n return false;\n }\n\n return Object.entries(bundle).every(([key, value]) =>\n isTree(value) ? hasAllKeys(value, candidate[key]) : key in candidate\n );\n}\n\n/**\n * Merges the bundled texts into `TranslateService` whenever the host loads or replaces a\n * language. Host loaders never lose these texts, and keys the host defines under\n * `nh-two-factor.` win over the bundle. Languages without a bundle receive the English texts.\n */\n@Injectable({providedIn: 'root'})\nexport class NhTwoFactorTranslationMerger {\n private readonly translate = inject(TranslateService, {optional: true});\n private readonly destroyRef = inject(DestroyRef);\n private started = false;\n\n start(): void {\n const translate = this.translate;\n if (this.started || !translate) {\n return;\n }\n this.started = true;\n\n const subscription = merge(translate.onTranslationChange, translate.onLangChange).subscribe(event => {\n if (event.lang && isTree(event.translations)) {\n this.ensure(event.lang, event.translations[rootKey]);\n }\n });\n this.destroyRef.onDestroy(() => subscription.unsubscribe());\n\n // The current language is loaded or already requested by the host, so merging into it\n // never pre-empts the host loader; a later load triggers a new merge.\n const current = translate.getCurrentLang();\n if (current) {\n this.ensure(current, translate.instant(rootKey));\n }\n }\n\n private ensure(language: string, existing: unknown): void {\n const bundle = (NH_TWO_FACTOR_TRANSLATIONS[language as 'en' | 'nl'] ?? NH_TWO_FACTOR_TRANSLATIONS.en) as TranslationTree;\n const bundleRoot = bundle[rootKey] as TranslationTree;\n if (hasAllKeys(bundleRoot, existing)) {\n return;\n }\n\n const merged = mergeTrees(bundleRoot, isTree(existing) ? existing : {});\n this.translate?.setTranslation(language, {[rootKey]: merged} as TranslationObject, true);\n }\n}\n","import {NhTwoFactorFailureCodes, TaskResult} from '@newheap/platform-common';\n\nconst failureCodePrefix = 'two-factor-';\nconst translationPrefix = 'nh-two-factor.';\n\n/**\n * Returns the translation keys for a failed two-factor result. Two-factor failure codes map\n * to `nh-two-factor.<suffix>`; other failures use a generic message.\n */\nexport function nhTwoFactorErrorKeys(result: TaskResult<unknown>): string[] {\n const keys = result.items.map(item => {\n if (item.name.startsWith(failureCodePrefix)) {\n return translationPrefix + item.name.substring(failureCodePrefix.length);\n }\n\n const message = item.errorMessages[0];\n return message?.startsWith(translationPrefix) ? message : translationPrefix + 'ui.error';\n });\n\n return keys.length > 0 ? [...new Set(keys)] : [translationPrefix + 'ui.error'];\n}\n\n/**\n * Whether the server ended the pending sign-in step, so the user has to sign in again.\n */\nexport function nhTwoFactorStepEnded(result: TaskResult<unknown>): boolean {\n return result.items.some(item =>\n item.name === NhTwoFactorFailureCodes.ChallengeExpired || item.name === NhTwoFactorFailureCodes.LockedOut);\n}\n\n/** Reads the value of the input that raised an event. */\nexport function nhTwoFactorInputValue(event: Event): string {\n return (event.target as HTMLInputElement).value;\n}\n\n/** Reads the checked state of the checkbox that raised an event. */\nexport function nhTwoFactorInputChecked(event: Event): boolean {\n return (event.target as HTMLInputElement).checked;\n}\n","import {\n afterNextRender,\n ChangeDetectionStrategy,\n Component,\n computed,\n ElementRef,\n inject,\n Injector,\n input,\n output,\n signal,\n viewChild\n} from '@angular/core';\nimport {DatePipe} from '@angular/common';\nimport {TranslatePipe} from '@ngx-translate/core';\nimport {\n INhAuthorization,\n NhAuthService,\n NhTwoFactorChallenge,\n NhTwoFactorEmailCodeSent,\n NhTwoFactorMethods,\n NhTwoFactorVerifyModel,\n TaskResult\n} from '@newheap/platform-common';\nimport {NhTwoFactorTranslationMerger} from '../i18n/nh-two-factor-translations';\nimport {nhTwoFactorErrorKeys, nhTwoFactorInputChecked, nhTwoFactorInputValue, nhTwoFactorStepEnded} from '../nh-two-factor-errors';\n\nlet nextId = 0;\n\n/**\n * Completes a second-factor challenge with a code, an e-mailed code, a recovery code or a\n * passkey. The session is stored by the auth service before `authenticated` emits.\n */\n@Component({\n selector: 'nh-two-factor-challenge',\n standalone: true,\n imports: [TranslatePipe, DatePipe],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './nh-two-factor-challenge.component.html',\n styleUrl: '../nh-two-factor.scss'\n})\nexport class NhTwoFactorChallengeComponent {\n private readonly auth = inject(NhAuthService);\n private readonly injector = inject(Injector);\n private readonly codeInput = viewChild<ElementRef<HTMLInputElement>>('codeInput');\n\n /** The pending challenge from the login response. */\n readonly challenge = input.required<NhTwoFactorChallenge>();\n /** Whether to offer \"remember this device\" when the server allows it for this challenge. */\n readonly allowRememberDevice = input(true);\n\n readonly authenticated = output<INhAuthorization>();\n /** The challenge expired or the account was locked; the user has to sign in again. */\n readonly expired = output<void>();\n readonly cancelled = output<void>();\n\n readonly id = `nh-two-factor-challenge-${nextId++}`;\n readonly passkeySupported = this.auth.isPasskeySupported();\n readonly selectedMethod = signal<string | null>(null);\n readonly code = signal('');\n readonly rememberDevice = signal(false);\n readonly busy = signal(false);\n readonly errorKeys = signal<string[]>([]);\n readonly emailSent = signal<NhTwoFactorEmailCodeSent | null>(null);\n\n readonly methods = computed(() => this.challenge().methods\n .filter(method => method !== NhTwoFactorMethods.passkey || this.passkeySupported));\n readonly method = computed(() => this.selectedMethod() ?? this.defaultMethod());\n readonly usesCode = computed(() => this.method() !== NhTwoFactorMethods.passkey);\n readonly numericCode = computed(() => this.method() !== NhTwoFactorMethods.recoveryCode);\n readonly offerRememberDevice = computed(() => this.allowRememberDevice() && this.challenge().rememberDeviceAvailable);\n\n readonly value = nhTwoFactorInputValue;\n readonly checked = nhTwoFactorInputChecked;\n\n constructor() {\n inject(NhTwoFactorTranslationMerger).start();\n }\n\n selectMethod(method: string): void {\n this.selectedMethod.set(method);\n this.code.set('');\n this.errorKeys.set([]);\n afterNextRender(() => this.codeInput()?.nativeElement.focus(), {injector: this.injector});\n }\n\n async verify(): Promise<void> {\n if (this.busy()) {\n return;\n }\n\n if (!this.usesCode()) {\n await this.run(() => this.auth.verifyTwoFactorWithPasskey(this.challenge().challengeToken, this.rememberDevice()));\n return;\n }\n\n const code = this.code().trim();\n if (!code) {\n this.errorKeys.set(['nh-two-factor.invalid-code']);\n return;\n }\n\n await this.run(() => this.auth.verifyTwoFactor(new NhTwoFactorVerifyModel({\n challengeToken: this.challenge().challengeToken,\n method: this.method(),\n code: code,\n rememberDevice: this.rememberDevice()\n })));\n }\n\n async sendEmailCode(): Promise<void> {\n if (this.busy()) {\n return;\n }\n\n this.busy.set(true);\n this.errorKeys.set([]);\n const result = await this.auth.sendTwoFactorEmailCode(this.challenge().challengeToken);\n this.busy.set(false);\n\n if (!result.isSuccess) {\n this.fail(result);\n return;\n }\n\n this.emailSent.set(result.data ?? null);\n afterNextRender(() => this.codeInput()?.nativeElement.focus(), {injector: this.injector});\n }\n\n private async run(verification: () => Promise<TaskResult<INhAuthorization>>): Promise<void> {\n this.busy.set(true);\n this.errorKeys.set([]);\n const result = await verification();\n this.busy.set(false);\n\n if (!result.isSuccess || !result.data) {\n this.code.set('');\n this.fail(result);\n return;\n }\n\n this.authenticated.emit(result.data);\n }\n\n private fail(result: TaskResult<unknown>): void {\n this.errorKeys.set(nhTwoFactorErrorKeys(result));\n if (nhTwoFactorStepEnded(result)) {\n this.expired.emit();\n }\n }\n\n private defaultMethod(): string {\n const methods = this.methods();\n return methods.find(method => method !== NhTwoFactorMethods.recoveryCode)\n ?? methods[0]\n ?? NhTwoFactorMethods.authenticator;\n }\n}\n","<form class=\"nh-two-factor\" [attr.aria-labelledby]=\"id + '-title'\" [attr.aria-busy]=\"busy()\" (submit)=\"$event.preventDefault(); verify()\">\n <h2 class=\"nh-two-factor__title\" [id]=\"id + '-title'\">{{ 'nh-two-factor.ui.challenge-title' | translate }}</h2>\n\n @if (methods().length > 1) {\n <fieldset class=\"nh-two-factor__methods\">\n <legend class=\"nh-two-factor__legend\">{{ 'nh-two-factor.ui.method-label' | translate }}</legend>\n @for (option of methods(); track option) {\n <label class=\"nh-two-factor__method\">\n <input\n type=\"radio\"\n [name]=\"id + '-method'\"\n [value]=\"option\"\n [checked]=\"method() === option\"\n [disabled]=\"busy()\"\n (change)=\"selectMethod(option)\" />\n <span>{{ 'nh-two-factor.ui.method.' + option | translate }}</span>\n </label>\n }\n </fieldset>\n }\n\n @if (method() === 'email') {\n <p class=\"nh-two-factor__hint\">{{ 'nh-two-factor.ui.email-instructions' | translate }}</p>\n <div class=\"nh-two-factor__actions\">\n <button type=\"button\" class=\"nh-two-factor__button\" [disabled]=\"busy()\" (click)=\"sendEmailCode()\">\n {{ (emailSent() ? 'nh-two-factor.ui.resend-email-code' : 'nh-two-factor.ui.send-email-code') | translate }}\n </button>\n </div>\n @if (emailSent(); as sent) {\n <p class=\"nh-two-factor__hint\" role=\"status\">\n {{ 'nh-two-factor.ui.email-code-sent' | translate: { time: (sent.expiresAt | date: 'shortTime') } }}\n </p>\n }\n }\n\n @if (usesCode()) {\n <div class=\"nh-two-factor__field\">\n <label [for]=\"id + '-code'\">{{ 'nh-two-factor.ui.code-label.' + method() | translate }}</label>\n <input\n #codeInput\n type=\"text\"\n class=\"nh-two-factor__input nh-two-factor__input--code\"\n autocomplete=\"one-time-code\"\n spellcheck=\"false\"\n [id]=\"id + '-code'\"\n [attr.inputmode]=\"numericCode() ? 'numeric' : 'text'\"\n [value]=\"code()\"\n [disabled]=\"busy()\"\n [attr.aria-invalid]=\"errorKeys().length > 0 ? true : null\"\n [attr.aria-describedby]=\"errorKeys().length > 0 ? id + '-errors' : null\"\n (input)=\"code.set(value($event))\" />\n </div>\n } @else {\n <p class=\"nh-two-factor__hint\">{{ 'nh-two-factor.ui.passkey-verify-instructions' | translate }}</p>\n }\n\n @if (offerRememberDevice()) {\n <label class=\"nh-two-factor__check\">\n <input type=\"checkbox\" [checked]=\"rememberDevice()\" [disabled]=\"busy()\" (change)=\"rememberDevice.set(checked($event))\" />\n <span>{{ 'nh-two-factor.ui.remember-device' | translate }}</span>\n </label>\n }\n\n <div [id]=\"id + '-errors'\" aria-live=\"assertive\">\n @if (errorKeys().length > 0) {\n <ul class=\"nh-two-factor__errors\" role=\"alert\">\n @for (key of errorKeys(); track key) {\n <li>{{ key | translate }}</li>\n }\n </ul>\n }\n </div>\n\n <div class=\"nh-two-factor__actions\">\n <button type=\"submit\" class=\"nh-two-factor__button nh-two-factor__button--primary\" [disabled]=\"busy()\">\n @if (busy()) {\n {{ 'nh-two-factor.ui.verifying' | translate }}\n } @else {\n {{ (usesCode() ? 'nh-two-factor.ui.verify' : 'nh-two-factor.ui.use-passkey') | translate }}\n }\n </button>\n <button type=\"button\" class=\"nh-two-factor__button\" [disabled]=\"busy()\" (click)=\"cancelled.emit()\">\n {{ 'nh-two-factor.ui.cancel' | translate }}\n </button>\n </div>\n</form>\n","import {ChangeDetectionStrategy, Component, inject, input, output, signal} from '@angular/core';\nimport {TranslatePipe} from '@ngx-translate/core';\nimport {NhTwoFactorTranslationMerger} from '../i18n/nh-two-factor-translations';\nimport {nhTwoFactorInputChecked} from '../nh-two-factor-errors';\n\nlet nextId = 0;\n\n/**\n * Shows recovery codes once, with copy and download actions. The user confirms that the\n * codes were saved before continuing.\n */\n@Component({\n selector: 'nh-two-factor-recovery-codes',\n standalone: true,\n imports: [TranslatePipe],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './nh-two-factor-recovery-codes.component.html',\n styleUrl: '../nh-two-factor.scss'\n})\nexport class NhTwoFactorRecoveryCodesComponent {\n readonly codes = input.required<readonly string[]>();\n /** File name of the downloaded codes. */\n readonly fileName = input('recovery-codes.txt');\n readonly acknowledged = output<void>();\n\n readonly id = `nh-two-factor-recovery-codes-${nextId++}`;\n readonly saved = signal(false);\n readonly copied = signal(false);\n readonly checked = nhTwoFactorInputChecked;\n\n constructor() {\n inject(NhTwoFactorTranslationMerger).start();\n }\n\n async copy(): Promise<void> {\n try {\n await navigator.clipboard.writeText(this.codes().join('\\n'));\n this.copied.set(true);\n } catch {\n // Clipboard access can be denied; the codes stay visible for manual copying.\n this.copied.set(false);\n }\n }\n\n download(): void {\n const url = URL.createObjectURL(new Blob([this.codes().join('\\r\\n') + '\\r\\n'], {type: 'text/plain'}));\n const link = document.createElement('a');\n link.href = url;\n link.download = this.fileName();\n link.click();\n URL.revokeObjectURL(url);\n }\n}\n","<section class=\"nh-two-factor\" [attr.aria-labelledby]=\"id + '-title'\">\n <h3 class=\"nh-two-factor__subtitle\" [id]=\"id + '-title'\">{{ 'nh-two-factor.ui.recovery-codes-title' | translate }}</h3>\n <p class=\"nh-two-factor__text\">{{ 'nh-two-factor.ui.recovery-codes-instructions' | translate }}</p>\n\n <ul class=\"nh-two-factor__codes\" [attr.aria-labelledby]=\"id + '-title'\">\n @for (code of codes(); track code) {\n <li>{{ code }}</li>\n }\n </ul>\n\n <div class=\"nh-two-factor__actions\">\n <button type=\"button\" class=\"nh-two-factor__button\" (click)=\"copy()\">\n {{ (copied() ? 'nh-two-factor.ui.copied' : 'nh-two-factor.ui.copy') | translate }}\n </button>\n <button type=\"button\" class=\"nh-two-factor__button\" (click)=\"download()\">\n {{ 'nh-two-factor.ui.download' | translate }}\n </button>\n </div>\n\n <label class=\"nh-two-factor__check\">\n <input type=\"checkbox\" [checked]=\"saved()\" (change)=\"saved.set(checked($event))\" />\n <span>{{ 'nh-two-factor.ui.recovery-codes-saved' | translate }}</span>\n </label>\n\n <div class=\"nh-two-factor__actions\">\n <button type=\"button\" class=\"nh-two-factor__button nh-two-factor__button--primary\" [disabled]=\"!saved()\" (click)=\"acknowledged.emit()\">\n {{ 'nh-two-factor.ui.continue' | translate }}\n </button>\n </div>\n</section>\n","import {\n afterNextRender,\n ChangeDetectionStrategy,\n Component,\n computed,\n ElementRef,\n inject,\n Injector,\n input,\n OnInit,\n output,\n signal,\n viewChild\n} from '@angular/core';\nimport {DatePipe} from '@angular/common';\nimport {TranslatePipe} from '@ngx-translate/core';\nimport {\n NhAuthenticatorSetup,\n NhAuthService,\n NhTwoFactorChallenge,\n NhTwoFactorEmailCodeSent,\n NhTwoFactorEnrollmentResult,\n NhTwoFactorMethods,\n TaskResult\n} from '@newheap/platform-common';\nimport {NhTwoFactorTranslationMerger} from '../i18n/nh-two-factor-translations';\nimport {nhTwoFactorErrorKeys, nhTwoFactorInputValue, nhTwoFactorStepEnded} from '../nh-two-factor-errors';\nimport {NhTwoFactorRecoveryCodesComponent} from '../recovery-codes/nh-two-factor-recovery-codes.component';\n\nlet nextId = 0;\n\n/**\n * Enrolls a second factor for a user whom the policy requires to use one, during sign-in.\n * The session is stored by the auth service; `completed` emits after the user saved the\n * recovery codes.\n */\n@Component({\n selector: 'nh-two-factor-enrollment',\n standalone: true,\n imports: [TranslatePipe, DatePipe, NhTwoFactorRecoveryCodesComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './nh-two-factor-enrollment.component.html',\n styleUrl: '../nh-two-factor.scss'\n})\nexport class NhTwoFactorEnrollmentComponent implements OnInit {\n private readonly auth = inject(NhAuthService);\n private readonly injector = inject(Injector);\n private readonly codeInput = viewChild<ElementRef<HTMLInputElement>>('codeInput');\n\n /** The enrollment step from the login response (status `enrollment-required`). */\n readonly enrollment = input.required<NhTwoFactorChallenge>();\n\n readonly completed = output<NhTwoFactorEnrollmentResult>();\n /** The enrollment expired or the account was locked; the user has to sign in again. */\n readonly expired = output<void>();\n readonly cancelled = output<void>();\n\n readonly id = `nh-two-factor-enrollment-${nextId++}`;\n readonly passkeySupported = this.auth.isPasskeySupported();\n readonly selectedMethod = signal<string | null>(null);\n readonly setup = signal<NhAuthenticatorSetup | null>(null);\n readonly emailSent = signal<NhTwoFactorEmailCodeSent | null>(null);\n readonly code = signal('');\n readonly passkeyName = signal('');\n readonly busy = signal(false);\n readonly errorKeys = signal<string[]>([]);\n readonly result = signal<NhTwoFactorEnrollmentResult | null>(null);\n\n readonly methods = computed(() => this.enrollment().methods\n .filter(method => method !== NhTwoFactorMethods.passkey || this.passkeySupported));\n readonly method = computed(() => this.selectedMethod() ?? this.methods()[0] ?? NhTwoFactorMethods.authenticator);\n\n readonly value = nhTwoFactorInputValue;\n\n constructor() {\n inject(NhTwoFactorTranslationMerger).start();\n }\n\n ngOnInit(): void {\n if (this.method() === NhTwoFactorMethods.authenticator) {\n void this.startAuthenticator();\n }\n }\n\n selectMethod(method: string): void {\n this.selectedMethod.set(method);\n this.code.set('');\n this.errorKeys.set([]);\n\n if (method === NhTwoFactorMethods.authenticator && !this.setup()) {\n void this.startAuthenticator();\n }\n }\n\n async startAuthenticator(): Promise<void> {\n const setup = await this.run(() => this.auth.beginEnrollmentAuthenticatorSetup(this.token()));\n if (setup) {\n this.setup.set(setup);\n this.focusCode();\n }\n }\n\n async sendEmailCode(): Promise<void> {\n const sent = await this.run(() => this.auth.sendEnrollmentEmailCode(this.token()));\n if (sent) {\n this.emailSent.set(sent);\n this.focusCode();\n }\n }\n\n async confirm(): Promise<void> {\n if (this.busy()) {\n return;\n }\n\n const method = this.method();\n if (method === NhTwoFactorMethods.passkey) {\n this.complete(await this.run(() => this.auth.enrollPasskey(this.token(), this.passkeyName().trim() || undefined)));\n return;\n }\n\n const code = this.code().trim();\n if (!code) {\n this.errorKeys.set(['nh-two-factor.invalid-code']);\n return;\n }\n\n const confirmation = method === NhTwoFactorMethods.email\n ? () => this.auth.confirmEnrollmentEmail(this.token(), code)\n : () => this.auth.confirmEnrollmentAuthenticator(this.token(), code);\n\n this.complete(await this.run(confirmation));\n }\n\n /** Emits the result after the user saved the recovery codes. */\n finish(): void {\n const result = this.result();\n if (result) {\n this.completed.emit(result);\n }\n }\n\n private complete(result: NhTwoFactorEnrollmentResult | undefined): void {\n if (!result) {\n this.code.set('');\n return;\n }\n\n if (result.recoveryCodes?.length) {\n this.result.set(result);\n return;\n }\n\n this.completed.emit(result);\n }\n\n private async run<T>(action: () => Promise<TaskResult<T>>): Promise<T | undefined> {\n this.busy.set(true);\n this.errorKeys.set([]);\n const result = await action();\n this.busy.set(false);\n\n if (!result.isSuccess) {\n this.errorKeys.set(nhTwoFactorErrorKeys(result));\n if (nhTwoFactorStepEnded(result)) {\n this.expired.emit();\n }\n\n return undefined;\n }\n\n return result.data;\n }\n\n private token(): string {\n return this.enrollment().challengeToken;\n }\n\n private focusCode(): void {\n afterNextRender(() => this.codeInput()?.nativeElement.focus(), {injector: this.injector});\n }\n}\n","@if (result(); as completedResult) {\n <nh-two-factor-recovery-codes [codes]=\"completedResult.recoveryCodes ?? []\" (acknowledged)=\"finish()\" />\n} @else {\n <form class=\"nh-two-factor\" [attr.aria-labelledby]=\"id + '-title'\" [attr.aria-busy]=\"busy()\" (submit)=\"$event.preventDefault(); confirm()\">\n <h2 class=\"nh-two-factor__title\" [id]=\"id + '-title'\">{{ 'nh-two-factor.ui.enrollment-title' | translate }}</h2>\n <p class=\"nh-two-factor__text\">{{ 'nh-two-factor.ui.enrollment-instructions' | translate }}</p>\n\n @if (methods().length > 1) {\n <fieldset class=\"nh-two-factor__methods\">\n <legend class=\"nh-two-factor__legend\">{{ 'nh-two-factor.ui.method-label' | translate }}</legend>\n @for (option of methods(); track option) {\n <label class=\"nh-two-factor__method\">\n <input\n type=\"radio\"\n [name]=\"id + '-method'\"\n [value]=\"option\"\n [checked]=\"method() === option\"\n [disabled]=\"busy()\"\n (change)=\"selectMethod(option)\" />\n <span>{{ 'nh-two-factor.ui.method.' + option | translate }}</span>\n </label>\n }\n </fieldset>\n }\n\n @switch (method()) {\n @case ('authenticator') {\n <p class=\"nh-two-factor__hint\">{{ 'nh-two-factor.ui.authenticator-instructions' | translate }}</p>\n @if (setup(); as authenticator) {\n <div class=\"nh-two-factor__setup\">\n @if (authenticator.qrCodeDataUri) {\n <img class=\"nh-two-factor__qr\" [src]=\"authenticator.qrCodeDataUri\" [alt]=\"'nh-two-factor.ui.qr-code-alt' | translate\" />\n }\n <p class=\"nh-two-factor__text\">\n {{ 'nh-two-factor.ui.shared-key' | translate }}:\n <span class=\"nh-two-factor__key\">{{ authenticator.sharedKey }}</span>\n </p>\n </div>\n } @else if (busy()) {\n <p class=\"nh-two-factor__hint\" role=\"status\">{{ 'nh-two-factor.ui.loading' | translate }}</p>\n }\n }\n @case ('email') {\n <p class=\"nh-two-factor__hint\">{{ 'nh-two-factor.ui.email-instructions' | translate }}</p>\n <div class=\"nh-two-factor__actions\">\n <button type=\"button\" class=\"nh-two-factor__button\" [disabled]=\"busy()\" (click)=\"sendEmailCode()\">\n {{ (emailSent() ? 'nh-two-factor.ui.resend-email-code' : 'nh-two-factor.ui.send-email-code') | translate }}\n </button>\n </div>\n @if (emailSent(); as sent) {\n <p class=\"nh-two-factor__hint\" role=\"status\">\n {{ 'nh-two-factor.ui.email-code-sent' | translate: { time: (sent.expiresAt | date: 'shortTime') } }}\n </p>\n }\n }\n @case ('passkey') {\n <p class=\"nh-two-factor__hint\">{{ 'nh-two-factor.ui.passkey-instructions' | translate }}</p>\n <div class=\"nh-two-factor__field\">\n <label [for]=\"id + '-passkey-name'\">{{ 'nh-two-factor.ui.passkey-name' | translate }}</label>\n <input\n type=\"text\"\n class=\"nh-two-factor__input\"\n maxlength=\"100\"\n autocomplete=\"off\"\n [id]=\"id + '-passkey-name'\"\n [value]=\"passkeyName()\"\n [disabled]=\"busy()\"\n (input)=\"passkeyName.set(value($event))\" />\n </div>\n }\n }\n\n @if (method() !== 'passkey' && (method() !== 'authenticator' || setup())) {\n <div class=\"nh-two-factor__field\">\n <label [for]=\"id + '-code'\">{{ 'nh-two-factor.ui.code-label.' + method() | translate }}</label>\n <input\n #codeInput\n type=\"text\"\n class=\"nh-two-factor__input nh-two-factor__input--code\"\n inputmode=\"numeric\"\n autocomplete=\"one-time-code\"\n spellcheck=\"false\"\n [id]=\"id + '-code'\"\n [value]=\"code()\"\n [disabled]=\"busy()\"\n [attr.aria-invalid]=\"errorKeys().length > 0 ? true : null\"\n [attr.aria-describedby]=\"errorKeys().length > 0 ? id + '-errors' : null\"\n (input)=\"code.set(value($event))\" />\n </div>\n }\n\n <div [id]=\"id + '-errors'\" aria-live=\"assertive\">\n @if (errorKeys().length > 0) {\n <ul class=\"nh-two-factor__errors\" role=\"alert\">\n @for (key of errorKeys(); track key) {\n <li>{{ key | translate }}</li>\n }\n </ul>\n }\n </div>\n\n <div class=\"nh-two-factor__actions\">\n <button type=\"submit\" class=\"nh-two-factor__button nh-two-factor__button--primary\" [disabled]=\"busy()\">\n {{ (method() === 'passkey' ? 'nh-two-factor.ui.create-passkey' : 'nh-two-factor.ui.confirm') | translate }}\n </button>\n <button type=\"button\" class=\"nh-two-factor__button\" [disabled]=\"busy()\" (click)=\"cancelled.emit()\">\n {{ 'nh-two-factor.ui.cancel' | translate }}\n </button>\n </div>\n </form>\n}\n","import {\n afterNextRender,\n ChangeDetectionStrategy,\n Component,\n computed,\n ElementRef,\n inject,\n Injector,\n input,\n OnInit,\n output,\n signal,\n viewChild\n} from '@angular/core';\nimport {DatePipe} from '@angular/common';\nimport {TranslatePipe} from '@ngx-translate/core';\nimport {\n NhAuthenticatorSetup,\n NhAuthService,\n NhPasskey,\n NhTwoFactorChange,\n NhTwoFactorEmailCodeSent,\n NhTwoFactorMethods,\n NhTwoFactorReauthentication,\n NhTwoFactorStatus,\n TaskResult\n} from '@newheap/platform-common';\nimport {NhTwoFactorTranslationMerger} from '../i18n/nh-two-factor-translations';\nimport {nhTwoFactorErrorKeys, nhTwoFactorInputValue} from '../nh-two-factor-errors';\nimport {NhTwoFactorRecoveryCodesComponent} from '../recovery-codes/nh-two-factor-recovery-codes.component';\n\n/** A change on the settings page; some need reauthentication before they run. */\nexport type NhTwoFactorSettingsAction =\n | { kind: 'authenticator' }\n | { kind: 'email' }\n | { kind: 'recovery-codes' }\n | { kind: 'forget-devices' }\n | { kind: 'disable' }\n | { kind: 'add-passkey' }\n | { kind: 'remove-passkey', passkeyId: string };\n\nconst passwordReauthentication = 'password';\n\nlet nextId = 0;\n\n/**\n * Two-factor settings of the signed-in user: authenticator app, e-mail codes, passkeys,\n * recovery codes, remembered devices and turning two-factor authentication off. Sensitive\n * changes ask for the password or a code first.\n */\n@Component({\n selector: 'nh-two-factor-settings',\n standalone: true,\n imports: [TranslatePipe, DatePipe, NhTwoFactorRecoveryCodesComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './nh-two-factor-settings.component.html',\n styleUrl: '../nh-two-factor.scss'\n})\nexport class NhTwoFactorSettingsComponent implements OnInit {\n private readonly auth = inject(NhAuthService);\n private readonly injector = inject(Injector);\n private readonly reauthenticationInput = viewChild<ElementRef<HTMLInputElement>>('reauthenticationInput');\n private readonly codeInput = viewChild<ElementRef<HTMLInputElement>>('codeInput');\n /** Reauthentication of a running e-mail setup, reused when the user requests a new code. */\n private emailReauthentication?: NhTwoFactorReauthentication;\n\n /** Whether the title is visible. Hosts with their own heading hide it; screen readers keep it. */\n readonly showTitle = input(true);\n\n /** Emits the reloaded status after every saved change. */\n readonly changed = output<NhTwoFactorStatus>();\n\n readonly id = `nh-two-factor-settings-${nextId++}`;\n readonly passkeySupported = this.auth.isPasskeySupported();\n readonly status = signal<NhTwoFactorStatus | null>(null);\n readonly passkeys = signal<NhPasskey[]>([]);\n readonly loading = signal(true);\n readonly busy = signal(false);\n readonly errorKeys = signal<string[]>([]);\n readonly noticeKey = signal<string | null>(null);\n readonly setupPanel = signal<'authenticator' | 'email' | null>(null);\n readonly setup = signal<NhAuthenticatorSetup | null>(null);\n readonly emailSent = signal<NhTwoFactorEmailCodeSent | null>(null);\n readonly code = signal('');\n readonly recoveryCodes = signal<string[] | null>(null);\n readonly pendingAction = signal<NhTwoFactorSettingsAction | null>(null);\n readonly reauthenticationMethod = signal(passwordReauthentication);\n readonly reauthenticationSecret = signal('');\n readonly newPasskeyName = signal('');\n readonly renamingId = signal<string | null>(null);\n readonly renameValue = signal('');\n\n readonly enabled = computed(() => this.status()?.enabled === true);\n readonly required = computed(() => this.status()?.required === true);\n readonly hasAuthenticator = computed(() => this.hasMethod(NhTwoFactorMethods.authenticator));\n readonly hasEmail = computed(() => this.hasMethod(NhTwoFactorMethods.email));\n readonly authenticatorAvailable = computed(() => this.isAvailable(NhTwoFactorMethods.authenticator));\n readonly emailAvailable = computed(() => this.isAvailable(NhTwoFactorMethods.email));\n readonly passkeysAvailable = computed(() => this.isAvailable(NhTwoFactorMethods.passkey));\n readonly recoveryCodesAvailable = computed(() => this.isAvailable(NhTwoFactorMethods.recoveryCode));\n readonly reauthenticationMethods = computed(() => [\n passwordReauthentication,\n ...(this.status()?.methods ?? []).filter(method =>\n method === NhTwoFactorMethods.authenticator || method === NhTwoFactorMethods.recoveryCode)\n ]);\n\n readonly value = nhTwoFactorInputValue;\n\n constructor() {\n inject(NhTwoFactorTranslationMerger).start();\n }\n\n ngOnInit(): void {\n void this.load();\n }\n\n async load(): Promise<void> {\n this.loading.set(true);\n const status = await this.auth.getTwoFactorStatus();\n\n if (!status.isSuccess || !status.data) {\n this.errorKeys.set(nhTwoFactorErrorKeys(status));\n this.loading.set(false);\n return;\n }\n\n this.status.set(status.data);\n\n if (status.data.availableMethods.includes(NhTwoFactorMethods.passkey)) {\n const passkeys = await this.auth.getPasskeys();\n this.passkeys.set(passkeys.data ?? []);\n }\n\n this.loading.set(false);\n }\n\n /** Starts a change, asking for reauthentication first when the change needs it. */\n request(action: NhTwoFactorSettingsAction): void {\n this.errorKeys.set([]);\n this.noticeKey.set(null);\n\n if (!this.needsReauthentication(action)) {\n void this.perform(action);\n return;\n }\n\n this.pendingAction.set(action);\n this.reauthenticationMethod.set(passwordReauthentication);\n this.reauthenticationSecret.set('');\n afterNextRender(() => this.reauthenticationInput()?.nativeElement.focus(), {injector: this.injector});\n }\n\n async confirmReauthentication(): Promise<void> {\n const action = this.pendingAction();\n const secret = this.reauthenticationSecret().trim();\n if (!action || this.busy()) {\n return;\n }\n\n if (!secret) {\n this.errorKeys.set(['nh-two-factor.reauthentication-required']);\n return;\n }\n\n const method = this.reauthenticationMethod();\n const reauthentication = method === passwordReauthentication\n ? new NhTwoFactorReauthentication({password: secret})\n : new NhTwoFactorReauthentication({method: method, code: secret});\n\n this.pendingAction.set(null);\n this.reauthenticationSecret.set('');\n await this.perform(action, reauthentication);\n }\n\n cancelReauthentication(): void {\n this.pendingAction.set(null);\n this.reauthenticationSecret.set('');\n this.errorKeys.set([]);\n }\n\n async confirmSetup(): Promise<void> {\n const code = this.code().trim();\n if (!code) {\n this.errorKeys.set(['nh-two-factor.invalid-code']);\n return;\n }\n\n const change = await this.run(() => this.setupPanel() === 'email'\n ? this.auth.confirmEmailSetup(code)\n : this.auth.confirmAuthenticator(code));\n\n this.code.set('');\n if (change) {\n this.closeSetup();\n await this.applyChange(change);\n }\n }\n\n closeSetup(): void {\n this.setupPanel.set(null);\n this.setup.set(null);\n this.emailSent.set(null);\n this.code.set('');\n this.emailReauthentication = undefined;\n }\n\n async resendEmailCode(): Promise<void> {\n const sent = await this.run(() => this.auth.beginEmailSetup(this.emailReauthentication));\n if (sent) {\n this.emailSent.set(sent);\n }\n }\n\n startRename(passkey: NhPasskey): void {\n this.renamingId.set(passkey.id);\n this.renameValue.set(passkey.name);\n }\n\n cancelRename(): void {\n this.renamingId.set(null);\n this.renameValue.set('');\n }\n\n async saveRename(passkey: NhPasskey): Promise<void> {\n const name = this.renameValue().trim();\n if (!name || this.busy()) {\n return;\n }\n\n this.busy.set(true);\n this.errorKeys.set([]);\n const result = await this.auth.renamePasskey(passkey.id, name);\n this.busy.set(false);\n\n if (!result.isSuccess) {\n this.errorKeys.set(nhTwoFactorErrorKeys(result));\n return;\n }\n\n this.cancelRename();\n this.passkeys.update(passkeys => passkeys.map(item => item.id === passkey.id ? new NhPasskey({...item, name: name}) : item));\n this.noticeKey.set('nh-two-factor.ui.change-saved');\n }\n\n private needsReauthentication(action: NhTwoFactorSettingsAction): boolean {\n switch (action.kind) {\n case 'authenticator':\n case 'email':\n case 'add-passkey':\n return this.enabled();\n default:\n return true;\n }\n }\n\n private async perform(action: NhTwoFactorSettingsAction, reauthentication?: NhTwoFactorReauthentication): Promise<void> {\n switch (action.kind) {\n case 'authenticator': {\n const setup = await this.run(() => this.auth.beginAuthenticatorSetup(reauthentication));\n if (setup) {\n this.openSetup('authenticator');\n this.setup.set(setup);\n }\n return;\n }\n case 'email': {\n const sent = await this.run(() => this.auth.beginEmailSetup(reauthentication));\n if (sent) {\n this.openSetup('email');\n this.emailSent.set(sent);\n this.emailReauthentication = reauthentication;\n }\n return;\n }\n case 'recovery-codes':\n await this.applyChange(await this.run(() => this.auth.regenerateRecoveryCodes(reauthentication!)));\n return;\n case 'forget-devices':\n await this.applyChange(\n await this.run(() => this.auth.forgetTwoFactorDevices(reauthentication!)),\n 'nh-two-factor.ui.devices-forgotten');\n return;\n case 'disable':\n await this.applyChange(await this.run(() => this.auth.disableTwoFactor(reauthentication!)));\n return;\n case 'add-passkey': {\n const name = this.newPasskeyName().trim() || undefined;\n const change = await this.run(() => this.auth.registerPasskey(name, reauthentication));\n if (change) {\n this.newPasskeyName.set('');\n }\n await this.applyChange(change);\n return;\n }\n case 'remove-passkey':\n await this.applyChange(await this.run(() => this.auth.removePasskey(action.passkeyId, reauthentication!)));\n return;\n }\n }\n\n private openSetup(panel: 'authenticator' | 'email'): void {\n this.closeSetup();\n this.setupPanel.set(panel);\n afterNextRender(() => this.codeInput()?.nativeElement.focus(), {injector: this.injector});\n }\n\n private async applyChange(change: NhTwoFactorChange | undefined, noticeKey?: string): Promise<void> {\n if (!change) {\n return;\n }\n\n this.recoveryCodes.set(change.recoveryCodes?.length ? change.recoveryCodes : null);\n this.noticeKey.set(noticeKey ?? (change.sessionRenewed ? 'nh-two-factor.ui.session-renewed' : 'nh-two-factor.ui.change-saved'));\n\n await this.load();\n const status = this.status();\n if (status) {\n this.changed.emit(status);\n }\n }\n\n private async run<T>(action: () => Promise<TaskResult<T>>): Promise<T | undefined> {\n this.busy.set(true);\n this.errorKeys.set([]);\n const result = await action();\n this.busy.set(false);\n\n if (!result.isSuccess) {\n this.errorKeys.set(nhTwoFactorErrorKeys(result));\n return undefined;\n }\n\n return result.data;\n }\n\n private hasMethod(method: string): boolean {\n return this.status()?.methods.includes(method) === true;\n }\n\n private isAvailable(method: string): boolean {\n return this.status()?.availableMethods.includes(method) === true;\n }\n}\n","<section class=\"nh-two-factor\" [attr.aria-labelledby]=\"id + '-title'\" [attr.aria-busy]=\"loading() || busy()\">\n <div class=\"nh-two-factor__status\">\n <h2 class=\"nh-two-factor__title\" [class.visually-hidden]=\"!showTitle()\" [id]=\"id + '-title'\">{{ 'nh-two-factor.ui.settings-title' | translate }}</h2>\n @if (status(); as current) {\n <span class=\"nh-two-factor__badge\" [class.nh-two-factor__badge--on]=\"current.enabled\">\n {{ (current.enabled ? 'nh-two-factor.ui.status-enabled' : 'nh-two-factor.ui.status-disabled') | translate }}\n </span>\n @if (current.required) {\n <span class=\"nh-two-factor__badge\">{{ 'nh-two-factor.ui.status-required' | translate }}</span>\n }\n }\n </div>\n\n @if (loading() && !status()) {\n <p class=\"nh-two-factor__hint\" role=\"status\">{{ 'nh-two-factor.ui.loading' | translate }}</p>\n }\n\n <div role=\"status\">\n @if (noticeKey(); as notice) {\n <p class=\"nh-two-factor__notice\">{{ notice | translate }}</p>\n }\n </div>\n\n <div [id]=\"id + '-errors'\" aria-live=\"assertive\">\n @if (errorKeys().length > 0) {\n <ul class=\"nh-two-factor__errors\" role=\"alert\">\n @for (key of errorKeys(); track key) {\n <li>{{ key | translate }}</li>\n }\n </ul>\n }\n </div>\n\n @if (pendingAction()) {\n <form class=\"nh-two-factor nh-two-factor__section\" [attr.aria-labelledby]=\"id + '-reauthentication-title'\" (submit)=\"$event.preventDefault(); confirmReauthentication()\">\n <h3 class=\"nh-two-factor__subtitle\" [id]=\"id + '-reauthentication-title'\">{{ 'nh-two-factor.ui.reauthentication-title' | translate }}</h3>\n\n @if (reauthenticationMethods().length > 1) {\n <fieldset class=\"nh-two-factor__methods\">\n <legend class=\"nh-two-factor__legend\">{{ 'nh-two-factor.ui.reauthentication-method' | translate }}</legend>\n @for (option of reauthenticationMethods(); track option) {\n <label class=\"nh-two-factor__method\">\n <input\n type=\"radio\"\n [name]=\"id + '-reauthentication-method'\"\n [value]=\"option\"\n [checked]=\"reauthenticationMethod() === option\"\n (change)=\"reauthenticationMethod.set(option); reauthenticationSecret.set('')\" />\n <span>{{ (option === 'password' ? 'nh-two-factor.ui.password' : 'nh-two-factor.ui.method.' + option) | translate }}</span>\n </label>\n }\n </fieldset>\n }\n\n <div class=\"nh-two-factor__field\">\n <label [for]=\"id + '-reauthentication'\">\n {{ (reauthenticationMethod() === 'password' ? 'nh-two-factor.ui.password' : 'nh-two-factor.ui.code-label.' + reauthenticationMethod()) | translate }}\n </label>\n <input\n #reauthenticationInput\n class=\"nh-two-factor__input\"\n [id]=\"id + '-reauthentication'\"\n [type]=\"reauthenticationMethod() === 'password' ? 'password' : 'text'\"\n [attr.autocomplete]=\"reauthenticationMethod() === 'password' ? 'current-password' : 'one-time-code'\"\n [value]=\"reauthenticationSecret()\"\n [disabled]=\"busy()\"\n (input)=\"reauthenticationSecret.set(value($event))\" />\n </div>\n\n <div class=\"nh-two-factor__actions\">\n <button type=\"submit\" class=\"nh-two-factor__button nh-two-factor__button--primary\" [disabled]=\"busy()\">\n {{ 'nh-two-factor.ui.confirm' | translate }}\n </button>\n <button type=\"button\" class=\"nh-two-factor__button\" [disabled]=\"busy()\" (click)=\"cancelReauthentication()\">\n {{ 'nh-two-factor.ui.cancel' | translate }}\n </button>\n </div>\n </form>\n }\n\n @if (recoveryCodes(); as codes) {\n <div class=\"nh-two-factor__section\">\n <nh-two-factor-recovery-codes [codes]=\"codes\" (acknowledged)=\"recoveryCodes.set(null)\" />\n </div>\n }\n\n @if (setupPanel(); as panel) {\n <form class=\"nh-two-factor nh-two-factor__section\" [attr.aria-labelledby]=\"id + '-setup-title'\" (submit)=\"$event.preventDefault(); confirmSetup()\">\n <h3 class=\"nh-two-factor__subtitle\" [id]=\"id + '-setup-title'\">{{ 'nh-two-factor.ui.method.' + panel | translate }}</h3>\n\n @if (panel === 'authenticator') {\n <p class=\"nh-two-factor__hint\">{{ 'nh-two-factor.ui.authenticator-instructions' | translate }}</p>\n @if (setup(); as authenticator) {\n <div class=\"nh-two-factor__setup\">\n @if (authenticator.qrCodeDataUri) {\n <img class=\"nh-two-factor__qr\" [src]=\"authenticator.qrCodeDataUri\" [alt]=\"'nh-two-factor.ui.qr-code-alt' | translate\" />\n }\n <p class=\"nh-two-factor__text\">\n {{ 'nh-two-factor.ui.shared-key' | translate }}:\n <span class=\"nh-two-factor__key\">{{ authenticator.sharedKey }}</span>\n </p>\n </div>\n }\n } @else {\n <p class=\"nh-two-factor__hint\">{{ 'nh-two-factor.ui.email-instructions' | translate }}</p>\n @if (emailSent(); as sent) {\n <p class=\"nh-two-factor__hint\">\n {{ 'nh-two-factor.ui.email-code-sent' | translate: { time: (sent.expiresAt | date: 'shortTime') } }}\n </p>\n }\n }\n\n <div class=\"nh-two-factor__field\">\n <label [for]=\"id + '-code'\">{{ 'nh-two-factor.ui.code-label.' + panel | translate }}</label>\n <input\n #codeInput\n type=\"text\"\n class=\"nh-two-factor__input nh-two-factor__input--code\"\n inputmode=\"numeric\"\n autocomplete=\"one-time-code\"\n spellcheck=\"false\"\n [id]=\"id + '-code'\"\n [value]=\"code()\"\n [disabled]=\"busy()\"\n (input)=\"code.set(value($event))\" />\n </div>\n\n <div class=\"nh-two-factor__actions\">\n <button type=\"submit\" class=\"nh-two-factor__button nh-two-factor__button--primary\" [disabled]=\"busy()\">\n {{ 'nh-two-factor.ui.confirm' | translate }}\n </button>\n @if (panel === 'email') {\n <button type=\"button\" class=\"nh-two-factor__button\" [disabled]=\"busy()\" (click)=\"resendEmailCode()\">\n {{ 'nh-two-factor.ui.resend-email-code' | translate }}\n </button>\n }\n <button type=\"button\" class=\"nh-two-factor__button\" [disabled]=\"busy()\" (click)=\"closeSetup()\">\n {{ 'nh-two-factor.ui.cancel' | translate }}\n </button>\n </div>\n </form>\n }\n\n @if (status(); as current) {\n @if (!setupPanel() && !pendingAction()) {\n <div class=\"nh-two-factor__actions\">\n @if (authenticatorAvailable()) {\n <button type=\"button\" class=\"nh-two-factor__button\" [disabled]=\"busy()\" (click)=\"request({ kind: 'authenticator' })\">\n {{ (hasAuthenticator() ? 'nh-two-factor.ui.change-authenticator' : 'nh-two-factor.ui.set-up-authenticator') | translate }}\n </button>\n }\n @if (emailAvailable() && !hasEmail()) {\n <button type=\"button\" class=\"nh-two-factor__button\" [disabled]=\"busy()\" (click)=\"request({ kind: 'email' })\">\n {{ 'nh-two-factor.ui.set-up-email' | translate }}\n </button>\n }\n </div>\n }\n\n @if (passkeysAvailable()) {\n <div class=\"nh-two-factor__section\">\n <h3 class=\"nh-two-factor__subtitle\">{{ 'nh-two-factor.ui.passkeys-title' | translate }}</h3>\n\n @if (passkeys().length === 0) {\n <p class=\"nh-two-factor__hint\">{{ 'nh-two-factor.ui.no-passkeys' | translate }}</p>\n } @else {\n <ul class=\"nh-two-factor__list\">\n @for (passkey of passkeys(); track passkey.id) {\n <li class=\"nh-two-factor__item\">\n @if (renamingId() === passkey.id) {\n <form class=\"nh-two-factor__actions\" (submit)=\"$event.preventDefault(); saveRename(passkey)\">\n <label class=\"visually-hidden\" [for]=\"id + '-rename-' + $index\">{{ 'nh-two-factor.ui.passkey-name' | translate }}</label>\n <input\n type=\"text\"\n class=\"nh-two-factor__input\"\n maxlength=\"100\"\n [id]=\"id + '-rename-' + $index\"\n [value]=\"renameValue()\"\n [disabled]=\"busy()\"\n (input)=\"renameValue.set(value($event))\" />\n <button type=\"submit\" class=\"nh-two-factor__button nh-two-factor__button--primary\" [disabled]=\"busy()\">\n {{ 'nh-two-factor.ui.save' | translate }}\n </button>\n <button type=\"button\" class=\"nh-two-factor__button\" [disabled]=\"busy()\" (click)=\"cancelRename()\">\n {{ 'nh-two-factor.ui.cancel' | translate }}\n </button>\n </form>\n } @else {\n <div>\n <p class=\"nh-two-factor__text\"><strong>{{ passkey.name }}</strong></p>\n <p class=\"nh-two-factor__hint\">\n {{ 'nh-two-factor.ui.passkey-created' | translate: { date: (passkey.createdAt | date: 'mediumDate') } }}\n @if (passkey.isBackedUp) {\n · {{ 'nh-two-factor.ui.passkey-synced' | translate }}\n }\n </p>\n </div>\n <div class=\"nh-two-factor__actions\">\n <button type=\"button\" class=\"nh-two-factor__button\" [disabled]=\"busy()\" (click)=\"startRename(passkey)\">\n {{ 'nh-two-factor.ui.rename' | translate }}\n </button>\n <button type=\"button\" class=\"nh-two-factor__button nh-two-factor__button--danger\" [disabled]=\"busy()\" (click)=\"request({ kind: 'remove-passkey', passkeyId: passkey.id })\">\n {{ 'nh-two-factor.ui.remove' | translate }}\n </button>\n </div>\n }\n </li>\n }\n </ul>\n }\n\n @if (passkeySupported && !pendingAction()) {\n <form class=\"nh-two-factor__actions\" (submit)=\"$event.preventDefault(); request({ kind: 'add-passkey' })\">\n <label class=\"visually-hidden\" [for]=\"id + '-new-passkey'\">{{ 'nh-two-factor.ui.passkey-name' | translate }}</label>\n <input\n type=\"text\"\n class=\"nh-two-factor__input\"\n maxlength=\"100\"\n autocomplete=\"off\"\n [id]=\"id + '-new-passkey'\"\n [attr.placeholder]=\"'nh-two-factor.ui.passkey-name' | translate\"\n [value]=\"newPasskeyName()\"\n [disabled]=\"busy()\"\n (input)=\"newPasskeyName.set(value($event))\" />\n <button type=\"submit\" class=\"nh-two-factor__button\" [disabled]=\"busy()\">\n {{ 'nh-two-factor.ui.add-passkey' | translate }}\n </button>\n </form>\n }\n </div>\n }\n\n @if (current.enabled && !pendingAction()) {\n <div class=\"nh-two-factor__section\">\n @if (recoveryCodesAvailable()) {\n <p class=\"nh-two-factor__hint\">{{ 'nh-two-factor.ui.recovery-codes-left' | translate: { count: current.recoveryCodesLeft } }}</p>\n }\n <div class=\"nh-two-factor__actions\">\n @if (recoveryCodesAvailable()) {\n <button type=\"button\" class=\"nh-two-factor__button\" [disabled]=\"busy()\" (click)=\"request({ kind: 'recovery-codes' })\">\n {{ 'nh-two-factor.ui.regenerate-recovery-codes' | translate }}\n </button>\n }\n @if (current.rememberDeviceAvailable) {\n <button type=\"button\" class=\"nh-two-factor__button\" [disabled]=\"busy()\" (click)=\"request({ kind: 'forget-devices' })\">\n {{ 'nh-two-factor.ui.forget-devices' | translate }}\n </button>\n }\n @if (!required()) {\n <button type=\"button\" class=\"nh-two-factor__button nh-two-factor__button--danger\" [disabled]=\"busy()\" (click)=\"request({ kind: 'disable' })\">\n {{ 'nh-two-factor.ui.disable' | translate }}\n </button>\n }\n </div>\n </div>\n }\n }\n</section>\n","import {ChangeDetectionStrategy, Component, inject, input, output, signal} from '@angular/core';\nimport {TranslatePipe} from '@ngx-translate/core';\nimport {INhAuthorization, NhAuthenticationStep, NhAuthService} from '@newheap/platform-common';\nimport {NhTwoFactorTranslationMerger} from '../i18n/nh-two-factor-translations';\nimport {nhTwoFactorErrorKeys} from '../nh-two-factor-errors';\n\nlet nextId = 0;\n\n/**\n * Signs in with a discoverable passkey, without a username or password. Renders nothing in\n * browsers without passkey support.\n */\n@Component({\n selector: 'nh-passkey-login-button',\n standalone: true,\n imports: [TranslatePipe],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './nh-passkey-login-button.component.html',\n styleUrl: '../nh-two-factor.scss'\n})\nexport class NhPasskeyLoginButtonComponent {\n private readonly auth = inject(NhAuthService);\n\n /** Whether the button shows failures itself. */\n readonly showErrors = input(true);\n\n readonly authenticated = output<INhAuthorization>();\n /** The policy asked for more: a second-factor challenge or an enrollment. */\n readonly pending = output<NhAuthenticationStep>();\n /** Translation keys of a failed sign-in. */\n readonly failed = output<string[]>();\n\n readonly id = `nh-passkey-login-${nextId++}`;\n readonly supported = this.auth.isPasskeySupported();\n readonly busy = signal(false);\n readonly errorKeys = signal<string[]>([]);\n\n constructor() {\n inject(NhTwoFactorTranslationMerger).start();\n }\n\n async signIn(): Promise<void> {\n if (this.busy()) {\n return;\n }\n\n this.busy.set(true);\n this.errorKeys.set([]);\n const result = await this.auth.signInWithPasskey();\n this.busy.set(false);\n\n if (!result.isSuccess || !result.data) {\n const keys = nhTwoFactorErrorKeys(result);\n this.errorKeys.set(keys);\n this.failed.emit(keys);\n return;\n }\n\n if (result.data.status === 'authenticated' && result.data.authorization) {\n this.authenticated.emit(result.data.authorization);\n return;\n }\n\n this.pending.emit(result.data);\n }\n}\n","@if (supported) {\n <div class=\"nh-two-factor\">\n <div class=\"nh-two-factor__actions\">\n <button\n type=\"button\"\n class=\"nh-two-factor__button\"\n [disabled]=\"busy()\"\n [attr.aria-busy]=\"busy()\"\n [attr.aria-describedby]=\"errorKeys().length > 0 ? id + '-errors' : null\"\n (click)=\"signIn()\">\n {{ 'nh-two-factor.ui.sign-in-with-passkey' | translate }}\n </button>\n </div>\n\n @if (showErrors()) {\n <div [id]=\"id + '-errors'\" aria-live=\"assertive\">\n @if (errorKeys().length > 0) {\n <ul class=\"nh-two-factor__errors\" role=\"alert\">\n @for (key of errorKeys(); track key) {\n <li>{{ key | translate }}</li>\n }\n </ul>\n }\n </div>\n }\n </div>\n}\n","import {EnvironmentProviders, inject, makeEnvironmentProviders, provideEnvironmentInitializer} from '@angular/core';\nimport {NhTwoFactorTranslationMerger} from './i18n/nh-two-factor-translations';\n\n/**\n * Registers the two-factor texts at startup. The components also register them when they are\n * first created, so this provider is only needed to translate `nh-two-factor.` failure keys\n * outside the components, for example on a custom login page.\n */\nexport function provideNhTwoFactor(): EnvironmentProviders {\n return makeEnvironmentProviders([\n provideEnvironmentInitializer(() => inject(NhTwoFactorTranslationMerger).start())\n ]);\n}\n","/*\n * Public API surface of @newheap/platform-common/two-factor.\n *\n * The two-factor components are a separate entry point, so applications that do not import\n * it ship none of their code. The service and models live in @newheap/platform-common.\n */\nexport * from './lib/challenge/nh-two-factor-challenge.component';\nexport * from './lib/enrollment/nh-two-factor-enrollment.component';\nexport * from './lib/recovery-codes/nh-two-factor-recovery-codes.component';\nexport * from './lib/settings/nh-two-factor-settings.component';\nexport * from './lib/passkey-login/nh-passkey-login-button.component';\nexport {NH_TWO_FACTOR_TRANSLATIONS, NhTwoFactorTranslationMerger} from './lib/i18n/nh-two-factor-translations';\nexport {nhTwoFactorErrorKeys, nhTwoFactorStepEnded} from './lib/nh-two-factor-errors';\nexport * from './lib/provide-nh-two-factor';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["nextId"],"mappings":"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"}