@dloizides/auth-web 1.9.1 → 1.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,58 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.10.0 (2026-07-17)
4
+
5
+ Additive release adding the shared **logout sequencer**. Purely additive — every
6
+ 1.9.x export is unchanged, no component behaviour changes, and apps that do not
7
+ import `performBffLogout` are byte-identical.
8
+
9
+ ### Added
10
+
11
+ - **`performBffLogout({ client, onClearSession?, onRedirect?, onError?, navigateToIdp? })`**
12
+ — the shared logout sequence, extracted because all six consuming apps
13
+ hand-rolled it in their own `AuthProvider` and the orderings disagreed. Runs:
14
+ 1. `onClearSession()` — local state first, so the UI reflects the sign-out
15
+ immediately.
16
+ 2. `await client.logout({ redirect: false })` — lets the `POST /bff/logout`
17
+ SETTLE, and takes the IdP logout URL rather than letting the client navigate
18
+ mid-sequence.
19
+ 3. Navigates exactly once, last: to the IdP logout URL when the BFF returned
20
+ one (ending the IdP browser session), otherwise `onRedirect()`. When it
21
+ navigates to the IdP it deliberately does NOT also call `onRedirect` — two
22
+ competing navigations would race, and the IdP round-trip already returns the
23
+ user to the app.
24
+
25
+ Never rejects; always navigates, even when the BFF logout fails (a down BFF
26
+ must not trap the user on a page they asked to leave).
27
+ - **`BffLogoutClient`** / **`PerformBffLogoutOptions`** types.
28
+
29
+ ### Why
30
+
31
+ `zygos-web` and `agora-web` navigated FIRST and called the BFF second:
32
+
33
+ ```ts
34
+ redirectTo('/(auth)/login'); // → window.location.replace() → document unload
35
+ await bffAuthClient.logout(); // races the unload — may never be sent
36
+ ```
37
+
38
+ That is wrong twice over:
39
+
40
+ 1. **The BFF call can be cancelled.** A document navigation kills in-flight
41
+ fetches, so `POST /bff/logout` may never reach the server: the SPA looks
42
+ logged out while the httpOnly session cookie stays alive. The `catch` logged
43
+ it "non-fatal", so the defect was silent.
44
+ 2. **The IdP session survives.** `BffAuthClient.logout()` ends the identity
45
+ provider's browser session with a top-level navigation to its RP-initiated
46
+ logout URL (only a real navigation carries the IdP's own cookie — a
47
+ back-channel POST cannot clear it). An app that navigates to its own login
48
+ route first pre-empts that navigation, so the IdP still considers the user
49
+ signed in and the next authorize round-trip silently re-authenticates them —
50
+ the "sign-out that signs you back in" bug the client's own docs warn about.
51
+
52
+ Synthetic tests that stub the client never reproduce either failure (there is no
53
+ real navigation to cancel the request), which is why they survived. The helper
54
+ owns the sequence so neither can be reintroduced per-app.
55
+
3
56
  ## 1.8.0 (2026-07-09)
4
57
 
5
58
  Additive release for the Move 2b passkey in-app rebuild — the passkey ceremony
package/dist/index.d.mts CHANGED
@@ -1925,6 +1925,97 @@ declare function resolvePostLoginRoute(user: BffUser, table: RoleRouteTable): st
1925
1925
  */
1926
1926
  declare function resolveAccessibleRoutes(user: BffUser, table: RoleRouteTable): RoleRoute[];
1927
1927
 
1928
+ /**
1929
+ * `performBffLogout` — the shared logout sequencer.
1930
+ *
1931
+ * Every app hand-rolled its own logout ordering inside its `AuthProvider`, and
1932
+ * the orderings disagreed. Two of them (zygos-web, agora-web) navigated FIRST
1933
+ * and called the BFF second:
1934
+ *
1935
+ * ```ts
1936
+ * redirectTo('/(auth)/login'); // window.location.replace() → document unload
1937
+ * await bffAuthClient.logout(); // races the unload — may never be sent
1938
+ * ```
1939
+ *
1940
+ * That is wrong twice over:
1941
+ *
1942
+ * 1. **The BFF call can be cancelled.** A document navigation kills in-flight
1943
+ * fetches, so `POST /bff/logout` may never reach the server: the SPA looks
1944
+ * logged out while the httpOnly session cookie stays ALIVE. The `catch`
1945
+ * logged it "non-fatal", so the defect was silent.
1946
+ * 2. **The IdP session survives.** `BffAuthClient.logout()` ends the *identity
1947
+ * provider's* browser session by doing a top-level navigation to the IdP's
1948
+ * RP-initiated logout URL (only a real navigation carries the IdP's own
1949
+ * cookie — a back-channel POST cannot clear it). An app that navigates to
1950
+ * its own login route first pre-empts that navigation, so the IdP still
1951
+ * considers the user signed in and the next authorize round-trip silently
1952
+ * re-authenticates them. That is the "sign-out that signs you back in" bug
1953
+ * the client's own docs warn about.
1954
+ *
1955
+ * This helper owns the whole sequence so neither can be reintroduced per-app:
1956
+ *
1957
+ * 1. `onClearSession()` — drop local state immediately so the UI reflects the
1958
+ * sign-out right away (perceived performance; no spinner needed).
1959
+ * 2. `await client.logout({ redirect: false })` — let the network call SETTLE,
1960
+ * and take the IdP logout URL rather than letting the client navigate mid-
1961
+ * sequence. Errors are captured, never rethrown.
1962
+ * 3. Navigate LAST, exactly once, when nothing is in flight to cancel:
1963
+ * - an IdP logout URL → a top-level navigation to the IdP, which ends that
1964
+ * session and bounces the user back. `onRedirect` is deliberately NOT
1965
+ * called: two competing navigations would race, and the IdP round-trip
1966
+ * already returns the user to the app.
1967
+ * - otherwise (ROPC / OTP / device-PIN logins never had an IdP cookie, so
1968
+ * the URL is `null`) → `onRedirect()`, the app's own login route.
1969
+ *
1970
+ * Step 3 runs even when step 2 rejects: a BFF that is down must not trap the
1971
+ * user on a page they asked to leave. The local session is already gone, so the
1972
+ * client-side sign-out holds regardless.
1973
+ *
1974
+ * Headless and framework-free: it takes callbacks, so an app can pair it with
1975
+ * Redux, a context, expo-router, or `window.location` without this package
1976
+ * knowing about any of them.
1977
+ */
1978
+ /**
1979
+ * The only part of a `BffAuthClient` this helper needs. Structural, so it is
1980
+ * trivially fakeable in tests and does not couple to the full client surface.
1981
+ */
1982
+ interface BffLogoutClient {
1983
+ /**
1984
+ * `POST /bff/logout` — ends the server-side session. With `redirect: false`
1985
+ * it returns the IdP's RP-initiated logout URL (or `null` when the session
1986
+ * never involved an IdP browser cookie) instead of navigating there itself.
1987
+ */
1988
+ logout: (options?: {
1989
+ redirect?: boolean;
1990
+ }) => Promise<string | null>;
1991
+ }
1992
+ /** Callbacks + client for {@link performBffLogout}. */
1993
+ interface PerformBffLogoutOptions {
1994
+ /** The BFF auth client whose `logout()` ends the server-side session. */
1995
+ client: BffLogoutClient;
1996
+ /** Drop local session state. Runs BEFORE the network call. Optional. */
1997
+ onClearSession?: () => void;
1998
+ /**
1999
+ * Navigate to the app's logged-out route. Runs only AFTER the network call
2000
+ * settles, and only when there is no IdP logout URL to honour. Optional.
2001
+ */
2002
+ onRedirect?: () => void;
2003
+ /** Observe a failed logout step (e.g. to log it). Never rethrown. Optional. */
2004
+ onError?: (error: Error) => void;
2005
+ /**
2006
+ * Test seam: perform the top-level navigation to the IdP logout URL. Defaults
2007
+ * to `window.location.assign`. Must be a real navigation — a `fetch` here
2008
+ * would not carry the IdP cookie and would silently fail to end the session.
2009
+ */
2010
+ navigateToIdp?: (url: string) => void;
2011
+ }
2012
+ /**
2013
+ * End the session: clear locally, await the BFF, then navigate exactly once.
2014
+ *
2015
+ * Never rejects — callers may `void` it safely.
2016
+ */
2017
+ declare function performBffLogout(options: Readonly<PerformBffLogoutOptions>): Promise<void>;
2018
+
1928
2019
  /**
1929
2020
  * The discrete ways a password can fail the shared client-side policy.
1930
2021
  *
@@ -1970,4 +2061,4 @@ declare function validatePasswordPolicy(password: string): PasswordPolicyError[]
1970
2061
  /** `true` when the password satisfies every policy rule. */
1971
2062
  declare function isPasswordValid(password: string): boolean;
1972
2063
 
1973
- 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 };
2064
+ 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_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, 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 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, 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
@@ -1925,6 +1925,97 @@ declare function resolvePostLoginRoute(user: BffUser, table: RoleRouteTable): st
1925
1925
  */
1926
1926
  declare function resolveAccessibleRoutes(user: BffUser, table: RoleRouteTable): RoleRoute[];
1927
1927
 
1928
+ /**
1929
+ * `performBffLogout` — the shared logout sequencer.
1930
+ *
1931
+ * Every app hand-rolled its own logout ordering inside its `AuthProvider`, and
1932
+ * the orderings disagreed. Two of them (zygos-web, agora-web) navigated FIRST
1933
+ * and called the BFF second:
1934
+ *
1935
+ * ```ts
1936
+ * redirectTo('/(auth)/login'); // window.location.replace() → document unload
1937
+ * await bffAuthClient.logout(); // races the unload — may never be sent
1938
+ * ```
1939
+ *
1940
+ * That is wrong twice over:
1941
+ *
1942
+ * 1. **The BFF call can be cancelled.** A document navigation kills in-flight
1943
+ * fetches, so `POST /bff/logout` may never reach the server: the SPA looks
1944
+ * logged out while the httpOnly session cookie stays ALIVE. The `catch`
1945
+ * logged it "non-fatal", so the defect was silent.
1946
+ * 2. **The IdP session survives.** `BffAuthClient.logout()` ends the *identity
1947
+ * provider's* browser session by doing a top-level navigation to the IdP's
1948
+ * RP-initiated logout URL (only a real navigation carries the IdP's own
1949
+ * cookie — a back-channel POST cannot clear it). An app that navigates to
1950
+ * its own login route first pre-empts that navigation, so the IdP still
1951
+ * considers the user signed in and the next authorize round-trip silently
1952
+ * re-authenticates them. That is the "sign-out that signs you back in" bug
1953
+ * the client's own docs warn about.
1954
+ *
1955
+ * This helper owns the whole sequence so neither can be reintroduced per-app:
1956
+ *
1957
+ * 1. `onClearSession()` — drop local state immediately so the UI reflects the
1958
+ * sign-out right away (perceived performance; no spinner needed).
1959
+ * 2. `await client.logout({ redirect: false })` — let the network call SETTLE,
1960
+ * and take the IdP logout URL rather than letting the client navigate mid-
1961
+ * sequence. Errors are captured, never rethrown.
1962
+ * 3. Navigate LAST, exactly once, when nothing is in flight to cancel:
1963
+ * - an IdP logout URL → a top-level navigation to the IdP, which ends that
1964
+ * session and bounces the user back. `onRedirect` is deliberately NOT
1965
+ * called: two competing navigations would race, and the IdP round-trip
1966
+ * already returns the user to the app.
1967
+ * - otherwise (ROPC / OTP / device-PIN logins never had an IdP cookie, so
1968
+ * the URL is `null`) → `onRedirect()`, the app's own login route.
1969
+ *
1970
+ * Step 3 runs even when step 2 rejects: a BFF that is down must not trap the
1971
+ * user on a page they asked to leave. The local session is already gone, so the
1972
+ * client-side sign-out holds regardless.
1973
+ *
1974
+ * Headless and framework-free: it takes callbacks, so an app can pair it with
1975
+ * Redux, a context, expo-router, or `window.location` without this package
1976
+ * knowing about any of them.
1977
+ */
1978
+ /**
1979
+ * The only part of a `BffAuthClient` this helper needs. Structural, so it is
1980
+ * trivially fakeable in tests and does not couple to the full client surface.
1981
+ */
1982
+ interface BffLogoutClient {
1983
+ /**
1984
+ * `POST /bff/logout` — ends the server-side session. With `redirect: false`
1985
+ * it returns the IdP's RP-initiated logout URL (or `null` when the session
1986
+ * never involved an IdP browser cookie) instead of navigating there itself.
1987
+ */
1988
+ logout: (options?: {
1989
+ redirect?: boolean;
1990
+ }) => Promise<string | null>;
1991
+ }
1992
+ /** Callbacks + client for {@link performBffLogout}. */
1993
+ interface PerformBffLogoutOptions {
1994
+ /** The BFF auth client whose `logout()` ends the server-side session. */
1995
+ client: BffLogoutClient;
1996
+ /** Drop local session state. Runs BEFORE the network call. Optional. */
1997
+ onClearSession?: () => void;
1998
+ /**
1999
+ * Navigate to the app's logged-out route. Runs only AFTER the network call
2000
+ * settles, and only when there is no IdP logout URL to honour. Optional.
2001
+ */
2002
+ onRedirect?: () => void;
2003
+ /** Observe a failed logout step (e.g. to log it). Never rethrown. Optional. */
2004
+ onError?: (error: Error) => void;
2005
+ /**
2006
+ * Test seam: perform the top-level navigation to the IdP logout URL. Defaults
2007
+ * to `window.location.assign`. Must be a real navigation — a `fetch` here
2008
+ * would not carry the IdP cookie and would silently fail to end the session.
2009
+ */
2010
+ navigateToIdp?: (url: string) => void;
2011
+ }
2012
+ /**
2013
+ * End the session: clear locally, await the BFF, then navigate exactly once.
2014
+ *
2015
+ * Never rejects — callers may `void` it safely.
2016
+ */
2017
+ declare function performBffLogout(options: Readonly<PerformBffLogoutOptions>): Promise<void>;
2018
+
1928
2019
  /**
1929
2020
  * The discrete ways a password can fail the shared client-side policy.
1930
2021
  *
@@ -1970,4 +2061,4 @@ declare function validatePasswordPolicy(password: string): PasswordPolicyError[]
1970
2061
  /** `true` when the password satisfies every policy rule. */
1971
2062
  declare function isPasswordValid(password: string): boolean;
1972
2063
 
1973
- 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 };
2064
+ 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_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, 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 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, resolvePostLoginRoute, startPasskeyLogin, startPasskeyRegistration, syncPreferredMethodFromServer, useAuthTheme, useBffAuth, useBffForgotPassword, useBffLoginConfig, useBffResetPassword, useDevicePinDisable, useDevicePinEnroll, useDevicePinUnlock, useForgotPasswordSubmit, useOtpLogin, usePasskeyCeremony, usePinLogin, usePreferredMethodSetting, useResetPasswordForm, validatePasswordPolicy, withTestIdPrefix };
package/dist/index.js CHANGED
@@ -3286,6 +3286,43 @@ function resolveAccessibleRoutes(user, table) {
3286
3286
  return table.routes.filter((entry) => userRoles.has(entry.role));
3287
3287
  }
3288
3288
 
3289
+ // src/session/performBffLogout.ts
3290
+ function toError4(caught) {
3291
+ return caught instanceof Error ? caught : new Error(String(caught));
3292
+ }
3293
+ function runGuarded(callback, onError) {
3294
+ if (callback === void 0) {
3295
+ return;
3296
+ }
3297
+ try {
3298
+ callback();
3299
+ } catch (caught) {
3300
+ onError?.(toError4(caught));
3301
+ }
3302
+ }
3303
+ function assignLocation(url) {
3304
+ if (typeof window === "undefined") {
3305
+ return;
3306
+ }
3307
+ window.location.assign(url);
3308
+ }
3309
+ async function performBffLogout(options) {
3310
+ const { client, onClearSession, onRedirect, onError, navigateToIdp = assignLocation } = options;
3311
+ runGuarded(onClearSession, onError);
3312
+ let idpLogoutUrl = null;
3313
+ try {
3314
+ idpLogoutUrl = await client.logout({ redirect: false });
3315
+ } catch (caught) {
3316
+ onError?.(toError4(caught));
3317
+ }
3318
+ if (idpLogoutUrl !== null) {
3319
+ const url = idpLogoutUrl;
3320
+ runGuarded(() => navigateToIdp(url), onError);
3321
+ return;
3322
+ }
3323
+ runGuarded(onRedirect, onError);
3324
+ }
3325
+
3289
3326
  Object.defineProperty(exports, "BffAuthClient", {
3290
3327
  enumerable: true,
3291
3328
  get: function () { return authClient.BffAuthClient; }
@@ -3348,6 +3385,7 @@ exports.defaultAuthTheme = defaultAuthTheme;
3348
3385
  exports.isAllowedPinDigits = isAllowedPinDigits;
3349
3386
  exports.isPasswordValid = isPasswordValid;
3350
3387
  exports.isValidForgotPasswordEmail = isValidForgotPasswordEmail;
3388
+ exports.performBffLogout = performBffLogout;
3351
3389
  exports.readCachedPreferredMethod = readCachedPreferredMethod;
3352
3390
  exports.readPasskeyError = readPasskeyError;
3353
3391
  exports.readPasskeyRegistered = readPasskeyRegistered;