@dloizides/auth-web 1.7.0 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +31 -0
- package/dist/index.d.mts +105 -17
- package/dist/index.d.ts +105 -17
- package/dist/index.js +279 -13
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +277 -14
- package/dist/index.mjs.map +1 -1
- package/package.json +110 -110
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,36 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.8.0 (2026-07-09)
|
|
4
|
+
|
|
5
|
+
Additive release for the Move 2b passkey in-app rebuild — the passkey ceremony
|
|
6
|
+
now runs **in-page** (`navigator.credentials.*` against the BFF's same-origin
|
|
7
|
+
`/bff/passkey/*` fetch endpoints) instead of a full-page redirect to Keycloak.
|
|
8
|
+
**Inert by default / no behaviour change until the BFF's WebAuthn RP is
|
|
9
|
+
configured:** when the RP is off the options endpoint returns 501 and the hook
|
|
10
|
+
transparently falls back to the legacy redirect. No breaking changes; every
|
|
11
|
+
1.7.x export is unchanged and the legacy `startPasskeyLogin` /
|
|
12
|
+
`startPasskeyRegistration` navigation helpers stay exported (they ARE the
|
|
13
|
+
fallback).
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
|
|
17
|
+
- **`usePasskeyCeremony({ mode, returnUrl, onSuccess })`** — the react-query-free
|
|
18
|
+
in-page ceremony hook: options fetch → `navigator.credentials.create/get` →
|
|
19
|
+
verify fetch. Returns `{ status, error, isSupported, start, reset }`. Falls
|
|
20
|
+
back to the legacy Keycloak redirect on a 501 (RP not configured), any non-2xx
|
|
21
|
+
options response, or an unsupported browser — so nothing regresses until the
|
|
22
|
+
owner flips `Bff:Passkey`. A cancelled/timed-out ceremony (`NotAllowedError` /
|
|
23
|
+
`AbortError`) surfaces as `'cancelled'`, anything else as `'failed'`.
|
|
24
|
+
- **`PasskeyCeremonyMode`** (`Login` / `Register`) and **`PasskeyCeremonyStatus`**
|
|
25
|
+
(`Idle` / `Running` / `Success` / `Error`) `const enum`s.
|
|
26
|
+
|
|
27
|
+
### Changed
|
|
28
|
+
|
|
29
|
+
- **`<PasskeyLoginButton>`** and **`<PasskeySettingsCard>`** now drive
|
|
30
|
+
`usePasskeyCeremony` instead of `window.location.assign`. Same exported props,
|
|
31
|
+
same testIDs — a drop-in bump for consumers; the in-page path only activates
|
|
32
|
+
once the BFF RP is configured, otherwise they behave exactly as before.
|
|
33
|
+
|
|
3
34
|
## 1.7.0 (2026-07-07)
|
|
4
35
|
|
|
5
36
|
Additive release for the Kefi multi-role overhaul — the shared machinery for a
|
package/dist/index.d.mts
CHANGED
|
@@ -345,6 +345,13 @@ interface PasskeyLoginLabels {
|
|
|
345
345
|
errorCancelled: string;
|
|
346
346
|
/** Error banner when the ceremony failed. */
|
|
347
347
|
errorFailed: string;
|
|
348
|
+
/**
|
|
349
|
+
* The "try another way" affordance shown after an in-page ceremony error — it
|
|
350
|
+
* hands off to the Keycloak-hosted passkey/password flow. This is the seam that
|
|
351
|
+
* rescues a user whose credential is only enrolled in Keycloak (not the in-page
|
|
352
|
+
* RP store): the in-page ceremony can't see it, so they fall back to KC.
|
|
353
|
+
*/
|
|
354
|
+
tryAnotherWay: string;
|
|
348
355
|
}
|
|
349
356
|
/** Strings rendered by `<PasskeySettingsCard>` — the account passkey card. */
|
|
350
357
|
interface PasskeySettingsLabels {
|
|
@@ -1022,16 +1029,18 @@ declare function DevicePinSettingsCard({ client, initialHasPin, theme: themeProp
|
|
|
1022
1029
|
* The "Sign in with a passkey" button rendered on the unified login surface when
|
|
1023
1030
|
* the BFF advertises the `passkey` method.
|
|
1024
1031
|
*
|
|
1025
|
-
*
|
|
1026
|
-
*
|
|
1027
|
-
*
|
|
1028
|
-
*
|
|
1029
|
-
*
|
|
1030
|
-
*
|
|
1032
|
+
* The passkey login runs IN-PAGE via `usePasskeyCeremony`
|
|
1033
|
+
* (`navigator.credentials.get` against the same-origin `/bff/passkey/login/*`
|
|
1034
|
+
* fetch endpoints), landing the authenticated user on `returnUrl` (default `'/'`)
|
|
1035
|
+
* with a session cookie set. When the BFF's WebAuthn RP is not configured the
|
|
1036
|
+
* options endpoint returns 501 and the hook transparently falls back to the
|
|
1037
|
+
* legacy Keycloak redirect — so nothing regresses until the flag flips. A
|
|
1038
|
+
* cancelled / failed in-page ceremony surfaces as an inline error banner; a prior
|
|
1039
|
+
* redirect round-trip's `?passkeyError=…` is still honoured too.
|
|
1031
1040
|
*
|
|
1032
|
-
* react-query-free:
|
|
1033
|
-
* `
|
|
1034
|
-
* has no QueryClient provider.
|
|
1041
|
+
* react-query-free: the hook uses plain `fetch` + `useState` (see
|
|
1042
|
+
* `usePasskeyCeremony`), so it is safe to mount inside the login route group
|
|
1043
|
+
* which has no QueryClient provider.
|
|
1035
1044
|
*/
|
|
1036
1045
|
|
|
1037
1046
|
interface PasskeyLoginButtonProps {
|
|
@@ -1051,14 +1060,16 @@ declare function PasskeyLoginButton({ returnUrl, theme: themeProp, labels: label
|
|
|
1051
1060
|
* The authenticated "Passkeys" settings card.
|
|
1052
1061
|
*
|
|
1053
1062
|
* Mount on an authenticated settings / account surface (alongside the device-PIN
|
|
1054
|
-
* card). Adding a passkey
|
|
1055
|
-
*
|
|
1056
|
-
*
|
|
1057
|
-
*
|
|
1058
|
-
*
|
|
1063
|
+
* card). Adding a passkey runs IN-PAGE via `usePasskeyCeremony`
|
|
1064
|
+
* (`navigator.credentials.create` against the same-origin
|
|
1065
|
+
* `/bff/passkey/register/*` fetch endpoints, session-cookie authenticated); on
|
|
1066
|
+
* success we show an inline success line — no navigation. When the BFF's WebAuthn
|
|
1067
|
+
* RP is not configured the options endpoint returns 501 and the hook falls back
|
|
1068
|
+
* to the legacy Keycloak redirect, which returns here with `?passkey=registered`;
|
|
1069
|
+
* that param is still honoured on mount, so nothing regresses until the flag flips.
|
|
1059
1070
|
*
|
|
1060
|
-
* react-query-free: the
|
|
1061
|
-
* `
|
|
1071
|
+
* react-query-free: the hook uses plain `fetch` + `useState` (see
|
|
1072
|
+
* `usePasskeyCeremony`). Mirrors `DevicePinSettingsCard`.
|
|
1062
1073
|
*/
|
|
1063
1074
|
|
|
1064
1075
|
interface PasskeySettingsCardProps {
|
|
@@ -1297,6 +1308,7 @@ declare const AuthTestIds: {
|
|
|
1297
1308
|
readonly passkeyLogin: "auth-passkey-login";
|
|
1298
1309
|
readonly passkeyLoginButton: "auth-passkey-login-button";
|
|
1299
1310
|
readonly passkeyLoginError: "auth-passkey-login-error";
|
|
1311
|
+
readonly passkeyLoginFallback: "auth-passkey-login-fallback";
|
|
1300
1312
|
readonly passkeySettings: "auth-passkey-settings";
|
|
1301
1313
|
readonly passkeySettingsAdd: "auth-passkey-settings-add";
|
|
1302
1314
|
readonly passkeySettingsSuccess: "auth-passkey-settings-success";
|
|
@@ -1644,6 +1656,44 @@ declare const DEVICE_PIN_DEFAULT_DIGITS = 4;
|
|
|
1644
1656
|
/** Guard: is `value` one of the BFF-accepted PIN lengths? */
|
|
1645
1657
|
declare function isAllowedPinDigits(value: number): boolean;
|
|
1646
1658
|
|
|
1659
|
+
/**
|
|
1660
|
+
* Which WebAuthn ceremony {@link usePasskeyCeremony} drives.
|
|
1661
|
+
*
|
|
1662
|
+
* `Login` runs a usernameless/discoverable assertion
|
|
1663
|
+
* (`navigator.credentials.get`) from the login surface; `Register` runs an
|
|
1664
|
+
* attestation (`navigator.credentials.create`) from an authenticated settings
|
|
1665
|
+
* surface. The mode selects the `/bff/passkey/{login,register}/*` endpoint pair
|
|
1666
|
+
* and the matching redirect fallback.
|
|
1667
|
+
*/
|
|
1668
|
+
declare const enum PasskeyCeremonyMode {
|
|
1669
|
+
/** Assertion ceremony — sign in with an existing passkey. */
|
|
1670
|
+
Login = "login",
|
|
1671
|
+
/** Attestation ceremony — add a passkey to the signed-in account. */
|
|
1672
|
+
Register = "register"
|
|
1673
|
+
}
|
|
1674
|
+
|
|
1675
|
+
/**
|
|
1676
|
+
* The lifecycle state of an in-page passkey ceremony.
|
|
1677
|
+
*
|
|
1678
|
+
* `Idle` before the user acts; `Running` while options are fetched, the
|
|
1679
|
+
* authenticator prompts, and the assertion/attestation is verified; `Success`
|
|
1680
|
+
* once the BFF confirms (a login has a session cookie set, a registration has a
|
|
1681
|
+
* stored credential); `Error` on a genuine in-page failure (see
|
|
1682
|
+
* {@link PasskeyErrorCode}). A redirect fallback (RP not configured / unsupported
|
|
1683
|
+
* browser) navigates the page away, so the hook never lands in a terminal state
|
|
1684
|
+
* for that path.
|
|
1685
|
+
*/
|
|
1686
|
+
declare const enum PasskeyCeremonyStatus {
|
|
1687
|
+
/** No ceremony has started. */
|
|
1688
|
+
Idle = "idle",
|
|
1689
|
+
/** A ceremony is in flight (fetch → authenticator → verify). */
|
|
1690
|
+
Running = "running",
|
|
1691
|
+
/** The ceremony completed and the BFF confirmed it. */
|
|
1692
|
+
Success = "success",
|
|
1693
|
+
/** The ceremony failed in-page (cancelled or failed). */
|
|
1694
|
+
Error = "error"
|
|
1695
|
+
}
|
|
1696
|
+
|
|
1647
1697
|
/**
|
|
1648
1698
|
* Navigation helpers for the passkey (WebAuthn) BFF endpoints.
|
|
1649
1699
|
*
|
|
@@ -1700,6 +1750,44 @@ declare function readPasskeyError(): PasskeyErrorCode | null;
|
|
|
1700
1750
|
*/
|
|
1701
1751
|
declare function readPasskeyRegistered(): boolean;
|
|
1702
1752
|
|
|
1753
|
+
/** Options for {@link usePasskeyCeremony}. */
|
|
1754
|
+
interface UsePasskeyCeremonyOptions {
|
|
1755
|
+
/** Which ceremony to run — login (assertion) or register (attestation). */
|
|
1756
|
+
mode: PasskeyCeremonyMode;
|
|
1757
|
+
/**
|
|
1758
|
+
* Relative app path used two ways: the redirect fallback returns here, and (for
|
|
1759
|
+
* login) a successful in-page ceremony navigates here unless `onSuccess` is set.
|
|
1760
|
+
*/
|
|
1761
|
+
returnUrl: string;
|
|
1762
|
+
/**
|
|
1763
|
+
* Called on a successful in-page ceremony. For login it receives the signed-in
|
|
1764
|
+
* `BffUser`; for register it receives `undefined`. When omitted, a login
|
|
1765
|
+
* navigates to `returnUrl` and a register just resolves to `Success`.
|
|
1766
|
+
*/
|
|
1767
|
+
onSuccess?: (user: BffUser | undefined) => void;
|
|
1768
|
+
}
|
|
1769
|
+
/** The state + controls {@link usePasskeyCeremony} returns. */
|
|
1770
|
+
interface UsePasskeyCeremonyResult {
|
|
1771
|
+
/** Current lifecycle state. */
|
|
1772
|
+
status: PasskeyCeremonyStatus;
|
|
1773
|
+
/** The in-page error code, or `null`. */
|
|
1774
|
+
error: PasskeyErrorCode | null;
|
|
1775
|
+
/** `true` when the browser can run the in-page ceremony (else it redirects). */
|
|
1776
|
+
isSupported: boolean;
|
|
1777
|
+
/** Start the ceremony (or redirect-fallback when the RP is off / unsupported). */
|
|
1778
|
+
start: () => void;
|
|
1779
|
+
/**
|
|
1780
|
+
* Hand off to the legacy Keycloak redirect explicitly. Wired to the "try
|
|
1781
|
+
* another way" affordance a surface shows after an in-page error — the escape
|
|
1782
|
+
* hatch for a credential enrolled only in Keycloak (invisible to the in-page
|
|
1783
|
+
* RP store), which the in-page ceremony cannot use.
|
|
1784
|
+
*/
|
|
1785
|
+
fallbackToRedirect: () => void;
|
|
1786
|
+
/** Clear a terminal state so the affordance can be retried. */
|
|
1787
|
+
reset: () => void;
|
|
1788
|
+
}
|
|
1789
|
+
declare function usePasskeyCeremony(optionsArg: UsePasskeyCeremonyOptions): UsePasskeyCeremonyResult;
|
|
1790
|
+
|
|
1703
1791
|
/**
|
|
1704
1792
|
* Device-local cache of the user's preferred login method (unified-login D5).
|
|
1705
1793
|
*
|
|
@@ -1906,4 +1994,4 @@ declare function validatePasswordPolicy(password: string): PasswordPolicyError[]
|
|
|
1906
1994
|
/** `true` when the password satisfies every policy rule. */
|
|
1907
1995
|
declare function isPasswordValid(password: string): boolean;
|
|
1908
1996
|
|
|
1909
|
-
export { AuthScreen, type AuthScreenProps, AuthTestIds, type AuthTheme, type AuthThemeColors, AuthThemeProvider, type AuthThemeProviderProps, type AuthThemeRadii, type AuthThemeSpacing, type AuthThemeTypography, BffAuthStatus, type BffDeviceState, type BffLoginConfig, type CreateBffAuthClientOptions, DEFAULT_AUTH_CARD_MAX_WIDTH, 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 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, type PasskeyErrorCode, PasskeyLoginButton, type PasskeyLoginButtonProps, type PasskeyLoginLabels, PasskeySettingsCard, type PasskeySettingsCardProps, type PasskeySettingsLabels, PasswordPolicyError, 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 UseDevicePinDisableArgs, type UseDevicePinDisableResult, type UseDevicePinEnrollArgs, type UseDevicePinEnrollResult, type UseDevicePinUnlockArgs, type UseDevicePinUnlockResult, type UseForgotPasswordSubmitArgs, type UseForgotPasswordSubmitResult, type UseOtpLoginOptions, type UseOtpLoginResult, type UsePinLoginOptions, type UsePinLoginResult, type UsePreferredMethodSettingArgs, type UsePreferredMethodSettingResult, type UseResetPasswordFormArgs, type UseResetPasswordFormResult, cachePreferredMethod, clearCachedPreferredMethod, collectUserRoles, createBffAuthClient, createPreferencesClient, defaultAuthTheme, isAllowedPinDigits, isPasswordValid, isValidForgotPasswordEmail, readCachedPreferredMethod, readPasskeyError, readPasskeyRegistered, resolveAccessibleRoutes, resolvePostLoginRoute, startPasskeyLogin, startPasskeyRegistration, syncPreferredMethodFromServer, useAuthTheme, useBffAuth, useBffForgotPassword, useBffLoginConfig, useBffResetPassword, useDevicePinDisable, useDevicePinEnroll, useDevicePinUnlock, useForgotPasswordSubmit, useOtpLogin, usePinLogin, usePreferredMethodSetting, useResetPasswordForm, validatePasswordPolicy, withTestIdPrefix };
|
|
1997
|
+
export { AuthScreen, type AuthScreenProps, AuthTestIds, type AuthTheme, type AuthThemeColors, AuthThemeProvider, type AuthThemeProviderProps, type AuthThemeRadii, type AuthThemeSpacing, type AuthThemeTypography, BffAuthStatus, type BffDeviceState, type BffLoginConfig, type CreateBffAuthClientOptions, DEFAULT_AUTH_CARD_MAX_WIDTH, 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 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, 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 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, readCachedPreferredMethod, readPasskeyError, readPasskeyRegistered, resolveAccessibleRoutes, resolvePostLoginRoute, startPasskeyLogin, startPasskeyRegistration, syncPreferredMethodFromServer, useAuthTheme, useBffAuth, useBffForgotPassword, useBffLoginConfig, useBffResetPassword, useDevicePinDisable, useDevicePinEnroll, useDevicePinUnlock, useForgotPasswordSubmit, useOtpLogin, usePasskeyCeremony, usePinLogin, usePreferredMethodSetting, useResetPasswordForm, validatePasswordPolicy, withTestIdPrefix };
|
package/dist/index.d.ts
CHANGED
|
@@ -345,6 +345,13 @@ interface PasskeyLoginLabels {
|
|
|
345
345
|
errorCancelled: string;
|
|
346
346
|
/** Error banner when the ceremony failed. */
|
|
347
347
|
errorFailed: string;
|
|
348
|
+
/**
|
|
349
|
+
* The "try another way" affordance shown after an in-page ceremony error — it
|
|
350
|
+
* hands off to the Keycloak-hosted passkey/password flow. This is the seam that
|
|
351
|
+
* rescues a user whose credential is only enrolled in Keycloak (not the in-page
|
|
352
|
+
* RP store): the in-page ceremony can't see it, so they fall back to KC.
|
|
353
|
+
*/
|
|
354
|
+
tryAnotherWay: string;
|
|
348
355
|
}
|
|
349
356
|
/** Strings rendered by `<PasskeySettingsCard>` — the account passkey card. */
|
|
350
357
|
interface PasskeySettingsLabels {
|
|
@@ -1022,16 +1029,18 @@ declare function DevicePinSettingsCard({ client, initialHasPin, theme: themeProp
|
|
|
1022
1029
|
* The "Sign in with a passkey" button rendered on the unified login surface when
|
|
1023
1030
|
* the BFF advertises the `passkey` method.
|
|
1024
1031
|
*
|
|
1025
|
-
*
|
|
1026
|
-
*
|
|
1027
|
-
*
|
|
1028
|
-
*
|
|
1029
|
-
*
|
|
1030
|
-
*
|
|
1032
|
+
* The passkey login runs IN-PAGE via `usePasskeyCeremony`
|
|
1033
|
+
* (`navigator.credentials.get` against the same-origin `/bff/passkey/login/*`
|
|
1034
|
+
* fetch endpoints), landing the authenticated user on `returnUrl` (default `'/'`)
|
|
1035
|
+
* with a session cookie set. When the BFF's WebAuthn RP is not configured the
|
|
1036
|
+
* options endpoint returns 501 and the hook transparently falls back to the
|
|
1037
|
+
* legacy Keycloak redirect — so nothing regresses until the flag flips. A
|
|
1038
|
+
* cancelled / failed in-page ceremony surfaces as an inline error banner; a prior
|
|
1039
|
+
* redirect round-trip's `?passkeyError=…` is still honoured too.
|
|
1031
1040
|
*
|
|
1032
|
-
* react-query-free:
|
|
1033
|
-
* `
|
|
1034
|
-
* has no QueryClient provider.
|
|
1041
|
+
* react-query-free: the hook uses plain `fetch` + `useState` (see
|
|
1042
|
+
* `usePasskeyCeremony`), so it is safe to mount inside the login route group
|
|
1043
|
+
* which has no QueryClient provider.
|
|
1035
1044
|
*/
|
|
1036
1045
|
|
|
1037
1046
|
interface PasskeyLoginButtonProps {
|
|
@@ -1051,14 +1060,16 @@ declare function PasskeyLoginButton({ returnUrl, theme: themeProp, labels: label
|
|
|
1051
1060
|
* The authenticated "Passkeys" settings card.
|
|
1052
1061
|
*
|
|
1053
1062
|
* Mount on an authenticated settings / account surface (alongside the device-PIN
|
|
1054
|
-
* card). Adding a passkey
|
|
1055
|
-
*
|
|
1056
|
-
*
|
|
1057
|
-
*
|
|
1058
|
-
*
|
|
1063
|
+
* card). Adding a passkey runs IN-PAGE via `usePasskeyCeremony`
|
|
1064
|
+
* (`navigator.credentials.create` against the same-origin
|
|
1065
|
+
* `/bff/passkey/register/*` fetch endpoints, session-cookie authenticated); on
|
|
1066
|
+
* success we show an inline success line — no navigation. When the BFF's WebAuthn
|
|
1067
|
+
* RP is not configured the options endpoint returns 501 and the hook falls back
|
|
1068
|
+
* to the legacy Keycloak redirect, which returns here with `?passkey=registered`;
|
|
1069
|
+
* that param is still honoured on mount, so nothing regresses until the flag flips.
|
|
1059
1070
|
*
|
|
1060
|
-
* react-query-free: the
|
|
1061
|
-
* `
|
|
1071
|
+
* react-query-free: the hook uses plain `fetch` + `useState` (see
|
|
1072
|
+
* `usePasskeyCeremony`). Mirrors `DevicePinSettingsCard`.
|
|
1062
1073
|
*/
|
|
1063
1074
|
|
|
1064
1075
|
interface PasskeySettingsCardProps {
|
|
@@ -1297,6 +1308,7 @@ declare const AuthTestIds: {
|
|
|
1297
1308
|
readonly passkeyLogin: "auth-passkey-login";
|
|
1298
1309
|
readonly passkeyLoginButton: "auth-passkey-login-button";
|
|
1299
1310
|
readonly passkeyLoginError: "auth-passkey-login-error";
|
|
1311
|
+
readonly passkeyLoginFallback: "auth-passkey-login-fallback";
|
|
1300
1312
|
readonly passkeySettings: "auth-passkey-settings";
|
|
1301
1313
|
readonly passkeySettingsAdd: "auth-passkey-settings-add";
|
|
1302
1314
|
readonly passkeySettingsSuccess: "auth-passkey-settings-success";
|
|
@@ -1644,6 +1656,44 @@ declare const DEVICE_PIN_DEFAULT_DIGITS = 4;
|
|
|
1644
1656
|
/** Guard: is `value` one of the BFF-accepted PIN lengths? */
|
|
1645
1657
|
declare function isAllowedPinDigits(value: number): boolean;
|
|
1646
1658
|
|
|
1659
|
+
/**
|
|
1660
|
+
* Which WebAuthn ceremony {@link usePasskeyCeremony} drives.
|
|
1661
|
+
*
|
|
1662
|
+
* `Login` runs a usernameless/discoverable assertion
|
|
1663
|
+
* (`navigator.credentials.get`) from the login surface; `Register` runs an
|
|
1664
|
+
* attestation (`navigator.credentials.create`) from an authenticated settings
|
|
1665
|
+
* surface. The mode selects the `/bff/passkey/{login,register}/*` endpoint pair
|
|
1666
|
+
* and the matching redirect fallback.
|
|
1667
|
+
*/
|
|
1668
|
+
declare const enum PasskeyCeremonyMode {
|
|
1669
|
+
/** Assertion ceremony — sign in with an existing passkey. */
|
|
1670
|
+
Login = "login",
|
|
1671
|
+
/** Attestation ceremony — add a passkey to the signed-in account. */
|
|
1672
|
+
Register = "register"
|
|
1673
|
+
}
|
|
1674
|
+
|
|
1675
|
+
/**
|
|
1676
|
+
* The lifecycle state of an in-page passkey ceremony.
|
|
1677
|
+
*
|
|
1678
|
+
* `Idle` before the user acts; `Running` while options are fetched, the
|
|
1679
|
+
* authenticator prompts, and the assertion/attestation is verified; `Success`
|
|
1680
|
+
* once the BFF confirms (a login has a session cookie set, a registration has a
|
|
1681
|
+
* stored credential); `Error` on a genuine in-page failure (see
|
|
1682
|
+
* {@link PasskeyErrorCode}). A redirect fallback (RP not configured / unsupported
|
|
1683
|
+
* browser) navigates the page away, so the hook never lands in a terminal state
|
|
1684
|
+
* for that path.
|
|
1685
|
+
*/
|
|
1686
|
+
declare const enum PasskeyCeremonyStatus {
|
|
1687
|
+
/** No ceremony has started. */
|
|
1688
|
+
Idle = "idle",
|
|
1689
|
+
/** A ceremony is in flight (fetch → authenticator → verify). */
|
|
1690
|
+
Running = "running",
|
|
1691
|
+
/** The ceremony completed and the BFF confirmed it. */
|
|
1692
|
+
Success = "success",
|
|
1693
|
+
/** The ceremony failed in-page (cancelled or failed). */
|
|
1694
|
+
Error = "error"
|
|
1695
|
+
}
|
|
1696
|
+
|
|
1647
1697
|
/**
|
|
1648
1698
|
* Navigation helpers for the passkey (WebAuthn) BFF endpoints.
|
|
1649
1699
|
*
|
|
@@ -1700,6 +1750,44 @@ declare function readPasskeyError(): PasskeyErrorCode | null;
|
|
|
1700
1750
|
*/
|
|
1701
1751
|
declare function readPasskeyRegistered(): boolean;
|
|
1702
1752
|
|
|
1753
|
+
/** Options for {@link usePasskeyCeremony}. */
|
|
1754
|
+
interface UsePasskeyCeremonyOptions {
|
|
1755
|
+
/** Which ceremony to run — login (assertion) or register (attestation). */
|
|
1756
|
+
mode: PasskeyCeremonyMode;
|
|
1757
|
+
/**
|
|
1758
|
+
* Relative app path used two ways: the redirect fallback returns here, and (for
|
|
1759
|
+
* login) a successful in-page ceremony navigates here unless `onSuccess` is set.
|
|
1760
|
+
*/
|
|
1761
|
+
returnUrl: string;
|
|
1762
|
+
/**
|
|
1763
|
+
* Called on a successful in-page ceremony. For login it receives the signed-in
|
|
1764
|
+
* `BffUser`; for register it receives `undefined`. When omitted, a login
|
|
1765
|
+
* navigates to `returnUrl` and a register just resolves to `Success`.
|
|
1766
|
+
*/
|
|
1767
|
+
onSuccess?: (user: BffUser | undefined) => void;
|
|
1768
|
+
}
|
|
1769
|
+
/** The state + controls {@link usePasskeyCeremony} returns. */
|
|
1770
|
+
interface UsePasskeyCeremonyResult {
|
|
1771
|
+
/** Current lifecycle state. */
|
|
1772
|
+
status: PasskeyCeremonyStatus;
|
|
1773
|
+
/** The in-page error code, or `null`. */
|
|
1774
|
+
error: PasskeyErrorCode | null;
|
|
1775
|
+
/** `true` when the browser can run the in-page ceremony (else it redirects). */
|
|
1776
|
+
isSupported: boolean;
|
|
1777
|
+
/** Start the ceremony (or redirect-fallback when the RP is off / unsupported). */
|
|
1778
|
+
start: () => void;
|
|
1779
|
+
/**
|
|
1780
|
+
* Hand off to the legacy Keycloak redirect explicitly. Wired to the "try
|
|
1781
|
+
* another way" affordance a surface shows after an in-page error — the escape
|
|
1782
|
+
* hatch for a credential enrolled only in Keycloak (invisible to the in-page
|
|
1783
|
+
* RP store), which the in-page ceremony cannot use.
|
|
1784
|
+
*/
|
|
1785
|
+
fallbackToRedirect: () => void;
|
|
1786
|
+
/** Clear a terminal state so the affordance can be retried. */
|
|
1787
|
+
reset: () => void;
|
|
1788
|
+
}
|
|
1789
|
+
declare function usePasskeyCeremony(optionsArg: UsePasskeyCeremonyOptions): UsePasskeyCeremonyResult;
|
|
1790
|
+
|
|
1703
1791
|
/**
|
|
1704
1792
|
* Device-local cache of the user's preferred login method (unified-login D5).
|
|
1705
1793
|
*
|
|
@@ -1906,4 +1994,4 @@ declare function validatePasswordPolicy(password: string): PasswordPolicyError[]
|
|
|
1906
1994
|
/** `true` when the password satisfies every policy rule. */
|
|
1907
1995
|
declare function isPasswordValid(password: string): boolean;
|
|
1908
1996
|
|
|
1909
|
-
export { AuthScreen, type AuthScreenProps, AuthTestIds, type AuthTheme, type AuthThemeColors, AuthThemeProvider, type AuthThemeProviderProps, type AuthThemeRadii, type AuthThemeSpacing, type AuthThemeTypography, BffAuthStatus, type BffDeviceState, type BffLoginConfig, type CreateBffAuthClientOptions, DEFAULT_AUTH_CARD_MAX_WIDTH, 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 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, type PasskeyErrorCode, PasskeyLoginButton, type PasskeyLoginButtonProps, type PasskeyLoginLabels, PasskeySettingsCard, type PasskeySettingsCardProps, type PasskeySettingsLabels, PasswordPolicyError, 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 UseDevicePinDisableArgs, type UseDevicePinDisableResult, type UseDevicePinEnrollArgs, type UseDevicePinEnrollResult, type UseDevicePinUnlockArgs, type UseDevicePinUnlockResult, type UseForgotPasswordSubmitArgs, type UseForgotPasswordSubmitResult, type UseOtpLoginOptions, type UseOtpLoginResult, type UsePinLoginOptions, type UsePinLoginResult, type UsePreferredMethodSettingArgs, type UsePreferredMethodSettingResult, type UseResetPasswordFormArgs, type UseResetPasswordFormResult, cachePreferredMethod, clearCachedPreferredMethod, collectUserRoles, createBffAuthClient, createPreferencesClient, defaultAuthTheme, isAllowedPinDigits, isPasswordValid, isValidForgotPasswordEmail, readCachedPreferredMethod, readPasskeyError, readPasskeyRegistered, resolveAccessibleRoutes, resolvePostLoginRoute, startPasskeyLogin, startPasskeyRegistration, syncPreferredMethodFromServer, useAuthTheme, useBffAuth, useBffForgotPassword, useBffLoginConfig, useBffResetPassword, useDevicePinDisable, useDevicePinEnroll, useDevicePinUnlock, useForgotPasswordSubmit, useOtpLogin, usePinLogin, usePreferredMethodSetting, useResetPasswordForm, validatePasswordPolicy, withTestIdPrefix };
|
|
1997
|
+
export { AuthScreen, type AuthScreenProps, AuthTestIds, type AuthTheme, type AuthThemeColors, AuthThemeProvider, type AuthThemeProviderProps, type AuthThemeRadii, type AuthThemeSpacing, type AuthThemeTypography, BffAuthStatus, type BffDeviceState, type BffLoginConfig, type CreateBffAuthClientOptions, DEFAULT_AUTH_CARD_MAX_WIDTH, 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 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, 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 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, readCachedPreferredMethod, readPasskeyError, readPasskeyRegistered, resolveAccessibleRoutes, resolvePostLoginRoute, startPasskeyLogin, startPasskeyRegistration, syncPreferredMethodFromServer, useAuthTheme, useBffAuth, useBffForgotPassword, useBffLoginConfig, useBffResetPassword, useDevicePinDisable, useDevicePinEnroll, useDevicePinUnlock, useForgotPasswordSubmit, useOtpLogin, usePasskeyCeremony, usePinLogin, usePreferredMethodSetting, useResetPasswordForm, validatePasswordPolicy, withTestIdPrefix };
|