@atlasauth/angular 0.15.0 → 0.16.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/CHANGELOG.md +8 -0
- package/dist/esm2022/lib/components/attempt-flow.component.mjs +69 -11
- package/dist/esm2022/lib/components/email-link.component.mjs +103 -0
- package/dist/esm2022/lib/components/flow-controller.mjs +6 -3
- package/dist/esm2022/lib/components/sign-in.component.mjs +22 -5
- package/dist/esm2022/lib/components/sign-up.component.mjs +22 -5
- package/dist/esm2022/lib/i18n.mjs +19 -1
- package/dist/esm2022/lib/version.mjs +2 -2
- package/dist/esm2022/public-api.mjs +2 -1
- package/dist/fesm2022/atlasauth-angular.mjs +227 -21
- package/dist/fesm2022/atlasauth-angular.mjs.map +1 -1
- package/dist/lib/components/attempt-flow.component.d.ts +5 -1
- package/dist/lib/components/email-link.component.d.ts +26 -0
- package/dist/lib/components/sign-in.component.d.ts +4 -0
- package/dist/lib/components/sign-up.component.d.ts +4 -0
- package/dist/lib/version.d.ts +1 -1
- package/dist/public-api.d.ts +1 -0
- package/package.json +2 -2
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { InjectionToken, signal, inject, PLATFORM_ID, computed, Injectable, TemplateRef, ViewContainerRef, Directive, Input, ElementRef, Renderer2, EventEmitter, Output, ChangeDetectionStrategy, Component, ChangeDetectorRef, effect, untracked, DestroyRef, makeEnvironmentProviders, ENVIRONMENT_INITIALIZER, NgModule } from '@angular/core';
|
|
2
|
+
import { InjectionToken, signal, inject, PLATFORM_ID, computed, Injectable, TemplateRef, ViewContainerRef, Directive, Input, ElementRef, Renderer2, EventEmitter, Output, ChangeDetectionStrategy, Component, ChangeDetectorRef, afterNextRender, effect, untracked, DestroyRef, makeEnvironmentProviders, ENVIRONMENT_INITIALIZER, NgModule } from '@angular/core';
|
|
3
3
|
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, groupSetupKey, enrollmentSubmitKey, nextStep, awaitingSignUpLink, 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, 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, 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';
|
|
@@ -266,6 +266,23 @@ const EN_US = {
|
|
|
266
266
|
'mfa.enrollChoose': 'Set up a second step for signing in.',
|
|
267
267
|
'mfa.enrollTotpOption': 'Use an authenticator app',
|
|
268
268
|
'mfa.enrollSmsOption': 'Use text messages',
|
|
269
|
+
'link.title': "Confirm it's you",
|
|
270
|
+
'link.matchCodeHint': 'Opening the link on another device? Enter this code there.',
|
|
271
|
+
'link.checking': 'Checking your link…',
|
|
272
|
+
'link.enterCodeHelp': 'Enter the code shown on the device where you started.',
|
|
273
|
+
'link.codeLabel': 'Code',
|
|
274
|
+
'link.confirm': 'Confirm',
|
|
275
|
+
'link.confirmed': 'Confirmed. You can close this tab and go back to where you started.',
|
|
276
|
+
'link.invalid': 'This link is no longer valid. Go back to where you started and ask for a new one.',
|
|
277
|
+
'mfa.enrollHotpOption': 'Use a counter-based code generator',
|
|
278
|
+
'mfa.enrollYubikeyOption': 'Use a YubiKey',
|
|
279
|
+
'mfa.enrollDuoOption': 'Use Duo',
|
|
280
|
+
'mfa.enrollPasskeyOption': 'Use a passkey',
|
|
281
|
+
'mfa.yubikeyLabel': 'Touch your YubiKey',
|
|
282
|
+
'mfa.enrollDuoHelp': 'Open Duo and approve the request, then come back and continue.',
|
|
283
|
+
'mfa.enrollDuoOpen': 'Open Duo',
|
|
284
|
+
'mfa.enrollPasskeyHelp': 'Create a passkey on this device to use as your second step. It must ask for your PIN or biometrics.',
|
|
285
|
+
'mfa.enrollPasskeyCreate': 'Create passkey',
|
|
269
286
|
'mfa.enrollScan': 'Scan this QR code with your authenticator app, or enter the setup key.',
|
|
270
287
|
'mfa.enrollQrAlt': 'QR code for your authenticator app',
|
|
271
288
|
'mfa.enrollSetupKey': 'Setup key',
|
|
@@ -364,6 +381,7 @@ const EN_US = {
|
|
|
364
381
|
'error.form_password_reused': 'Your new password must not match any of your last {history_count} passwords.',
|
|
365
382
|
'error.password_expired': 'Your password has expired. Reset it to continue.',
|
|
366
383
|
'error.email_not_verified': 'Your email address is not verified yet. Verify it before signing in with your password.',
|
|
384
|
+
'error.mfa_setup_unavailable': "This account needs 2-Step Verification, but it can't be set up here. Contact the app's support to continue.",
|
|
367
385
|
'error.sign_in_token_invalid': 'That sign-in token is invalid or has expired.',
|
|
368
386
|
'error.too_many_attempts': 'Too many failed attempts. Try again later.',
|
|
369
387
|
'error.too_many_requests': 'Too many requests. Please try again later.',
|
|
@@ -403,7 +421,7 @@ function withFallback(locale) {
|
|
|
403
421
|
}
|
|
404
422
|
|
|
405
423
|
/** This package's version, sent as `X-Atlas-SDK` (kept in step with package.json by a test). */
|
|
406
|
-
const ATLAS_ANGULAR_VERSION = '0.
|
|
424
|
+
const ATLAS_ANGULAR_VERSION = '0.16.0';
|
|
407
425
|
const ATLAS_ANGULAR_SDK = { name: '@atlasauth/angular', version: ATLAS_ANGULAR_VERSION };
|
|
408
426
|
|
|
409
427
|
/**
|
|
@@ -1536,6 +1554,8 @@ class AttemptFlowComponent {
|
|
|
1536
1554
|
* while the flow polls, and offers a resend (`resend`).
|
|
1537
1555
|
*/
|
|
1538
1556
|
emailVerification = 'code';
|
|
1557
|
+
/** `FlowState.matchCode`: shown while a mailed link waits, to type if it's opened on another device. */
|
|
1558
|
+
matchCode = null;
|
|
1539
1559
|
resend = new EventEmitter();
|
|
1540
1560
|
/** The user declined a policy the sign-in was waiting on (`needs_policy_acceptance`): cancel the attempt. */
|
|
1541
1561
|
policyDeclined = new EventEmitter();
|
|
@@ -1583,6 +1603,12 @@ class AttemptFlowComponent {
|
|
|
1583
1603
|
resendEnrollment() {
|
|
1584
1604
|
void this.enrollment?.resend();
|
|
1585
1605
|
}
|
|
1606
|
+
optionKey(method) {
|
|
1607
|
+
return enrollmentOptionKey(method);
|
|
1608
|
+
}
|
|
1609
|
+
showMatchCode() {
|
|
1610
|
+
return !!this.matchCode && (this.step().kind === 'collect_email_code' || this.linkSentText() !== null);
|
|
1611
|
+
}
|
|
1586
1612
|
otherMethods(state) {
|
|
1587
1613
|
return state.options.filter((m) => m !== state.method);
|
|
1588
1614
|
}
|
|
@@ -1730,7 +1756,7 @@ class AttemptFlowComponent {
|
|
|
1730
1756
|
}
|
|
1731
1757
|
}
|
|
1732
1758
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AttemptFlowComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1733
|
-
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", captcha: "captcha", firstFactors: "firstFactors", preparedFactor: "preparedFactor", passwordHold: "passwordHold", holdProof: "holdProof", offerEmailSecondFactor: "offerEmailSecondFactor", emailedSecondFactor: "emailedSecondFactor", offerSmsSecondFactor: "offerSmsSecondFactor", textedSecondFactor: "textedSecondFactor", enrollment: "enrollment", enrollmentState: "enrollmentState", emailVerification: "emailVerification" }, outputs: { submitFlow: "submitFlow", chooseFactor: "chooseFactor", usePassword: "usePassword", emailSecondFactor: "emailSecondFactor", smsSecondFactor: "smsSecondFactor", resend: "resend", policyDeclined: "policyDeclined" }, ngImport: i0, template: `
|
|
1759
|
+
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", 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: `
|
|
1734
1760
|
<div [class]="cls('card', 'atlas-card')">
|
|
1735
1761
|
<h1 [class]="cls('headerTitle', 'atlas-title')">{{ t(titleKey) }}</h1>
|
|
1736
1762
|
|
|
@@ -1760,6 +1786,9 @@ class AttemptFlowComponent {
|
|
|
1760
1786
|
{{ t('signIn.resendLink') }}
|
|
1761
1787
|
</button>
|
|
1762
1788
|
}
|
|
1789
|
+
@if (showMatchCode()) {
|
|
1790
|
+
<p class="atlas-text" data-atlas="link-match-code">{{ t('link.matchCodeHint') }} <strong><code>{{ matchCode }}</code></strong></p>
|
|
1791
|
+
}
|
|
1763
1792
|
@if (enrolling() && enrollmentState; as enrol) {
|
|
1764
1793
|
@if (enrol.method === null) {
|
|
1765
1794
|
<p class="atlas-text">{{ t('mfa.enrollChoose') }}</p>
|
|
@@ -1771,10 +1800,31 @@ class AttemptFlowComponent {
|
|
|
1771
1800
|
[disabled]="busy || enrol.busy"
|
|
1772
1801
|
(click)="chooseMethod(m)"
|
|
1773
1802
|
>
|
|
1774
|
-
{{ t(m
|
|
1803
|
+
{{ t(optionKey(m)) }}
|
|
1775
1804
|
</button>
|
|
1776
1805
|
}
|
|
1777
|
-
} @else if (enrol.method === '
|
|
1806
|
+
} @else if (enrol.method === 'yubikey') {
|
|
1807
|
+
<label class="atlas-field">
|
|
1808
|
+
<span>{{ t('mfa.yubikeyLabel') }}</span>
|
|
1809
|
+
<input [class]="cls('formFieldInput', 'atlas-input')" type="text" name="otp" autocomplete="off" [value]="values['otp'] ?? ''" (input)="setValue('otp', $any($event.target).value)" />
|
|
1810
|
+
@for (error of fieldErrorsFor('otp'); track error.code) {
|
|
1811
|
+
<span [class]="cls('formFieldError', 'atlas-error')">{{ errorText(error) }}</span>
|
|
1812
|
+
}
|
|
1813
|
+
</label>
|
|
1814
|
+
} @else if (enrol.method === 'duo' || enrol.method === 'passkey') {
|
|
1815
|
+
@if (enrol.enrollment; as setup) {
|
|
1816
|
+
@if (enrol.method === 'passkey') {
|
|
1817
|
+
<p class="atlas-text">{{ t('mfa.enrollPasskeyHelp') }}</p>
|
|
1818
|
+
} @else {
|
|
1819
|
+
<p class="atlas-text">{{ t('mfa.enrollDuoHelp') }}</p>
|
|
1820
|
+
@if (setup.authorizationUrl) {
|
|
1821
|
+
<a class="atlas-link" data-atlas="mfa-duo-open" [href]="setup.authorizationUrl" target="_blank" rel="noopener noreferrer">{{ t('mfa.enrollDuoOpen') }}</a>
|
|
1822
|
+
}
|
|
1823
|
+
}
|
|
1824
|
+
} @else {
|
|
1825
|
+
<p class="atlas-text" aria-live="polite">{{ enrol.busy ? t('mfa.enrollPreparing') : '' }}</p>
|
|
1826
|
+
}
|
|
1827
|
+
} @else if (enrol.method === 'totp' || enrol.method === 'hotp') {
|
|
1778
1828
|
@if (enrol.enrollment; as setup) {
|
|
1779
1829
|
<p class="atlas-text">{{ t('mfa.enrollScan') }}</p>
|
|
1780
1830
|
@if (setup.qrCode) {
|
|
@@ -1787,7 +1837,7 @@ class AttemptFlowComponent {
|
|
|
1787
1837
|
<span>{{ t('mfa.enrollFirstCodeLabel') }}</span>
|
|
1788
1838
|
<input [class]="cls('formFieldInput', 'atlas-input')" type="text" name="code" autocomplete="one-time-code" inputmode="numeric" [value]="values['code'] ?? ''" (input)="setValue('code', $any($event.target).value)" />
|
|
1789
1839
|
</label>
|
|
1790
|
-
@if (enrol.totpCodes >= 2) {
|
|
1840
|
+
@if (enrol.method === 'totp' && enrol.totpCodes >= 2) {
|
|
1791
1841
|
<label class="atlas-field">
|
|
1792
1842
|
<span>{{ t('mfa.enrollSecondCodeLabel') }}</span>
|
|
1793
1843
|
<input [class]="cls('formFieldInput', 'atlas-input')" type="text" name="secondCode" autocomplete="one-time-code" inputmode="numeric" [value]="values['secondCode'] ?? ''" (input)="setValue('secondCode', $any($event.target).value)" />
|
|
@@ -1832,7 +1882,7 @@ class AttemptFlowComponent {
|
|
|
1832
1882
|
[disabled]="busy || enrol.busy"
|
|
1833
1883
|
(click)="chooseMethod(other)"
|
|
1834
1884
|
>
|
|
1835
|
-
{{ t(other
|
|
1885
|
+
{{ t(optionKey(other)) }}
|
|
1836
1886
|
</button>
|
|
1837
1887
|
}
|
|
1838
1888
|
}
|
|
@@ -2002,6 +2052,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
2002
2052
|
{{ t('signIn.resendLink') }}
|
|
2003
2053
|
</button>
|
|
2004
2054
|
}
|
|
2055
|
+
@if (showMatchCode()) {
|
|
2056
|
+
<p class="atlas-text" data-atlas="link-match-code">{{ t('link.matchCodeHint') }} <strong><code>{{ matchCode }}</code></strong></p>
|
|
2057
|
+
}
|
|
2005
2058
|
@if (enrolling() && enrollmentState; as enrol) {
|
|
2006
2059
|
@if (enrol.method === null) {
|
|
2007
2060
|
<p class="atlas-text">{{ t('mfa.enrollChoose') }}</p>
|
|
@@ -2013,10 +2066,31 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
2013
2066
|
[disabled]="busy || enrol.busy"
|
|
2014
2067
|
(click)="chooseMethod(m)"
|
|
2015
2068
|
>
|
|
2016
|
-
{{ t(m
|
|
2069
|
+
{{ t(optionKey(m)) }}
|
|
2017
2070
|
</button>
|
|
2018
2071
|
}
|
|
2019
|
-
} @else if (enrol.method === '
|
|
2072
|
+
} @else if (enrol.method === 'yubikey') {
|
|
2073
|
+
<label class="atlas-field">
|
|
2074
|
+
<span>{{ t('mfa.yubikeyLabel') }}</span>
|
|
2075
|
+
<input [class]="cls('formFieldInput', 'atlas-input')" type="text" name="otp" autocomplete="off" [value]="values['otp'] ?? ''" (input)="setValue('otp', $any($event.target).value)" />
|
|
2076
|
+
@for (error of fieldErrorsFor('otp'); track error.code) {
|
|
2077
|
+
<span [class]="cls('formFieldError', 'atlas-error')">{{ errorText(error) }}</span>
|
|
2078
|
+
}
|
|
2079
|
+
</label>
|
|
2080
|
+
} @else if (enrol.method === 'duo' || enrol.method === 'passkey') {
|
|
2081
|
+
@if (enrol.enrollment; as setup) {
|
|
2082
|
+
@if (enrol.method === 'passkey') {
|
|
2083
|
+
<p class="atlas-text">{{ t('mfa.enrollPasskeyHelp') }}</p>
|
|
2084
|
+
} @else {
|
|
2085
|
+
<p class="atlas-text">{{ t('mfa.enrollDuoHelp') }}</p>
|
|
2086
|
+
@if (setup.authorizationUrl) {
|
|
2087
|
+
<a class="atlas-link" data-atlas="mfa-duo-open" [href]="setup.authorizationUrl" target="_blank" rel="noopener noreferrer">{{ t('mfa.enrollDuoOpen') }}</a>
|
|
2088
|
+
}
|
|
2089
|
+
}
|
|
2090
|
+
} @else {
|
|
2091
|
+
<p class="atlas-text" aria-live="polite">{{ enrol.busy ? t('mfa.enrollPreparing') : '' }}</p>
|
|
2092
|
+
}
|
|
2093
|
+
} @else if (enrol.method === 'totp' || enrol.method === 'hotp') {
|
|
2020
2094
|
@if (enrol.enrollment; as setup) {
|
|
2021
2095
|
<p class="atlas-text">{{ t('mfa.enrollScan') }}</p>
|
|
2022
2096
|
@if (setup.qrCode) {
|
|
@@ -2029,7 +2103,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
2029
2103
|
<span>{{ t('mfa.enrollFirstCodeLabel') }}</span>
|
|
2030
2104
|
<input [class]="cls('formFieldInput', 'atlas-input')" type="text" name="code" autocomplete="one-time-code" inputmode="numeric" [value]="values['code'] ?? ''" (input)="setValue('code', $any($event.target).value)" />
|
|
2031
2105
|
</label>
|
|
2032
|
-
@if (enrol.totpCodes >= 2) {
|
|
2106
|
+
@if (enrol.method === 'totp' && enrol.totpCodes >= 2) {
|
|
2033
2107
|
<label class="atlas-field">
|
|
2034
2108
|
<span>{{ t('mfa.enrollSecondCodeLabel') }}</span>
|
|
2035
2109
|
<input [class]="cls('formFieldInput', 'atlas-input')" type="text" name="secondCode" autocomplete="one-time-code" inputmode="numeric" [value]="values['secondCode'] ?? ''" (input)="setValue('secondCode', $any($event.target).value)" />
|
|
@@ -2074,7 +2148,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
2074
2148
|
[disabled]="busy || enrol.busy"
|
|
2075
2149
|
(click)="chooseMethod(other)"
|
|
2076
2150
|
>
|
|
2077
|
-
{{ t(other
|
|
2151
|
+
{{ t(optionKey(other)) }}
|
|
2078
2152
|
</button>
|
|
2079
2153
|
}
|
|
2080
2154
|
}
|
|
@@ -2251,6 +2325,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
2251
2325
|
type: Input
|
|
2252
2326
|
}], emailVerification: [{
|
|
2253
2327
|
type: Input
|
|
2328
|
+
}], matchCode: [{
|
|
2329
|
+
type: Input
|
|
2254
2330
|
}], resend: [{
|
|
2255
2331
|
type: Output
|
|
2256
2332
|
}], policyDeclined: [{
|
|
@@ -2264,6 +2340,103 @@ function released() {
|
|
|
2264
2340
|
return { kind: 'released', name: '', labelKey: 'signIn.passwordHoldReleased', type: 'text' };
|
|
2265
2341
|
}
|
|
2266
2342
|
|
|
2343
|
+
/**
|
|
2344
|
+
* What `<atlas-sign-in>` / `<atlas-sign-up>` draw when opened from a mailed link:
|
|
2345
|
+
* tries this browser's stored secret, then asks for the code the starting tab
|
|
2346
|
+
* shows. A success signs nobody in here: the starting tab continues on its own.
|
|
2347
|
+
*/
|
|
2348
|
+
class EmailLinkComponent {
|
|
2349
|
+
atlas = inject(AtlasService);
|
|
2350
|
+
link;
|
|
2351
|
+
state = signal({ status: 'checking', busy: false, errors: [] });
|
|
2352
|
+
code = '';
|
|
2353
|
+
controller = null;
|
|
2354
|
+
stop = null;
|
|
2355
|
+
ngOnInit() {
|
|
2356
|
+
this.controller = createEmailLinkConfirmation(this.atlas.createFapiClient(), this.link);
|
|
2357
|
+
this.stop = this.controller.subscribe((next) => this.state.set(next));
|
|
2358
|
+
void this.controller.start();
|
|
2359
|
+
}
|
|
2360
|
+
ngOnDestroy() {
|
|
2361
|
+
this.stop?.();
|
|
2362
|
+
}
|
|
2363
|
+
onSubmit(event) {
|
|
2364
|
+
event.preventDefault();
|
|
2365
|
+
void this.controller?.submitCode(this.code);
|
|
2366
|
+
}
|
|
2367
|
+
message() {
|
|
2368
|
+
const status = this.state().status;
|
|
2369
|
+
return status === 'confirmed' ? 'link.confirmed' : status === 'invalid' ? 'link.invalid' : 'link.checking';
|
|
2370
|
+
}
|
|
2371
|
+
t(key) {
|
|
2372
|
+
return translate(this.atlas.localization, key);
|
|
2373
|
+
}
|
|
2374
|
+
cls(key, base) {
|
|
2375
|
+
return classFor(key, this.atlas.appearance, base);
|
|
2376
|
+
}
|
|
2377
|
+
errorText(error) {
|
|
2378
|
+
return localizedErrorMessage(error, this.atlas.localization);
|
|
2379
|
+
}
|
|
2380
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: EmailLinkComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2381
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: EmailLinkComponent, isStandalone: true, selector: "atlas-email-link", inputs: { link: "link" }, ngImport: i0, template: `
|
|
2382
|
+
<div [class]="cls('card', 'atlas-card')" data-atlas="email-link" [attr.data-atlas-status]="state().status">
|
|
2383
|
+
<h1 [class]="cls('headerTitle', 'atlas-title')">{{ t('link.title') }}</h1>
|
|
2384
|
+
@if (state().status === 'needs_code') {
|
|
2385
|
+
<form (submit)="onSubmit($event)">
|
|
2386
|
+
<p class="atlas-text">{{ t('link.enterCodeHelp') }}</p>
|
|
2387
|
+
<label class="atlas-field">
|
|
2388
|
+
<span>{{ t('link.codeLabel') }}</span>
|
|
2389
|
+
<input [class]="cls('formFieldInput', 'atlas-input')" type="text" name="match_code" autocomplete="off" inputmode="numeric" required [value]="code" (input)="code = $any($event.target).value" />
|
|
2390
|
+
</label>
|
|
2391
|
+
@for (error of state().errors; track error.code) {
|
|
2392
|
+
<p [class]="cls('formFieldError', 'atlas-error')" role="alert">{{ errorText(error) }}</p>
|
|
2393
|
+
}
|
|
2394
|
+
<button [class]="cls('formButtonPrimary', 'atlas-button')" type="submit" [disabled]="state().busy">{{ t('link.confirm') }}</button>
|
|
2395
|
+
</form>
|
|
2396
|
+
} @else {
|
|
2397
|
+
<p class="atlas-text" role="status" aria-live="polite">{{ t(message()) }}</p>
|
|
2398
|
+
}
|
|
2399
|
+
@if (state().resetUrl; as resetUrl) {
|
|
2400
|
+
<p class="atlas-text"><a class="atlas-link" data-atlas-reset-link="" [href]="resetUrl">{{ t('signIn.forgotPassword') }}</a></p>
|
|
2401
|
+
}
|
|
2402
|
+
</div>
|
|
2403
|
+
`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2404
|
+
}
|
|
2405
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: EmailLinkComponent, decorators: [{
|
|
2406
|
+
type: Component,
|
|
2407
|
+
args: [{
|
|
2408
|
+
selector: 'atlas-email-link',
|
|
2409
|
+
standalone: true,
|
|
2410
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
2411
|
+
template: `
|
|
2412
|
+
<div [class]="cls('card', 'atlas-card')" data-atlas="email-link" [attr.data-atlas-status]="state().status">
|
|
2413
|
+
<h1 [class]="cls('headerTitle', 'atlas-title')">{{ t('link.title') }}</h1>
|
|
2414
|
+
@if (state().status === 'needs_code') {
|
|
2415
|
+
<form (submit)="onSubmit($event)">
|
|
2416
|
+
<p class="atlas-text">{{ t('link.enterCodeHelp') }}</p>
|
|
2417
|
+
<label class="atlas-field">
|
|
2418
|
+
<span>{{ t('link.codeLabel') }}</span>
|
|
2419
|
+
<input [class]="cls('formFieldInput', 'atlas-input')" type="text" name="match_code" autocomplete="off" inputmode="numeric" required [value]="code" (input)="code = $any($event.target).value" />
|
|
2420
|
+
</label>
|
|
2421
|
+
@for (error of state().errors; track error.code) {
|
|
2422
|
+
<p [class]="cls('formFieldError', 'atlas-error')" role="alert">{{ errorText(error) }}</p>
|
|
2423
|
+
}
|
|
2424
|
+
<button [class]="cls('formButtonPrimary', 'atlas-button')" type="submit" [disabled]="state().busy">{{ t('link.confirm') }}</button>
|
|
2425
|
+
</form>
|
|
2426
|
+
} @else {
|
|
2427
|
+
<p class="atlas-text" role="status" aria-live="polite">{{ t(message()) }}</p>
|
|
2428
|
+
}
|
|
2429
|
+
@if (state().resetUrl; as resetUrl) {
|
|
2430
|
+
<p class="atlas-text"><a class="atlas-link" data-atlas-reset-link="" [href]="resetUrl">{{ t('signIn.forgotPassword') }}</a></p>
|
|
2431
|
+
}
|
|
2432
|
+
</div>
|
|
2433
|
+
`,
|
|
2434
|
+
}]
|
|
2435
|
+
}], propDecorators: { link: [{
|
|
2436
|
+
type: Input,
|
|
2437
|
+
args: [{ required: true }]
|
|
2438
|
+
}] } });
|
|
2439
|
+
|
|
2267
2440
|
/**
|
|
2268
2441
|
* The recovery codes a mid-sign-in MFA enrolment came with, shown once before
|
|
2269
2442
|
* the sign-in finishes: copy them, download them as a .txt file, then
|
|
@@ -2801,8 +2974,11 @@ class AtlasFlowController {
|
|
|
2801
2974
|
return;
|
|
2802
2975
|
this.pollTimer = setInterval(() => {
|
|
2803
2976
|
void (async () => {
|
|
2804
|
-
const
|
|
2805
|
-
this.
|
|
2977
|
+
const polled = this.state();
|
|
2978
|
+
const { state: next, ticket } = await pollAttempt(this.client, polled);
|
|
2979
|
+
// A resend rotated the secret meanwhile: this answer is stale.
|
|
2980
|
+
if (this.state().pollSecret === polled.pollSecret)
|
|
2981
|
+
this.setState(next);
|
|
2806
2982
|
// e.g. a passkey sign-up whose email was just proven: only this tab can go on.
|
|
2807
2983
|
if (!ticket && !shouldKeepPolling(next))
|
|
2808
2984
|
this.stopPolling();
|
|
@@ -2847,6 +3023,11 @@ class AtlasFlowController {
|
|
|
2847
3023
|
*/
|
|
2848
3024
|
class SignInComponent {
|
|
2849
3025
|
atlas = inject(AtlasService);
|
|
3026
|
+
/** Opened from a mailed link: that page, not the flow. Read after the first render, so hydration matches. */
|
|
3027
|
+
emailLink = signal(null);
|
|
3028
|
+
constructor() {
|
|
3029
|
+
afterNextRender(() => this.emailLink.set(emailLinkFromUrl(undefined, 'sign_in')));
|
|
3030
|
+
}
|
|
2850
3031
|
/** Where to send the user once the flow completes. Reserved for host routing. */
|
|
2851
3032
|
afterUrl;
|
|
2852
3033
|
/**
|
|
@@ -2912,6 +3093,9 @@ class SignInComponent {
|
|
|
2912
3093
|
}
|
|
2913
3094
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: SignInComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2914
3095
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: SignInComponent, isStandalone: true, selector: "atlas-sign-in", inputs: { afterUrl: "afterUrl", signUpUrl: "signUpUrl" }, ngImport: i0, template: `
|
|
3096
|
+
@if (emailLink(); as link) {
|
|
3097
|
+
<atlas-email-link [link]="link"></atlas-email-link>
|
|
3098
|
+
} @else {
|
|
2915
3099
|
@if (lastUsedLabel(); as label) {
|
|
2916
3100
|
<p class="atlas-text atlas-last-used-hint" data-atlas="last-used" [attr.data-atlas-method]="flow.lastMethod()">
|
|
2917
3101
|
{{ t('signIn.lastUsed') }}: {{ label }}
|
|
@@ -2937,6 +3121,7 @@ class SignInComponent {
|
|
|
2937
3121
|
[captcha]="flow.captchaDrawn() ? flow.captcha : null"
|
|
2938
3122
|
[firstFactors]="flow.firstFactors()"
|
|
2939
3123
|
[preparedFactor]="flow.preparedFactor()"
|
|
3124
|
+
[matchCode]="flow.state().matchCode ?? null"
|
|
2940
3125
|
[passwordHold]="flow.state().passwordHold ?? null"
|
|
2941
3126
|
[holdProof]="flow.holdProof()"
|
|
2942
3127
|
(usePassword)="flow.usePassword()"
|
|
@@ -2969,7 +3154,8 @@ class SignInComponent {
|
|
|
2969
3154
|
{{ t('signIn.noAccount') }} <a class="atlas-link" [href]="href">{{ t('signIn.signUpLink') }}</a>
|
|
2970
3155
|
</p>
|
|
2971
3156
|
}
|
|
2972
|
-
|
|
3157
|
+
}
|
|
3158
|
+
`, 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", "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 });
|
|
2973
3159
|
}
|
|
2974
3160
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: SignInComponent, decorators: [{
|
|
2975
3161
|
type: Component,
|
|
@@ -2977,8 +3163,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
2977
3163
|
selector: 'atlas-sign-in',
|
|
2978
3164
|
standalone: true,
|
|
2979
3165
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
2980
|
-
imports: [AttemptFlowComponent, RecoveryCodesComponent],
|
|
3166
|
+
imports: [EmailLinkComponent, AttemptFlowComponent, RecoveryCodesComponent],
|
|
2981
3167
|
template: `
|
|
3168
|
+
@if (emailLink(); as link) {
|
|
3169
|
+
<atlas-email-link [link]="link"></atlas-email-link>
|
|
3170
|
+
} @else {
|
|
2982
3171
|
@if (lastUsedLabel(); as label) {
|
|
2983
3172
|
<p class="atlas-text atlas-last-used-hint" data-atlas="last-used" [attr.data-atlas-method]="flow.lastMethod()">
|
|
2984
3173
|
{{ t('signIn.lastUsed') }}: {{ label }}
|
|
@@ -3004,6 +3193,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
3004
3193
|
[captcha]="flow.captchaDrawn() ? flow.captcha : null"
|
|
3005
3194
|
[firstFactors]="flow.firstFactors()"
|
|
3006
3195
|
[preparedFactor]="flow.preparedFactor()"
|
|
3196
|
+
[matchCode]="flow.state().matchCode ?? null"
|
|
3007
3197
|
[passwordHold]="flow.state().passwordHold ?? null"
|
|
3008
3198
|
[holdProof]="flow.holdProof()"
|
|
3009
3199
|
(usePassword)="flow.usePassword()"
|
|
@@ -3036,9 +3226,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
3036
3226
|
{{ t('signIn.noAccount') }} <a class="atlas-link" [href]="href">{{ t('signIn.signUpLink') }}</a>
|
|
3037
3227
|
</p>
|
|
3038
3228
|
}
|
|
3229
|
+
}
|
|
3039
3230
|
`,
|
|
3040
3231
|
}]
|
|
3041
|
-
}], propDecorators: { afterUrl: [{
|
|
3232
|
+
}], ctorParameters: () => [], propDecorators: { afterUrl: [{
|
|
3042
3233
|
type: Input
|
|
3043
3234
|
}], signUpUrl: [{
|
|
3044
3235
|
type: Input
|
|
@@ -3615,6 +3806,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
3615
3806
|
*/
|
|
3616
3807
|
class SignUpComponent {
|
|
3617
3808
|
atlas = inject(AtlasService);
|
|
3809
|
+
/** Opened from a mailed link: that page, not the flow. Read after the first render, so hydration matches. */
|
|
3810
|
+
emailLink = signal(null);
|
|
3811
|
+
constructor() {
|
|
3812
|
+
afterNextRender(() => this.emailLink.set(emailLinkFromUrl(undefined, 'sign_up')));
|
|
3813
|
+
}
|
|
3618
3814
|
/** Where to send the user once the flow completes. Reserved for host routing. */
|
|
3619
3815
|
afterUrl;
|
|
3620
3816
|
/** Where the existing-account notice's "Forgot password?" goes. Default: the hosted sign-in page; `null` hides it. */
|
|
@@ -3670,6 +3866,9 @@ class SignUpComponent {
|
|
|
3670
3866
|
}
|
|
3671
3867
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: SignUpComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3672
3868
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: SignUpComponent, isStandalone: true, selector: "atlas-sign-up", inputs: { afterUrl: "afterUrl", resetPasswordUrl: "resetPasswordUrl", signInUrl: "signInUrl" }, ngImport: i0, template: `
|
|
3869
|
+
@if (emailLink(); as link) {
|
|
3870
|
+
<atlas-email-link [link]="link"></atlas-email-link>
|
|
3871
|
+
} @else {
|
|
3673
3872
|
@if (flow.recoveryCodes(); as codes) {
|
|
3674
3873
|
<atlas-recovery-codes [codes]="codes" [busy]="flow.state().busy" (saved)="flow.saveRecoveryCodes()"></atlas-recovery-codes>
|
|
3675
3874
|
} @else if (flow.existingAccountNotice()) {
|
|
@@ -3722,6 +3921,7 @@ class SignUpComponent {
|
|
|
3722
3921
|
[emailVerification]="flow.settings()?.account?.emailVerification ?? 'code'"
|
|
3723
3922
|
(submitFlow)="flow.submit($event)"
|
|
3724
3923
|
(resend)="flow.resendSignUp()"
|
|
3924
|
+
[matchCode]="flow.state().matchCode ?? null"
|
|
3725
3925
|
[offerEmailSecondFactor]="flow.settings()?.account?.emailSecondFactor === true"
|
|
3726
3926
|
[emailedSecondFactor]="flow.emailSecondFactor()"
|
|
3727
3927
|
[offerSmsSecondFactor]="flow.settings() !== null && flow.mfaChoices().sms"
|
|
@@ -3747,7 +3947,8 @@ class SignUpComponent {
|
|
|
3747
3947
|
"
|
|
3748
3948
|
></atlas-sign-up-form>
|
|
3749
3949
|
}
|
|
3750
|
-
|
|
3950
|
+
}
|
|
3951
|
+
`, 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", "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 });
|
|
3751
3952
|
}
|
|
3752
3953
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: SignUpComponent, decorators: [{
|
|
3753
3954
|
type: Component,
|
|
@@ -3755,8 +3956,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
3755
3956
|
selector: 'atlas-sign-up',
|
|
3756
3957
|
standalone: true,
|
|
3757
3958
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
3758
|
-
imports: [AttemptFlowComponent, RecoveryCodesComponent, SignUpFormComponent],
|
|
3959
|
+
imports: [EmailLinkComponent, AttemptFlowComponent, RecoveryCodesComponent, SignUpFormComponent],
|
|
3759
3960
|
template: `
|
|
3961
|
+
@if (emailLink(); as link) {
|
|
3962
|
+
<atlas-email-link [link]="link"></atlas-email-link>
|
|
3963
|
+
} @else {
|
|
3760
3964
|
@if (flow.recoveryCodes(); as codes) {
|
|
3761
3965
|
<atlas-recovery-codes [codes]="codes" [busy]="flow.state().busy" (saved)="flow.saveRecoveryCodes()"></atlas-recovery-codes>
|
|
3762
3966
|
} @else if (flow.existingAccountNotice()) {
|
|
@@ -3809,6 +4013,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
3809
4013
|
[emailVerification]="flow.settings()?.account?.emailVerification ?? 'code'"
|
|
3810
4014
|
(submitFlow)="flow.submit($event)"
|
|
3811
4015
|
(resend)="flow.resendSignUp()"
|
|
4016
|
+
[matchCode]="flow.state().matchCode ?? null"
|
|
3812
4017
|
[offerEmailSecondFactor]="flow.settings()?.account?.emailSecondFactor === true"
|
|
3813
4018
|
[emailedSecondFactor]="flow.emailSecondFactor()"
|
|
3814
4019
|
[offerSmsSecondFactor]="flow.settings() !== null && flow.mfaChoices().sms"
|
|
@@ -3834,9 +4039,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
3834
4039
|
"
|
|
3835
4040
|
></atlas-sign-up-form>
|
|
3836
4041
|
}
|
|
4042
|
+
}
|
|
3837
4043
|
`,
|
|
3838
4044
|
}]
|
|
3839
|
-
}], propDecorators: { afterUrl: [{
|
|
4045
|
+
}], ctorParameters: () => [], propDecorators: { afterUrl: [{
|
|
3840
4046
|
type: Input
|
|
3841
4047
|
}], resetPasswordUrl: [{
|
|
3842
4048
|
type: Input
|
|
@@ -5298,5 +5504,5 @@ function atlasChildGuard(options = {}) {
|
|
|
5298
5504
|
* Generated bundle index. Do not edit.
|
|
5299
5505
|
*/
|
|
5300
5506
|
|
|
5301
|
-
export { ATLAS_ANGULAR_SDK, ATLAS_ANGULAR_VERSION, ATLAS_OPTIONS, ATLAS_UI, AtlasCaptchaSlotDirective, AtlasFlowController, AtlasLoadedDirective, AtlasLoadingDirective, AtlasModule, AtlasOrganizationAuditLog, AtlasPoliciesDirective, AtlasProtectDirective, AtlasRootDirective, AtlasService, AtlasSignedInDirective, AtlasSignedOutDirective, AttemptFlowComponent, DEFAULT_TOKENS, EN_US, ImpersonationBannerComponent, ManageCibaComponent, OrganizationAuditLogComponent, OrganizationProfileComponent, OrganizationSwitcherComponent, PolicyAcceptStepComponent, PolicyGateComponent, SignInComponent, SignUpComponent, SignUpFormComponent, THEMES, UserButtonComponent, UserProfileComponent, atlasChildGuard, atlasGuard, classFor, cssVariables, explicitTokens, provideAtlas, renderAppearance, resolveTokens, translate, withFallback };
|
|
5507
|
+
export { ATLAS_ANGULAR_SDK, ATLAS_ANGULAR_VERSION, ATLAS_OPTIONS, ATLAS_UI, AtlasCaptchaSlotDirective, AtlasFlowController, AtlasLoadedDirective, AtlasLoadingDirective, AtlasModule, AtlasOrganizationAuditLog, AtlasPoliciesDirective, AtlasProtectDirective, AtlasRootDirective, AtlasService, AtlasSignedInDirective, AtlasSignedOutDirective, AttemptFlowComponent, DEFAULT_TOKENS, EN_US, EmailLinkComponent, ImpersonationBannerComponent, ManageCibaComponent, OrganizationAuditLogComponent, OrganizationProfileComponent, OrganizationSwitcherComponent, PolicyAcceptStepComponent, PolicyGateComponent, SignInComponent, SignUpComponent, SignUpFormComponent, THEMES, UserButtonComponent, UserProfileComponent, atlasChildGuard, atlasGuard, classFor, cssVariables, explicitTokens, provideAtlas, renderAppearance, resolveTokens, translate, withFallback };
|
|
5302
5508
|
//# sourceMappingURL=atlasauth-angular.mjs.map
|