@dloizides/auth-web 1.11.0 → 1.12.1

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 CHANGED
@@ -1,5 +1,81 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.12.1 (2026-07-17)
4
+
5
+ Internal refactor only — **no API change, no behaviour change**. The public
6
+ export surface (`src/index.ts`) is byte-identical to 1.12.0; every consumer
7
+ (zygos, katalogos, erevna, kefi, ichnos) keeps importing the same symbols with
8
+ the same types from the same entry point.
9
+
10
+ Two oversized source files from the demo-credential work were split to satisfy
11
+ the repo size limits (files < 300 lines, components < 200):
12
+
13
+ - **`src/components/labels.ts` (511 lines) → `src/components/labels/`.** The
14
+ single label bag is now one file per component family (`loginLabels.ts`,
15
+ `forgotPasswordLabels.ts`, `otpLabels.ts`, `pinLabels.ts`, `devicePinLabels.ts`,
16
+ `passkeyLabels.ts`, `preferredMethodLabels.ts`, `demoLabels.ts`,
17
+ `resetPasswordLabels.ts`) behind a `labels/index.ts` barrel that re-exports the
18
+ exact same names, so `./labels` remains a single import site.
19
+ - **`src/components/LoginForm.tsx` (253 lines) → render body slimmed.** The
20
+ prop-doc-heavy `LoginFormProps` interface moved to a co-located
21
+ `LoginForm.types.ts` (re-exported from `LoginForm.tsx`), and the submit branch
22
+ logic moved into a unit-tested `useLoginSubmit` hook.
23
+
24
+ ### Changed
25
+
26
+ - No runtime change. Splitting only; identical bundled output.
27
+
28
+ Completes the demo-credential feature for **BFF-fronted apps**, whose demo pair
29
+ arrives ASYNChronously from `GET /bff/config` rather than a module-level const (a
30
+ const would bake the credentials into a bundle handed to a customer to
31
+ self-deploy). Two gaps closed:
32
+
33
+ 1. `prefillOnMount` was inert for async credentials (1.11.0 bug).
34
+ 2. `useBffLoginConfig().config` dropped the `demo` field the BFF now serves.
35
+
36
+ Requires `@dloizides/auth-client` **>= 4.2.0** (which surfaces `demo` on
37
+ `BffLoginConfig`) — the peer floor is raised accordingly. Additive for existing
38
+ consumers: the new `LoginForm` prop is optional and the synchronous /
39
+ module-const path is byte-identical.
40
+
41
+ ### Fixed
42
+
43
+ - **`prefillOnMount` now honours credentials that arrive AFTER mount.** `useState`
44
+ reads its initial argument on the first render only, so a demo pair landing a
45
+ render later (every BFF app) was silently dropped and the form stayed empty
46
+ beside a populated hint. `useDemoCredentials` now seeds when the resolved pair
47
+ transitions to non-null (or to a genuinely different pair), gated by VALUE so a
48
+ react-query refetch handing back a fresh-but-equal object does not re-seed on a
49
+ loop.
50
+
51
+ ### Added
52
+
53
+ - **`config.demo` carries through `useBffLoginConfig`.** `BffLoginConfig` gains
54
+ `demo?: DemoCredentials | null`, so the intended wiring works end-to-end:
55
+ ```tsx
56
+ const { config } = useBffLoginConfig(bffAuthClient);
57
+ const demo = useDemoCredentials({ credentials: config.demo ?? undefined, prefillOnMount: true });
58
+ ```
59
+ - **`PrefillIntent`** enum + **`LoginForm` gains `prefillIntent`** — the "don't
60
+ fight the user" control. An `Opportunistic` re-seed (a late config fetch) is
61
+ DROPPED unless both fields are still empty, so it never overwrites what a real
62
+ account holder is typing while `/bff/config` is in flight; an `Explicit` re-seed
63
+ (the user tapped "use these credentials") always applies. `useDemoCredentials`
64
+ sets the right intent automatically — most apps never touch this prop.
65
+ - **`DemoCredentials` is now re-exported from `@dloizides/auth-client`** (its
66
+ canonical owner) rather than defined locally, so there is exactly ONE shape
67
+ across the two packages. Structurally identical to 1.11.0 — no consumer change.
68
+
69
+ ### "Don't fight the user" — what the hook can and cannot know
70
+
71
+ `useDemoCredentials` does not own the input fields (`<LoginForm>` does), so it
72
+ cannot observe keystrokes. The interaction test it CAN make is on the field
73
+ values: an opportunistic seed applies only when both fields are still empty
74
+ (pristine). This is intentionally conservative — a user who typed and then
75
+ cleared a field keeps control for the rest of the session (a dropped
76
+ opportunistic bump is not retried). An explicit user request is never subject to
77
+ this test.
78
+
3
79
  ## 1.11.0 (2026-07-17)
4
80
 
5
81
  Additive release adding **public demo-credential support** for products with an
package/README.md CHANGED
@@ -197,16 +197,22 @@ same BFF, same Keycloak, same session cookie, same roles. There is no auth
197
197
  bypass and no credential inside this package: the host supplies the pair, and the
198
198
  demo account's blast radius is whatever the IdP grants it.
199
199
 
200
- `useDemoCredentials` owns the wiring, so apps don't hand-roll it:
200
+ The demo pair comes from the BFF (`GET /bff/config` → `config.demo`), not a
201
+ client const — the BFF is the only thing that knows whether a deployment has a
202
+ demo configured, and a bundled const would ship credentials into every customer's
203
+ self-hosted build. `useBffLoginConfig` already fetches that config, so it also
204
+ carries `demo`. `useDemoCredentials` owns the hint↔form wiring:
201
205
 
202
206
  ```tsx
203
- import { AuthScreen, DemoCredentialsHint, LoginForm, useDemoCredentials } from '@dloizides/auth-web';
204
-
205
- // Hoisted (or memoised): a new object each render re-creates the prop bags.
206
- const DEMO = { username: 'demo', password: 'ZygosDemo!2026.Try' };
207
+ import {
208
+ AuthScreen, DemoCredentialsHint, LoginForm,
209
+ useBffLoginConfig, useDemoCredentials,
210
+ } from '@dloizides/auth-web';
207
211
 
208
212
  function LoginScreen() {
209
- const demo = useDemoCredentials({ credentials: DEMO, prefillOnMount: true });
213
+ const { config } = useBffLoginConfig(bffAuthClient);
214
+ // Credentials arrive ASYNC — prefillOnMount honours a late arrival (see below).
215
+ const demo = useDemoCredentials({ credentials: config.demo ?? undefined, prefillOnMount: true });
210
216
 
211
217
  return (
212
218
  <AuthScreen theme={authTheme}>
@@ -219,7 +225,7 @@ function LoginScreen() {
219
225
  <LoginForm
220
226
  {...demo.loginFormProps}
221
227
  chromeless
222
- client={client}
228
+ client={bffAuthClient}
223
229
  labels={authLabels.login}
224
230
  theme={authTheme}
225
231
  onSuccess={handleSignedIn}
@@ -230,7 +236,25 @@ function LoginScreen() {
230
236
  ```
231
237
 
232
238
  `hintProps` carries `{ credentials, onUse }`; `loginFormProps` carries
233
- `{ initialUsername, initialPassword, prefillNonce }`.
239
+ `{ initialUsername, initialPassword, prefillNonce, prefillIntent }`. A module-const
240
+ demo works too — just pass it as `credentials` instead of `config.demo`.
241
+
242
+ > Requires `@dloizides/auth-client >= 4.2.0`, which surfaces `demo` on
243
+ > `BffLoginConfig` (mapped from the wire's `publishedUsername` /
244
+ > `publishedPassword`). `config.demo` is `DemoCredentials | null`.
245
+
246
+ ### Async credentials: `prefillOnMount` honours a late arrival
247
+
248
+ Because the pair arrives a render or two after mount, `prefillOnMount` cannot lean
249
+ on `useState`'s initial value (React reads it on the first render only). The hook
250
+ seeds the form when `config.demo` resolves to a usable pair — but as an
251
+ **opportunistic** seed: `<LoginForm>` applies it only while both fields are still
252
+ empty, so a late `/bff/config` response never overwrites a username a real account
253
+ holder was typing meanwhile. Tapping *Use these credentials* is an **explicit**
254
+ seed and always applies. Seeding is gated by value, so a react-query refetch
255
+ returning an equal-valued object does not re-seed. `useDemoCredentials` chooses
256
+ the intent for you via the `prefillIntent` prop; you only touch `PrefillIntent`
257
+ if you drive `<LoginForm>` without the hook.
234
258
 
235
259
  **`prefillOnMount`** (default `false`) chooses the trade:
236
260
 
@@ -292,7 +316,7 @@ const route = resolvePostLoginRoute(user, roleRoutes);
292
316
  |--------|------|
293
317
  | `LoginForm`, `ForgotPasswordForm`, `ResetPasswordForm`, `OtpForm`, `PinForm` | Components |
294
318
  | `AuthScreen`, `DemoCredentialsHint`, `PreferredMethodHint` | Composition + login-surface panels |
295
- | `useDemoCredentials`, `resolveDemoCredentials`, `DemoCredentials` | Public demo credentials |
319
+ | `useDemoCredentials`, `resolveDemoCredentials`, `DemoCredentials`, `PrefillIntent` | Public demo credentials |
296
320
  | `AuthThemeProvider`, `useAuthTheme`, `defaultAuthTheme`, `AuthTheme` | Theming |
297
321
  | `DEFAULT_LOGIN_LABELS`, `DEFAULT_FORGOT_PASSWORD_LABELS`, `DEFAULT_RESET_PASSWORD_LABELS`, `DEFAULT_OTP_LABELS`, `DEFAULT_PIN_LABELS` | Label bags |
298
322
  | `useBffAuth`, `useBffForgotPassword`, `useBffResetPassword`, `useResetPasswordForm`, `useOtpLogin`, `usePinLogin` | Headless hooks |
package/dist/index.d.mts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { ReactNode, ReactElement } from 'react';
2
- import { BffAuthClient, BffUser, HttpClient, BffLoginRequest, BffForgotPasswordRequest, BffResetPasswordRequest, BffOtpRequestResult } from '@dloizides/auth-client';
3
- export { BffAuthClient, BffAuthClientOptions, BffForgotPasswordRequest, BffLoginRequest, BffOtpRequestRequest, BffOtpRequestResult, BffOtpVerifyRequest, BffPinLoginRequest, BffRegisterRequest, BffResetPasswordRequest, BffUser, HttpClient, HttpRequest, HttpResponse, createFetchHttpClient } from '@dloizides/auth-client';
2
+ import { BffAuthClient, BffUser, DemoCredentials, HttpClient, BffLoginRequest, BffForgotPasswordRequest, BffResetPasswordRequest, BffOtpRequestResult } from '@dloizides/auth-client';
3
+ export { BffAuthClient, BffAuthClientOptions, BffForgotPasswordRequest, BffLoginRequest, BffOtpRequestRequest, BffOtpRequestResult, BffOtpVerifyRequest, BffPinLoginRequest, BffRegisterRequest, BffResetPasswordRequest, BffUser, DemoCredentials, HttpClient, HttpRequest, HttpResponse, createFetchHttpClient } from '@dloizides/auth-client';
4
4
  import { UseMutationOptions, UseMutationResult } from '@tanstack/react-query';
5
5
 
6
6
  /**
@@ -129,18 +129,6 @@ interface AuthScreenProps {
129
129
  /** The screen-level auth composition: one centered card the controls share. */
130
130
  declare function AuthScreen({ children, theme: themeProp, testID, cardTestID, maxWidth, title, subtitle, footer, }: Readonly<AuthScreenProps>): ReactElement;
131
131
 
132
- /**
133
- * Label bags for the auth components.
134
- *
135
- * `@dloizides/auth-web` ships **no** translation framework — it is i18n-agnostic
136
- * by design (each app already owns its own i18n). Every user-facing string a
137
- * component renders is supplied by the consuming app through a typed `labels`
138
- * prop. The app passes strings it has already localised with `FM()` / `t()`.
139
- *
140
- * Each bag has a `DEFAULT_*` constant (English) so a component renders sensibly
141
- * with no `labels` prop and a consuming app can spread-override only the keys
142
- * it wants to change.
143
- */
144
132
  /** Strings rendered by `<LoginForm>`. */
145
133
  interface LoginFormLabels {
146
134
  title: string;
@@ -162,6 +150,8 @@ interface LoginFormLabels {
162
150
  /** Shown when one or both fields are empty on submit. */
163
151
  missingFields: string;
164
152
  }
153
+ declare const DEFAULT_LOGIN_LABELS: LoginFormLabels;
154
+
165
155
  /** Strings rendered by `<ForgotPasswordForm>`. */
166
156
  interface ForgotPasswordFormLabels {
167
157
  title: string;
@@ -189,6 +179,9 @@ interface ForgotPasswordFieldsLabels extends ForgotPasswordFormLabels {
189
179
  /** The "close" button shown on the success state. */
190
180
  close: string;
191
181
  }
182
+ declare const DEFAULT_FORGOT_PASSWORD_LABELS: ForgotPasswordFormLabels;
183
+ declare const DEFAULT_FORGOT_PASSWORD_FIELDS_LABELS: ForgotPasswordFieldsLabels;
184
+
192
185
  /** Strings rendered by `<OtpForm>` — the two-step email-OTP login form. */
193
186
  interface OtpFormLabels {
194
187
  /** Title shown on the request-a-code step. */
@@ -224,6 +217,8 @@ interface OtpFormLabels {
224
217
  /** The "use a different email" link text — returns to step 1. */
225
218
  changeEmail: string;
226
219
  }
220
+ declare const DEFAULT_OTP_LABELS: OtpFormLabels;
221
+
227
222
  /** Strings rendered by `<PinForm>` — the single-step event-PIN login form. */
228
223
  interface PinFormLabels {
229
224
  /** Title shown above the PIN field. */
@@ -241,6 +236,8 @@ interface PinFormLabels {
241
236
  /** Generic "that PIN was wrong / expired / locked out" message. */
242
237
  invalidPin: string;
243
238
  }
239
+ declare const DEFAULT_PIN_LABELS: PinFormLabels;
240
+
244
241
  /**
245
242
  * Strings rendered by `<DevicePinUnlockScreen>` — the returning-device unlock
246
243
  * gate. `{name}` / `{count}` placeholders are substituted by the component.
@@ -336,6 +333,10 @@ interface DevicePinSettingsLabels {
336
333
  /** Error shown when disabling fails. */
337
334
  disableFailed: string;
338
335
  }
336
+ declare const DEFAULT_DEVICE_PIN_UNLOCK_LABELS: DevicePinUnlockLabels;
337
+ declare const DEFAULT_DEVICE_PIN_ENROLL_LABELS: DevicePinEnrollLabels;
338
+ declare const DEFAULT_DEVICE_PIN_SETTINGS_LABELS: DevicePinSettingsLabels;
339
+
339
340
  /** Strings rendered by `<PasskeyLoginButton>` — the login-surface passkey CTA. */
340
341
  interface PasskeyLoginLabels {
341
342
  /** The "sign in with a passkey" button. */
@@ -365,6 +366,9 @@ interface PasskeySettingsLabels {
365
366
  /** Success line shown after returning from a registration. */
366
367
  registeredSuccess: string;
367
368
  }
369
+ declare const DEFAULT_PASSKEY_LOGIN_LABELS: PasskeyLoginLabels;
370
+ declare const DEFAULT_PASSKEY_SETTINGS_LABELS: PasskeySettingsLabels;
371
+
368
372
  /** Strings rendered by `<PreferredMethodSettingsCard>` — the cross-device default-method picker. */
369
373
  interface PreferredMethodSettingsLabels {
370
374
  title: string;
@@ -391,6 +395,9 @@ interface PreferredMethodHintLabels {
391
395
  /** Full sentence shown when the cached preference is passkey. */
392
396
  passkey: string;
393
397
  }
398
+ declare const DEFAULT_PREFERRED_METHOD_SETTINGS_LABELS: PreferredMethodSettingsLabels;
399
+ declare const DEFAULT_PREFERRED_METHOD_HINT_LABELS: PreferredMethodHintLabels;
400
+
394
401
  /** Strings rendered by `<DemoCredentialsHint>` — the public-demo credentials panel. */
395
402
  interface DemoCredentialsHintLabels {
396
403
  /** Panel heading (e.g. "Demo access"). */
@@ -406,6 +413,8 @@ interface DemoCredentialsHintLabels {
406
413
  /** Accessibility hint for that button. */
407
414
  useCredentialsHint: string;
408
415
  }
416
+ declare const DEFAULT_DEMO_CREDENTIALS_HINT_LABELS: DemoCredentialsHintLabels;
417
+
409
418
  /** Strings rendered by `<ResetPasswordForm>`. */
410
419
  interface ResetPasswordFormLabels {
411
420
  title: string;
@@ -427,33 +436,32 @@ interface ResetPasswordFormLabels {
427
436
  /** Error: a network / 5xx failure. */
428
437
  errorNetwork: string;
429
438
  }
430
- declare const DEFAULT_LOGIN_LABELS: LoginFormLabels;
431
- declare const DEFAULT_FORGOT_PASSWORD_LABELS: ForgotPasswordFormLabels;
432
- declare const DEFAULT_FORGOT_PASSWORD_FIELDS_LABELS: ForgotPasswordFieldsLabels;
433
- declare const DEFAULT_OTP_LABELS: OtpFormLabels;
434
- declare const DEFAULT_PIN_LABELS: PinFormLabels;
435
- declare const DEFAULT_DEVICE_PIN_UNLOCK_LABELS: DevicePinUnlockLabels;
436
- declare const DEFAULT_DEVICE_PIN_ENROLL_LABELS: DevicePinEnrollLabels;
437
- declare const DEFAULT_DEVICE_PIN_SETTINGS_LABELS: DevicePinSettingsLabels;
438
- declare const DEFAULT_PASSKEY_LOGIN_LABELS: PasskeyLoginLabels;
439
- declare const DEFAULT_PASSKEY_SETTINGS_LABELS: PasskeySettingsLabels;
440
- declare const DEFAULT_PREFERRED_METHOD_SETTINGS_LABELS: PreferredMethodSettingsLabels;
441
- declare const DEFAULT_PREFERRED_METHOD_HINT_LABELS: PreferredMethodHintLabels;
442
- declare const DEFAULT_DEMO_CREDENTIALS_HINT_LABELS: DemoCredentialsHintLabels;
443
439
  declare const DEFAULT_RESET_PASSWORD_LABELS: ResetPasswordFormLabels;
444
440
 
445
441
  /**
446
- * `<LoginForm>` — the ready-made, themeable password-login form.
442
+ * Who asked for a prefill — the difference between "the user requested this" and
443
+ * "the app offered it".
447
444
  *
448
- * The "themeable component" half of the package design: drop it in, pass a
449
- * `client`, a `theme` (or wrap in `<AuthThemeProvider>`) and a localised
450
- * `labels` bag, and you have a branded login surface. It is built on the
451
- * headless `useBffAuth` hook, so the ready-made and custom-layout paths share
452
- * one code path.
445
+ * A seed that the USER asked for (tapping "use these credentials") must always
446
+ * apply: they can see the fields, they know what is in them, and they asked
447
+ * anyway. A seed the APP offers (a demo pair arriving from `GET /bff/config`
448
+ * mid-typing) must not: it is an unrequested, racing write against a field the
449
+ * user may already be filling in.
453
450
  *
454
- * The package ships no router and no i18n. `onSuccess` hands the signed-in
455
- * `BffUser` back to the app, which decides where to navigate (typically via
456
- * `resolvePostLoginRoute`). All copy comes from `labels`.
451
+ * Collapsing the two into a bare nonce bump is what makes a late-arriving config
452
+ * fetch overwrite the username a real account holder is halfway through typing.
453
+ * `<LoginForm>` switches on this, never on a string literal.
454
+ */
455
+ declare const enum PrefillIntent {
456
+ /** The user asked for it. Always applies, over whatever is in the fields. */
457
+ Explicit = "explicit",
458
+ /** The app offered it. Applies only to untouched, empty fields. */
459
+ Opportunistic = "opportunistic"
460
+ }
461
+
462
+ /**
463
+ * Props for `<LoginForm>`, split out of the component file to keep the render
464
+ * body under the component size limit. Purely a type module — no runtime code.
457
465
  */
458
466
 
459
467
  interface LoginFormProps {
@@ -498,12 +506,35 @@ interface LoginFormProps {
498
506
  * props alone does nothing once mounted.
499
507
  *
500
508
  * Most apps should not manage this by hand: `useDemoCredentials` returns a
501
- * `loginFormProps` bag carrying all three, ready to spread.
509
+ * `loginFormProps` bag carrying all four, ready to spread.
502
510
  */
503
511
  prefillNonce?: number;
512
+ /**
513
+ * Whether the pending re-seed was requested by the user or offered by the app.
514
+ * An {@link PrefillIntent.Opportunistic} re-seed (e.g. a demo pair arriving
515
+ * from `GET /bff/config` after mount) is DROPPED unless both fields are still
516
+ * empty, so a late fetch never overwrites what someone is typing. Defaults to
517
+ * unconditional — omit it and every nonce bump applies.
518
+ */
519
+ prefillIntent?: PrefillIntent;
504
520
  }
521
+
522
+ /**
523
+ * `<LoginForm>` — the ready-made, themeable password-login form.
524
+ *
525
+ * The "themeable component" half of the package design: drop it in, pass a
526
+ * `client`, a `theme` (or wrap in `<AuthThemeProvider>`) and a localised
527
+ * `labels` bag, and you have a branded login surface. It is built on the
528
+ * headless `useBffAuth` hook, so the ready-made and custom-layout paths share
529
+ * one code path.
530
+ *
531
+ * The package ships no router and no i18n. `onSuccess` hands the signed-in
532
+ * `BffUser` back to the app, which decides where to navigate (typically via
533
+ * `resolvePostLoginRoute`). All copy comes from `labels`.
534
+ */
535
+
505
536
  /** Themeable password-login form built on `useBffAuth`. */
506
- declare function LoginForm({ client, theme: themeProp, labels: labelsProp, onSuccess, onForgotPassword, onSignUp, testIdPrefix, chromeless, initialUsername, initialPassword, prefillNonce, }: Readonly<LoginFormProps>): ReactElement;
537
+ declare function LoginForm({ client, theme: themeProp, labels: labelsProp, onSuccess, onForgotPassword, onSignUp, testIdPrefix, chromeless, initialUsername, initialPassword, prefillNonce, prefillIntent, }: Readonly<LoginFormProps>): ReactElement;
507
538
 
508
539
  /**
509
540
  * `<ForgotPasswordForm>` — the ready-made, themeable "request a reset link"
@@ -802,6 +833,7 @@ declare const enum DevicePinErrorKey {
802
833
  * error) so the unlock / enrol UIs can route on each one rather than collapsing
803
834
  * them into a single opaque failure.
804
835
  */
836
+
805
837
  /**
806
838
  * The per-device half of `GET /bff/config` — what this device remembers about
807
839
  * the last user, all fields safe-defaulted by the parser when absent.
@@ -824,6 +856,14 @@ interface BffLoginConfig {
824
856
  registrationEnabled: boolean;
825
857
  /** The per-device remembered state. */
826
858
  deviceState: BffDeviceState;
859
+ /**
860
+ * The published demo credentials this deployment advertises, or `null` when
861
+ * none is configured. Feeds `useDemoCredentials` / `<DemoCredentialsHint>`:
862
+ * `useDemoCredentials({ credentials: config.demo ?? undefined })`. `auth-client`
863
+ * 4.2.0 populates it; older clients (and hand-rolled objects) simply omit it,
864
+ * which reads as `undefined` — treated the same as "no demo" by the hint.
865
+ */
866
+ demo?: DemoCredentials | null;
827
867
  }
828
868
  /**
829
869
  * Discriminated result of a device-PIN UNLOCK attempt. The client never rejects;
@@ -1245,23 +1285,6 @@ interface PreferredMethodHintProps {
1245
1285
  /** Themeable login-screen preferred-method hint. Renders `null` when there is nothing to say. */
1246
1286
  declare function PreferredMethodHint({ method, theme: themeProp, labels: labelsProp, testIdPrefix, }: Readonly<PreferredMethodHintProps>): ReactElement | null;
1247
1287
 
1248
- /**
1249
- * Public demo-credential contracts.
1250
- *
1251
- * A "demo credential" is a REAL account that a product publishes openly so a
1252
- * prospective evaluator can sign in without a sign-up step. It is not a bypass:
1253
- * the credentials travel the ordinary login path (same BFF, same Keycloak, same
1254
- * session cookie, same roles). The package only makes them *discoverable* and
1255
- * *one-click fillable* — it never authenticates anything itself.
1256
- */
1257
- /** A publishable demo username + password pair. */
1258
- interface DemoCredentials {
1259
- /** The demo account's username. */
1260
- username: string;
1261
- /** The demo account's password. */
1262
- password: string;
1263
- }
1264
-
1265
1288
  /**
1266
1289
  * `<DemoCredentialsHint>` — the public-demo credentials panel.
1267
1290
  *
@@ -1942,6 +1965,7 @@ interface DemoCredentialsLoginFormProps {
1942
1965
  initialUsername?: string;
1943
1966
  initialPassword?: string;
1944
1967
  prefillNonce: number;
1968
+ prefillIntent: PrefillIntent;
1945
1969
  }
1946
1970
  /** The `<DemoCredentialsHint>` props that carry the credentials + fill action. */
1947
1971
  interface DemoCredentialsHintWiring {
@@ -2231,4 +2255,4 @@ declare function validatePasswordPolicy(password: string): PasswordPolicyError[]
2231
2255
  /** `true` when the password satisfies every policy rule. */
2232
2256
  declare function isPasswordValid(password: string): boolean;
2233
2257
 
2234
- export { AuthScreen, type AuthScreenProps, AuthTestIds, type AuthTheme, type AuthThemeColors, AuthThemeProvider, type AuthThemeProviderProps, type AuthThemeRadii, type AuthThemeSpacing, type AuthThemeTypography, BffAuthStatus, type BffDeviceState, type BffLoginConfig, type BffLogoutClient, type CreateBffAuthClientOptions, DEFAULT_AUTH_CARD_MAX_WIDTH, DEFAULT_DEMO_CREDENTIALS_HINT_LABELS, DEFAULT_DEVICE_PIN_ENROLL_LABELS, DEFAULT_DEVICE_PIN_SETTINGS_LABELS, DEFAULT_DEVICE_PIN_UNLOCK_LABELS, DEFAULT_FORGOT_PASSWORD_FIELDS_LABELS, DEFAULT_FORGOT_PASSWORD_LABELS, DEFAULT_LOGIN_LABELS, DEFAULT_OTP_LABELS, DEFAULT_PASSKEY_LOGIN_LABELS, DEFAULT_PASSKEY_SETTINGS_LABELS, DEFAULT_PIN_LABELS, DEFAULT_PREFERRED_METHOD_HINT_LABELS, DEFAULT_PREFERRED_METHOD_SETTINGS_LABELS, DEFAULT_RESET_PASSWORD_LABELS, DEVICE_PIN_ALLOWED_DIGITS, DEVICE_PIN_DEFAULT_DIGITS, type DemoCredentials, DemoCredentialsHint, type DemoCredentialsHintLabels, type DemoCredentialsHintProps, type DemoCredentialsHintWiring, type DemoCredentialsLoginFormProps, type DevicePinCapableClient, type DevicePinDisableCapableClient, type DevicePinEnrollCapableClient, DevicePinEnrollErrorKey, DevicePinEnrollForm, type DevicePinEnrollFormProps, type DevicePinEnrollLabels, type DevicePinEnrollResult, DevicePinErrorKey, DevicePinInput, type DevicePinInputProps, DevicePinLengthPicker, type DevicePinLengthPickerProps, DevicePinOffer, type DevicePinOfferProps, DevicePinSettingsCard, type DevicePinSettingsCardProps, type DevicePinSettingsLabels, type DevicePinUnlockCapableClient, type DevicePinUnlockLabels, type DevicePinUnlockResult, DevicePinUnlockScreen, type DevicePinUnlockScreenProps, type DevicePinUnlockedUser, ForgotPasswordFields, type ForgotPasswordFieldsLabels, type ForgotPasswordFieldsProps, ForgotPasswordForm, type ForgotPasswordFormLabels, type ForgotPasswordFormProps, type LoginConfigCapableClient, LoginForm, type LoginFormLabels, type LoginFormProps, OtpForm, type OtpFormLabels, type OtpFormProps, OtpLoginStep, PASSWORD_MAX_LENGTH, PASSWORD_MIN_LENGTH, PasskeyCeremonyMode, PasskeyCeremonyStatus, type PasskeyErrorCode, PasskeyLoginButton, type PasskeyLoginButtonProps, type PasskeyLoginLabels, PasskeySettingsCard, type PasskeySettingsCardProps, type PasskeySettingsLabels, PasswordPolicyError, type PerformBffLogoutOptions, PinForm, type PinFormLabels, type PinFormProps, type PreferencesClientOptions, type PreferredMethodClient, PreferredMethodHint, type PreferredMethodHintLabels, type PreferredMethodHintProps, PreferredMethodSettingsCard, type PreferredMethodSettingsCardProps, type PreferredMethodSettingsLabels, ResetPasswordError, ResetPasswordForm, type ResetPasswordFormLabels, type ResetPasswordFormProps, type RoleRoute, type RoleRouteTable, type UseBffAuthOptions, type UseBffAuthResult, type UseBffForgotPasswordOptions, type UseBffLoginConfigResult, type UseBffResetPasswordOptions, type UseDemoCredentialsOptions, type UseDemoCredentialsResult, type UseDevicePinDisableArgs, type UseDevicePinDisableResult, type UseDevicePinEnrollArgs, type UseDevicePinEnrollResult, type UseDevicePinUnlockArgs, type UseDevicePinUnlockResult, type UseForgotPasswordSubmitArgs, type UseForgotPasswordSubmitResult, type UseOtpLoginOptions, type UseOtpLoginResult, type UsePasskeyCeremonyOptions, type UsePasskeyCeremonyResult, type UsePinLoginOptions, type UsePinLoginResult, type UsePreferredMethodSettingArgs, type UsePreferredMethodSettingResult, type UseResetPasswordFormArgs, type UseResetPasswordFormResult, cachePreferredMethod, clearCachedPreferredMethod, collectUserRoles, createBffAuthClient, createPreferencesClient, defaultAuthTheme, isAllowedPinDigits, isPasswordValid, isValidForgotPasswordEmail, performBffLogout, readCachedPreferredMethod, readPasskeyError, readPasskeyRegistered, resolveAccessibleRoutes, resolveDemoCredentials, resolvePostLoginRoute, startPasskeyLogin, startPasskeyRegistration, syncPreferredMethodFromServer, useAuthTheme, useBffAuth, useBffForgotPassword, useBffLoginConfig, useBffResetPassword, useDemoCredentials, useDevicePinDisable, useDevicePinEnroll, useDevicePinUnlock, useForgotPasswordSubmit, useOtpLogin, usePasskeyCeremony, usePinLogin, usePreferredMethodSetting, useResetPasswordForm, validatePasswordPolicy, withTestIdPrefix };
2258
+ export { AuthScreen, type AuthScreenProps, AuthTestIds, type AuthTheme, type AuthThemeColors, AuthThemeProvider, type AuthThemeProviderProps, type AuthThemeRadii, type AuthThemeSpacing, type AuthThemeTypography, BffAuthStatus, type BffDeviceState, type BffLoginConfig, type BffLogoutClient, type CreateBffAuthClientOptions, DEFAULT_AUTH_CARD_MAX_WIDTH, DEFAULT_DEMO_CREDENTIALS_HINT_LABELS, DEFAULT_DEVICE_PIN_ENROLL_LABELS, DEFAULT_DEVICE_PIN_SETTINGS_LABELS, DEFAULT_DEVICE_PIN_UNLOCK_LABELS, DEFAULT_FORGOT_PASSWORD_FIELDS_LABELS, DEFAULT_FORGOT_PASSWORD_LABELS, DEFAULT_LOGIN_LABELS, DEFAULT_OTP_LABELS, DEFAULT_PASSKEY_LOGIN_LABELS, DEFAULT_PASSKEY_SETTINGS_LABELS, DEFAULT_PIN_LABELS, DEFAULT_PREFERRED_METHOD_HINT_LABELS, DEFAULT_PREFERRED_METHOD_SETTINGS_LABELS, DEFAULT_RESET_PASSWORD_LABELS, DEVICE_PIN_ALLOWED_DIGITS, DEVICE_PIN_DEFAULT_DIGITS, DemoCredentialsHint, type DemoCredentialsHintLabels, type DemoCredentialsHintProps, type DemoCredentialsHintWiring, type DemoCredentialsLoginFormProps, type DevicePinCapableClient, type DevicePinDisableCapableClient, type DevicePinEnrollCapableClient, DevicePinEnrollErrorKey, DevicePinEnrollForm, type DevicePinEnrollFormProps, type DevicePinEnrollLabels, type DevicePinEnrollResult, DevicePinErrorKey, DevicePinInput, type DevicePinInputProps, DevicePinLengthPicker, type DevicePinLengthPickerProps, DevicePinOffer, type DevicePinOfferProps, DevicePinSettingsCard, type DevicePinSettingsCardProps, type DevicePinSettingsLabels, type DevicePinUnlockCapableClient, type DevicePinUnlockLabels, type DevicePinUnlockResult, DevicePinUnlockScreen, type DevicePinUnlockScreenProps, type DevicePinUnlockedUser, ForgotPasswordFields, type ForgotPasswordFieldsLabels, type ForgotPasswordFieldsProps, ForgotPasswordForm, type ForgotPasswordFormLabels, type ForgotPasswordFormProps, type LoginConfigCapableClient, LoginForm, type LoginFormLabels, type LoginFormProps, OtpForm, type OtpFormLabels, type OtpFormProps, OtpLoginStep, PASSWORD_MAX_LENGTH, PASSWORD_MIN_LENGTH, PasskeyCeremonyMode, PasskeyCeremonyStatus, type PasskeyErrorCode, PasskeyLoginButton, type PasskeyLoginButtonProps, type PasskeyLoginLabels, PasskeySettingsCard, type PasskeySettingsCardProps, type PasskeySettingsLabels, PasswordPolicyError, type PerformBffLogoutOptions, PinForm, type PinFormLabels, type PinFormProps, type PreferencesClientOptions, type PreferredMethodClient, PreferredMethodHint, type PreferredMethodHintLabels, type PreferredMethodHintProps, PreferredMethodSettingsCard, type PreferredMethodSettingsCardProps, type PreferredMethodSettingsLabels, PrefillIntent, ResetPasswordError, ResetPasswordForm, type ResetPasswordFormLabels, type ResetPasswordFormProps, type RoleRoute, type RoleRouteTable, type UseBffAuthOptions, type UseBffAuthResult, type UseBffForgotPasswordOptions, type UseBffLoginConfigResult, type UseBffResetPasswordOptions, type UseDemoCredentialsOptions, type UseDemoCredentialsResult, type UseDevicePinDisableArgs, type UseDevicePinDisableResult, type UseDevicePinEnrollArgs, type UseDevicePinEnrollResult, type UseDevicePinUnlockArgs, type UseDevicePinUnlockResult, type UseForgotPasswordSubmitArgs, type UseForgotPasswordSubmitResult, type UseOtpLoginOptions, type UseOtpLoginResult, type UsePasskeyCeremonyOptions, type UsePasskeyCeremonyResult, type UsePinLoginOptions, type UsePinLoginResult, type UsePreferredMethodSettingArgs, type UsePreferredMethodSettingResult, type UseResetPasswordFormArgs, type UseResetPasswordFormResult, cachePreferredMethod, clearCachedPreferredMethod, collectUserRoles, createBffAuthClient, createPreferencesClient, defaultAuthTheme, isAllowedPinDigits, isPasswordValid, isValidForgotPasswordEmail, performBffLogout, readCachedPreferredMethod, readPasskeyError, readPasskeyRegistered, resolveAccessibleRoutes, resolveDemoCredentials, resolvePostLoginRoute, startPasskeyLogin, startPasskeyRegistration, syncPreferredMethodFromServer, useAuthTheme, useBffAuth, useBffForgotPassword, useBffLoginConfig, useBffResetPassword, useDemoCredentials, useDevicePinDisable, useDevicePinEnroll, useDevicePinUnlock, useForgotPasswordSubmit, useOtpLogin, usePasskeyCeremony, usePinLogin, usePreferredMethodSetting, useResetPasswordForm, validatePasswordPolicy, withTestIdPrefix };