@atlasauth/angular 0.8.0 → 0.10.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.
Files changed (41) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/dist/esm2022/lib/appearance.mjs +1 -1
  3. package/dist/esm2022/lib/atlas.service.mjs +40 -3
  4. package/dist/esm2022/lib/atlas.ui.mjs +7 -1
  5. package/dist/esm2022/lib/components/attempt-flow.component.mjs +419 -11
  6. package/dist/esm2022/lib/components/flow-controller.mjs +132 -2
  7. package/dist/esm2022/lib/components/impersonation-banner.component.mjs +75 -0
  8. package/dist/esm2022/lib/components/organization-audit-log.component.mjs +115 -0
  9. package/dist/esm2022/lib/components/organization-audit-log.mjs +40 -0
  10. package/dist/esm2022/lib/components/organization-profile.component.mjs +602 -27
  11. package/dist/esm2022/lib/components/policy-host.mjs +254 -0
  12. package/dist/esm2022/lib/components/recovery-codes.component.mjs +122 -0
  13. package/dist/esm2022/lib/components/sign-in.component.mjs +47 -4
  14. package/dist/esm2022/lib/components/sign-up-form.component.mjs +136 -10
  15. package/dist/esm2022/lib/components/sign-up.component.mjs +86 -8
  16. package/dist/esm2022/lib/i18n.mjs +61 -1
  17. package/dist/esm2022/lib/provide-atlas.mjs +4 -2
  18. package/dist/esm2022/lib/types.mjs +1 -1
  19. package/dist/esm2022/lib/version.mjs +2 -2
  20. package/dist/esm2022/public-api.mjs +6 -1
  21. package/dist/fesm2022/atlasauth-angular.mjs +2129 -95
  22. package/dist/fesm2022/atlasauth-angular.mjs.map +1 -1
  23. package/dist/lib/appearance.d.ts +1 -1
  24. package/dist/lib/atlas.service.d.ts +23 -1
  25. package/dist/lib/atlas.ui.d.ts +3 -1
  26. package/dist/lib/components/attempt-flow.component.d.ts +61 -2
  27. package/dist/lib/components/flow-controller.d.ts +73 -1
  28. package/dist/lib/components/impersonation-banner.component.d.ts +27 -0
  29. package/dist/lib/components/organization-audit-log.component.d.ts +34 -0
  30. package/dist/lib/components/organization-audit-log.d.ts +25 -0
  31. package/dist/lib/components/organization-profile.component.d.ts +55 -6
  32. package/dist/lib/components/policy-host.d.ts +88 -0
  33. package/dist/lib/components/recovery-codes.component.d.ts +26 -0
  34. package/dist/lib/components/sign-in.component.d.ts +2 -0
  35. package/dist/lib/components/sign-up-form.component.d.ts +22 -4
  36. package/dist/lib/components/sign-up.component.d.ts +13 -0
  37. package/dist/lib/provide-atlas.d.ts +3 -1
  38. package/dist/lib/types.d.ts +6 -0
  39. package/dist/lib/version.d.ts +1 -1
  40. package/dist/public-api.d.ts +5 -0
  41. package/package.json +3 -3
@@ -0,0 +1,254 @@
1
+ import { ChangeDetectionStrategy, Component, Directive, ElementRef, EventEmitter, Input, Output, inject, signal, } from '@angular/core';
2
+ import { PolicyGateController, controllerForPending, formatPolicyDate, injectPolicyStyles, joinTitles, mountPolicyAcceptStep, mountPolicyClickwrap, mountPolicyConsent, policyTranslator, } from '@atlasauth/js';
3
+ import { AtlasService } from '../atlas.service';
4
+ import { classFor } from '../appearance';
5
+ import { translate } from '../i18n';
6
+ import * as i0 from "@angular/core";
7
+ /** The policy UI's translator (the localization bundle, else the English policy strings) for the current Atlas service. */
8
+ export function policyUi(atlas) {
9
+ return {
10
+ t: policyTranslator((key, vars) => translate(atlas.localization, key, vars)),
11
+ classes: {
12
+ link: 'atlas-link',
13
+ text: 'atlas-text',
14
+ primaryButton: classFor('formButtonPrimary', atlas.appearance, 'atlas-button'),
15
+ error: classFor('formFieldError', atlas.appearance, 'atlas-error'),
16
+ },
17
+ };
18
+ }
19
+ /**
20
+ * `[atlasPolicies]="controller"` — draws the instance's policies (terms, privacy,
21
+ * …) into the host element: `kind="consent"` (default) is the checkbox block with
22
+ * its in-page viewer, `kind="clickwrap"` the "By continuing you agree to …" line.
23
+ * The state is the controller's (`AtlasFlowController.policies`); the DOM comes
24
+ * from `@atlasauth/js`, shared with every SDK.
25
+ */
26
+ export class AtlasPoliciesDirective {
27
+ host = inject(ElementRef);
28
+ atlas = inject(AtlasService);
29
+ mounted = null;
30
+ ready = false;
31
+ controller = null;
32
+ atlasPolicyKind = 'consent';
33
+ ngOnInit() {
34
+ this.ready = true;
35
+ this.draw();
36
+ }
37
+ ngOnChanges(changes) {
38
+ if (this.ready && (changes['controller'] || changes['atlasPolicyKind']))
39
+ this.draw();
40
+ }
41
+ ngOnDestroy() {
42
+ this.mounted?.destroy();
43
+ }
44
+ draw() {
45
+ this.mounted?.destroy();
46
+ this.mounted = null;
47
+ if (!this.controller)
48
+ return;
49
+ const el = this.host.nativeElement;
50
+ injectPolicyStyles(el.ownerDocument);
51
+ const ui = policyUi(this.atlas);
52
+ this.mounted =
53
+ this.atlasPolicyKind === 'clickwrap'
54
+ ? mountPolicyClickwrap(el, this.controller, ui)
55
+ : mountPolicyConsent(el, this.controller, ui);
56
+ }
57
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AtlasPoliciesDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
58
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: AtlasPoliciesDirective, isStandalone: true, selector: "[atlasPolicies]", inputs: { controller: ["atlasPolicies", "controller"], atlasPolicyKind: "atlasPolicyKind" }, usesOnChanges: true, ngImport: i0 });
59
+ }
60
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AtlasPoliciesDirective, decorators: [{
61
+ type: Directive,
62
+ args: [{ selector: '[atlasPolicies]', standalone: true }]
63
+ }], propDecorators: { controller: [{
64
+ type: Input,
65
+ args: ['atlasPolicies']
66
+ }], atlasPolicyKind: [{
67
+ type: Input
68
+ }] } });
69
+ /**
70
+ * `<atlas-policy-accept-step>` — the sign-in step for a `needs_policy_acceptance`
71
+ * attempt: scroll-mode policies in their unskippable dialog, the rest as
72
+ * checkboxes, then "Accept and continue". Emits `submitFlow` with the
73
+ * `policy_acceptances` JSON for the flow, and `declined` with the policy title
74
+ * when the user declines (cancel the attempt).
75
+ */
76
+ export class PolicyAcceptStepComponent {
77
+ host = inject(ElementRef);
78
+ atlas = inject(AtlasService);
79
+ step = null;
80
+ alive = true;
81
+ attempt = null;
82
+ busy = false;
83
+ submitFlow = new EventEmitter();
84
+ declined = new EventEmitter();
85
+ loading = signal(true);
86
+ loadingText = policyUi(this.atlas).t('policy.loading');
87
+ ngOnInit() {
88
+ const client = this.atlas.createFapiClient();
89
+ void controllerForPending(client, this.attempt, { locale: this.atlas.locale ?? undefined }).then((controller) => {
90
+ if (!this.alive)
91
+ return;
92
+ this.loading.set(false);
93
+ const el = this.host.nativeElement.querySelector('.atlas-policy-step-host');
94
+ if (!el)
95
+ return;
96
+ injectPolicyStyles(el.ownerDocument);
97
+ this.step = mountPolicyAcceptStep(el, controller, {
98
+ ...policyUi(this.atlas),
99
+ onSubmit: (acceptances) => this.submitFlow.emit({ policy_acceptances: JSON.stringify(acceptances) }),
100
+ onDecline: (policy) => this.declined.emit(policy.title),
101
+ });
102
+ this.step.setBusy(this.busy);
103
+ });
104
+ }
105
+ ngOnChanges(changes) {
106
+ if (changes['busy'])
107
+ this.step?.setBusy(this.busy);
108
+ }
109
+ ngOnDestroy() {
110
+ this.alive = false;
111
+ this.step?.destroy();
112
+ }
113
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: PolicyAcceptStepComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
114
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: PolicyAcceptStepComponent, isStandalone: true, selector: "atlas-policy-accept-step", inputs: { attempt: "attempt", busy: "busy" }, outputs: { submitFlow: "submitFlow", declined: "declined" }, usesOnChanges: true, ngImport: i0, template: `@if (loading()) {<p class="atlas-text">{{ loadingText }}</p>}<div class="atlas-policy-step-host"></div>`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
115
+ }
116
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: PolicyAcceptStepComponent, decorators: [{
117
+ type: Component,
118
+ args: [{
119
+ selector: 'atlas-policy-accept-step',
120
+ standalone: true,
121
+ changeDetection: ChangeDetectionStrategy.OnPush,
122
+ template: `@if (loading()) {<p class="atlas-text">{{ loadingText }}</p>}<div class="atlas-policy-step-host"></div>`,
123
+ }]
124
+ }], propDecorators: { attempt: [{
125
+ type: Input
126
+ }], busy: [{
127
+ type: Input
128
+ }], submitFlow: [{
129
+ type: Output
130
+ }], declined: [{
131
+ type: Output
132
+ }] } });
133
+ /**
134
+ * `<atlas-policy-gate>` — in-app re-acceptance. For a signed-in user, a banner
135
+ * when a policy needs re-acceptance; "Review and accept" opens the unskippable
136
+ * dialog / checkboxes and posts `/v1/client/me/policies/accept`. Projects its
137
+ * content always.
138
+ */
139
+ export class PolicyGateComponent {
140
+ host = inject(ElementRef);
141
+ atlas = inject(AtlasService);
142
+ ui = policyUi(this.atlas);
143
+ gate;
144
+ off = null;
145
+ step = null;
146
+ version = signal(0);
147
+ accepted = new EventEmitter();
148
+ reviewing = signal(false);
149
+ error = signal('');
150
+ title = this.ui.t('policy.bannerTitle');
151
+ reviewText = this.ui.t('policy.bannerReview');
152
+ linkClass = this.ui.classes.link ?? '';
153
+ errorClass = this.ui.classes.error ?? '';
154
+ bannerClass = 'atlas-policy-banner';
155
+ cardClass = classFor('card', this.atlas.appearance, 'atlas-card');
156
+ bannerText() {
157
+ this.version();
158
+ if (!this.gate || this.gate.pending.length === 0 || this.reviewing())
159
+ return null;
160
+ const t = this.ui.t;
161
+ const grace = this.gate.graceEndsAt;
162
+ return (t('policy.bannerBody', { policies: joinTitles(this.gate.pending.map((p) => p.title), t('policy.and')) }) +
163
+ (grace ? ` ${t('policy.bannerGrace', { date: formatPolicyDate(grace) })}` : ''));
164
+ }
165
+ ngOnInit() {
166
+ this.gate = new PolicyGateController(this.atlas.createFapiClient(), this.atlas.locale ?? undefined);
167
+ this.off = this.gate.subscribe(() => this.version.update((n) => n + 1));
168
+ if (this.atlas.status() === 'signed_in')
169
+ void this.gate.load();
170
+ }
171
+ async begin() {
172
+ const controller = await this.gate.begin();
173
+ this.reviewing.set(true);
174
+ await Promise.resolve();
175
+ const el = this.host.nativeElement.querySelector('.atlas-policy-gate-host');
176
+ if (!el)
177
+ return;
178
+ injectPolicyStyles(el.ownerDocument);
179
+ this.step = mountPolicyAcceptStep(el, controller, {
180
+ ...this.ui,
181
+ onSubmit: async () => {
182
+ this.step?.setBusy(true);
183
+ const res = await this.gate.accept(controller);
184
+ this.step?.setBusy(false);
185
+ if (!res.ok) {
186
+ this.error.set(res.errors[0]?.message ?? this.ui.t('policy.requiredGeneric'));
187
+ return;
188
+ }
189
+ this.close();
190
+ this.accepted.emit();
191
+ },
192
+ onDecline: () => this.close(),
193
+ });
194
+ }
195
+ close() {
196
+ this.step?.destroy();
197
+ this.step = null;
198
+ this.reviewing.set(false);
199
+ }
200
+ ngOnDestroy() {
201
+ this.off?.();
202
+ this.step?.destroy();
203
+ }
204
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: PolicyGateComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
205
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: PolicyGateComponent, isStandalone: true, selector: "atlas-policy-gate", outputs: { accepted: "accepted" }, ngImport: i0, template: `
206
+ @if (bannerText(); as text) {
207
+ <div [class]="bannerClass" role="status" data-atlas-policy-banner="">
208
+ <span
209
+ ><strong>{{ title }}. </strong>{{ text }}</span
210
+ >
211
+ <button type="button" [class]="linkClass" (click)="begin()">{{ reviewText }}</button>
212
+ </div>
213
+ }
214
+ @if (reviewing()) {
215
+ <div [class]="cardClass" data-atlas-policy-gate="">
216
+ <div class="atlas-policy-gate-host"></div>
217
+ @if (error()) {
218
+ <p [class]="errorClass" role="alert">{{ error() }}</p>
219
+ }
220
+ </div>
221
+ }
222
+ <ng-content></ng-content>
223
+ `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
224
+ }
225
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: PolicyGateComponent, decorators: [{
226
+ type: Component,
227
+ args: [{
228
+ selector: 'atlas-policy-gate',
229
+ standalone: true,
230
+ changeDetection: ChangeDetectionStrategy.OnPush,
231
+ template: `
232
+ @if (bannerText(); as text) {
233
+ <div [class]="bannerClass" role="status" data-atlas-policy-banner="">
234
+ <span
235
+ ><strong>{{ title }}. </strong>{{ text }}</span
236
+ >
237
+ <button type="button" [class]="linkClass" (click)="begin()">{{ reviewText }}</button>
238
+ </div>
239
+ }
240
+ @if (reviewing()) {
241
+ <div [class]="cardClass" data-atlas-policy-gate="">
242
+ <div class="atlas-policy-gate-host"></div>
243
+ @if (error()) {
244
+ <p [class]="errorClass" role="alert">{{ error() }}</p>
245
+ }
246
+ </div>
247
+ }
248
+ <ng-content></ng-content>
249
+ `,
250
+ }]
251
+ }], propDecorators: { accepted: [{
252
+ type: Output
253
+ }] } });
254
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicG9saWN5LWhvc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL2NvbXBvbmVudHMvcG9saWN5LWhvc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLHVCQUF1QixFQUN2QixTQUFTLEVBQ1QsU0FBUyxFQUNULFVBQVUsRUFDVixZQUFZLEVBQ1osS0FBSyxFQUlMLE1BQU0sRUFDTixNQUFNLEVBQ04sTUFBTSxHQUVQLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFDTCxvQkFBb0IsRUFDcEIsb0JBQW9CLEVBQ3BCLGdCQUFnQixFQUNoQixrQkFBa0IsRUFDbEIsVUFBVSxFQUNWLHFCQUFxQixFQUNyQixvQkFBb0IsRUFDcEIsa0JBQWtCLEVBQ2xCLGdCQUFnQixHQU9qQixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDaEQsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN6QyxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sU0FBUyxDQUFDOztBQUVwQywySEFBMkg7QUFDM0gsTUFBTSxVQUFVLFFBQVEsQ0FBQyxLQUFtQjtJQUMxQyxPQUFPO1FBQ0wsQ0FBQyxFQUFFLGdCQUFnQixDQUFDLENBQUMsR0FBRyxFQUFFLElBQUksRUFBRSxFQUFFLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxZQUFZLEVBQUUsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQzVFLE9BQU8sRUFBRTtZQUNQLElBQUksRUFBRSxZQUFZO1lBQ2xCLElBQUksRUFBRSxZQUFZO1lBQ2xCLGFBQWEsRUFBRSxRQUFRLENBQUMsbUJBQW1CLEVBQUUsS0FBSyxDQUFDLFVBQVUsRUFBRSxjQUFjLENBQUM7WUFDOUUsS0FBSyxFQUFFLFFBQVEsQ0FBQyxnQkFBZ0IsRUFBRSxLQUFLLENBQUMsVUFBVSxFQUFFLGFBQWEsQ0FBQztTQUNu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QUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsQ0FBQztvQkFDWixJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLE9BQU8sSUFBSSxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDLENBQUM7b0JBQzlFLE9BQU87Z0JBQ1QsQ0FBQztnQkFDRCxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7Z0JBQ2IsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUN2QixDQUFDO1lBQ0QsU0FBUyxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUU7U0FDOUIsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVPLEtBQUs7UUFDWCxJQUFJLENBQUMsSUFBSSxFQUFFLE9BQU8sRUFBRSxDQUFDO1FBQ3JCLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO1FBQ2pCLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzVCLENBQUM7SUFFRCxXQUFXO1FBQ1QsSUFBSSxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUM7UUFDYixJQUFJLENBQUMsSUFBSSxFQUFFLE9BQU8sRUFBRSxDQUFDO0lBQ3ZCLENBQUM7d0dBdEVVLG1CQUFtQjs0RkFBbkIsbUJBQW1CLGdIQXBCcEI7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQWtCVDs7NEZBRVUsbUJBQW1CO2tCQXhCL0IsU0FBUzttQkFBQztvQkFDVCxRQUFRLEVBQUUsbUJBQW1CO29CQUM3QixVQUFVLEVBQUUsSUFBSTtvQkFDaEIsZUFBZSxFQUFFLHVCQUF1QixDQUFDLE1BQU07b0JBQy9DLFFBQVEsRUFBRTs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBa0JUO2lCQUNGOzhCQVVXLFFBQVE7c0JBQWpCLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgQ29tcG9uZW50LFxuICBEaXJlY3RpdmUsXG4gIEVsZW1lbnRSZWYsXG4gIEV2ZW50RW1pdHRlcixcbiAgSW5wdXQsXG4gIE9uQ2hhbmdlcyxcbiAgT25EZXN0cm95LFxuICBPbkluaXQsXG4gIE91dHB1dCxcbiAgaW5qZWN0LFxuICBzaWduYWwsXG4gIHR5cGUgU2ltcGxlQ2hhbmdlcyxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge1xuICBQb2xpY3lHYXRlQ29udHJvbGxlcixcbiAgY29udHJvbGxlckZvclBlbmRpbmcsXG4gIGZvcm1hdFBvbGljeURhdGUsXG4gIGluamVjdFBvbGljeVN0eWxlcyxcbiAgam9pblRpdGxlcyxcbiAgbW91bnRQb2xpY3lBY2NlcHRTdGVwLFxuICBtb3VudFBvbGljeUNsaWNrd3JhcCxcbiAgbW91bnRQb2xpY3lDb25zZW50LFxuICBwb2xpY3lUcmFuc2xhdG9yLFxuICB0eXBlIE1vdW50ZWRQb2xpY3lTdGVwLFxuICB0eXBlIE1vdW50ZWRQb2xpY3lVaSxcbiAgdHlwZSBQb2xpY3ksXG4gIHR5cGUgUG9saWN5QWNjZXB0YW5jZUNvbnRyb2xsZXIsXG4gIHR5cGUgUG9saWN5Q2xhc3NlcyxcbiAgdHlwZSBQb2xpY3lULFxufSBmcm9tICdAYXRsYXNhdXRoL2pzJztcbmltcG9ydCB7IEF0bGFzU2VydmljZSB9IGZyb20gJy4uL2F0bGFzLnNlcnZpY2UnO1xuaW1wb3J0IHsgY2xhc3NGb3IgfSBmcm9tICcuLi9hcHBlYXJhbmNlJztcbmltcG9ydCB7IHRyYW5zbGF0ZSB9IGZyb20gJy4uL2kxOG4nO1xuXG4vKiogVGhlIHBvbGljeSBVSSdzIHRyYW5zbGF0b3IgKHRoZSBsb2NhbGl6YXRpb24gYnVuZGxlLCBlbHNlIHRoZSBFbmdsaXNoIHBvbGljeSBzdHJpbmdzKSBmb3IgdGhlIGN1cnJlbnQgQXRsYXMgc2VydmljZS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwb2xpY3lVaShhdGxhczogQXRsYXNTZXJ2aWNlKTogeyB0OiBQb2xpY3lUOyBjbGFzc2VzOiBQb2xpY3lDbGFzc2VzIH0ge1xuICByZXR1cm4ge1xuICAgIHQ6IHBvbGljeVRyYW5zbGF0b3IoKGtleSwgdmFycykgPT4gdHJhbnNsYXRlKGF0bGFzLmxvY2FsaXphdGlvbiwga2V5LCB2YXJzKSksXG4gICAgY2xhc3Nlczoge1xuICAgICAgbGluazogJ2F0bGFzLWxpbmsnLFxuICAgICAgdGV4dDogJ2F0bGFzLXRleHQnLFxuICAgICAgcHJpbWFyeUJ1dHRvbjogY2xhc3NGb3IoJ2Zvcm1CdXR0b25QcmltYXJ5JywgYXRsYXMuYXBwZWFyYW5jZSwgJ2F0bGFzLWJ1dHRvbicpLFxuICAgICAgZXJyb3I6IGNsYXNzRm9yKCdmb3JtRmllbGRFcnJvcicsIGF0bGFzLmFwcGVhcmFuY2UsICdhdGxhcy1lcnJvcicpLFxuICAgIH0sXG4gIH07XG59XG5cbi8qKlxuICogYFthdGxhc1BvbGljaWVzXT1cImNvbnRyb2xsZXJcImAg4oCUIGRyYXdzIHRoZSBpbnN0YW5jZSdzIHBvbGljaWVzICh0ZXJtcywgcHJpdmFjeSxcbiAqIOKApikgaW50byB0aGUgaG9zdCBlbGVtZW50OiBga2luZD1cImNvbnNlbnRcImAgKGRlZmF1bHQpIGlzIHRoZSBjaGVja2JveCBibG9jayB3aXRoXG4gKiBpdHMgaW4tcGFnZSB2aWV3ZXIsIGBraW5kPVwiY2xpY2t3cmFwXCJgIHRoZSBcIkJ5IGNvbnRpbnVpbmcgeW91IGFncmVlIHRvIOKAplwiIGxpbmUuXG4gKiBUaGUgc3RhdGUgaXMgdGhlIGNvbnRyb2xsZXIncyAoYEF0bGFzRmxvd0NvbnRyb2xsZXIucG9saWNpZXNgKTsgdGhlIERPTSBjb21lc1xuICogZnJvbSBgQGF0bGFzYXV0aC9qc2AsIHNoYXJlZCB3aXRoIGV2ZXJ5IFNESy5cbiAqL1xuQERpcmVjdGl2ZSh7IHNlbGVjdG9yOiAnW2F0bGFzUG9saWNpZXNdJywgc3RhbmRhbG9uZTogdHJ1ZSB9KVxuZXhwb3J0IGNsYXNzIEF0bGFzUG9saWNpZXNEaXJlY3RpdmUgaW1wbGVtZW50cyBPbkluaXQsIE9uQ2hhbmdlcywgT25EZXN0cm95IHtcbiAgcHJpdmF0ZSByZWFkb25seSBob3N0ID0gaW5qZWN0PEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+PihFbGVtZW50UmVmKTtcbiAgcHJpdmF0ZSByZWFkb25seSBhdGxhcyA9IGluamVjdChBdGxhc1NlcnZpY2UpO1xuICBwcml2YXRlIG1vdW50ZWQ6IE1vdW50ZWRQb2xpY3lVaSB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIHJlYWR5ID0gZmFsc2U7XG5cbiAgQElucHV0KCdhdGxhc1BvbGljaWVzJykgY29udHJvbGxlcjogUG9saWN5QWNjZXB0YW5jZUNvbnRyb2xsZXIgfCBudWxsID0gbnVsbDtcbiAgQElucHV0KCkgYXRsYXNQb2xpY3lLaW5kOiAnY29uc2VudCcgfCAnY2xpY2t3cmFwJyA9ICdjb25zZW50JztcblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLnJlYWR5ID0gdHJ1ZTtcbiAgICB0aGlzLmRyYXcoKTtcbiAgfVxuXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5yZWFkeSAmJiAoY2hhbmdlc1snY29udHJvbGxlciddIHx8IGNoYW5nZXNbJ2F0bGFzUG9saWN5S2luZCddKSkgdGhpcy5kcmF3KCk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLm1vdW50ZWQ/LmRlc3Ryb3koKTtcbiAgfVxuXG4gIHByaXZhdGUgZHJhdygpOiB2b2lkIHtcbiAgICB0aGlzLm1vdW50ZWQ/LmRlc3Ryb3koKTtcbiAgICB0aGlzLm1vdW50ZWQgPSBudWxsO1xuICAgIGlmICghdGhpcy5jb250cm9sbGVyKSByZXR1cm47XG4gICAgY29uc3QgZWwgPSB0aGlzLmhvc3QubmF0aXZlRWxlbWVudDtcbiAgICBpbmplY3RQb2xpY3lTdHlsZXMoZWwub3duZXJEb2N1bWVudCk7XG4gICAgY29uc3QgdWkgPSBwb2xpY3lVaSh0aGlzLmF0bGFzKTtcbiAgICB0aGlzLm1vdW50ZWQgPVxuICAgICAgdGhpcy5hdGxhc1BvbGljeUtpbmQgPT09ICdjbGlja3dyYXAnXG4gICAgICAgID8gbW91bnRQb2xpY3lDbGlja3dyYXAoZWwsIHRoaXMuY29udHJvbGxlciwgdWkpXG4gICAgICAgIDogbW91bnRQb2xpY3lDb25zZW50KGVsLCB0aGlzLmNvbnRyb2xsZXIsIHVpKTtcbiAgfVxufVxuXG4vKipcbiAqIGA8YXRsYXMtcG9saWN5LWFjY2VwdC1zdGVwPmAg4oCUIHRoZSBzaWduLWluIHN0ZXAgZm9yIGEgYG5lZWRzX3BvbGljeV9hY2NlcHRhbmNlYFxuICogYXR0ZW1wdDogc2Nyb2xsLW1vZGUgcG9saWNpZXMgaW4gdGhlaXIgdW5za2lwcGFibGUgZGlhbG9nLCB0aGUgcmVzdCBhc1xuICogY2hlY2tib3hlcywgdGhlbiBcIkFjY2VwdCBhbmQgY29udGludWVcIi4gRW1pdHMgYHN1Ym1pdEZsb3dgIHdpdGggdGhlXG4gKiBgcG9saWN5X2FjY2VwdGFuY2VzYCBKU09OIGZvciB0aGUgZmxvdywgYW5kIGBkZWNsaW5lZGAgd2l0aCB0aGUgcG9saWN5IHRpdGxlXG4gKiB3aGVuIHRoZSB1c2VyIGRlY2xpbmVzIChjYW5jZWwgdGhlIGF0dGVtcHQpLlxuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdhdGxhcy1wb2xpY3ktYWNjZXB0LXN0ZXAnLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgdGVtcGxhdGU6IGBAaWYgKGxvYWRpbmcoKSkgezxwIGNsYXNzPVwiYXRsYXMtdGV4dFwiPnt7IGxvYWRpbmdUZXh0IH19PC9wPn08ZGl2IGNsYXNzPVwiYXRsYXMtcG9saWN5LXN0ZXAtaG9zdFwiPjwvZGl2PmAsXG59KVxuZXhwb3J0IGNsYXNzIFBvbGljeUFjY2VwdFN0ZXBDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uQ2hhbmdlcywgT25EZXN0cm95IHtcbiAgcHJpdmF0ZSByZWFkb25seSBob3N0ID0gaW5qZWN0PEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+PihFbGVtZW50UmVmKTtcbiAgcHJpdmF0ZSByZWFkb25seSBhdGxhcyA9IGluamVjdChBdGxhc1NlcnZpY2UpO1xuICBwcml2YXRlIHN0ZXA6IE1vdW50ZWRQb2xpY3lTdGVwIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgYWxpdmUgPSB0cnVlO1xuXG4gIEBJbnB1dCgpIGF0dGVtcHQ6IHsgaWQ6IHN0cmluZyB8IG51bGw7IHBlbmRpbmdfcG9saWNpZXM/OiB1bmtub3duIH0gfCBudWxsID0gbnVsbDtcbiAgQElucHV0KCkgYnVzeSA9IGZhbHNlO1xuICBAT3V0cHV0KCkgc3VibWl0RmxvdyA9IG5ldyBFdmVudEVtaXR0ZXI8UmVjb3JkPHN0cmluZywgc3RyaW5nPj4oKTtcbiAgQE91dHB1dCgpIGRlY2xpbmVkID0gbmV3IEV2ZW50RW1pdHRlcjxzdHJpbmc+KCk7XG5cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGxvYWRpbmcgPSBzaWduYWwodHJ1ZSk7XG4gIHByb3RlY3RlZCBsb2FkaW5nVGV4dCA9IHBvbGljeVVpKHRoaXMuYXRsYXMpLnQoJ3BvbGljeS5sb2FkaW5nJyk7XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgY29uc3QgY2xpZW50ID0gdGhpcy5hdGxhcy5jcmVhdGVGYXBpQ2xpZW50KCk7XG4gICAgdm9pZCBjb250cm9sbGVyRm9yUGVuZGluZyhjbGllbnQsIHRoaXMuYXR0ZW1wdCwgeyBsb2NhbGU6IHRoaXMuYXRsYXMubG9jYWxlID8/IHVuZGVmaW5lZCB9KS50aGVuKChjb250cm9sbGVyKSA9PiB7XG4gICAgICBpZiAoIXRoaXMuYWxpdmUpIHJldHVybjtcbiAgICAgIHRoaXMubG9hZGluZy5zZXQoZmFsc2UpO1xuICAgICAgY29uc3QgZWwgPSB0aGlzLmhvc3QubmF0aXZlRWxlbWVudC5xdWVyeVNlbGVjdG9yKCcuYXRsYXMtcG9saWN5LXN0ZXAtaG9zdCcpIGFzIEhUTUxFbGVtZW50IHwgbnVsbDtcbiAgICAgIGlmICghZWwpIHJldHVybjtcbiAgICAgIGluamVjdFBvbGljeVN0eWxlcyhlbC5vd25lckRvY3VtZW50KTtcbiAgICAgIHRoaXMuc3RlcCA9IG1vdW50UG9saWN5QWNjZXB0U3RlcChlbCwgY29udHJvbGxlciwge1xuICAgICAgICAuLi5wb2xpY3lVaSh0aGlzLmF0bGFzKSxcbiAgICAgICAgb25TdWJtaXQ6IChhY2NlcHRhbmNlcykgPT4gdGhpcy5zdWJtaXRGbG93LmVtaXQoeyBwb2xpY3lfYWNjZXB0YW5jZXM6IEpTT04uc3RyaW5naWZ5KGFjY2VwdGFuY2VzKSB9KSxcbiAgICAgICAgb25EZWNsaW5lOiAocG9saWN5OiBQb2xpY3kpID0+IHRoaXMuZGVjbGluZWQuZW1pdChwb2xpY3kudGl0bGUpLFxuICAgICAgfSk7XG4gICAgICB0aGlzLnN0ZXAuc2V0QnVzeSh0aGlzLmJ1c3kpO1xuICAgIH0pO1xuICB9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgIGlmIChjaGFuZ2VzWydidXN5J10pIHRoaXMuc3RlcD8uc2V0QnVzeSh0aGlzLmJ1c3kpO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5hbGl2ZSA9IGZhbHNlO1xuICAgIHRoaXMuc3RlcD8uZGVzdHJveSgpO1xuICB9XG59XG5cbi8qKlxuICogYDxhdGxhcy1wb2xpY3ktZ2F0ZT5gIOKAlCBpbi1hcHAgcmUtYWNjZXB0YW5jZS4gRm9yIGEgc2lnbmVkLWluIHVzZXIsIGEgYmFubmVyXG4gKiB3aGVuIGEgcG9saWN5IG5lZWRzIHJlLWFjY2VwdGFuY2U7IFwiUmV2aWV3IGFuZCBhY2NlcHRcIiBvcGVucyB0aGUgdW5za2lwcGFibGVcbiAqIGRpYWxvZyAvIGNoZWNrYm94ZXMgYW5kIHBvc3RzIGAvdjEvY2xpZW50L21lL3BvbGljaWVzL2FjY2VwdGAuIFByb2plY3RzIGl0c1xuICogY29udGVudCBhbHdheXMuXG4gKi9cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2F0bGFzLXBvbGljeS1nYXRlJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gIHRlbXBsYXRlOiBgXG4gICAgQGlmIChiYW5uZXJUZXh0KCk7IGFzIHRleHQpIHtcbiAgICAgIDxkaXYgW2NsYXNzXT1cImJhbm5lckNsYXNzXCIgcm9sZT1cInN0YXR1c1wiIGRhdGEtYXRsYXMtcG9saWN5LWJhbm5lcj1cIlwiPlxuICAgICAgICA8c3BhblxuICAgICAgICAgID48c3Ryb25nPnt7IHRpdGxlIH19LiA8L3N0cm9uZz57eyB0ZXh0IH19PC9zcGFuXG4gICAgICAgID5cbiAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgW2NsYXNzXT1cImxpbmtDbGFzc1wiIChjbGljayk9XCJiZWdpbigpXCI+e3sgcmV2aWV3VGV4dCB9fTwvYnV0dG9uPlxuICAgICAgPC9kaXY+XG4gICAgfVxuICAgIEBpZiAocmV2aWV3aW5nKCkpIHtcbiAgICAgIDxkaXYgW2NsYXNzXT1cImNhcmRDbGFzc1wiIGRhdGEtYXRsYXMtcG9saWN5LWdhdGU9XCJcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImF0bGFzLXBvbGljeS1nYXRlLWhvc3RcIj48L2Rpdj5cbiAgICAgICAgQGlmIChlcnJvcigpKSB7XG4gICAgICAgICAgPHAgW2NsYXNzXT1cImVycm9yQ2xhc3NcIiByb2xlPVwiYWxlcnRcIj57eyBlcnJvcigpIH19PC9wPlxuICAgICAgICB9XG4gICAgICA8L2Rpdj5cbiAgICB9XG4gICAgPG5nLWNvbnRlbnQ+PC9uZy1jb250ZW50PlxuICBgLFxufSlcbmV4cG9ydCBjbGFzcyBQb2xpY3lHYXRlQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3kge1xuICBwcml2YXRlIHJlYWRvbmx5IGhvc3QgPSBpbmplY3Q8RWxlbWVudFJlZjxIVE1MRWxlbWVudD4+KEVsZW1lbnRSZWYpO1xuICBwcml2YXRlIHJlYWRvbmx5IGF0bGFzID0gaW5qZWN0KEF0bGFzU2VydmljZSk7XG4gIHByaXZhdGUgcmVhZG9ubHkgdWkgPSBwb2xpY3lVaSh0aGlzLmF0bGFzKTtcbiAgcHJpdmF0ZSBnYXRlITogUG9saWN5R2F0ZUNvbnRyb2xsZXI7XG4gIHByaXZhdGUgb2ZmOiAoKCkgPT4gdm9pZCkgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBzdGVwOiBNb3VudGVkUG9saWN5U3RlcCB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIHJlYWRvbmx5IHZlcnNpb24gPSBzaWduYWwoMCk7XG5cbiAgQE91dHB1dCgpIGFjY2VwdGVkID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuXG4gIHByb3RlY3RlZCByZWFkb25seSByZXZpZXdpbmcgPSBzaWduYWwoZmFsc2UpO1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgZXJyb3IgPSBzaWduYWwoJycpO1xuICBwcm90ZWN0ZWQgdGl0bGUgPSB0aGlzLnVpLnQoJ3BvbGljeS5iYW5uZXJUaXRsZScpO1xuICBwcm90ZWN0ZWQgcmV2aWV3VGV4dCA9IHRoaXMudWkudCgncG9saWN5LmJhbm5lclJldmlldycpO1xuICBwcm90ZWN0ZWQgbGlua0NsYXNzID0gdGhpcy51aS5jbGFzc2VzLmxpbmsgPz8gJyc7XG4gIHByb3RlY3RlZCBlcnJvckNsYXNzID0gdGhpcy51aS5jbGFzc2VzLmVycm9yID8/ICcnO1xuICBwcm90ZWN0ZWQgYmFubmVyQ2xhc3MgPSAnYXRsYXMtcG9saWN5LWJhbm5lcic7XG4gIHByb3RlY3RlZCBjYXJkQ2xhc3MgPSBjbGFzc0ZvcignY2FyZCcsIHRoaXMuYXRsYXMuYXBwZWFyYW5jZSwgJ2F0bGFzLWNhcmQnKTtcblxuICBwcm90ZWN0ZWQgYmFubmVyVGV4dCgpOiBzdHJpbmcgfCBudWxsIHtcbiAgICB0aGlzLnZlcnNpb24oKTtcbiAgICBpZiAoIXRoaXMuZ2F0ZSB8fCB0aGlzLmdhdGUucGVuZGluZy5sZW5ndGggPT09IDAgfHwgdGhpcy5yZXZpZXdpbmcoKSkgcmV0dXJuIG51bGw7XG4gICAgY29uc3QgdCA9IHRoaXMudWkudDtcbiAgICBjb25zdCBncmFjZSA9IHRoaXMuZ2F0ZS5ncmFjZUVuZHNBdDtcbiAgICByZXR1cm4gKFxuICAgICAgdCgncG9saWN5LmJhbm5lckJvZHknLCB7IHBvbGljaWVzOiBqb2luVGl0bGVzKHRoaXMuZ2F0ZS5wZW5kaW5nLm1hcCgocCkgPT4gcC50aXRsZSksIHQoJ3BvbGljeS5hbmQnKSkgfSkgK1xuICAgICAgKGdyYWNlID8gYCAke3QoJ3BvbGljeS5iYW5uZXJHcmFjZScsIHsgZGF0ZTogZm9ybWF0UG9saWN5RGF0ZShncmFjZSkgfSl9YCA6ICcnKVxuICAgICk7XG4gIH1cblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLmdhdGUgPSBuZXcgUG9saWN5R2F0ZUNvbnRyb2xsZXIodGhpcy5hdGxhcy5jcmVhdGVGYXBpQ2xpZW50KCksIHRoaXMuYXRsYXMubG9jYWxlID8/IHVuZGVmaW5lZCk7XG4gICAgdGhpcy5vZmYgPSB0aGlzLmdhdGUuc3Vic2NyaWJlKCgpID0+IHRoaXMudmVyc2lvbi51cGRhdGUoKG4pID0+IG4gKyAxKSk7XG4gICAgaWYgKHRoaXMuYXRsYXMuc3RhdHVzKCkgPT09ICdzaWduZWRfaW4nKSB2b2lkIHRoaXMuZ2F0ZS5sb2FkKCk7XG4gIH1cblxuICBhc3luYyBiZWdpbigpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBjb250cm9sbGVyID0gYXdhaXQgdGhpcy5nYXRlLmJlZ2luKCk7XG4gICAgdGhpcy5yZXZpZXdpbmcuc2V0KHRydWUpO1xuICAgIGF3YWl0IFByb21pc2UucmVzb2x2ZSgpO1xuICAgIGNvbnN0IGVsID0gdGhpcy5ob3N0Lm5hdGl2ZUVsZW1lbnQucXVlcnlTZWxlY3RvcignLmF0bGFzLXBvbGljeS1nYXRlLWhvc3QnKSBhcyBIVE1MRWxlbWVudCB8IG51bGw7XG4gICAgaWYgKCFlbCkgcmV0dXJuO1xuICAgIGluamVjdFBvbGljeVN0eWxlcyhlbC5vd25lckRvY3VtZW50KTtcbiAgICB0aGlzLnN0ZXAgPSBtb3VudFBvbGljeUFjY2VwdFN0ZXAoZWwsIGNvbnRyb2xsZXIsIHtcbiAgICAgIC4uLnRoaXMudWksXG4gICAgICBvblN1Ym1pdDogYXN5bmMgKCkgPT4ge1xuICAgICAgICB0aGlzLnN0ZXA/LnNldEJ1c3kodHJ1ZSk7XG4gICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IHRoaXMuZ2F0ZS5hY2NlcHQoY29udHJvbGxlcik7XG4gICAgICAgIHRoaXMuc3RlcD8uc2V0QnVzeShmYWxzZSk7XG4gICAgICAgIGlmICghcmVzLm9rKSB7XG4gICAgICAgICAgdGhpcy5lcnJvci5zZXQocmVzLmVycm9yc1swXT8ubWVzc2FnZSA/PyB0aGlzLnVpLnQoJ3BvbGljeS5yZXF1aXJlZEdlbmVyaWMnKSk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuY2xvc2UoKTtcbiAgICAgICAgdGhpcy5hY2NlcHRlZC5lbWl0KCk7XG4gICAgICB9LFxuICAgICAgb25EZWNsaW5lOiAoKSA9PiB0aGlzLmNsb3NlKCksXG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGNsb3NlKCk6IHZvaWQge1xuICAgIHRoaXMuc3RlcD8uZGVzdHJveSgpO1xuICAgIHRoaXMuc3RlcCA9IG51bGw7XG4gICAgdGhpcy5yZXZpZXdpbmcuc2V0KGZhbHNlKTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMub2ZmPy4oKTtcbiAgICB0aGlzLnN0ZXA/LmRlc3Ryb3koKTtcbiAgfVxufVxuIl19
@@ -0,0 +1,122 @@
1
+ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, Input, Output, inject, } from '@angular/core';
2
+ import { canDownloadRecoveryCodes, copyRecoveryCodes, downloadRecoveryCodes } from '@atlasauth/js';
3
+ import { AtlasService } from '../atlas.service';
4
+ import { classFor } from '../appearance';
5
+ import { translate } from '../i18n';
6
+ import * as i0 from "@angular/core";
7
+ /**
8
+ * The recovery codes a mid-sign-in MFA enrolment came with, shown once before
9
+ * the sign-in finishes: copy them, download them as a .txt file, then
10
+ * "I've saved my codes" (`saved`) exchanges the ticket. The codes live only in
11
+ * the flow controller's memory and are forgotten once saved.
12
+ */
13
+ export class RecoveryCodesComponent {
14
+ atlas = inject(AtlasService);
15
+ cdr = inject(ChangeDetectorRef);
16
+ codes = [];
17
+ busy = false;
18
+ saved = new EventEmitter();
19
+ canCopy = typeof navigator !== 'undefined' && !!navigator.clipboard?.writeText;
20
+ canDownload = canDownloadRecoveryCodes();
21
+ copied = false;
22
+ ngOnChanges() {
23
+ this.copied = false;
24
+ }
25
+ t(key) {
26
+ return translate(this.atlas.localization, key);
27
+ }
28
+ cls(key, base) {
29
+ return classFor(key, this.atlas.appearance, base);
30
+ }
31
+ copy() {
32
+ void copyRecoveryCodes(this.codes).then((ok) => {
33
+ this.copied = ok;
34
+ this.cdr.markForCheck();
35
+ });
36
+ }
37
+ download() {
38
+ downloadRecoveryCodes(this.codes);
39
+ }
40
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: RecoveryCodesComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
41
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: RecoveryCodesComponent, isStandalone: true, selector: "atlas-recovery-codes", inputs: { codes: "codes", busy: "busy" }, outputs: { saved: "saved" }, usesOnChanges: true, ngImport: i0, template: `
42
+ <div [class]="cls('card', 'atlas-card')" data-atlas="recovery-codes">
43
+ <h1 [class]="cls('headerTitle', 'atlas-title')">{{ t('mfa.recoveryCodesTitle') }}</h1>
44
+ <p class="atlas-text">{{ t('mfa.recoveryCodesHelp') }}</p>
45
+ <ul
46
+ class="atlas-recovery-codes"
47
+ data-atlas="recovery-codes-list"
48
+ style="list-style:none;padding:0;margin:8px 0 12px;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:6px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;text-align:center"
49
+ >
50
+ @for (code of codes; track code) {
51
+ <li><code>{{ code }}</code></li>
52
+ }
53
+ </ul>
54
+ <div class="atlas-alternatives">
55
+ @if (canCopy) {
56
+ <button [class]="cls('formButtonSecondary', 'atlas-button-secondary')" type="button" data-atlas="recovery-codes-copy" (click)="copy()">
57
+ {{ t('mfa.recoveryCodesCopy') }}
58
+ </button>
59
+ }
60
+ @if (canDownload) {
61
+ <button [class]="cls('formButtonSecondary', 'atlas-button-secondary')" type="button" data-atlas="recovery-codes-download" (click)="download()">
62
+ {{ t('mfa.recoveryCodesDownload') }}
63
+ </button>
64
+ }
65
+ </div>
66
+ @if (copied) {
67
+ <p class="atlas-text" aria-live="polite" data-atlas="recovery-codes-copied">{{ t('mfa.recoveryCodesCopied') }}</p>
68
+ }
69
+ <button [class]="cls('formButtonPrimary', 'atlas-button')" type="button" data-atlas="recovery-codes-saved" [disabled]="busy" (click)="saved.emit()">
70
+ {{ t('mfa.recoveryCodesSaved') }}
71
+ </button>
72
+ </div>
73
+ `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
74
+ }
75
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: RecoveryCodesComponent, decorators: [{
76
+ type: Component,
77
+ args: [{
78
+ selector: 'atlas-recovery-codes',
79
+ standalone: true,
80
+ changeDetection: ChangeDetectionStrategy.OnPush,
81
+ template: `
82
+ <div [class]="cls('card', 'atlas-card')" data-atlas="recovery-codes">
83
+ <h1 [class]="cls('headerTitle', 'atlas-title')">{{ t('mfa.recoveryCodesTitle') }}</h1>
84
+ <p class="atlas-text">{{ t('mfa.recoveryCodesHelp') }}</p>
85
+ <ul
86
+ class="atlas-recovery-codes"
87
+ data-atlas="recovery-codes-list"
88
+ style="list-style:none;padding:0;margin:8px 0 12px;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:6px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;text-align:center"
89
+ >
90
+ @for (code of codes; track code) {
91
+ <li><code>{{ code }}</code></li>
92
+ }
93
+ </ul>
94
+ <div class="atlas-alternatives">
95
+ @if (canCopy) {
96
+ <button [class]="cls('formButtonSecondary', 'atlas-button-secondary')" type="button" data-atlas="recovery-codes-copy" (click)="copy()">
97
+ {{ t('mfa.recoveryCodesCopy') }}
98
+ </button>
99
+ }
100
+ @if (canDownload) {
101
+ <button [class]="cls('formButtonSecondary', 'atlas-button-secondary')" type="button" data-atlas="recovery-codes-download" (click)="download()">
102
+ {{ t('mfa.recoveryCodesDownload') }}
103
+ </button>
104
+ }
105
+ </div>
106
+ @if (copied) {
107
+ <p class="atlas-text" aria-live="polite" data-atlas="recovery-codes-copied">{{ t('mfa.recoveryCodesCopied') }}</p>
108
+ }
109
+ <button [class]="cls('formButtonPrimary', 'atlas-button')" type="button" data-atlas="recovery-codes-saved" [disabled]="busy" (click)="saved.emit()">
110
+ {{ t('mfa.recoveryCodesSaved') }}
111
+ </button>
112
+ </div>
113
+ `,
114
+ }]
115
+ }], propDecorators: { codes: [{
116
+ type: Input
117
+ }], busy: [{
118
+ type: Input
119
+ }], saved: [{
120
+ type: Output
121
+ }] } });
122
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVjb3ZlcnktY29kZXMuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2xpYi9jb21wb25lbnRzL3JlY292ZXJ5LWNvZGVzLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsdUJBQXVCLEVBQ3ZCLGlCQUFpQixFQUNqQixTQUFTLEVBQ1QsWUFBWSxFQUNaLEtBQUssRUFFTCxNQUFNLEVBQ04sTUFBTSxHQUNQLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSx3QkFBd0IsRUFBRSxpQkFBaUIsRUFBRSxxQkFBcUIsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNuRyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDaEQsT0FBTyxFQUFFLFFBQVEsRUFBbUIsTUFBTSxlQUFlLENBQUM7QUFDMUQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLFNBQVMsQ0FBQzs7QUFFcEM7Ozs7O0dBS0c7QUF1Q0gsTUFBTSxPQUFPLHNCQUFzQjtJQUNoQixLQUFLLEdBQUcsTUFBTSxDQUFDLFlBQVksQ0FBQyxDQUFDO0lBQzdCLEdBQUcsR0FBRyxNQUFNLENBQUMsaUJBQWlCLENBQUMsQ0FBQztJQUV4QyxLQUFLLEdBQWEsRUFBRSxDQUFDO0lBQ3JCLElBQUksR0FBRyxLQUFLLENBQUM7SUFDWixLQUFLLEdBQUcsSUFBSSxZQUFZLEVBQVEsQ0FBQztJQUV4QixPQUFPLEdBQUcsT0FBTyxTQUFTLEtBQUssV0FBVyxJQUFJLENBQUMsQ0FBQyxTQUFTLENBQUMsU0FBUyxFQUFFLFNBQVMsQ0FBQztJQUMvRSxXQUFXLEdBQUcsd0JBQXdCLEVBQUUsQ0FBQztJQUNsRCxNQUFNLEdBQUcsS0FBSyxDQUFDO0lBRXpCLFdBQVc7UUFDVCxJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQztJQUN0QixDQUFDO0lBRVMsQ0FBQyxDQUFDLEdBQVc7UUFDckIsT0FBTyxTQUFTLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLEVBQUUsR0FBRyxDQUFDLENBQUM7SUFDakQsQ0FBQztJQUVTLEdBQUcsQ0FBQyxHQUFlLEVBQUUsSUFBWTtRQUN6QyxPQUFPLFFBQVEsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDcEQsQ0FBQztJQUVTLElBQUk7UUFDWixLQUFLLGlCQUFpQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRTtZQUM3QyxJQUFJLENBQUMsTUFBTSxHQUFHLEVBQUUsQ0FBQztZQUNqQixJQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQzFCLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVTLFFBQVE7UUFDaEIscUJBQXFCLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ3BDLENBQUM7d0dBakNVLHNCQUFzQjs0RkFBdEIsc0JBQXNCLDRLQWxDdkI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBZ0NUOzs0RkFFVSxzQkFBc0I7a0JBdENsQyxTQUFTO21CQUFDO29CQUNULFFBQVEsRUFBRSxzQkFBc0I7b0JBQ2hDLFVBQVUsRUFBRSxJQUFJO29CQUNoQixlQUFlLEVBQUUsdUJBQXVCLENBQUMsTUFBTTtvQkFDL0MsUUFBUSxFQUFFOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQWdDVDtpQkFDRjs4QkFLVSxLQUFLO3NCQUFiLEtBQUs7Z0JBQ0csSUFBSTtzQkFBWixLQUFLO2dCQUNJLEtBQUs7c0JBQWQsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgQ29tcG9uZW50LFxuICBFdmVudEVtaXR0ZXIsXG4gIElucHV0LFxuICBPbkNoYW5nZXMsXG4gIE91dHB1dCxcbiAgaW5qZWN0LFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IGNhbkRvd25sb2FkUmVjb3ZlcnlDb2RlcywgY29weVJlY292ZXJ5Q29kZXMsIGRvd25sb2FkUmVjb3ZlcnlDb2RlcyB9IGZyb20gJ0BhdGxhc2F1dGgvanMnO1xuaW1wb3J0IHsgQXRsYXNTZXJ2aWNlIH0gZnJvbSAnLi4vYXRsYXMuc2VydmljZSc7XG5pbXBvcnQgeyBjbGFzc0ZvciwgdHlwZSBFbGVtZW50S2V5IH0gZnJvbSAnLi4vYXBwZWFyYW5jZSc7XG5pbXBvcnQgeyB0cmFuc2xhdGUgfSBmcm9tICcuLi9pMThuJztcblxuLyoqXG4gKiBUaGUgcmVjb3ZlcnkgY29kZXMgYSBtaWQtc2lnbi1pbiBNRkEgZW5yb2xtZW50IGNhbWUgd2l0aCwgc2hvd24gb25jZSBiZWZvcmVcbiAqIHRoZSBzaWduLWluIGZpbmlzaGVzOiBjb3B5IHRoZW0sIGRvd25sb2FkIHRoZW0gYXMgYSAudHh0IGZpbGUsIHRoZW5cbiAqIFwiSSd2ZSBzYXZlZCBteSBjb2Rlc1wiIChgc2F2ZWRgKSBleGNoYW5nZXMgdGhlIHRpY2tldC4gVGhlIGNvZGVzIGxpdmUgb25seSBpblxuICogdGhlIGZsb3cgY29udHJvbGxlcidzIG1lbW9yeSBhbmQgYXJlIGZvcmdvdHRlbiBvbmNlIHNhdmVkLlxuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdhdGxhcy1yZWNvdmVyeS1jb2RlcycsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxkaXYgW2NsYXNzXT1cImNscygnY2FyZCcsICdhdGxhcy1jYXJkJylcIiBkYXRhLWF0bGFzPVwicmVjb3ZlcnktY29kZXNcIj5cbiAgICAgIDxoMSBbY2xhc3NdPVwiY2xzKCdoZWFkZXJUaXRsZScsICdhdGxhcy10aXRsZScpXCI+e3sgdCgnbWZhLnJlY292ZXJ5Q29kZXNUaXRsZScpIH19PC9oMT5cbiAgICAgIDxwIGNsYXNzPVwiYXRsYXMtdGV4dFwiPnt7IHQoJ21mYS5yZWNvdmVyeUNvZGVzSGVscCcpIH19PC9wPlxuICAgICAgPHVsXG4gICAgICAgIGNsYXNzPVwiYXRsYXMtcmVjb3ZlcnktY29kZXNcIlxuICAgICAgICBkYXRhLWF0bGFzPVwicmVjb3ZlcnktY29kZXMtbGlzdFwiXG4gICAgICAgIHN0eWxlPVwibGlzdC1zdHlsZTpub25lO3BhZGRpbmc6MDttYXJnaW46OHB4IDAgMTJweDtkaXNwbGF5OmdyaWQ7Z3JpZC10ZW1wbGF0ZS1jb2x1bW5zOnJlcGVhdCgyLG1pbm1heCgwLDFmcikpO2dhcDo2cHg7Zm9udC1mYW1pbHk6dWktbW9ub3NwYWNlLFNGTW9uby1SZWd1bGFyLE1lbmxvLG1vbm9zcGFjZTt0ZXh0LWFsaWduOmNlbnRlclwiXG4gICAgICA+XG4gICAgICAgIEBmb3IgKGNvZGUgb2YgY29kZXM7IHRyYWNrIGNvZGUpIHtcbiAgICAgICAgICA8bGk+PGNvZGU+e3sgY29kZSB9fTwvY29kZT48L2xpPlxuICAgICAgICB9XG4gICAgICA8L3VsPlxuICAgICAgPGRpdiBjbGFzcz1cImF0bGFzLWFsdGVybmF0aXZlc1wiPlxuICAgICAgICBAaWYgKGNhbkNvcHkpIHtcbiAgICAgICAgICA8YnV0dG9uIFtjbGFzc109XCJjbHMoJ2Zvcm1CdXR0b25TZWNvbmRhcnknLCAnYXRsYXMtYnV0dG9uLXNlY29uZGFyeScpXCIgdHlwZT1cImJ1dHRvblwiIGRhdGEtYXRsYXM9XCJyZWNvdmVyeS1jb2Rlcy1jb3B5XCIgKGNsaWNrKT1cImNvcHkoKVwiPlxuICAgICAgICAgICAge3sgdCgnbWZhLnJlY292ZXJ5Q29kZXNDb3B5JykgfX1cbiAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgfVxuICAgICAgICBAaWYgKGNhbkRvd25sb2FkKSB7XG4gICAgICAgICAgPGJ1dHRvbiBbY2xhc3NdPVwiY2xzKCdmb3JtQnV0dG9uU2Vjb25kYXJ5JywgJ2F0bGFzLWJ1dHRvbi1zZWNvbmRhcnknKVwiIHR5cGU9XCJidXR0b25cIiBkYXRhLWF0bGFzPVwicmVjb3ZlcnktY29kZXMtZG93bmxvYWRcIiAoY2xpY2spPVwiZG93bmxvYWQoKVwiPlxuICAgICAgICAgICAge3sgdCgnbWZhLnJlY292ZXJ5Q29kZXNEb3dubG9hZCcpIH19XG4gICAgICAgICAgPC9idXR0b24+XG4gICAgICAgIH1cbiAgICAgIDwvZGl2PlxuICAgICAgQGlmIChjb3BpZWQpIHtcbiAgICAgICAgPHAgY2xhc3M9XCJhdGxhcy10ZXh0XCIgYXJpYS1saXZlPVwicG9saXRlXCIgZGF0YS1hdGxhcz1cInJlY292ZXJ5LWNvZGVzLWNvcGllZFwiPnt7IHQoJ21mYS5yZWNvdmVyeUNvZGVzQ29waWVkJykgfX08L3A+XG4gICAgICB9XG4gICAgICA8YnV0dG9uIFtjbGFzc109XCJjbHMoJ2Zvcm1CdXR0b25QcmltYXJ5JywgJ2F0bGFzLWJ1dHRvbicpXCIgdHlwZT1cImJ1dHRvblwiIGRhdGEtYXRsYXM9XCJyZWNvdmVyeS1jb2Rlcy1zYXZlZFwiIFtkaXNhYmxlZF09XCJidXN5XCIgKGNsaWNrKT1cInNhdmVkLmVtaXQoKVwiPlxuICAgICAgICB7eyB0KCdtZmEucmVjb3ZlcnlDb2Rlc1NhdmVkJykgfX1cbiAgICAgIDwvYnV0dG9uPlxuICAgIDwvZGl2PlxuICBgLFxufSlcbmV4cG9ydCBjbGFzcyBSZWNvdmVyeUNvZGVzQ29tcG9uZW50IGltcGxlbWVudHMgT25DaGFuZ2VzIHtcbiAgcHJpdmF0ZSByZWFkb25seSBhdGxhcyA9IGluamVjdChBdGxhc1NlcnZpY2UpO1xuICBwcml2YXRlIHJlYWRvbmx5IGNkciA9IGluamVjdChDaGFuZ2VEZXRlY3RvclJlZik7XG5cbiAgQElucHV0KCkgY29kZXM6IHN0cmluZ1tdID0gW107XG4gIEBJbnB1dCgpIGJ1c3kgPSBmYWxzZTtcbiAgQE91dHB1dCgpIHNhdmVkID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuXG4gIHByb3RlY3RlZCByZWFkb25seSBjYW5Db3B5ID0gdHlwZW9mIG5hdmlnYXRvciAhPT0gJ3VuZGVmaW5lZCcgJiYgISFuYXZpZ2F0b3IuY2xpcGJvYXJkPy53cml0ZVRleHQ7XG4gIHByb3RlY3RlZCByZWFkb25seSBjYW5Eb3dubG9hZCA9IGNhbkRvd25sb2FkUmVjb3ZlcnlDb2RlcygpO1xuICBwcm90ZWN0ZWQgY29waWVkID0gZmFsc2U7XG5cbiAgbmdPbkNoYW5nZXMoKTogdm9pZCB7XG4gICAgdGhpcy5jb3BpZWQgPSBmYWxzZTtcbiAgfVxuXG4gIHByb3RlY3RlZCB0KGtleTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdHJhbnNsYXRlKHRoaXMuYXRsYXMubG9jYWxpemF0aW9uLCBrZXkpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGNscyhrZXk6IEVsZW1lbnRLZXksIGJhc2U6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGNsYXNzRm9yKGtleSwgdGhpcy5hdGxhcy5hcHBlYXJhbmNlLCBiYXNlKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBjb3B5KCk6IHZvaWQge1xuICAgIHZvaWQgY29weVJlY292ZXJ5Q29kZXModGhpcy5jb2RlcykudGhlbigob2spID0+IHtcbiAgICAgIHRoaXMuY29waWVkID0gb2s7XG4gICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByb3RlY3RlZCBkb3dubG9hZCgpOiB2b2lkIHtcbiAgICBkb3dubG9hZFJlY292ZXJ5Q29kZXModGhpcy5jb2Rlcyk7XG4gIH1cbn1cbiJdfQ==
@@ -1,8 +1,9 @@
1
1
  import { ChangeDetectionStrategy, Component, Input, inject, } from '@angular/core';
2
- import { signUp as hostedSignUp } from '@atlasauth/js';
2
+ import { lastUsedMethodLabel, signUp as hostedSignUp } from '@atlasauth/js';
3
3
  import { AtlasService } from '../atlas.service';
4
4
  import { translate } from '../i18n';
5
5
  import { AttemptFlowComponent } from './attempt-flow.component';
6
+ import { RecoveryCodesComponent } from './recovery-codes.component';
6
7
  import { AtlasFlowController } from './flow-controller';
7
8
  import * as i0 from "@angular/core";
8
9
  /**
@@ -28,6 +29,12 @@ export class SignInComponent {
28
29
  t(key) {
29
30
  return translate(this.atlas.localization, key);
30
31
  }
32
+ /** "Last used: Password" on the identifier step, when the instance shows the hint. */
33
+ lastUsedLabel() {
34
+ if (this.flow.state().attempt)
35
+ return null;
36
+ return lastUsedMethodLabel(this.flow.lastMethod(), (key) => this.t(key));
37
+ }
31
38
  signUpHref() {
32
39
  if (this.signUpUrl === null)
33
40
  return null;
@@ -61,6 +68,14 @@ export class SignInComponent {
61
68
  }
62
69
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: SignInComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
63
70
  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: `
71
+ @if (lastUsedLabel(); as label) {
72
+ <p class="atlas-text atlas-last-used-hint" data-atlas="last-used" [attr.data-atlas-method]="flow.lastMethod()">
73
+ {{ t('signIn.lastUsed') }}: {{ label }}
74
+ </p>
75
+ }
76
+ @if (flow.recoveryCodes(); as codes) {
77
+ <atlas-recovery-codes [codes]="codes" [busy]="flow.state().busy" (saved)="flow.saveRecoveryCodes()"></atlas-recovery-codes>
78
+ } @else {
64
79
  <atlas-attempt-flow
65
80
  [attempt]="flow.state().attempt"
66
81
  [busy]="flow.state().busy"
@@ -70,15 +85,25 @@ export class SignInComponent {
70
85
  [captcha]="flow.captchaDrawn() ? flow.captcha : null"
71
86
  [firstFactors]="flow.firstFactors()"
72
87
  [preparedFactor]="flow.preparedFactor()"
88
+ [offerEmailSecondFactor]="flow.settings()?.account?.emailSecondFactor === true"
89
+ [emailedSecondFactor]="flow.emailSecondFactor()"
73
90
  (submitFlow)="flow.submit($event)"
74
91
  (chooseFactor)="flow.prepare($event)"
92
+ [offerSmsSecondFactor]="flow.settings() !== null && flow.mfaChoices().sms"
93
+ [textedSecondFactor]="flow.smsSecondFactor()"
94
+ [enrollment]="flow.enrollment"
95
+ [enrollmentState]="flow.enrollmentState()"
96
+ (emailSecondFactor)="flow.sendEmailSecondFactor()"
97
+ (smsSecondFactor)="flow.sendSmsSecondFactor()"
98
+ (policyDeclined)="flow.declinePolicy($event)"
75
99
  ></atlas-attempt-flow>
100
+ }
76
101
  @if (flow.state().attempt?.status !== 'complete' && signUpHref(); as href) {
77
102
  <p class="atlas-footer" data-atlas-sign-up-prompt="">
78
103
  {{ t('signIn.noAccount') }} <a class="atlas-link" [href]="href">{{ t('signIn.signUpLink') }}</a>
79
104
  </p>
80
105
  }
81
- `, 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 });
106
+ `, isInline: true, dependencies: [{ kind: "component", type: AttemptFlowComponent, selector: "atlas-attempt-flow", inputs: ["attempt", "busy", "errors", "sessionKept", "titleKey", "captcha", "firstFactors", "preparedFactor", "offerEmailSecondFactor", "emailedSecondFactor", "offerSmsSecondFactor", "textedSecondFactor", "enrollment", "enrollmentState", "emailVerification"], outputs: ["submitFlow", "chooseFactor", "emailSecondFactor", "smsSecondFactor", "resend", "policyDeclined"] }, { kind: "component", type: RecoveryCodesComponent, selector: "atlas-recovery-codes", inputs: ["codes", "busy"], outputs: ["saved"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
82
107
  }
83
108
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: SignInComponent, decorators: [{
84
109
  type: Component,
@@ -86,8 +111,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
86
111
  selector: 'atlas-sign-in',
87
112
  standalone: true,
88
113
  changeDetection: ChangeDetectionStrategy.OnPush,
89
- imports: [AttemptFlowComponent],
114
+ imports: [AttemptFlowComponent, RecoveryCodesComponent],
90
115
  template: `
116
+ @if (lastUsedLabel(); as label) {
117
+ <p class="atlas-text atlas-last-used-hint" data-atlas="last-used" [attr.data-atlas-method]="flow.lastMethod()">
118
+ {{ t('signIn.lastUsed') }}: {{ label }}
119
+ </p>
120
+ }
121
+ @if (flow.recoveryCodes(); as codes) {
122
+ <atlas-recovery-codes [codes]="codes" [busy]="flow.state().busy" (saved)="flow.saveRecoveryCodes()"></atlas-recovery-codes>
123
+ } @else {
91
124
  <atlas-attempt-flow
92
125
  [attempt]="flow.state().attempt"
93
126
  [busy]="flow.state().busy"
@@ -97,9 +130,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
97
130
  [captcha]="flow.captchaDrawn() ? flow.captcha : null"
98
131
  [firstFactors]="flow.firstFactors()"
99
132
  [preparedFactor]="flow.preparedFactor()"
133
+ [offerEmailSecondFactor]="flow.settings()?.account?.emailSecondFactor === true"
134
+ [emailedSecondFactor]="flow.emailSecondFactor()"
100
135
  (submitFlow)="flow.submit($event)"
101
136
  (chooseFactor)="flow.prepare($event)"
137
+ [offerSmsSecondFactor]="flow.settings() !== null && flow.mfaChoices().sms"
138
+ [textedSecondFactor]="flow.smsSecondFactor()"
139
+ [enrollment]="flow.enrollment"
140
+ [enrollmentState]="flow.enrollmentState()"
141
+ (emailSecondFactor)="flow.sendEmailSecondFactor()"
142
+ (smsSecondFactor)="flow.sendSmsSecondFactor()"
143
+ (policyDeclined)="flow.declinePolicy($event)"
102
144
  ></atlas-attempt-flow>
145
+ }
103
146
  @if (flow.state().attempt?.status !== 'complete' && signUpHref(); as href) {
104
147
  <p class="atlas-footer" data-atlas-sign-up-prompt="">
105
148
  {{ t('signIn.noAccount') }} <a class="atlas-link" [href]="href">{{ t('signIn.signUpLink') }}</a>
@@ -112,4 +155,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
112
155
  }], signUpUrl: [{
113
156
  type: Input
114
157
  }] } });
115
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2lnbi1pbi5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL2NvbXBvbmVudHMvc2lnbi1pbi5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLHVCQUF1QixFQUN2QixTQUFTLEVBQ1QsS0FBSyxFQUdMLE1BQU0sR0FDUCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsTUFBTSxJQUFJLFlBQVksRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN2RCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDaEQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUNwQyxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUNoRSxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQzs7QUFFeEQ7Ozs7Ozs7OztHQVNHO0FBMEJILE1BQU0sT0FBTyxlQUFlO0lBQ1QsS0FBSyxHQUFHLE1BQU0sQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUU5QyxpRkFBaUY7SUFDeEUsUUFBUSxDQUFVO0lBQzNCOzs7O09BSUc7SUFDTSxTQUFTLENBQWlCO0lBRXpCLENBQUMsQ0FBQyxHQUFXO1FBQ3JCLE9BQU8sU0FBUyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxFQUFFLEdBQUcsQ0FBQyxDQUFDO0lBQ2pELENBQUM7SUFFUyxVQUFVO1FBQ2xCLElBQUksSUFBSSxDQUFDLFNBQVMsS0FBSyxJQUFJO1lBQUUsT0FBTyxJQUFJLENBQUM7UUFDekMsSUFBSSxJQUFJLENBQUMsU0FBUztZQUFFLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQztRQUMxQyxJQUFJLENBQUM7WUFDSCxPQUFPLFlBQVksQ0FBQztnQkFDbEIsV0FBVyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVztnQkFDbkMsV0FBVyxFQUFFLElBQUksQ0FBQyxRQUFRLElBQUksQ0FBQyxPQUFPLE1BQU0sS0FBSyxXQUFXLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7Z0JBQ2hHLFFBQVEsRUFBRSxLQUFLO2FBQ2hCLENBQUMsQ0FBQztRQUNMLENBQUM7UUFBQyxNQUFNLENBQUM7WUFDUCxPQUFPLElBQUksQ0FBQztRQUNkLENBQUM7SUFDSCxDQUFDO0lBRWtCLElBQUksR0FBRyxJQUFJLG1CQUFtQixDQUMvQyxJQUFJLENBQUMsS0FBSyxDQUFDLGdCQUFnQixFQUFFLEVBQzdCLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFO0lBQ3pCLHdFQUF3RTtJQUN4RSxJQUFJLENBQUMsS0FBSyxDQUFDLGNBQWMsRUFDekIsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFlBQVksRUFBRSxHQUFHLENBQUMsQ0FDakQsQ0FBQztJQUVGLFFBQVE7UUFDTiw0RUFBNEU7UUFDNUUsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUN4Qiw0RUFBNEU7UUFDNUUseUVBQXlFO1FBQ3pFLDJDQUEyQztRQUMzQyxJQUFJLE9BQU8sTUFBTSxLQUFLLFdBQVc7WUFBRSxLQUFLLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7SUFDbkUsQ0FBQztJQUVELFdBQVc7UUFDVCxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO0lBQ3RCLENBQUM7d0dBakRVLGVBQWU7NEZBQWYsZUFBZSxtSUFwQmhCOzs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FrQlQsNERBbkJTLG9CQUFvQjs7NEZBcUJuQixlQUFlO2tCQXpCM0IsU0FBUzttQkFBQztvQkFDVCxRQUFRLEVBQUUsZUFBZTtvQkFDekIsVUFBVSxFQUFFLElBQUk7b0JBQ2hCLGVBQWUsRUFBRSx1QkFBdUIsQ0FBQyxNQUFNO29CQUMvQyxPQUFPLEVBQUUsQ0FBQyxvQkFBb0IsQ0FBQztvQkFDL0IsUUFBUSxFQUFFOzs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FrQlQ7aUJBQ0Y7OEJBS1UsUUFBUTtzQkFBaEIsS0FBSztnQkFNRyxTQUFTO3NCQUFqQixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENvbXBvbmVudCxcbiAgSW5wdXQsXG4gIE9uRGVzdHJveSxcbiAgT25Jbml0LFxuICBpbmplY3QsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgc2lnblVwIGFzIGhvc3RlZFNpZ25VcCB9IGZyb20gJ0BhdGxhc2F1dGgvanMnO1xuaW1wb3J0IHsgQXRsYXNTZXJ2aWNlIH0gZnJvbSAnLi4vYXRsYXMuc2VydmljZSc7XG5pbXBvcnQgeyB0cmFuc2xhdGUgfSBmcm9tICcuLi9pMThuJztcbmltcG9ydCB7IEF0dGVtcHRGbG93Q29tcG9uZW50IH0gZnJvbSAnLi9hdHRlbXB0LWZsb3cuY29tcG9uZW50JztcbmltcG9ydCB7IEF0bGFzRmxvd0NvbnRyb2xsZXIgfSBmcm9tICcuL2Zsb3ctY29udHJvbGxlcic7XG5cbi8qKlxuICogYDxhdGxhcy1zaWduLWluPmAg4oCUIHRoZSBmdWxsLCBtdWx0aS1zdGVwIHNpZ24taW4gZmxvdyBkcml2ZW4gZW50aXJlbHkgYnkgdGhlXG4gKiBzZXJ2ZXItc2lkZSBhdHRlbXB0IHN0YXR1cy4gVGhlIEFuZ3VsYXIgcGVlciBvZiBSZWFjdCdzIGA8U2lnbkluLz5gLiBEcmF3cyB0aGVcbiAqIGluc3RhbmNlJ3Mgc2lnbi1pbiBjYXB0Y2hhIHdoZW4gaXQgaXMgcmVxdWlyZWQgKGFsd2F5cy1vbiwgb3IgYVxuICogYG5lZWRzX2NhcHRjaGFgIGNoYWxsZW5nZSkuXG4gKlxuICogYGBgaHRtbFxuICogPGF0bGFzLXNpZ24taW4gKmF0bGFzU2lnbmVkT3V0IGFmdGVyVXJsPVwiL2Rhc2hib2FyZFwiPjwvYXRsYXMtc2lnbi1pbj5cbiAqIGBgYFxuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdhdGxhcy1zaWduLWluJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gIGltcG9ydHM6IFtBdHRlbXB0Rmxvd0NvbXBvbmVudF0sXG4gIHRlbXBsYXRlOiBgXG4gICAgPGF0bGFzLWF0dGVtcHQtZmxvd1xuICAgICAgW2F0dGVtcHRdPVwiZmxvdy5zdGF0ZSgpLmF0dGVtcHRcIlxuICAgICAgW2J1c3ldPVwiZmxvdy5zdGF0ZSgpLmJ1c3lcIlxuICAgICAgW2Vycm9yc109XCJmbG93LnN0YXRlKCkuZXJyb3JzXCJcbiAgICAgIFtzZXNzaW9uS2VwdF09XCJmbG93LnN0YXRlKCkuc2Vzc2lvbktlcHRcIlxuICAgICAgdGl0bGVLZXk9XCJzaWduSW4udGl0bGVcIlxuICAgICAgW2NhcHRjaGFdPVwiZmxvdy5jYXB0Y2hhRHJhd24oKSA/IGZsb3cuY2FwdGNoYSA6IG51bGxcIlxuICAgICAgW2ZpcnN0RmFjdG9yc109XCJmbG93LmZpcnN0RmFjdG9ycygpXCJcbiAgICAgIFtwcmVwYXJlZEZhY3Rvcl09XCJmbG93LnByZXBhcmVkRmFjdG9yKClcIlxuICAgICAgKHN1Ym1pdEZsb3cpPVwiZmxvdy5zdWJtaXQoJGV2ZW50KVwiXG4gICAgICAoY2hvb3NlRmFjdG9yKT1cImZsb3cucHJlcGFyZSgkZXZlbnQpXCJcbiAgICA+PC9hdGxhcy1hdHRlbXB0LWZsb3c+XG4gICAgQGlmIChmbG93LnN0YXRlKCkuYXR0ZW1wdD8uc3RhdHVzICE9PSAnY29tcGxldGUnICYmIHNpZ25VcEhyZWYoKTsgYXMgaHJlZikge1xuICAgICAgPHAgY2xhc3M9XCJhdGxhcy1mb290ZXJcIiBkYXRhLWF0bGFzLXNpZ24tdXAtcHJvbXB0PVwiXCI+XG4gICAgICAgIHt7IHQoJ3NpZ25Jbi5ub0FjY291bnQnKSB9fSA8YSBjbGFzcz1cImF0bGFzLWxpbmtcIiBbaHJlZl09XCJocmVmXCI+e3sgdCgnc2lnbkluLnNpZ25VcExpbmsnKSB9fTwvYT5cbiAgICAgIDwvcD5cbiAgICB9XG4gIGAsXG59KVxuZXhwb3J0IGNsYXNzIFNpZ25JbkNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcbiAgcHJpdmF0ZSByZWFkb25seSBhdGxhcyA9IGluamVjdChBdGxhc1NlcnZpY2UpO1xuXG4gIC8qKiBXaGVyZSB0byBzZW5kIHRoZSB1c2VyIG9uY2UgdGhlIGZsb3cgY29tcGxldGVzLiBSZXNlcnZlZCBmb3IgaG9zdCByb3V0aW5nLiAqL1xuICBASW5wdXQoKSBhZnRlclVybD86IHN0cmluZztcbiAgLyoqXG4gICAqIFdoZXJlIFwiTm8gYWNjb3VudD8gU2lnbiB1cFwiIGdvZXMuIERlZmF1bHQ6IHRoZSBpbnN0YW5jZSdzIGhvc3RlZCBzaWduLXVwXG4gICAqIHBhZ2UgKGNhcnJ5aW5nIHRoZSB2aXNpdG9yJ3MgcmVmZXJyYWwpLiBgbnVsbGAgaGlkZXMgaXQuIEFsd2F5cyBzaG93biwgbmV2ZXJcbiAgICogb25seSBhZnRlciBhIGZhaWxlZCBzaWduLWluLCBzbyBpdCBzYXlzIG5vdGhpbmcgYWJvdXQgd2hldGhlciBhbiBlbWFpbCBoYXMgYW4gYWNjb3VudC5cbiAgICovXG4gIEBJbnB1dCgpIHNpZ25VcFVybD86IHN0cmluZyB8IG51bGw7XG5cbiAgcHJvdGVjdGVkIHQoa2V5OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiB0cmFuc2xhdGUodGhpcy5hdGxhcy5sb2NhbGl6YXRpb24sIGtleSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgc2lnblVwSHJlZigpOiBzdHJpbmcgfCBudWxsIHtcbiAgICBpZiAodGhpcy5zaWduVXBVcmwgPT09IG51bGwpIHJldHVybiBudWxsO1xuICAgIGlmICh0aGlzLnNpZ25VcFVybCkgcmV0dXJuIHRoaXMuc2lnblVwVXJsO1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gaG9zdGVkU2lnblVwKHtcbiAgICAgICAgZnJvbnRlbmRBcGk6IHRoaXMuYXRsYXMuZnJvbnRlbmRBcGksXG4gICAgICAgIHJlZGlyZWN0VXJsOiB0aGlzLmFmdGVyVXJsID8/ICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyA/IHdpbmRvdy5sb2NhdGlvbi5ocmVmIDogdW5kZWZpbmVkKSxcbiAgICAgICAgbmF2aWdhdGU6IGZhbHNlLFxuICAgICAgfSk7XG4gICAgfSBjYXRjaCB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgcmVhZG9ubHkgZmxvdyA9IG5ldyBBdGxhc0Zsb3dDb250cm9sbGVyKFxuICAgIHRoaXMuYXRsYXMuY3JlYXRlRmFwaUNsaWVudCgpLFxuICAgICgpID0+IHRoaXMuYXRsYXMucmVsb2FkKCksXG4gICAgLy8gUmVzdW1lIG1pZC1mbG93IGlmIGFuIE9BdXRoIHJlZGlyZWN0IGNhbWUgYmFjayBvd2luZyBhIHNlY29uZCBmYWN0b3IuXG4gICAgdGhpcy5hdGxhcy5wZW5kaW5nQXR0ZW1wdCxcbiAgICAoa2V5KSA9PiB0cmFuc2xhdGUodGhpcy5hdGxhcy5sb2NhbGl6YXRpb24sIGtleSksXG4gICk7XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgLy8gSWYgc2VlZGVkIGZyb20gYSBwZW5kaW5nIGF0dGVtcHQgdGhhdCBpcyBhbHJlYWR5IHBvbGxhYmxlLCBzdGFydCBwb2xsaW5nLlxuICAgIHRoaXMuZmxvdy5zeW5jUG9sbGluZygpO1xuICAgIC8vIMKnNSB0aGUgaW5zdGFuY2UncyBjYXB0Y2hhIHNldHRpbmdzIChzd2l0Y2hpbmcgY2FwdGNoYSBvbiBpbiB0aGUgZGFzaGJvYXJkXG4gICAgLy8gZHJhd3MgaXQgaGVyZSB3aXRoIG5vIGNvZGUgY2hhbmdlKSBhbmQgZW1haWwgZGVsaXZlcnkgKG5vIGVtYWlsZWQtY29kZVxuICAgIC8vIG9wdGlvbiB3aGlsZSB0aGUgYXBwIGNhbm5vdCBzZW5kIGVtYWlsKS5cbiAgICBpZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcpIHZvaWQgdGhpcy5mbG93LmxvYWRTZXR0aW5ncygpO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5mbG93LmRlc3Ryb3koKTtcbiAgfVxufVxuIl19
158
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2lnbi1pbi5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL2NvbXBvbmVudHMvc2lnbi1pbi5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLHVCQUF1QixFQUN2QixTQUFTLEVBQ1QsS0FBSyxFQUdMLE1BQU0sR0FDUCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxJQUFJLFlBQVksRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUM1RSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDaEQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUNwQyxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUNoRSxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUNwRSxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQzs7QUFFeEQ7Ozs7Ozs7OztHQVNHO0FBNENILE1BQU0sT0FBTyxlQUFlO0lBQ1QsS0FBSyxHQUFHLE1BQU0sQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUU5QyxpRkFBaUY7SUFDeEUsUUFBUSxDQUFVO0lBQzNCOzs7O09BSUc7SUFDTSxTQUFTLENBQWlCO0lBRXpCLENBQUMsQ0FBQyxHQUFXO1FBQ3JCLE9BQU8sU0FBUyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxFQUFFLEdBQUcsQ0FBQyxDQUFDO0lBQ2pELENBQUM7SUFFRCxzRkFBc0Y7SUFDNUUsYUFBYTtRQUNyQixJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUMsT0FBTztZQUFFLE9BQU8sSUFBSSxDQUFDO1FBQzNDLE9BQU8sbUJBQW1CLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUUsRUFBRSxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0lBQzNFLENBQUM7SUFFUyxVQUFVO1FBQ2xCLElBQUksSUFBSSxDQUFDLFNBQVMsS0FBSyxJQUFJO1lBQUUsT0FBTyxJQUFJLENBQUM7UUFDekMsSUFBSSxJQUFJLENBQUMsU0FBUztZQUFFLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQztRQUMxQyxJQUFJLENBQUM7WUFDSCxPQUFPLFlBQVksQ0FBQztnQkFDbEIsV0FBVyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVztnQkFDbkMsV0FBVyxFQUFFLElBQUksQ0FBQyxRQUFRLElBQUksQ0FBQyxPQUFPLE1BQU0sS0FBSyxXQUFXLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7Z0JBQ2hHLFFBQVEsRUFBRSxLQUFLO2FBQ2hCLENBQUMsQ0FBQztRQUNMLENBQUM7UUFBQyxNQUFNLENBQUM7WUFDUCxPQUFPLElBQUksQ0FBQztRQUNkLENBQUM7SUFDSCxDQUFDO0lBRWtCLElBQUksR0FBRyxJQUFJLG1CQUFtQixDQUMvQyxJQUFJLENBQUMsS0FBSyxDQUFDLGdCQUFnQixFQUFFLEVBQzdCLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFO0lBQ3pCLHdFQUF3RTtJQUN4RSxJQUFJLENBQUMsS0FBSyxDQUFDLGNBQWMsRUFDekIsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFlBQVksRUFBRSxHQUFHLENBQUMsQ0FDakQsQ0FBQztJQUVGLFFBQVE7UUFDTiw0RUFBNEU7UUFDNUUsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUN4Qiw0RUFBNEU7UUFDNUUseUVBQXlFO1FBQ3pFLDJDQUEyQztRQUMzQyxJQUFJLE9BQU8sTUFBTSxLQUFLLFdBQVc7WUFBRSxLQUFLLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7SUFDbkUsQ0FBQztJQUVELFdBQVc7UUFDVCxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO0lBQ3RCLENBQUM7d0dBdkRVLGVBQWU7NEZBQWYsZUFBZSxtSUF0Q2hCOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FvQ1QsNERBckNTLG9CQUFvQixnYkFBRSxzQkFBc0I7OzRGQXVDM0MsZUFBZTtrQkEzQzNCLFNBQVM7bUJBQUM7b0JBQ1QsUUFBUSxFQUFFLGVBQWU7b0JBQ3pCLFVBQVUsRUFBRSxJQUFJO29CQUNoQixlQUFlLEVBQUUsdUJBQXVCLENBQUMsTUFBTTtvQkFDL0MsT0FBTyxFQUFFLENBQUMsb0JBQW9CLEVBQUUsc0JBQXNCLENBQUM7b0JBQ3ZELFFBQVEsRUFBRTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBb0NUO2lCQUNGOzhCQUtVLFFBQVE7c0JBQWhCLEtBQUs7Z0JBTUcsU0FBUztzQkFBakIsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDb21wb25lbnQsXG4gIElucHV0LFxuICBPbkRlc3Ryb3ksXG4gIE9uSW5pdCxcbiAgaW5qZWN0LFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IGxhc3RVc2VkTWV0aG9kTGFiZWwsIHNpZ25VcCBhcyBob3N0ZWRTaWduVXAgfSBmcm9tICdAYXRsYXNhdXRoL2pzJztcbmltcG9ydCB7IEF0bGFzU2VydmljZSB9IGZyb20gJy4uL2F0bGFzLnNlcnZpY2UnO1xuaW1wb3J0IHsgdHJhbnNsYXRlIH0gZnJvbSAnLi4vaTE4bic7XG5pbXBvcnQgeyBBdHRlbXB0Rmxvd0NvbXBvbmVudCB9IGZyb20gJy4vYXR0ZW1wdC1mbG93LmNvbXBvbmVudCc7XG5pbXBvcnQgeyBSZWNvdmVyeUNvZGVzQ29tcG9uZW50IH0gZnJvbSAnLi9yZWNvdmVyeS1jb2Rlcy5jb21wb25lbnQnO1xuaW1wb3J0IHsgQXRsYXNGbG93Q29udHJvbGxlciB9IGZyb20gJy4vZmxvdy1jb250cm9sbGVyJztcblxuLyoqXG4gKiBgPGF0bGFzLXNpZ24taW4+YCDigJQgdGhlIGZ1bGwsIG11bHRpLXN0ZXAgc2lnbi1pbiBmbG93IGRyaXZlbiBlbnRpcmVseSBieSB0aGVcbiAqIHNlcnZlci1zaWRlIGF0dGVtcHQgc3RhdHVzLiBUaGUgQW5ndWxhciBwZWVyIG9mIFJlYWN0J3MgYDxTaWduSW4vPmAuIERyYXdzIHRoZVxuICogaW5zdGFuY2UncyBzaWduLWluIGNhcHRjaGEgd2hlbiBpdCBpcyByZXF1aXJlZCAoYWx3YXlzLW9uLCBvciBhXG4gKiBgbmVlZHNfY2FwdGNoYWAgY2hhbGxlbmdlKS5cbiAqXG4gKiBgYGBodG1sXG4gKiA8YXRsYXMtc2lnbi1pbiAqYXRsYXNTaWduZWRPdXQgYWZ0ZXJVcmw9XCIvZGFzaGJvYXJkXCI+PC9hdGxhcy1zaWduLWluPlxuICogYGBgXG4gKi9cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2F0bGFzLXNpZ24taW4nLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgaW1wb3J0czogW0F0dGVtcHRGbG93Q29tcG9uZW50LCBSZWNvdmVyeUNvZGVzQ29tcG9uZW50XSxcbiAgdGVtcGxhdGU6IGBcbiAgICBAaWYgKGxhc3RVc2VkTGFiZWwoKTsgYXMgbGFiZWwpIHtcbiAgICAgIDxwIGNsYXNzPVwiYXRsYXMtdGV4dCBhdGxhcy1sYXN0LXVzZWQtaGludFwiIGRhdGEtYXRsYXM9XCJsYXN0LXVzZWRcIiBbYXR0ci5kYXRhLWF0bGFzLW1ldGhvZF09XCJmbG93Lmxhc3RNZXRob2QoKVwiPlxuICAgICAgICB7eyB0KCdzaWduSW4ubGFzdFVzZWQnKSB9fToge3sgbGFiZWwgfX1cbiAgICAgIDwvcD5cbiAgICB9XG4gICAgQGlmIChmbG93LnJlY292ZXJ5Q29kZXMoKTsgYXMgY29kZXMpIHtcbiAgICAgIDxhdGxhcy1yZWNvdmVyeS1jb2RlcyBbY29kZXNdPVwiY29kZXNcIiBbYnVzeV09XCJmbG93LnN0YXRlKCkuYnVzeVwiIChzYXZlZCk9XCJmbG93LnNhdmVSZWNvdmVyeUNvZGVzKClcIj48L2F0bGFzLXJlY292ZXJ5LWNvZGVzPlxuICAgIH0gQGVsc2Uge1xuICAgIDxhdGxhcy1hdHRlbXB0LWZsb3dcbiAgICAgIFthdHRlbXB0XT1cImZsb3cuc3RhdGUoKS5hdHRlbXB0XCJcbiAgICAgIFtidXN5XT1cImZsb3cuc3RhdGUoKS5idXN5XCJcbiAgICAgIFtlcnJvcnNdPVwiZmxvdy5zdGF0ZSgpLmVycm9yc1wiXG4gICAgICBbc2Vzc2lvbktlcHRdPVwiZmxvdy5zdGF0ZSgpLnNlc3Npb25LZXB0XCJcbiAgICAgIHRpdGxlS2V5PVwic2lnbkluLnRpdGxlXCJcbiAgICAgIFtjYXB0Y2hhXT1cImZsb3cuY2FwdGNoYURyYXduKCkgPyBmbG93LmNhcHRjaGEgOiBudWxsXCJcbiAgICAgIFtmaXJzdEZhY3RvcnNdPVwiZmxvdy5maXJzdEZhY3RvcnMoKVwiXG4gICAgICBbcHJlcGFyZWRGYWN0b3JdPVwiZmxvdy5wcmVwYXJlZEZhY3RvcigpXCJcbiAgICAgIFtvZmZlckVtYWlsU2Vjb25kRmFjdG9yXT1cImZsb3cuc2V0dGluZ3MoKT8uYWNjb3VudD8uZW1haWxTZWNvbmRGYWN0b3IgPT09IHRydWVcIlxuICAgICAgW2VtYWlsZWRTZWNvbmRGYWN0b3JdPVwiZmxvdy5lbWFpbFNlY29uZEZhY3RvcigpXCJcbiAgICAgIChzdWJtaXRGbG93KT1cImZsb3cuc3VibWl0KCRldmVudClcIlxuICAgICAgKGNob29zZUZhY3Rvcik9XCJmbG93LnByZXBhcmUoJGV2ZW50KVwiXG4gICAgICBbb2ZmZXJTbXNTZWNvbmRGYWN0b3JdPVwiZmxvdy5zZXR0aW5ncygpICE9PSBudWxsICYmIGZsb3cubWZhQ2hvaWNlcygpLnNtc1wiXG4gICAgICBbdGV4dGVkU2Vjb25kRmFjdG9yXT1cImZsb3cuc21zU2Vjb25kRmFjdG9yKClcIlxuICAgICAgW2Vucm9sbG1lbnRdPVwiZmxvdy5lbnJvbGxtZW50XCJcbiAgICAgIFtlbnJvbGxtZW50U3RhdGVdPVwiZmxvdy5lbnJvbGxtZW50U3RhdGUoKVwiXG4gICAgICAoZW1haWxTZWNvbmRGYWN0b3IpPVwiZmxvdy5zZW5kRW1haWxTZWNvbmRGYWN0b3IoKVwiXG4gICAgICAoc21zU2Vjb25kRmFjdG9yKT1cImZsb3cuc2VuZFNtc1NlY29uZEZhY3RvcigpXCJcbiAgICAgIChwb2xpY3lEZWNsaW5lZCk9XCJmbG93LmRlY2xpbmVQb2xpY3koJGV2ZW50KVwiXG4gICAgPjwvYXRsYXMtYXR0ZW1wdC1mbG93PlxuICAgIH1cbiAgICBAaWYgKGZsb3cuc3RhdGUoKS5hdHRlbXB0Py5zdGF0dXMgIT09ICdjb21wbGV0ZScgJiYgc2lnblVwSHJlZigpOyBhcyBocmVmKSB7XG4gICAgICA8cCBjbGFzcz1cImF0bGFzLWZvb3RlclwiIGRhdGEtYXRsYXMtc2lnbi11cC1wcm9tcHQ9XCJcIj5cbiAgICAgICAge3sgdCgnc2lnbkluLm5vQWNjb3VudCcpIH19IDxhIGNsYXNzPVwiYXRsYXMtbGlua1wiIFtocmVmXT1cImhyZWZcIj57eyB0KCdzaWduSW4uc2lnblVwTGluaycpIH19PC9hPlxuICAgICAgPC9wPlxuICAgIH1cbiAgYCxcbn0pXG5leHBvcnQgY2xhc3MgU2lnbkluQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3kge1xuICBwcml2YXRlIHJlYWRvbmx5IGF0bGFzID0gaW5qZWN0KEF0bGFzU2VydmljZSk7XG5cbiAgLyoqIFdoZXJlIHRvIHNlbmQgdGhlIHVzZXIgb25jZSB0aGUgZmxvdyBjb21wbGV0ZXMuIFJlc2VydmVkIGZvciBob3N0IHJvdXRpbmcuICovXG4gIEBJbnB1dCgpIGFmdGVyVXJsPzogc3RyaW5nO1xuICAvKipcbiAgICogV2hlcmUgXCJObyBhY2NvdW50PyBTaWduIHVwXCIgZ29lcy4gRGVmYXVsdDogdGhlIGluc3RhbmNlJ3MgaG9zdGVkIHNpZ24tdXBcbiAgICogcGFnZSAoY2FycnlpbmcgdGhlIHZpc2l0b3IncyByZWZlcnJhbCkuIGBudWxsYCBoaWRlcyBpdC4gQWx3YXlzIHNob3duLCBuZXZlclxuICAgKiBvbmx5IGFmdGVyIGEgZmFpbGVkIHNpZ24taW4sIHNvIGl0IHNheXMgbm90aGluZyBhYm91dCB3aGV0aGVyIGFuIGVtYWlsIGhhcyBhbiBhY2NvdW50LlxuICAgKi9cbiAgQElucHV0KCkgc2lnblVwVXJsPzogc3RyaW5nIHwgbnVsbDtcblxuICBwcm90ZWN0ZWQgdChrZXk6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRyYW5zbGF0ZSh0aGlzLmF0bGFzLmxvY2FsaXphdGlvbiwga2V5KTtcbiAgfVxuXG4gIC8qKiBcIkxhc3QgdXNlZDogUGFzc3dvcmRcIiBvbiB0aGUgaWRlbnRpZmllciBzdGVwLCB3aGVuIHRoZSBpbnN0YW5jZSBzaG93cyB0aGUgaGludC4gKi9cbiAgcHJvdGVjdGVkIGxhc3RVc2VkTGFiZWwoKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgaWYgKHRoaXMuZmxvdy5zdGF0ZSgpLmF0dGVtcHQpIHJldHVybiBudWxsO1xuICAgIHJldHVybiBsYXN0VXNlZE1ldGhvZExhYmVsKHRoaXMuZmxvdy5sYXN0TWV0aG9kKCksIChrZXkpID0+IHRoaXMudChrZXkpKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBzaWduVXBIcmVmKCk6IHN0cmluZyB8IG51bGwge1xuICAgIGlmICh0aGlzLnNpZ25VcFVybCA9PT0gbnVsbCkgcmV0dXJuIG51bGw7XG4gICAgaWYgKHRoaXMuc2lnblVwVXJsKSByZXR1cm4gdGhpcy5zaWduVXBVcmw7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBob3N0ZWRTaWduVXAoe1xuICAgICAgICBmcm9udGVuZEFwaTogdGhpcy5hdGxhcy5mcm9udGVuZEFwaSxcbiAgICAgICAgcmVkaXJlY3RVcmw6IHRoaXMuYWZ0ZXJVcmwgPz8gKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnID8gd2luZG93LmxvY2F0aW9uLmhyZWYgOiB1bmRlZmluZWQpLFxuICAgICAgICBuYXZpZ2F0ZTogZmFsc2UsXG4gICAgICB9KTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgfVxuXG4gIHByb3RlY3RlZCByZWFkb25seSBmbG93ID0gbmV3IEF0bGFzRmxvd0NvbnRyb2xsZXIoXG4gICAgdGhpcy5hdGxhcy5jcmVhdGVGYXBpQ2xpZW50KCksXG4gICAgKCkgPT4gdGhpcy5hdGxhcy5yZWxvYWQoKSxcbiAgICAvLyBSZXN1bWUgbWlkLWZsb3cgaWYgYW4gT0F1dGggcmVkaXJlY3QgY2FtZSBiYWNrIG93aW5nIGEgc2Vjb25kIGZhY3Rvci5cbiAgICB0aGlzLmF0bGFzLnBlbmRpbmdBdHRlbXB0LFxuICAgIChrZXkpID0+IHRyYW5zbGF0ZSh0aGlzLmF0bGFzLmxvY2FsaXphdGlvbiwga2V5KSxcbiAgKTtcblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICAvLyBJZiBzZWVkZWQgZnJvbSBhIHBlbmRpbmcgYXR0ZW1wdCB0aGF0IGlzIGFscmVhZHkgcG9sbGFibGUsIHN0YXJ0IHBvbGxpbmcuXG4gICAgdGhpcy5mbG93LnN5bmNQb2xsaW5nKCk7XG4gICAgLy8gwqc1IHRoZSBpbnN0YW5jZSdzIGNhcHRjaGEgc2V0dGluZ3MgKHN3aXRjaGluZyBjYXB0Y2hhIG9uIGluIHRoZSBkYXNoYm9hcmRcbiAgICAvLyBkcmF3cyBpdCBoZXJlIHdpdGggbm8gY29kZSBjaGFuZ2UpIGFuZCBlbWFpbCBkZWxpdmVyeSAobm8gZW1haWxlZC1jb2RlXG4gICAgLy8gb3B0aW9uIHdoaWxlIHRoZSBhcHAgY2Fubm90IHNlbmQgZW1haWwpLlxuICAgIGlmICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJykgdm9pZCB0aGlzLmZsb3cubG9hZFNldHRpbmdzKCk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLmZsb3cuZGVzdHJveSgpO1xuICB9XG59XG4iXX0=