@atlasauth/angular 0.16.1 → 0.16.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/dist/esm2022/lib/components/attempt-flow.component.mjs +34 -3
- package/dist/esm2022/lib/components/flow-controller.mjs +22 -2
- package/dist/esm2022/lib/components/sign-in.component.mjs +6 -2
- package/dist/esm2022/lib/components/sign-up.component.mjs +6 -2
- package/dist/esm2022/lib/version.mjs +2 -2
- package/dist/fesm2022/atlasauth-angular.mjs +65 -6
- package/dist/fesm2022/atlasauth-angular.mjs.map +1 -1
- package/dist/lib/components/attempt-flow.component.d.ts +4 -1
- package/dist/lib/components/flow-controller.d.ts +5 -0
- package/dist/lib/version.d.ts +1 -1
- package/package.json +3 -3
|
@@ -4,7 +4,7 @@ import { isPlatformBrowser, DOCUMENT } from '@angular/common';
|
|
|
4
4
|
import { toSignal } from '@angular/core/rxjs-interop';
|
|
5
5
|
import { BehaviorSubject, Subject, combineLatest, firstValueFrom } from 'rxjs';
|
|
6
6
|
import { map, distinctUntilChanged, filter, take } from 'rxjs/operators';
|
|
7
|
-
import { createOrganizationAuditLog, POLICY_STRINGS, TokenCache, SignOutNotifier, resolveFrontendApi, withDevBrowser, catalogLocale, configureReferralCapture, FapiClient, SignOutGuard, localizedErrorMessage, reauthenticate, getTemplateToken, getProviderToken, signOutReasonFromClient, readRedirectResult, completeOAuthPopupLanding, mapOAuthPopupPayload, stripRedirectParams, closeOAuthPopupAfterSignIn, SDK_HEADER, sdkHeaderValue, reportSdkAdvisory, readExpiry, msUntilRefresh, policyTranslator, injectPolicyStyles, mountPolicyClickwrap, mountPolicyConsent, controllerForPending, mountPolicyAcceptStep, joinTitles, formatPolicyDate, PolicyGateController, enrollmentOptionKey, groupSetupKey, enrollmentSubmitKey, nextStep, awaitingSignUpLink, createEmailLinkConfirmation, canDownloadRecoveryCodes, copyRecoveryCodes, downloadRecoveryCodes, createCaptchaController, atlasCaptchaLabels, PolicyAcceptanceController, flowFromPending, initialFlow, createMfaEnrollment, createPasskeySignInController, startSignInWithAtlas, mfaChoicesFrom, fetchInstanceSettings, fetchLastSignInMethod, offeredFirstFactors, preparePasswordHoldProof, prepareFactor, signInCaptchaOptions, flowNeedsCaptcha, planFirstFactor, attemptPasswordHoldProof, advanceWithCaptcha, loadPolicies, createSignUp, prepareSecondFactorCode, resendSignUpVerification, createPasskeySignUp, finishPasskeySignUp, pendingRecoveryCodes, acknowledgeRecoveryCodes, pendingExistingAccountNotice, acknowledgeExistingAccount, shouldKeepPolling, pollAttempt, emailLinkFromUrl, lastUsedMethodLabel, signUp, passkeysSupported, confirmPolicies, existingAccountResetUrl, signUpProvedByLink, signInAfterProofUrl, awaitingPasskey, listCibaRequests, getCibaPin, decideCibaRequest, setCibaPin, clearCibaPin, OrganizationProfileController, describeAuditAction, actorFromClaims } from '@atlasauth/js';
|
|
7
|
+
import { createOrganizationAuditLog, POLICY_STRINGS, TokenCache, SignOutNotifier, resolveFrontendApi, withDevBrowser, catalogLocale, configureReferralCapture, FapiClient, SignOutGuard, localizedErrorMessage, reauthenticate, getTemplateToken, getProviderToken, signOutReasonFromClient, readRedirectResult, completeOAuthPopupLanding, mapOAuthPopupPayload, stripRedirectParams, closeOAuthPopupAfterSignIn, SDK_HEADER, sdkHeaderValue, reportSdkAdvisory, readExpiry, msUntilRefresh, policyTranslator, injectPolicyStyles, mountPolicyClickwrap, mountPolicyConsent, controllerForPending, mountPolicyAcceptStep, joinTitles, formatPolicyDate, PolicyGateController, enrollmentOptionKey, groupSetupKey, enrollmentSubmitKey, nextStep, awaitingSignUpLink, createEmailLinkConfirmation, canDownloadRecoveryCodes, copyRecoveryCodes, downloadRecoveryCodes, createCaptchaController, atlasCaptchaLabels, PolicyAcceptanceController, flowFromPending, initialFlow, createMfaEnrollment, createPasskeySignInController, startSignInWithAtlas, mfaChoicesFrom, fetchInstanceSettings, fetchLastSignInMethod, offeredFirstFactors, preparePasswordHoldProof, prepareFactor, signInCaptchaOptions, flowNeedsCaptcha, sendOnlyWaySecondFactorCode, continueOnHostedPage, planFirstFactor, attemptPasswordHoldProof, advanceWithCaptcha, loadPolicies, createSignUp, prepareSecondFactorCode, resendSignUpVerification, createPasskeySignUp, finishPasskeySignUp, pendingRecoveryCodes, acknowledgeRecoveryCodes, pendingExistingAccountNotice, acknowledgeExistingAccount, shouldKeepPolling, pollAttempt, emailLinkFromUrl, lastUsedMethodLabel, signUp, passkeysSupported, confirmPolicies, existingAccountResetUrl, signUpProvedByLink, signInAfterProofUrl, awaitingPasskey, listCibaRequests, getCibaPin, decideCibaRequest, setCibaPin, clearCibaPin, OrganizationProfileController, describeAuditAction, actorFromClaims } from '@atlasauth/js';
|
|
8
8
|
export { FapiClient, SIGN_OUT_EVENT, SignOutError, advance, flowFromPending, getProviderToken, initialFlow, onAtlasSignOut, pollAttempt, prepareFactor, requestForStep, shouldKeepPolling } from '@atlasauth/js';
|
|
9
9
|
import { evaluate } from '@atlasauth/authz';
|
|
10
10
|
export { evaluate, hasFromClaims } from '@atlasauth/authz';
|
|
@@ -421,7 +421,7 @@ function withFallback(locale) {
|
|
|
421
421
|
}
|
|
422
422
|
|
|
423
423
|
/** This package's version, sent as `X-Atlas-SDK` (kept in step with package.json by a test). */
|
|
424
|
-
const ATLAS_ANGULAR_VERSION = '0.16.
|
|
424
|
+
const ATLAS_ANGULAR_VERSION = '0.16.3';
|
|
425
425
|
const ATLAS_ANGULAR_SDK = { name: '@atlasauth/angular', version: ATLAS_ANGULAR_VERSION };
|
|
426
426
|
|
|
427
427
|
/**
|
|
@@ -1534,6 +1534,9 @@ class AttemptFlowComponent {
|
|
|
1534
1534
|
/** `AtlasFlowController.emailSecondFactor()`: in flight, where it went, or why not. */
|
|
1535
1535
|
emailedSecondFactor = null;
|
|
1536
1536
|
emailSecondFactor = new EventEmitter();
|
|
1537
|
+
/** "Use a passkey" at the second factor (`mfaChoices().passkey`): leaves for the hosted page. */
|
|
1538
|
+
offerPasskeySecondFactor = false;
|
|
1539
|
+
passkeySecondFactor = new EventEmitter();
|
|
1537
1540
|
/**
|
|
1538
1541
|
* Offer "Text me a code instead" at the second factor (where the app offers
|
|
1539
1542
|
* texted codes, `AtlasFlowController.mfaChoices().sms`); `smsSecondFactor`
|
|
@@ -1633,7 +1636,7 @@ class AttemptFlowComponent {
|
|
|
1633
1636
|
return this.errors.filter((error) => !error.param);
|
|
1634
1637
|
}
|
|
1635
1638
|
signInLink(error) {
|
|
1636
|
-
return this.step().kind === 'collect_email_code' && error.code === 'IDENTIFIER_EXISTS' ? this.signInHref : null;
|
|
1639
|
+
return this.step().kind === 'collect_email_code' && error.code === 'IDENTIFIER_EXISTS' && error.meta?.['identifier'] !== 'username' ? this.signInHref : null;
|
|
1637
1640
|
}
|
|
1638
1641
|
fieldErrorsFor(name) {
|
|
1639
1642
|
return this.errors.filter((error) => error.param === name);
|
|
@@ -1761,7 +1764,7 @@ class AttemptFlowComponent {
|
|
|
1761
1764
|
}
|
|
1762
1765
|
}
|
|
1763
1766
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AttemptFlowComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1764
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: AttemptFlowComponent, isStandalone: true, selector: "atlas-attempt-flow", inputs: { attempt: "attempt", busy: "busy", errors: "errors", sessionKept: "sessionKept", titleKey: "titleKey", signInHref: "signInHref", captcha: "captcha", firstFactors: "firstFactors", preparedFactor: "preparedFactor", passwordHold: "passwordHold", holdProof: "holdProof", offerEmailSecondFactor: "offerEmailSecondFactor", emailedSecondFactor: "emailedSecondFactor", offerSmsSecondFactor: "offerSmsSecondFactor", textedSecondFactor: "textedSecondFactor", enrollment: "enrollment", enrollmentState: "enrollmentState", emailVerification: "emailVerification", matchCode: "matchCode" }, outputs: { submitFlow: "submitFlow", chooseFactor: "chooseFactor", usePassword: "usePassword", emailSecondFactor: "emailSecondFactor", smsSecondFactor: "smsSecondFactor", resend: "resend", policyDeclined: "policyDeclined" }, ngImport: i0, template: `
|
|
1767
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: AttemptFlowComponent, isStandalone: true, selector: "atlas-attempt-flow", inputs: { attempt: "attempt", busy: "busy", errors: "errors", sessionKept: "sessionKept", titleKey: "titleKey", signInHref: "signInHref", captcha: "captcha", firstFactors: "firstFactors", preparedFactor: "preparedFactor", passwordHold: "passwordHold", holdProof: "holdProof", offerEmailSecondFactor: "offerEmailSecondFactor", emailedSecondFactor: "emailedSecondFactor", offerPasskeySecondFactor: "offerPasskeySecondFactor", offerSmsSecondFactor: "offerSmsSecondFactor", textedSecondFactor: "textedSecondFactor", enrollment: "enrollment", enrollmentState: "enrollmentState", emailVerification: "emailVerification", matchCode: "matchCode" }, outputs: { submitFlow: "submitFlow", chooseFactor: "chooseFactor", usePassword: "usePassword", emailSecondFactor: "emailSecondFactor", passkeySecondFactor: "passkeySecondFactor", smsSecondFactor: "smsSecondFactor", resend: "resend", policyDeclined: "policyDeclined" }, ngImport: i0, template: `
|
|
1765
1768
|
<div [class]="cls('card', 'atlas-card')">
|
|
1766
1769
|
<h1 [class]="cls('headerTitle', 'atlas-title')">{{ t(titleKey) }}</h1>
|
|
1767
1770
|
|
|
@@ -1984,6 +1987,18 @@ class AttemptFlowComponent {
|
|
|
1984
1987
|
}
|
|
1985
1988
|
}
|
|
1986
1989
|
|
|
1990
|
+
@if (offerPasskeySecondFactor && step().kind === 'collect_second_factor') {
|
|
1991
|
+
<button
|
|
1992
|
+
[class]="cls('formButtonSecondary', 'atlas-button-secondary')"
|
|
1993
|
+
type="button"
|
|
1994
|
+
data-atlas="passkey-second-factor"
|
|
1995
|
+
[disabled]="busy"
|
|
1996
|
+
(click)="passkeySecondFactor.emit()"
|
|
1997
|
+
>
|
|
1998
|
+
{{ t('mfa.enrollPasskeyOption') }}
|
|
1999
|
+
</button>
|
|
2000
|
+
}
|
|
2001
|
+
|
|
1987
2002
|
@if (showEmailCodeOption()) {
|
|
1988
2003
|
<button
|
|
1989
2004
|
[class]="cls('formButtonSecondary', 'atlas-button-secondary')"
|
|
@@ -2255,6 +2270,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
2255
2270
|
}
|
|
2256
2271
|
}
|
|
2257
2272
|
|
|
2273
|
+
@if (offerPasskeySecondFactor && step().kind === 'collect_second_factor') {
|
|
2274
|
+
<button
|
|
2275
|
+
[class]="cls('formButtonSecondary', 'atlas-button-secondary')"
|
|
2276
|
+
type="button"
|
|
2277
|
+
data-atlas="passkey-second-factor"
|
|
2278
|
+
[disabled]="busy"
|
|
2279
|
+
(click)="passkeySecondFactor.emit()"
|
|
2280
|
+
>
|
|
2281
|
+
{{ t('mfa.enrollPasskeyOption') }}
|
|
2282
|
+
</button>
|
|
2283
|
+
}
|
|
2284
|
+
|
|
2258
2285
|
@if (showEmailCodeOption()) {
|
|
2259
2286
|
<button
|
|
2260
2287
|
[class]="cls('formButtonSecondary', 'atlas-button-secondary')"
|
|
@@ -2330,6 +2357,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
2330
2357
|
type: Input
|
|
2331
2358
|
}], emailSecondFactor: [{
|
|
2332
2359
|
type: Output
|
|
2360
|
+
}], offerPasskeySecondFactor: [{
|
|
2361
|
+
type: Input
|
|
2362
|
+
}], passkeySecondFactor: [{
|
|
2363
|
+
type: Output
|
|
2333
2364
|
}], offerSmsSecondFactor: [{
|
|
2334
2365
|
type: Input
|
|
2335
2366
|
}], textedSecondFactor: [{
|
|
@@ -2808,8 +2839,28 @@ class AtlasFlowController {
|
|
|
2808
2839
|
this.syncCaptcha();
|
|
2809
2840
|
this.syncEnrollment();
|
|
2810
2841
|
this.autoSend();
|
|
2842
|
+
this.autoSendOnlyWay();
|
|
2811
2843
|
}
|
|
2812
2844
|
autoSentFor = null;
|
|
2845
|
+
onlyWayFor = null;
|
|
2846
|
+
/** Once per attempt, on arrival at the second factor: email the code if the inbox is the only way. */
|
|
2847
|
+
autoSendOnlyWay() {
|
|
2848
|
+
const { attempt } = this.state();
|
|
2849
|
+
const id = attempt?.id ?? null;
|
|
2850
|
+
if (!id || attempt?.status !== 'needs_second_factor' || this.onlyWayFor === id || !this.mfaChoices().emailCode)
|
|
2851
|
+
return;
|
|
2852
|
+
this.onlyWayFor = id;
|
|
2853
|
+
void sendOnlyWaySecondFactorCode(this.client, id).then((sentTo) => {
|
|
2854
|
+
// A stale answer (the flow moved to another attempt) is dropped.
|
|
2855
|
+
if (sentTo && this.state().attempt?.id === id)
|
|
2856
|
+
this.emailSecondFactor.set({ sentTo });
|
|
2857
|
+
});
|
|
2858
|
+
}
|
|
2859
|
+
/** "Use a passkey" at the second factor: leaves for the hosted page. */
|
|
2860
|
+
continueWithPasskey() {
|
|
2861
|
+
const id = this.state().attempt?.id;
|
|
2862
|
+
return !!id && continueOnHostedPage(this.mfaChoices(), id, 'needs_second_factor');
|
|
2863
|
+
}
|
|
2813
2864
|
/**
|
|
2814
2865
|
* With no password on offer, email the code as soon as the server asks for a
|
|
2815
2866
|
* first factor — once per attempt, so a failed send waits for the user's retry
|
|
@@ -3152,6 +3203,8 @@ class SignInComponent {
|
|
|
3152
3203
|
[enrollmentState]="flow.enrollmentState()"
|
|
3153
3204
|
(emailSecondFactor)="flow.sendEmailSecondFactor()"
|
|
3154
3205
|
(smsSecondFactor)="flow.sendSmsSecondFactor()"
|
|
3206
|
+
[offerPasskeySecondFactor]="flow.settings() !== null && flow.mfaChoices().passkey"
|
|
3207
|
+
(passkeySecondFactor)="flow.continueWithPasskey()"
|
|
3155
3208
|
(policyDeclined)="flow.declinePolicy($event)"
|
|
3156
3209
|
></atlas-attempt-flow>
|
|
3157
3210
|
}
|
|
@@ -3172,7 +3225,7 @@ class SignInComponent {
|
|
|
3172
3225
|
</p>
|
|
3173
3226
|
}
|
|
3174
3227
|
}
|
|
3175
|
-
`, isInline: true, dependencies: [{ kind: "component", type: EmailLinkComponent, selector: "atlas-email-link", inputs: ["link"] }, { kind: "component", type: AttemptFlowComponent, selector: "atlas-attempt-flow", inputs: ["attempt", "busy", "errors", "sessionKept", "titleKey", "signInHref", "captcha", "firstFactors", "preparedFactor", "passwordHold", "holdProof", "offerEmailSecondFactor", "emailedSecondFactor", "offerSmsSecondFactor", "textedSecondFactor", "enrollment", "enrollmentState", "emailVerification", "matchCode"], outputs: ["submitFlow", "chooseFactor", "usePassword", "emailSecondFactor", "smsSecondFactor", "resend", "policyDeclined"] }, { kind: "component", type: RecoveryCodesComponent, selector: "atlas-recovery-codes", inputs: ["codes", "busy"], outputs: ["saved"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3228
|
+
`, isInline: true, dependencies: [{ kind: "component", type: EmailLinkComponent, selector: "atlas-email-link", inputs: ["link"] }, { kind: "component", type: AttemptFlowComponent, selector: "atlas-attempt-flow", inputs: ["attempt", "busy", "errors", "sessionKept", "titleKey", "signInHref", "captcha", "firstFactors", "preparedFactor", "passwordHold", "holdProof", "offerEmailSecondFactor", "emailedSecondFactor", "offerPasskeySecondFactor", "offerSmsSecondFactor", "textedSecondFactor", "enrollment", "enrollmentState", "emailVerification", "matchCode"], outputs: ["submitFlow", "chooseFactor", "usePassword", "emailSecondFactor", "passkeySecondFactor", "smsSecondFactor", "resend", "policyDeclined"] }, { kind: "component", type: RecoveryCodesComponent, selector: "atlas-recovery-codes", inputs: ["codes", "busy"], outputs: ["saved"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3176
3229
|
}
|
|
3177
3230
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: SignInComponent, decorators: [{
|
|
3178
3231
|
type: Component,
|
|
@@ -3224,6 +3277,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
3224
3277
|
[enrollmentState]="flow.enrollmentState()"
|
|
3225
3278
|
(emailSecondFactor)="flow.sendEmailSecondFactor()"
|
|
3226
3279
|
(smsSecondFactor)="flow.sendSmsSecondFactor()"
|
|
3280
|
+
[offerPasskeySecondFactor]="flow.settings() !== null && flow.mfaChoices().passkey"
|
|
3281
|
+
(passkeySecondFactor)="flow.continueWithPasskey()"
|
|
3227
3282
|
(policyDeclined)="flow.declinePolicy($event)"
|
|
3228
3283
|
></atlas-attempt-flow>
|
|
3229
3284
|
}
|
|
@@ -3947,6 +4002,8 @@ class SignUpComponent {
|
|
|
3947
4002
|
[enrollmentState]="flow.enrollmentState()"
|
|
3948
4003
|
(emailSecondFactor)="flow.sendEmailSecondFactor()"
|
|
3949
4004
|
(smsSecondFactor)="flow.sendSmsSecondFactor()"
|
|
4005
|
+
[offerPasskeySecondFactor]="flow.settings() !== null && flow.mfaChoices().passkey"
|
|
4006
|
+
(passkeySecondFactor)="flow.continueWithPasskey()"
|
|
3950
4007
|
(policyDeclined)="flow.declinePolicy($event)"
|
|
3951
4008
|
[signInHref]="signInHref()"
|
|
3952
4009
|
></atlas-attempt-flow>
|
|
@@ -3966,7 +4023,7 @@ class SignUpComponent {
|
|
|
3966
4023
|
></atlas-sign-up-form>
|
|
3967
4024
|
}
|
|
3968
4025
|
}
|
|
3969
|
-
`, isInline: true, dependencies: [{ kind: "component", type: EmailLinkComponent, selector: "atlas-email-link", inputs: ["link"] }, { kind: "component", type: AttemptFlowComponent, selector: "atlas-attempt-flow", inputs: ["attempt", "busy", "errors", "sessionKept", "titleKey", "signInHref", "captcha", "firstFactors", "preparedFactor", "passwordHold", "holdProof", "offerEmailSecondFactor", "emailedSecondFactor", "offerSmsSecondFactor", "textedSecondFactor", "enrollment", "enrollmentState", "emailVerification", "matchCode"], outputs: ["submitFlow", "chooseFactor", "usePassword", "emailSecondFactor", "smsSecondFactor", "resend", "policyDeclined"] }, { kind: "component", type: RecoveryCodesComponent, selector: "atlas-recovery-codes", inputs: ["codes", "busy"], outputs: ["saved"] }, { kind: "component", type: SignUpFormComponent, selector: "atlas-sign-up-form", inputs: ["settings", "busy", "errors", "captcha", "passkey", "switchable", "policies"], outputs: ["switchMode", "submitSignUp"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
4026
|
+
`, isInline: true, dependencies: [{ kind: "component", type: EmailLinkComponent, selector: "atlas-email-link", inputs: ["link"] }, { kind: "component", type: AttemptFlowComponent, selector: "atlas-attempt-flow", inputs: ["attempt", "busy", "errors", "sessionKept", "titleKey", "signInHref", "captcha", "firstFactors", "preparedFactor", "passwordHold", "holdProof", "offerEmailSecondFactor", "emailedSecondFactor", "offerPasskeySecondFactor", "offerSmsSecondFactor", "textedSecondFactor", "enrollment", "enrollmentState", "emailVerification", "matchCode"], outputs: ["submitFlow", "chooseFactor", "usePassword", "emailSecondFactor", "passkeySecondFactor", "smsSecondFactor", "resend", "policyDeclined"] }, { kind: "component", type: RecoveryCodesComponent, selector: "atlas-recovery-codes", inputs: ["codes", "busy"], outputs: ["saved"] }, { kind: "component", type: SignUpFormComponent, selector: "atlas-sign-up-form", inputs: ["settings", "busy", "errors", "captcha", "passkey", "switchable", "policies"], outputs: ["switchMode", "submitSignUp"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3970
4027
|
}
|
|
3971
4028
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: SignUpComponent, decorators: [{
|
|
3972
4029
|
type: Component,
|
|
@@ -4040,6 +4097,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
4040
4097
|
[enrollmentState]="flow.enrollmentState()"
|
|
4041
4098
|
(emailSecondFactor)="flow.sendEmailSecondFactor()"
|
|
4042
4099
|
(smsSecondFactor)="flow.sendSmsSecondFactor()"
|
|
4100
|
+
[offerPasskeySecondFactor]="flow.settings() !== null && flow.mfaChoices().passkey"
|
|
4101
|
+
(passkeySecondFactor)="flow.continueWithPasskey()"
|
|
4043
4102
|
(policyDeclined)="flow.declinePolicy($event)"
|
|
4044
4103
|
[signInHref]="signInHref()"
|
|
4045
4104
|
></atlas-attempt-flow>
|