@atlasauth/angular 0.12.0 → 0.14.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.
@@ -1,5 +1,5 @@
1
1
  import { EventEmitter } from '@angular/core';
2
- import { type AttemptView, type CaptchaController, type FieldError, type MfaEnrollmentController, type MfaEnrollmentState, type MfaEnrollmentStrategy } from '@atlasauth/js';
2
+ import { type AttemptView, type CaptchaController, type FieldError, type FlowState, type MfaEnrollmentController, type MfaEnrollmentState, type MfaEnrollmentStrategy } from '@atlasauth/js';
3
3
  import { type ElementKey } from '../appearance';
4
4
  import * as i0 from "@angular/core";
5
5
  /**
@@ -9,10 +9,11 @@ import * as i0 from "@angular/core";
9
9
  * minor. For a `message` row, `labelKey` carries the message's i18n key.
10
10
  */
11
11
  interface StepField {
12
- kind: 'input' | 'message' | 'alert';
12
+ kind: 'input' | 'message' | 'alert' | 'released';
13
13
  name: string;
14
14
  labelKey: string;
15
15
  type: string;
16
+ autocomplete?: string;
16
17
  }
17
18
  /**
18
19
  * The server-driven flow shell, shared by `<atlas-sign-in>` and
@@ -46,10 +47,16 @@ export declare class AttemptFlowComponent {
46
47
  firstFactors: string[] | null;
47
48
  /** The first factor already sent (`AtlasFlowController.preparedFactor()`): its code is collected. */
48
49
  preparedFactor: string | null;
50
+ /** `FlowState.passwordHold`: where the proof went, and whether the password signs in now. */
51
+ passwordHold: FlowState['passwordHold'];
52
+ /** `AtlasFlowController.holdProof()`: the emailed proof a password hold still waits on. */
53
+ holdProof: 'email_code' | 'email_link' | null;
49
54
  /** Emits the collected field values when the form is submitted. */
50
55
  submitFlow: EventEmitter<Record<string, string>>;
51
56
  /** Emits when the user picks a first factor the server must send first (an emailed code). */
52
- chooseFactor: EventEmitter<"email_code">;
57
+ chooseFactor: EventEmitter<"email_code" | "email_link">;
58
+ /** Emits on "Use your password instead", from an emailed factor already sent. */
59
+ usePassword: EventEmitter<void>;
53
60
  /**
54
61
  * Offer "Email me a code instead" at the second factor (the instance's
55
62
  * `account.emailSecondFactor`); `emailSecondFactor` asks for it and
@@ -112,10 +119,42 @@ export declare class AttemptFlowComponent {
112
119
  protected smsSecondFactorSentTo(): string | null;
113
120
  protected formErrors(): FieldError[];
114
121
  protected fieldErrorsFor(name: string): FieldError[];
115
- private step;
122
+ protected step(): {
123
+ kind: "collect_first_factor";
124
+ strategies: string[];
125
+ } | {
126
+ kind: "collect_second_factor";
127
+ } | {
128
+ kind: "enroll_second_factor";
129
+ } | {
130
+ kind: "collect_email_code";
131
+ } | {
132
+ kind: "collect_captcha";
133
+ } | {
134
+ kind: "await_oauth";
135
+ } | {
136
+ kind: "collect_new_password";
137
+ } | {
138
+ kind: "accept_policies";
139
+ policies: import("@atlasauth/js").PendingPolicy[];
140
+ } | {
141
+ kind: "complete_required_action";
142
+ actions: import("@atlasauth/js").PendingRequiredAction[];
143
+ } | {
144
+ kind: "done";
145
+ sessionId: string;
146
+ } | {
147
+ kind: "restart";
148
+ reason: "abandoned";
149
+ } | {
150
+ kind: "unknown";
151
+ status: string;
152
+ } | {
153
+ readonly kind: "collect_identifier";
154
+ };
116
155
  protected showCaptcha(): boolean;
117
156
  /** The first factors on offer at a `needs_first_factor` step (empty on any other). */
118
- private offered;
157
+ protected offered(): string[];
119
158
  protected linkOnly(): boolean;
120
159
  protected showEmailSecondFactor(): boolean;
121
160
  /** Where the emailed second-factor code went (masked), once it was sent. */
@@ -123,11 +162,13 @@ export declare class AttemptFlowComponent {
123
162
  protected showEmailCodeOption(): boolean;
124
163
  /** The "we sent a code to …" line on the code step. */
125
164
  protected codeSentText(): string | null;
165
+ /** The "we sent a link to …" line, once a link was sent. */
166
+ protected linkSentText(): string | null;
126
167
  /** The attempt is `needs_policy_acceptance`. */
127
168
  protected awaitingPolicies(): boolean;
128
169
  protected showSubmit(): boolean;
129
170
  protected fields(): StepField[];
130
171
  static ɵfac: i0.ɵɵFactoryDeclaration<AttemptFlowComponent, never>;
131
- static ɵcmp: i0.ɵɵComponentDeclaration<AttemptFlowComponent, "atlas-attempt-flow", never, { "attempt": { "alias": "attempt"; "required": false; }; "busy": { "alias": "busy"; "required": false; }; "errors": { "alias": "errors"; "required": false; }; "sessionKept": { "alias": "sessionKept"; "required": false; }; "titleKey": { "alias": "titleKey"; "required": false; }; "captcha": { "alias": "captcha"; "required": false; }; "firstFactors": { "alias": "firstFactors"; "required": false; }; "preparedFactor": { "alias": "preparedFactor"; "required": false; }; "offerEmailSecondFactor": { "alias": "offerEmailSecondFactor"; "required": false; }; "emailedSecondFactor": { "alias": "emailedSecondFactor"; "required": false; }; "offerSmsSecondFactor": { "alias": "offerSmsSecondFactor"; "required": false; }; "textedSecondFactor": { "alias": "textedSecondFactor"; "required": false; }; "enrollment": { "alias": "enrollment"; "required": false; }; "enrollmentState": { "alias": "enrollmentState"; "required": false; }; "emailVerification": { "alias": "emailVerification"; "required": false; }; }, { "submitFlow": "submitFlow"; "chooseFactor": "chooseFactor"; "emailSecondFactor": "emailSecondFactor"; "smsSecondFactor": "smsSecondFactor"; "resend": "resend"; "policyDeclined": "policyDeclined"; }, never, never, true, never>;
172
+ static ɵcmp: i0.ɵɵComponentDeclaration<AttemptFlowComponent, "atlas-attempt-flow", never, { "attempt": { "alias": "attempt"; "required": false; }; "busy": { "alias": "busy"; "required": false; }; "errors": { "alias": "errors"; "required": false; }; "sessionKept": { "alias": "sessionKept"; "required": false; }; "titleKey": { "alias": "titleKey"; "required": false; }; "captcha": { "alias": "captcha"; "required": false; }; "firstFactors": { "alias": "firstFactors"; "required": false; }; "preparedFactor": { "alias": "preparedFactor"; "required": false; }; "passwordHold": { "alias": "passwordHold"; "required": false; }; "holdProof": { "alias": "holdProof"; "required": false; }; "offerEmailSecondFactor": { "alias": "offerEmailSecondFactor"; "required": false; }; "emailedSecondFactor": { "alias": "emailedSecondFactor"; "required": false; }; "offerSmsSecondFactor": { "alias": "offerSmsSecondFactor"; "required": false; }; "textedSecondFactor": { "alias": "textedSecondFactor"; "required": false; }; "enrollment": { "alias": "enrollment"; "required": false; }; "enrollmentState": { "alias": "enrollmentState"; "required": false; }; "emailVerification": { "alias": "emailVerification"; "required": false; }; }, { "submitFlow": "submitFlow"; "chooseFactor": "chooseFactor"; "usePassword": "usePassword"; "emailSecondFactor": "emailSecondFactor"; "smsSecondFactor": "smsSecondFactor"; "resend": "resend"; "policyDeclined": "policyDeclined"; }, never, never, true, never>;
132
173
  }
133
174
  export {};
@@ -1,5 +1,5 @@
1
1
  import { WritableSignal } from '@angular/core';
2
- import { FapiClient, PolicyAcceptanceController, type CaptchaController, type FlowState, type InstanceSettings, type MfaChoices, type MfaEnrollmentController, type MfaEnrollmentState } from '@atlasauth/js';
2
+ import { FapiClient, PolicyAcceptanceController, type CaptchaController, type FlowState, type InstanceSettings, type MfaChoices, type MfaEnrollmentController, type MfaEnrollmentState, type PasskeySignInController } from '@atlasauth/js';
3
3
  /**
4
4
  * The server-driven sign-in / sign-up engine, shared by `<atlas-sign-in>` and
5
5
  * `<atlas-sign-up>` — the Angular counterpart of React's `useFlow` hook.
@@ -19,6 +19,8 @@ export declare class AtlasFlowController {
19
19
  private readonly reload;
20
20
  /** Resolves the captcha messages' catalog keys. Defaults to en-US. */
21
21
  private readonly t;
22
+ /** Wait for {@link continueAfterExistingAccount} (`<atlas-sign-up>` draws the notice). */
23
+ private readonly holdExistingAccountNotice;
22
24
  readonly state: WritableSignal<FlowState>;
23
25
  /**
24
26
  * The instance's public sign-in / sign-up settings (captcha, sign-up fields,
@@ -44,7 +46,7 @@ export declare class AtlasFlowController {
44
46
  * current `needs_first_factor` step — the form then collects its code. Null
45
47
  * otherwise.
46
48
  */
47
- readonly preparedFactor: WritableSignal<"email_code">;
49
+ readonly preparedFactor: WritableSignal<"email_code" | "email_link">;
48
50
  /**
49
51
  * "Email me a code instead" at the second factor ({@link sendEmailSecondFactor}):
50
52
  * in flight, where the code went, or why it was not sent. Null until asked,
@@ -73,6 +75,13 @@ export declare class AtlasFlowController {
73
75
  * {@link create} sends their acceptances and reloads them after a refusal.
74
76
  */
75
77
  readonly policies: PolicyAcceptanceController;
78
+ /**
79
+ * Passkey sign-in (the "Sign in with a passkey" button and passkey autofill on
80
+ * the identifier field). The outcome goes through the same completion as every sign-in.
81
+ */
82
+ readonly passkey: PasskeySignInController;
83
+ /** Whether this browser can run WebAuthn; `<atlas-sign-in>` sets it after it is created in a browser. */
84
+ readonly passkeySupported: WritableSignal<boolean>;
76
85
  private pollTimer;
77
86
  private identifier;
78
87
  constructor(client: FapiClient, reload: () => Promise<boolean>, pending: {
@@ -80,7 +89,18 @@ export declare class AtlasFlowController {
80
89
  status: string;
81
90
  } | null,
82
91
  /** Resolves the captcha messages' catalog keys. Defaults to en-US. */
83
- t?: (key: string) => string);
92
+ t?: (key: string) => string,
93
+ /** Wait for {@link continueAfterExistingAccount} (`<atlas-sign-up>` draws the notice). */
94
+ holdExistingAccountNotice?: boolean);
95
+ /** Why "Continue with Atlas" could not start (the server's message); null otherwise. */
96
+ readonly signInWithAtlasError: WritableSignal<string>;
97
+ /**
98
+ * "Continue with Atlas" (when `settings().signInWithAtlas` is set): starts the
99
+ * SSO sign-in and sends the browser to Atlas.
100
+ */
101
+ signInWithAtlas(connectionId: string): Promise<void>;
102
+ /** "Sign in with a passkey" is offered: the first step, the instance turned passkey sign-in on, and the browser can. */
103
+ passkeyOffered(): boolean;
84
104
  /** What the app lets the MFA steps offer (from {@link settings}). */
85
105
  mfaChoices(): MfaChoices;
86
106
  /** Start the enrolment step for its attempt, or reset it once the flow leaves. */
@@ -93,6 +113,14 @@ export declare class AtlasFlowController {
93
113
  * (`settings.emailDelivery.available === false`). Empty on any other step.
94
114
  */
95
115
  firstFactors(): string[];
116
+ /**
117
+ * The emailed proof a password hold still waits on (`FlowState.passwordHold`): the
118
+ * code, or a link where the instance verifies by link only. Null with no hold, once
119
+ * proven, or while the app cannot deliver email.
120
+ */
121
+ holdProof(): 'email_code' | 'email_link' | null;
122
+ /** Back from the emailed factor to the password field. */
123
+ usePassword(): void;
96
124
  /**
97
125
  * True when email + password sign-up cannot complete because the app cannot
98
126
  * send the verification email (`settings.emailDelivery.passwordSignUp === false`):
@@ -104,9 +132,10 @@ export declare class AtlasFlowController {
104
132
  /**
105
133
  * Ask the server to email a sign-in code for the current `needs_first_factor`
106
134
  * step (`POST …/prepare_first_factor`); the form then collects the code, which
107
- * {@link submit} posts as the `email_code` strategy.
135
+ * {@link submit} posts as the `email_code` strategy. While a password hold waits
136
+ * on it ({@link holdProof}), this emails that proof instead.
108
137
  */
109
- prepare(strategy: 'email_code'): Promise<void>;
138
+ prepare(strategy: 'email_code' | 'email_link'): Promise<void>;
110
139
  /** Keep both captchas in step with the settings and the flow's current step. */
111
140
  private syncCaptcha;
112
141
  private setState;
@@ -166,6 +195,10 @@ export declare class AtlasFlowController {
166
195
  recoveryCodes(): string[] | null;
167
196
  /** "I've saved my codes": forget the recovery codes and finish the sign-in. */
168
197
  saveRecoveryCodes(): Promise<void>;
198
+ /** The address belonged to an existing account: the notice is up until {@link continueAfterExistingAccount}. */
199
+ existingAccountNotice(): boolean;
200
+ /** The user read the notice: finish the sign-up. */
201
+ continueAfterExistingAccount(): Promise<void>;
169
202
  private finish;
170
203
  /** Start/stop the §5.3 magic-link poll to match the current state. */
171
204
  syncPolling(): void;
@@ -24,8 +24,13 @@ export declare class SignInComponent implements OnInit, OnDestroy {
24
24
  protected t(key: string): string;
25
25
  /** "Last used: Password" on the identifier step, when the instance shows the hint. */
26
26
  protected lastUsedLabel(): string | null;
27
+ /** The "Sign in with Atlas" connection, on the first step, when the instance has it on. */
28
+ protected atlasConnection(): string | null;
27
29
  protected signUpHref(): string | null;
28
30
  protected readonly flow: AtlasFlowController;
31
+ private readonly passkeyOffered;
32
+ protected readonly passkeyAutofill: import("@angular/core").EffectRef;
33
+ protected submitIdentifier(values: Record<string, string>): void;
29
34
  ngOnInit(): void;
30
35
  ngOnDestroy(): void;
31
36
  static ɵfac: i0.ɵɵFactoryDeclaration<SignInComponent, never>;
@@ -19,6 +19,8 @@ export declare class SignUpComponent implements OnInit, OnDestroy {
19
19
  private readonly atlas;
20
20
  /** Where to send the user once the flow completes. Reserved for host routing. */
21
21
  afterUrl?: string;
22
+ /** Where the existing-account notice's "Forgot password?" goes. Default: the hosted sign-in page; `null` hides it. */
23
+ resetPasswordUrl?: string | null;
22
24
  protected readonly flow: AtlasFlowController;
23
25
  /** Password or passkey-only sign-up (the latter when the instance offers it). */
24
26
  protected readonly mode: import("@angular/core").WritableSignal<"password" | "passkey">;
@@ -27,6 +29,7 @@ export declare class SignUpComponent implements OnInit, OnDestroy {
27
29
  email: 'off' | 'optional' | 'required';
28
30
  } | null;
29
31
  protected toggleMode(): void;
32
+ protected resetHref(): string | null;
30
33
  protected awaitingPasskey(): boolean;
31
34
  protected t(key: string): string;
32
35
  protected cls(key: ElementKey, base: string): string;
@@ -34,5 +37,5 @@ export declare class SignUpComponent implements OnInit, OnDestroy {
34
37
  ngOnInit(): void;
35
38
  ngOnDestroy(): void;
36
39
  static ɵfac: i0.ɵɵFactoryDeclaration<SignUpComponent, never>;
37
- static ɵcmp: i0.ɵɵComponentDeclaration<SignUpComponent, "atlas-sign-up", never, { "afterUrl": { "alias": "afterUrl"; "required": false; }; }, {}, never, never, true, never>;
40
+ static ɵcmp: i0.ɵɵComponentDeclaration<SignUpComponent, "atlas-sign-up", never, { "afterUrl": { "alias": "afterUrl"; "required": false; }; "resetPasswordUrl": { "alias": "resetPasswordUrl"; "required": false; }; }, {}, never, never, true, never>;
38
41
  }
@@ -1,4 +1,4 @@
1
1
  import type { AtlasSdkInfo } from '@atlasauth/js';
2
2
  /** This package's version, sent as `X-Atlas-SDK` (kept in step with package.json by a test). */
3
- export declare const ATLAS_ANGULAR_VERSION = "0.11.0";
3
+ export declare const ATLAS_ANGULAR_VERSION = "0.14.0";
4
4
  export declare const ATLAS_ANGULAR_SDK: AtlasSdkInfo;
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "@atlasauth/angular",
3
- "version": "0.12.0",
3
+ "version": "0.14.0",
4
4
  "description": "Official Angular SDK for Atlas — the Angular peer of @atlasauth/react.",
5
5
  "license": "MIT",
6
- "module": "./dist/fesm2022/atlas-angular.mjs",
6
+ "module": "./dist/fesm2022/atlasauth-angular.mjs",
7
7
  "typings": "./dist/index.d.ts",
8
8
  "types": "./dist/index.d.ts",
9
9
  "exports": {
@@ -12,15 +12,15 @@
12
12
  },
13
13
  ".": {
14
14
  "types": "./dist/index.d.ts",
15
- "esm2022": "./dist/esm2022/atlas-angular.mjs",
16
- "default": "./dist/fesm2022/atlas-angular.mjs"
15
+ "esm2022": "./dist/esm2022/atlasauth-angular.mjs",
16
+ "default": "./dist/fesm2022/atlasauth-angular.mjs"
17
17
  }
18
18
  },
19
19
  "sideEffects": false,
20
20
  "dependencies": {
21
21
  "tslib": "^2.6.3",
22
22
  "@atlasauth/design": "0.3.0",
23
- "@atlasauth/js": "0.26.1",
23
+ "@atlasauth/js": "0.32.0",
24
24
  "@atlasauth/authz": "0.3.0"
25
25
  },
26
26
  "peerDependencies": {