@atlasauth/angular 0.6.1 → 0.8.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 +15 -0
- package/dist/esm2022/lib/atlas.config.mjs +1 -1
- package/dist/esm2022/lib/atlas.service.mjs +10 -4
- package/dist/esm2022/lib/components/attempt-flow.component.mjs +16 -2
- package/dist/esm2022/lib/components/flow-controller.mjs +13 -6
- package/dist/esm2022/lib/components/sign-in.component.mjs +43 -3
- package/dist/esm2022/lib/components/sign-up.component.mjs +4 -2
- package/dist/esm2022/lib/i18n.mjs +3 -1
- package/dist/esm2022/lib/version.mjs +2 -2
- package/dist/fesm2022/atlasauth-angular.mjs +83 -13
- package/dist/fesm2022/atlasauth-angular.mjs.map +1 -1
- package/dist/lib/atlas.config.d.ts +13 -1
- package/dist/lib/atlas.service.d.ts +2 -1
- package/dist/lib/components/attempt-flow.component.d.ts +4 -2
- package/dist/lib/components/flow-controller.d.ts +1 -1
- package/dist/lib/components/sign-in.component.d.ts +9 -1
- 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 { TokenCache, SignOutNotifier, resolveFrontendApi, catalogLocale, FapiClient, SignOutGuard, localizedErrorMessage, getTemplateToken, getProviderToken, signOutReasonFromClient, readRedirectResult, completeOAuthPopupLanding, mapOAuthPopupPayload, stripRedirectParams, closeOAuthPopupAfterSignIn, SDK_HEADER, sdkHeaderValue, reportSdkAdvisory, readExpiry, msUntilRefresh, nextStep, createCaptchaController, atlasCaptchaLabels, flowFromPending, initialFlow, fetchInstanceSettings, offeredFirstFactors, prepareFactor, signInCaptchaOptions, flowNeedsCaptcha, planFirstFactor, advanceWithCaptcha, createSignUp, shouldKeepPolling, pollAttempt } from '@atlasauth/js';
|
|
7
|
+
import { TokenCache, SignOutNotifier, resolveFrontendApi, withDevBrowser, catalogLocale, configureReferralCapture, FapiClient, SignOutGuard, localizedErrorMessage, getTemplateToken, getProviderToken, signOutReasonFromClient, readRedirectResult, completeOAuthPopupLanding, mapOAuthPopupPayload, stripRedirectParams, closeOAuthPopupAfterSignIn, SDK_HEADER, sdkHeaderValue, reportSdkAdvisory, readExpiry, msUntilRefresh, nextStep, createCaptchaController, atlasCaptchaLabels, flowFromPending, initialFlow, fetchInstanceSettings, offeredFirstFactors, prepareFactor, signInCaptchaOptions, flowNeedsCaptcha, planFirstFactor, advanceWithCaptcha, createSignUp, shouldKeepPolling, pollAttempt, signUp } 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';
|
|
@@ -171,6 +171,8 @@ const EN_US = {
|
|
|
171
171
|
'signIn.codeSentTo': 'We sent a code to {email}. Enter it below.',
|
|
172
172
|
'signIn.resendCode': 'Resend code',
|
|
173
173
|
'signIn.magicLinkSent': 'Check your email for a sign-in link.',
|
|
174
|
+
'signIn.signedIn': 'You\'re signed in.',
|
|
175
|
+
'signIn.sessionNotKept': 'You signed in, but this browser didn\'t keep the session. If it blocks third-party cookies, allow cookies for this site and try again.',
|
|
174
176
|
'signIn.checkOtherTab': 'You can close this tab — you are signed in where you started.',
|
|
175
177
|
'signUp.title': 'Create your account',
|
|
176
178
|
'signUp.submit': 'Continue',
|
|
@@ -291,7 +293,7 @@ function withFallback(locale) {
|
|
|
291
293
|
}
|
|
292
294
|
|
|
293
295
|
/** This package's version, sent as `X-Atlas-SDK` (kept in step with package.json by a test). */
|
|
294
|
-
const ATLAS_ANGULAR_VERSION = '0.
|
|
296
|
+
const ATLAS_ANGULAR_VERSION = '0.8.0';
|
|
295
297
|
const ATLAS_ANGULAR_SDK = { name: '@atlasauth/angular', version: ATLAS_ANGULAR_VERSION };
|
|
296
298
|
|
|
297
299
|
/**
|
|
@@ -398,10 +400,13 @@ class AtlasService {
|
|
|
398
400
|
this.baseUrl = resolveFrontendApi(options.frontendApi, {
|
|
399
401
|
component: 'provideAtlas() / AtlasModule.forRoot()',
|
|
400
402
|
});
|
|
401
|
-
|
|
403
|
+
// Development instances keep the session in a header where the browser blocks the cookie.
|
|
404
|
+
this.doFetch = withDevBrowser(options.publishableKey, options.fetchImpl ?? ((...args) => fetch(...args)));
|
|
402
405
|
this.catalog = options.localization ? withFallback(options.localization) : EN_US;
|
|
403
406
|
this.errorCatalog = options.localization ?? EN_US;
|
|
404
407
|
this.requestLocale = catalogLocale(options.localization);
|
|
408
|
+
// Referral attribution: app-wide options every FAPI client on the page falls back to.
|
|
409
|
+
configureReferralCapture({ referral: options.referral, referralConsent: options.referralConsent });
|
|
405
410
|
this.fapiClient = new FapiClient({
|
|
406
411
|
publishableKey: this.publishableKey,
|
|
407
412
|
baseUrl: this.baseUrl,
|
|
@@ -589,6 +594,7 @@ class AtlasService {
|
|
|
589
594
|
await this.reload();
|
|
590
595
|
}
|
|
591
596
|
/** Re-read `/v1/client`: refresh user, session, memberships and status. */
|
|
597
|
+
/** Re-boot from the Frontend API. Resolves true when a session now exists in this browser. */
|
|
592
598
|
async reload() {
|
|
593
599
|
try {
|
|
594
600
|
const response = await this.call('/v1/client');
|
|
@@ -599,7 +605,7 @@ class AtlasService {
|
|
|
599
605
|
// refresh cookie; the guard re-tries its revoke in the background.
|
|
600
606
|
if (!body.session || !body.user || this.guard.refuse(body.session.id)) {
|
|
601
607
|
this.clearLocalState(body.session ? 'other_tab' : signOutReasonFromClient(body));
|
|
602
|
-
return;
|
|
608
|
+
return false;
|
|
603
609
|
}
|
|
604
610
|
this.notifier.clear();
|
|
605
611
|
this._user.next(body.user);
|
|
@@ -609,6 +615,7 @@ class AtlasService {
|
|
|
609
615
|
this.applyToken(body.jwt, body.session.id);
|
|
610
616
|
this._status.next('signed_in');
|
|
611
617
|
this.scheduleRefresh();
|
|
618
|
+
return true;
|
|
612
619
|
}
|
|
613
620
|
catch {
|
|
614
621
|
// A failed boot is NOT signed-out. Rendering a sign-in form because the
|
|
@@ -616,6 +623,7 @@ class AtlasService {
|
|
|
616
623
|
// needless re-authentication. Only promote loading → signed_out.
|
|
617
624
|
if (this._status.value === 'loading')
|
|
618
625
|
this._status.next('signed_out');
|
|
626
|
+
return false;
|
|
619
627
|
}
|
|
620
628
|
}
|
|
621
629
|
// --- Internals --------------------------------------------------------------
|
|
@@ -1076,6 +1084,8 @@ class AttemptFlowComponent {
|
|
|
1076
1084
|
attempt = null;
|
|
1077
1085
|
busy = false;
|
|
1078
1086
|
errors = [];
|
|
1087
|
+
/** `FlowState.sessionKept`: whether this browser kept the session the sign-in created. */
|
|
1088
|
+
sessionKept = undefined;
|
|
1079
1089
|
titleKey = 'signIn.title';
|
|
1080
1090
|
/**
|
|
1081
1091
|
* The sign-in captcha, drawn above the submit button on the identifier step
|
|
@@ -1190,6 +1200,12 @@ class AttemptFlowComponent {
|
|
|
1190
1200
|
case 'await_oauth':
|
|
1191
1201
|
return [msg('signIn.magicLinkSent')];
|
|
1192
1202
|
case 'done':
|
|
1203
|
+
// Signed in only when this browser holds the session; a blocked cookie is said
|
|
1204
|
+
// plainly. "Check the other tab" is for a sign-in completed on another device.
|
|
1205
|
+
if (this.sessionKept === true)
|
|
1206
|
+
return [msg('signIn.signedIn')];
|
|
1207
|
+
if (this.sessionKept === false)
|
|
1208
|
+
return [{ kind: 'alert', name: '', labelKey: 'signIn.sessionNotKept', type: 'text' }];
|
|
1193
1209
|
return [msg('signIn.checkOtherTab')];
|
|
1194
1210
|
case 'restart':
|
|
1195
1211
|
return [msg('error.generic')];
|
|
@@ -1200,7 +1216,7 @@ class AttemptFlowComponent {
|
|
|
1200
1216
|
}
|
|
1201
1217
|
}
|
|
1202
1218
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AttemptFlowComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1203
|
-
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", titleKey: "titleKey", captcha: "captcha", firstFactors: "firstFactors", preparedFactor: "preparedFactor" }, outputs: { submitFlow: "submitFlow", chooseFactor: "chooseFactor" }, ngImport: i0, template: `
|
|
1219
|
+
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" }, outputs: { submitFlow: "submitFlow", chooseFactor: "chooseFactor" }, ngImport: i0, template: `
|
|
1204
1220
|
<div [class]="cls('card', 'atlas-card')">
|
|
1205
1221
|
<h1 [class]="cls('headerTitle', 'atlas-title')">{{ t(titleKey) }}</h1>
|
|
1206
1222
|
|
|
@@ -1227,6 +1243,8 @@ class AttemptFlowComponent {
|
|
|
1227
1243
|
<span [class]="cls('formFieldError', 'atlas-error')">{{ errorText(error) }}</span>
|
|
1228
1244
|
}
|
|
1229
1245
|
</label>
|
|
1246
|
+
} @else if (f.kind === 'alert') {
|
|
1247
|
+
<p [class]="cls('formFieldError', 'atlas-error')" role="alert">{{ t(f.labelKey) }}</p>
|
|
1230
1248
|
} @else {
|
|
1231
1249
|
<p>{{ t(f.labelKey) }}</p>
|
|
1232
1250
|
}
|
|
@@ -1292,6 +1310,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
1292
1310
|
<span [class]="cls('formFieldError', 'atlas-error')">{{ errorText(error) }}</span>
|
|
1293
1311
|
}
|
|
1294
1312
|
</label>
|
|
1313
|
+
} @else if (f.kind === 'alert') {
|
|
1314
|
+
<p [class]="cls('formFieldError', 'atlas-error')" role="alert">{{ t(f.labelKey) }}</p>
|
|
1295
1315
|
} @else {
|
|
1296
1316
|
<p>{{ t(f.labelKey) }}</p>
|
|
1297
1317
|
}
|
|
@@ -1329,6 +1349,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
1329
1349
|
type: Input
|
|
1330
1350
|
}], errors: [{
|
|
1331
1351
|
type: Input
|
|
1352
|
+
}], sessionKept: [{
|
|
1353
|
+
type: Input
|
|
1332
1354
|
}], titleKey: [{
|
|
1333
1355
|
type: Input
|
|
1334
1356
|
}], captcha: [{
|
|
@@ -1518,17 +1540,23 @@ class AtlasFlowController {
|
|
|
1518
1540
|
await this.finish(next);
|
|
1519
1541
|
}
|
|
1520
1542
|
async finish(next) {
|
|
1521
|
-
this.setState(next);
|
|
1522
1543
|
if (next.attempt?.status === 'complete') {
|
|
1544
|
+
// Stays busy until this browser actually holds the session: the completion
|
|
1545
|
+
// alone says nothing about whether the cookie was kept.
|
|
1546
|
+
this.setState({ ...next, busy: true });
|
|
1547
|
+
let exchanged = true;
|
|
1523
1548
|
if (next.ticket) {
|
|
1524
|
-
await this.client.post('/v1/client/tickets/exchange', {
|
|
1549
|
+
const res = await this.client.post('/v1/client/tickets/exchange', {
|
|
1525
1550
|
attempt_id: next.attempt.id,
|
|
1526
1551
|
ticket: next.ticket,
|
|
1527
1552
|
});
|
|
1553
|
+
exchanged = res.ok;
|
|
1528
1554
|
}
|
|
1529
|
-
await this.reload();
|
|
1555
|
+
const kept = exchanged && (await this.reload());
|
|
1556
|
+
this.setState({ ...next, busy: false, sessionKept: kept });
|
|
1530
1557
|
}
|
|
1531
1558
|
else {
|
|
1559
|
+
this.setState(next);
|
|
1532
1560
|
// A magic-link step may now be pollable (a link opened on another device).
|
|
1533
1561
|
this.syncPolling();
|
|
1534
1562
|
}
|
|
@@ -1553,11 +1581,12 @@ class AtlasFlowController {
|
|
|
1553
1581
|
return;
|
|
1554
1582
|
// The ticket is exchanged by a normal request, so no session token ever
|
|
1555
1583
|
// appears in a URL.
|
|
1556
|
-
await this.client.post('/v1/client/tickets/exchange', {
|
|
1584
|
+
const res = await this.client.post('/v1/client/tickets/exchange', {
|
|
1557
1585
|
attempt_id: next.attempt.id,
|
|
1558
1586
|
ticket,
|
|
1559
1587
|
});
|
|
1560
|
-
await this.reload();
|
|
1588
|
+
const kept = res.ok && (await this.reload());
|
|
1589
|
+
this.setState({ ...this.state(), sessionKept: kept });
|
|
1561
1590
|
this.stopPolling();
|
|
1562
1591
|
})();
|
|
1563
1592
|
}, 2_000);
|
|
@@ -1590,6 +1619,31 @@ class SignInComponent {
|
|
|
1590
1619
|
atlas = inject(AtlasService);
|
|
1591
1620
|
/** Where to send the user once the flow completes. Reserved for host routing. */
|
|
1592
1621
|
afterUrl;
|
|
1622
|
+
/**
|
|
1623
|
+
* Where "No account? Sign up" goes. Default: the instance's hosted sign-up
|
|
1624
|
+
* page (carrying the visitor's referral). `null` hides it. Always shown, never
|
|
1625
|
+
* only after a failed sign-in, so it says nothing about whether an email has an account.
|
|
1626
|
+
*/
|
|
1627
|
+
signUpUrl;
|
|
1628
|
+
t(key) {
|
|
1629
|
+
return translate(this.atlas.localization, key);
|
|
1630
|
+
}
|
|
1631
|
+
signUpHref() {
|
|
1632
|
+
if (this.signUpUrl === null)
|
|
1633
|
+
return null;
|
|
1634
|
+
if (this.signUpUrl)
|
|
1635
|
+
return this.signUpUrl;
|
|
1636
|
+
try {
|
|
1637
|
+
return signUp({
|
|
1638
|
+
frontendApi: this.atlas.frontendApi,
|
|
1639
|
+
redirectUrl: this.afterUrl ?? (typeof window !== 'undefined' ? window.location.href : undefined),
|
|
1640
|
+
navigate: false,
|
|
1641
|
+
});
|
|
1642
|
+
}
|
|
1643
|
+
catch {
|
|
1644
|
+
return null;
|
|
1645
|
+
}
|
|
1646
|
+
}
|
|
1593
1647
|
flow = new AtlasFlowController(this.atlas.createFapiClient(), () => this.atlas.reload(),
|
|
1594
1648
|
// Resume mid-flow if an OAuth redirect came back owing a second factor.
|
|
1595
1649
|
this.atlas.pendingAttempt, (key) => translate(this.atlas.localization, key));
|
|
@@ -1606,11 +1660,12 @@ class SignInComponent {
|
|
|
1606
1660
|
this.flow.destroy();
|
|
1607
1661
|
}
|
|
1608
1662
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: SignInComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1609
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
1663
|
+
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: `
|
|
1610
1664
|
<atlas-attempt-flow
|
|
1611
1665
|
[attempt]="flow.state().attempt"
|
|
1612
1666
|
[busy]="flow.state().busy"
|
|
1613
1667
|
[errors]="flow.state().errors"
|
|
1668
|
+
[sessionKept]="flow.state().sessionKept"
|
|
1614
1669
|
titleKey="signIn.title"
|
|
1615
1670
|
[captcha]="flow.captchaDrawn() ? flow.captcha : null"
|
|
1616
1671
|
[firstFactors]="flow.firstFactors()"
|
|
@@ -1618,7 +1673,12 @@ class SignInComponent {
|
|
|
1618
1673
|
(submitFlow)="flow.submit($event)"
|
|
1619
1674
|
(chooseFactor)="flow.prepare($event)"
|
|
1620
1675
|
></atlas-attempt-flow>
|
|
1621
|
-
|
|
1676
|
+
@if (flow.state().attempt?.status !== 'complete' && signUpHref(); as href) {
|
|
1677
|
+
<p class="atlas-footer" data-atlas-sign-up-prompt="">
|
|
1678
|
+
{{ t('signIn.noAccount') }} <a class="atlas-link" [href]="href">{{ t('signIn.signUpLink') }}</a>
|
|
1679
|
+
</p>
|
|
1680
|
+
}
|
|
1681
|
+
`, isInline: true, dependencies: [{ kind: "component", type: AttemptFlowComponent, selector: "atlas-attempt-flow", inputs: ["attempt", "busy", "errors", "sessionKept", "titleKey", "captcha", "firstFactors", "preparedFactor"], outputs: ["submitFlow", "chooseFactor"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1622
1682
|
}
|
|
1623
1683
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: SignInComponent, decorators: [{
|
|
1624
1684
|
type: Component,
|
|
@@ -1632,6 +1692,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
1632
1692
|
[attempt]="flow.state().attempt"
|
|
1633
1693
|
[busy]="flow.state().busy"
|
|
1634
1694
|
[errors]="flow.state().errors"
|
|
1695
|
+
[sessionKept]="flow.state().sessionKept"
|
|
1635
1696
|
titleKey="signIn.title"
|
|
1636
1697
|
[captcha]="flow.captchaDrawn() ? flow.captcha : null"
|
|
1637
1698
|
[firstFactors]="flow.firstFactors()"
|
|
@@ -1639,10 +1700,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
1639
1700
|
(submitFlow)="flow.submit($event)"
|
|
1640
1701
|
(chooseFactor)="flow.prepare($event)"
|
|
1641
1702
|
></atlas-attempt-flow>
|
|
1703
|
+
@if (flow.state().attempt?.status !== 'complete' && signUpHref(); as href) {
|
|
1704
|
+
<p class="atlas-footer" data-atlas-sign-up-prompt="">
|
|
1705
|
+
{{ t('signIn.noAccount') }} <a class="atlas-link" [href]="href">{{ t('signIn.signUpLink') }}</a>
|
|
1706
|
+
</p>
|
|
1707
|
+
}
|
|
1642
1708
|
`,
|
|
1643
1709
|
}]
|
|
1644
1710
|
}], propDecorators: { afterUrl: [{
|
|
1645
1711
|
type: Input
|
|
1712
|
+
}], signUpUrl: [{
|
|
1713
|
+
type: Input
|
|
1646
1714
|
}] } });
|
|
1647
1715
|
|
|
1648
1716
|
/**
|
|
@@ -2109,6 +2177,7 @@ class SignUpComponent {
|
|
|
2109
2177
|
[attempt]="flow.state().attempt"
|
|
2110
2178
|
[busy]="flow.state().busy"
|
|
2111
2179
|
[errors]="flow.state().errors"
|
|
2180
|
+
[sessionKept]="flow.state().sessionKept"
|
|
2112
2181
|
titleKey="signUp.title"
|
|
2113
2182
|
(submitFlow)="flow.submit($event)"
|
|
2114
2183
|
></atlas-attempt-flow>
|
|
@@ -2121,7 +2190,7 @@ class SignUpComponent {
|
|
|
2121
2190
|
(submitSignUp)="flow.create($event.values, $event.consent)"
|
|
2122
2191
|
></atlas-sign-up-form>
|
|
2123
2192
|
}
|
|
2124
|
-
`, isInline: true, dependencies: [{ kind: "component", type: AttemptFlowComponent, selector: "atlas-attempt-flow", inputs: ["attempt", "busy", "errors", "titleKey", "captcha", "firstFactors", "preparedFactor"], outputs: ["submitFlow", "chooseFactor"] }, { kind: "component", type: SignUpFormComponent, selector: "atlas-sign-up-form", inputs: ["settings", "busy", "errors", "captcha"], outputs: ["submitSignUp"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2193
|
+
`, isInline: true, dependencies: [{ kind: "component", type: AttemptFlowComponent, selector: "atlas-attempt-flow", inputs: ["attempt", "busy", "errors", "sessionKept", "titleKey", "captcha", "firstFactors", "preparedFactor"], outputs: ["submitFlow", "chooseFactor"] }, { kind: "component", type: SignUpFormComponent, selector: "atlas-sign-up-form", inputs: ["settings", "busy", "errors", "captcha"], outputs: ["submitSignUp"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2125
2194
|
}
|
|
2126
2195
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: SignUpComponent, decorators: [{
|
|
2127
2196
|
type: Component,
|
|
@@ -2136,6 +2205,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
2136
2205
|
[attempt]="flow.state().attempt"
|
|
2137
2206
|
[busy]="flow.state().busy"
|
|
2138
2207
|
[errors]="flow.state().errors"
|
|
2208
|
+
[sessionKept]="flow.state().sessionKept"
|
|
2139
2209
|
titleKey="signUp.title"
|
|
2140
2210
|
(submitFlow)="flow.submit($event)"
|
|
2141
2211
|
></atlas-attempt-flow>
|