@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 +76 -0
- package/README.md +33 -9
- package/dist/index.d.mts +80 -56
- package/dist/index.d.ts +80 -56
- package/dist/index.js +101 -28
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +101 -29
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
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
|
-
|
|
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 {
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
+
import {
|
|
208
|
+
AuthScreen, DemoCredentialsHint, LoginForm,
|
|
209
|
+
useBffLoginConfig, useDemoCredentials,
|
|
210
|
+
} from '@dloizides/auth-web';
|
|
207
211
|
|
|
208
212
|
function LoginScreen() {
|
|
209
|
-
const
|
|
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={
|
|
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
|
-
*
|
|
442
|
+
* Who asked for a prefill — the difference between "the user requested this" and
|
|
443
|
+
* "the app offered it".
|
|
447
444
|
*
|
|
448
|
-
*
|
|
449
|
-
*
|
|
450
|
-
*
|
|
451
|
-
*
|
|
452
|
-
*
|
|
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
|
-
*
|
|
455
|
-
*
|
|
456
|
-
*
|
|
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
|
|
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,
|
|
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 };
|