@feelflow/ffid-sdk 5.16.1 → 5.17.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/dist/index.d.cts CHANGED
@@ -1,6 +1,6 @@
1
- import { F as FFIDSubscriptionStatus, a as FFIDConfig, b as FFIDApiResponse, c as FFIDSessionResponse, d as FFIDRedirectResult, e as FFIDError, f as FFIDSubscriptionCheckResponse, g as FFIDCheckServiceAccessParams, h as FFIDServiceAccessDecision, i as FFIDAnalyticsConfig, j as FFIDVerifyAccessTokenOptions, k as FFIDOAuthUserInfo, l as FFIDInquiryCreateParams, m as FFIDInquiryCreateResponse, n as FFIDAuthMode, o as FFIDLogger, p as FFIDCacheAdapter, q as FFIDUser, r as FFIDOrganization, s as FFIDSubscription, t as FFIDSubscriptionContextValue, E as EffectiveSubscriptionStatus, u as FFIDOAuthUserInfoSubscription, v as FFIDAnnouncementsClientConfig, L as ListAnnouncementsOptions, w as FFIDAnnouncementsApiResponse, A as AnnouncementListResponse, x as FFIDAnnouncementsLogger } from './index-CsVJTuPv.cjs';
2
- export { y as Announcement, z as AnnouncementStatus, B as AnnouncementType, C as EFFECTIVE_SUBSCRIPTION_STATUSES, D as FFIDAnnouncementBadge, G as FFIDAnnouncementList, H as FFIDAnnouncementsError, I as FFIDAnnouncementsErrorCode, J as FFIDAnnouncementsServerResponse, K as FFIDCacheConfig, M as FFIDContextValue, N as FFIDInquiryCategory, O as FFIDInquiryCategorySite2026, P as FFIDInquiryForm, Q as FFIDInquiryFormCategoryItem, R as FFIDInquiryFormClassNames, S as FFIDInquiryFormLegalLayout, T as FFIDInquiryFormOrganization, U as FFIDInquiryFormPlaceholderContext, V as FFIDInquiryFormPrefill, W as FFIDInquiryFormProps, X as FFIDInquiryFormSubmitData, Y as FFIDInquiryFormSubmitResult, Z as FFIDJwtClaims, _ as FFIDLoginButton, $ as FFIDOAuthTokenResponse, a0 as FFIDOAuthUserInfoMemberRole, a1 as FFIDOrganizationSwitcher, a2 as FFIDRedirectErrorCode, a3 as FFIDSeatModel, a4 as FFIDServiceAccessDenialReason, a5 as FFIDServiceAccessFailPolicy, a6 as FFIDSubscriptionBadge, a7 as FFIDTokenIntrospectionResponse, a8 as FFIDUserMenu, a9 as FFID_INQUIRY_CATEGORIES, aa as FFID_INQUIRY_CATEGORIES_SITE_2026, ab as UseFFIDAnnouncementsOptions, ac as UseFFIDAnnouncementsReturn, ad as isFFIDInquiryCategorySite2026, ae as useFFIDAnnouncements } from './index-CsVJTuPv.cjs';
3
- export { A as ALL_DENIED_EXCEPT_NECESSARY, i as CONSENT_COOKIE_NAME, j as CONSENT_DISMISSAL_TIMESTAMP_KEY, l as COOKIE_VERSION, D as DEFAULT_CONSENT_ERROR_MESSAGES, o as FFIDAnalyticsProvider, p as FFIDAnalyticsProviderProps, c as FFIDConsentCategories, r as FFIDConsentCategoryCode, e as FFIDConsentCategoryMetadata, w as FFIDConsentError, x as FFIDConsentErrorCode, y as FFIDConsentMergeStrategy, B as FFIDConsentMergeWarning, E as FFIDConsentMergeWarningEvent, F as FFIDConsentResult, I as FFIDConsentSource, a as FFIDConsentState, d as FFIDConsentSyncResult, M as FFIDCookieBanner, N as FFIDCookieBannerClassNames, O as FFIDCookieBannerProps, Q as FFIDCookieLink, R as FFIDCookieLinkProps, f as FFIDCookiePolicy, T as FFIDCookieSettings, U as FFIDCookieSettingsClassNames, V as FFIDCookieSettingsProps, _ as FFID_CONSENT_ERROR_CODES, ae as UseFFIDConsentPreferencesReturn, af as UseFFIDConsentReturn, ag as clearConsentDismissalTimestamp, aj as decodeConsentCookie, al as encodeConsentCookie, an as readConsentCookie, ao as readConsentDismissalTimestamp, aq as useFFIDConsent, ar as useFFIDConsentPreferences, as as writeConsentCookie, at as writeConsentDismissalTimestamp } from './FFIDCookieLink-DrF5UXkd.cjs';
1
+ import { F as FFIDSubscriptionStatus, a as FFIDPrompt, b as FFIDConfig, c as FFIDApiResponse, d as FFIDSessionResponse, e as FFIDRedirectResult, f as FFIDError, g as FFIDSubscriptionCheckResponse, h as FFIDCheckServiceAccessParams, i as FFIDServiceAccessDecision, j as FFIDAnalyticsConfig, k as FFIDVerifyAccessTokenOptions, l as FFIDOAuthUserInfo, m as FFIDInquiryCreateParams, n as FFIDInquiryCreateResponse, o as FFIDAuthMode, p as FFIDLogger, q as FFIDCacheAdapter, r as FFIDUser, s as FFIDOrganization, t as FFIDSubscription, u as FFIDSubscriptionContextValue, E as EffectiveSubscriptionStatus, v as FFIDOAuthUserInfoSubscription, w as FFIDAnnouncementsClientConfig, L as ListAnnouncementsOptions, x as FFIDAnnouncementsApiResponse, A as AnnouncementListResponse, y as FFIDAnnouncementsLogger } from './index-CG0vObax.cjs';
2
+ export { z as Announcement, B as AnnouncementStatus, C as AnnouncementType, D as EFFECTIVE_SUBSCRIPTION_STATUSES, G as FFIDAnnouncementBadge, H as FFIDAnnouncementList, I as FFIDAnnouncementsError, J as FFIDAnnouncementsErrorCode, K as FFIDAnnouncementsServerResponse, M as FFIDCacheConfig, N as FFIDContextValue, O as FFIDInquiryCategory, P as FFIDInquiryCategorySite2026, Q as FFIDInquiryForm, R as FFIDInquiryFormCategoryItem, S as FFIDInquiryFormClassNames, T as FFIDInquiryFormLegalLayout, U as FFIDInquiryFormOrganization, V as FFIDInquiryFormPlaceholderContext, W as FFIDInquiryFormPrefill, X as FFIDInquiryFormProps, Y as FFIDInquiryFormSubmitData, Z as FFIDInquiryFormSubmitResult, _ as FFIDJwtClaims, $ as FFIDLoginButton, a0 as FFIDOAuthTokenResponse, a1 as FFIDOAuthUserInfoMemberRole, a2 as FFIDOrganizationSwitcher, a3 as FFIDRedirectErrorCode, a4 as FFIDSeatModel, a5 as FFIDServiceAccessDenialReason, a6 as FFIDServiceAccessFailPolicy, a7 as FFIDSubscriptionBadge, a8 as FFIDTokenIntrospectionResponse, a9 as FFIDUserMenu, aa as FFID_INQUIRY_CATEGORIES, ab as FFID_INQUIRY_CATEGORIES_SITE_2026, ac as UseFFIDAnnouncementsOptions, ad as UseFFIDAnnouncementsReturn, ae as isFFIDInquiryCategorySite2026, af as useFFIDAnnouncements } from './index-CG0vObax.cjs';
3
+ export { A as ALL_DENIED_EXCEPT_NECESSARY, i as CONSENT_COOKIE_NAME, j as CONSENT_DISMISSAL_TIMESTAMP_KEY, l as COOKIE_VERSION, D as DEFAULT_CONSENT_ERROR_MESSAGES, o as FFIDAnalyticsProvider, p as FFIDAnalyticsProviderProps, c as FFIDConsentCategories, r as FFIDConsentCategoryCode, e as FFIDConsentCategoryMetadata, w as FFIDConsentError, x as FFIDConsentErrorCode, y as FFIDConsentMergeStrategy, B as FFIDConsentMergeWarning, E as FFIDConsentMergeWarningEvent, F as FFIDConsentResult, I as FFIDConsentSource, a as FFIDConsentState, d as FFIDConsentSyncResult, M as FFIDCookieBanner, N as FFIDCookieBannerClassNames, O as FFIDCookieBannerProps, Q as FFIDCookieLink, R as FFIDCookieLinkProps, f as FFIDCookiePolicy, T as FFIDCookieSettings, U as FFIDCookieSettingsClassNames, V as FFIDCookieSettingsProps, _ as FFID_CONSENT_ERROR_CODES, ae as UseFFIDConsentPreferencesReturn, af as UseFFIDConsentReturn, ag as clearConsentDismissalTimestamp, aj as decodeConsentCookie, al as encodeConsentCookie, an as readConsentCookie, ao as readConsentDismissalTimestamp, aq as useFFIDConsent, ar as useFFIDConsentPreferences, as as writeConsentCookie, at as writeConsentDismissalTimestamp } from './FFIDCookieLink-BJgVcJyw.cjs';
4
4
  import * as react_jsx_runtime from 'react/jsx-runtime';
5
5
  import { ReactNode, ComponentType, FC } from 'react';
6
6
  import 'zod';
@@ -1111,6 +1111,20 @@ interface RedirectToAuthorizeOptions {
1111
1111
  * regardless of `authMode`.
1112
1112
  */
1113
1113
  screenHint?: typeof SCREEN_HINT_SIGNUP | 'login';
1114
+ /**
1115
+ * OIDC `prompt` to forward to FFID `/oauth/authorize` (#4027).
1116
+ *
1117
+ * - `'select_account'`: forwards `prompt=select_account` so the upstream IdP
1118
+ * (Google) account chooser is shown — used by {@link switchAccount} to enable
1119
+ * RP-initiated account switching after logout (residual upstream sessions would
1120
+ * otherwise auto-re-authenticate the same account).
1121
+ * - `'login'`: forces re-authentication (FFID `/login` is shown even with an
1122
+ * active session).
1123
+ *
1124
+ * Token mode: added to the `/oauth/authorize` query. Cookie mode: forwarded as
1125
+ * `?prompt=…` on the `/login` URL (ignored for the signup screen).
1126
+ */
1127
+ prompt?: FFIDPrompt;
1114
1128
  }
1115
1129
 
1116
1130
  /** Creates an FFID API client instance */
@@ -1120,7 +1134,12 @@ declare function createFFIDClient(config: FFIDConfig): {
1120
1134
  redirectToLogin: (options?: RedirectToAuthorizeOptions) => Promise<FFIDRedirectResult>;
1121
1135
  redirectToAuthorize: (options?: RedirectToAuthorizeOptions) => Promise<FFIDRedirectResult>;
1122
1136
  redirectToLogout: (postLogoutRedirectUri?: string) => FFIDRedirectResult;
1123
- getLoginUrl: (redirectUrl?: string) => string;
1137
+ switchAccount: (options?: {
1138
+ organizationId?: string;
1139
+ }) => Promise<FFIDRedirectResult>;
1140
+ getLoginUrl: (redirectUrl?: string, options?: {
1141
+ prompt?: FFIDPrompt;
1142
+ }) => string;
1124
1143
  getLogoutUrl: (postLogoutRedirectUri?: string) => string;
1125
1144
  getSignupUrl: (redirectUrl?: string) => string;
1126
1145
  createError: (code: string, message: string) => FFIDError;
@@ -1375,12 +1394,36 @@ interface UseFFIDReturn {
1375
1394
  * (forwards `screen_hint=signup` in token mode / redirects to `/signup`
1376
1395
  * in cookie mode). `'login'` and `undefined` use the default login flow.
1377
1396
  * See `RedirectToAuthorizeOptions` (#2908 / #2911).
1397
+ * @param options.prompt OIDC `prompt` forwarded to FFID `/oauth/authorize`
1398
+ * (e.g. `'select_account'` to force the upstream account chooser). For account
1399
+ * switching, prefer the dedicated {@link UseFFIDReturn.switchAccount} helper (#4027).
1378
1400
  */
1379
1401
  login: (options?: {
1380
1402
  screenHint?: 'signup' | 'login';
1403
+ prompt?: FFIDPrompt;
1381
1404
  }) => void;
1382
- /** Sign out */
1405
+ /** Sign out (client-side: clears local session via the signout API) */
1383
1406
  logout: () => Promise<void>;
1407
+ /**
1408
+ * Get the FFID SSO logout URL (RP-initiated logout). Includes `client_id` for
1409
+ * `post_logout_redirect_uri` validation. Use for cross-origin browser navigation
1410
+ * that must clear the SSO session cookie (#4027).
1411
+ */
1412
+ getLogoutUrl: (postLogoutRedirectUri?: string) => string;
1413
+ /**
1414
+ * Redirect to the FFID SSO logout endpoint (clears the SSO session cookie via a
1415
+ * top-level browser navigation, so SameSite=Lax cookies are sent). #4027.
1416
+ */
1417
+ redirectToLogout: (postLogoutRedirectUri?: string) => FFIDRedirectResult;
1418
+ /**
1419
+ * Switch / add account: forces the upstream Google account chooser via
1420
+ * `prompt=select_account` so RP-initiated account switching is not silently
1421
+ * re-authenticated against the residual upstream session. Pair with
1422
+ * {@link UseFFIDReturn.redirectToLogout} if an explicit signed-out step is needed (#4027).
1423
+ */
1424
+ switchAccount: (options?: {
1425
+ organizationId?: string;
1426
+ }) => Promise<FFIDRedirectResult>;
1384
1427
  /**
1385
1428
  * Switch current organization.
1386
1429
  * Cookie mode: local state change. Token mode: OAuth re-authorization redirect.
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- import { F as FFIDSubscriptionStatus, a as FFIDConfig, b as FFIDApiResponse, c as FFIDSessionResponse, d as FFIDRedirectResult, e as FFIDError, f as FFIDSubscriptionCheckResponse, g as FFIDCheckServiceAccessParams, h as FFIDServiceAccessDecision, i as FFIDAnalyticsConfig, j as FFIDVerifyAccessTokenOptions, k as FFIDOAuthUserInfo, l as FFIDInquiryCreateParams, m as FFIDInquiryCreateResponse, n as FFIDAuthMode, o as FFIDLogger, p as FFIDCacheAdapter, q as FFIDUser, r as FFIDOrganization, s as FFIDSubscription, t as FFIDSubscriptionContextValue, E as EffectiveSubscriptionStatus, u as FFIDOAuthUserInfoSubscription, v as FFIDAnnouncementsClientConfig, L as ListAnnouncementsOptions, w as FFIDAnnouncementsApiResponse, A as AnnouncementListResponse, x as FFIDAnnouncementsLogger } from './index-CsVJTuPv.js';
2
- export { y as Announcement, z as AnnouncementStatus, B as AnnouncementType, C as EFFECTIVE_SUBSCRIPTION_STATUSES, D as FFIDAnnouncementBadge, G as FFIDAnnouncementList, H as FFIDAnnouncementsError, I as FFIDAnnouncementsErrorCode, J as FFIDAnnouncementsServerResponse, K as FFIDCacheConfig, M as FFIDContextValue, N as FFIDInquiryCategory, O as FFIDInquiryCategorySite2026, P as FFIDInquiryForm, Q as FFIDInquiryFormCategoryItem, R as FFIDInquiryFormClassNames, S as FFIDInquiryFormLegalLayout, T as FFIDInquiryFormOrganization, U as FFIDInquiryFormPlaceholderContext, V as FFIDInquiryFormPrefill, W as FFIDInquiryFormProps, X as FFIDInquiryFormSubmitData, Y as FFIDInquiryFormSubmitResult, Z as FFIDJwtClaims, _ as FFIDLoginButton, $ as FFIDOAuthTokenResponse, a0 as FFIDOAuthUserInfoMemberRole, a1 as FFIDOrganizationSwitcher, a2 as FFIDRedirectErrorCode, a3 as FFIDSeatModel, a4 as FFIDServiceAccessDenialReason, a5 as FFIDServiceAccessFailPolicy, a6 as FFIDSubscriptionBadge, a7 as FFIDTokenIntrospectionResponse, a8 as FFIDUserMenu, a9 as FFID_INQUIRY_CATEGORIES, aa as FFID_INQUIRY_CATEGORIES_SITE_2026, ab as UseFFIDAnnouncementsOptions, ac as UseFFIDAnnouncementsReturn, ad as isFFIDInquiryCategorySite2026, ae as useFFIDAnnouncements } from './index-CsVJTuPv.js';
3
- export { A as ALL_DENIED_EXCEPT_NECESSARY, i as CONSENT_COOKIE_NAME, j as CONSENT_DISMISSAL_TIMESTAMP_KEY, l as COOKIE_VERSION, D as DEFAULT_CONSENT_ERROR_MESSAGES, o as FFIDAnalyticsProvider, p as FFIDAnalyticsProviderProps, c as FFIDConsentCategories, r as FFIDConsentCategoryCode, e as FFIDConsentCategoryMetadata, w as FFIDConsentError, x as FFIDConsentErrorCode, y as FFIDConsentMergeStrategy, B as FFIDConsentMergeWarning, E as FFIDConsentMergeWarningEvent, F as FFIDConsentResult, I as FFIDConsentSource, a as FFIDConsentState, d as FFIDConsentSyncResult, M as FFIDCookieBanner, N as FFIDCookieBannerClassNames, O as FFIDCookieBannerProps, Q as FFIDCookieLink, R as FFIDCookieLinkProps, f as FFIDCookiePolicy, T as FFIDCookieSettings, U as FFIDCookieSettingsClassNames, V as FFIDCookieSettingsProps, _ as FFID_CONSENT_ERROR_CODES, ae as UseFFIDConsentPreferencesReturn, af as UseFFIDConsentReturn, ag as clearConsentDismissalTimestamp, aj as decodeConsentCookie, al as encodeConsentCookie, an as readConsentCookie, ao as readConsentDismissalTimestamp, aq as useFFIDConsent, ar as useFFIDConsentPreferences, as as writeConsentCookie, at as writeConsentDismissalTimestamp } from './FFIDCookieLink-DrF5UXkd.js';
1
+ import { F as FFIDSubscriptionStatus, a as FFIDPrompt, b as FFIDConfig, c as FFIDApiResponse, d as FFIDSessionResponse, e as FFIDRedirectResult, f as FFIDError, g as FFIDSubscriptionCheckResponse, h as FFIDCheckServiceAccessParams, i as FFIDServiceAccessDecision, j as FFIDAnalyticsConfig, k as FFIDVerifyAccessTokenOptions, l as FFIDOAuthUserInfo, m as FFIDInquiryCreateParams, n as FFIDInquiryCreateResponse, o as FFIDAuthMode, p as FFIDLogger, q as FFIDCacheAdapter, r as FFIDUser, s as FFIDOrganization, t as FFIDSubscription, u as FFIDSubscriptionContextValue, E as EffectiveSubscriptionStatus, v as FFIDOAuthUserInfoSubscription, w as FFIDAnnouncementsClientConfig, L as ListAnnouncementsOptions, x as FFIDAnnouncementsApiResponse, A as AnnouncementListResponse, y as FFIDAnnouncementsLogger } from './index-CG0vObax.js';
2
+ export { z as Announcement, B as AnnouncementStatus, C as AnnouncementType, D as EFFECTIVE_SUBSCRIPTION_STATUSES, G as FFIDAnnouncementBadge, H as FFIDAnnouncementList, I as FFIDAnnouncementsError, J as FFIDAnnouncementsErrorCode, K as FFIDAnnouncementsServerResponse, M as FFIDCacheConfig, N as FFIDContextValue, O as FFIDInquiryCategory, P as FFIDInquiryCategorySite2026, Q as FFIDInquiryForm, R as FFIDInquiryFormCategoryItem, S as FFIDInquiryFormClassNames, T as FFIDInquiryFormLegalLayout, U as FFIDInquiryFormOrganization, V as FFIDInquiryFormPlaceholderContext, W as FFIDInquiryFormPrefill, X as FFIDInquiryFormProps, Y as FFIDInquiryFormSubmitData, Z as FFIDInquiryFormSubmitResult, _ as FFIDJwtClaims, $ as FFIDLoginButton, a0 as FFIDOAuthTokenResponse, a1 as FFIDOAuthUserInfoMemberRole, a2 as FFIDOrganizationSwitcher, a3 as FFIDRedirectErrorCode, a4 as FFIDSeatModel, a5 as FFIDServiceAccessDenialReason, a6 as FFIDServiceAccessFailPolicy, a7 as FFIDSubscriptionBadge, a8 as FFIDTokenIntrospectionResponse, a9 as FFIDUserMenu, aa as FFID_INQUIRY_CATEGORIES, ab as FFID_INQUIRY_CATEGORIES_SITE_2026, ac as UseFFIDAnnouncementsOptions, ad as UseFFIDAnnouncementsReturn, ae as isFFIDInquiryCategorySite2026, af as useFFIDAnnouncements } from './index-CG0vObax.js';
3
+ export { A as ALL_DENIED_EXCEPT_NECESSARY, i as CONSENT_COOKIE_NAME, j as CONSENT_DISMISSAL_TIMESTAMP_KEY, l as COOKIE_VERSION, D as DEFAULT_CONSENT_ERROR_MESSAGES, o as FFIDAnalyticsProvider, p as FFIDAnalyticsProviderProps, c as FFIDConsentCategories, r as FFIDConsentCategoryCode, e as FFIDConsentCategoryMetadata, w as FFIDConsentError, x as FFIDConsentErrorCode, y as FFIDConsentMergeStrategy, B as FFIDConsentMergeWarning, E as FFIDConsentMergeWarningEvent, F as FFIDConsentResult, I as FFIDConsentSource, a as FFIDConsentState, d as FFIDConsentSyncResult, M as FFIDCookieBanner, N as FFIDCookieBannerClassNames, O as FFIDCookieBannerProps, Q as FFIDCookieLink, R as FFIDCookieLinkProps, f as FFIDCookiePolicy, T as FFIDCookieSettings, U as FFIDCookieSettingsClassNames, V as FFIDCookieSettingsProps, _ as FFID_CONSENT_ERROR_CODES, ae as UseFFIDConsentPreferencesReturn, af as UseFFIDConsentReturn, ag as clearConsentDismissalTimestamp, aj as decodeConsentCookie, al as encodeConsentCookie, an as readConsentCookie, ao as readConsentDismissalTimestamp, aq as useFFIDConsent, ar as useFFIDConsentPreferences, as as writeConsentCookie, at as writeConsentDismissalTimestamp } from './FFIDCookieLink-BJgVcJyw.js';
4
4
  import * as react_jsx_runtime from 'react/jsx-runtime';
5
5
  import { ReactNode, ComponentType, FC } from 'react';
6
6
  import 'zod';
@@ -1111,6 +1111,20 @@ interface RedirectToAuthorizeOptions {
1111
1111
  * regardless of `authMode`.
1112
1112
  */
1113
1113
  screenHint?: typeof SCREEN_HINT_SIGNUP | 'login';
1114
+ /**
1115
+ * OIDC `prompt` to forward to FFID `/oauth/authorize` (#4027).
1116
+ *
1117
+ * - `'select_account'`: forwards `prompt=select_account` so the upstream IdP
1118
+ * (Google) account chooser is shown — used by {@link switchAccount} to enable
1119
+ * RP-initiated account switching after logout (residual upstream sessions would
1120
+ * otherwise auto-re-authenticate the same account).
1121
+ * - `'login'`: forces re-authentication (FFID `/login` is shown even with an
1122
+ * active session).
1123
+ *
1124
+ * Token mode: added to the `/oauth/authorize` query. Cookie mode: forwarded as
1125
+ * `?prompt=…` on the `/login` URL (ignored for the signup screen).
1126
+ */
1127
+ prompt?: FFIDPrompt;
1114
1128
  }
1115
1129
 
1116
1130
  /** Creates an FFID API client instance */
@@ -1120,7 +1134,12 @@ declare function createFFIDClient(config: FFIDConfig): {
1120
1134
  redirectToLogin: (options?: RedirectToAuthorizeOptions) => Promise<FFIDRedirectResult>;
1121
1135
  redirectToAuthorize: (options?: RedirectToAuthorizeOptions) => Promise<FFIDRedirectResult>;
1122
1136
  redirectToLogout: (postLogoutRedirectUri?: string) => FFIDRedirectResult;
1123
- getLoginUrl: (redirectUrl?: string) => string;
1137
+ switchAccount: (options?: {
1138
+ organizationId?: string;
1139
+ }) => Promise<FFIDRedirectResult>;
1140
+ getLoginUrl: (redirectUrl?: string, options?: {
1141
+ prompt?: FFIDPrompt;
1142
+ }) => string;
1124
1143
  getLogoutUrl: (postLogoutRedirectUri?: string) => string;
1125
1144
  getSignupUrl: (redirectUrl?: string) => string;
1126
1145
  createError: (code: string, message: string) => FFIDError;
@@ -1375,12 +1394,36 @@ interface UseFFIDReturn {
1375
1394
  * (forwards `screen_hint=signup` in token mode / redirects to `/signup`
1376
1395
  * in cookie mode). `'login'` and `undefined` use the default login flow.
1377
1396
  * See `RedirectToAuthorizeOptions` (#2908 / #2911).
1397
+ * @param options.prompt OIDC `prompt` forwarded to FFID `/oauth/authorize`
1398
+ * (e.g. `'select_account'` to force the upstream account chooser). For account
1399
+ * switching, prefer the dedicated {@link UseFFIDReturn.switchAccount} helper (#4027).
1378
1400
  */
1379
1401
  login: (options?: {
1380
1402
  screenHint?: 'signup' | 'login';
1403
+ prompt?: FFIDPrompt;
1381
1404
  }) => void;
1382
- /** Sign out */
1405
+ /** Sign out (client-side: clears local session via the signout API) */
1383
1406
  logout: () => Promise<void>;
1407
+ /**
1408
+ * Get the FFID SSO logout URL (RP-initiated logout). Includes `client_id` for
1409
+ * `post_logout_redirect_uri` validation. Use for cross-origin browser navigation
1410
+ * that must clear the SSO session cookie (#4027).
1411
+ */
1412
+ getLogoutUrl: (postLogoutRedirectUri?: string) => string;
1413
+ /**
1414
+ * Redirect to the FFID SSO logout endpoint (clears the SSO session cookie via a
1415
+ * top-level browser navigation, so SameSite=Lax cookies are sent). #4027.
1416
+ */
1417
+ redirectToLogout: (postLogoutRedirectUri?: string) => FFIDRedirectResult;
1418
+ /**
1419
+ * Switch / add account: forces the upstream Google account chooser via
1420
+ * `prompt=select_account` so RP-initiated account switching is not silently
1421
+ * re-authenticated against the residual upstream session. Pair with
1422
+ * {@link UseFFIDReturn.redirectToLogout} if an explicit signed-out step is needed (#4027).
1423
+ */
1424
+ switchAccount: (options?: {
1425
+ organizationId?: string;
1426
+ }) => Promise<FFIDRedirectResult>;
1384
1427
  /**
1385
1428
  * Switch current organization.
1386
1429
  * Cookie mode: local state change. Token mode: OAuth re-authorization redirect.
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
- import { useFFIDContext, useSubscription } from './chunk-XT4BAOKZ.js';
2
- export { ACCESS_GRANTING_EFFECTIVE_STATUSES, BLOCKING_EFFECTIVE_STATUSES, DEFAULT_API_BASE_URL, DEFAULT_OAUTH_SCOPES, EFFECTIVE_SUBSCRIPTION_STATUSES, FFIDAnnouncementBadge, FFIDAnnouncementList, FFIDInquiryForm, FFIDLoginButton, FFIDOrganizationSwitcher, FFIDProvider, FFIDSDKError, FFIDSubscriptionBadge, FFIDUserMenu, FFID_ANNOUNCEMENTS_ERROR_CODES, FFID_INQUIRY_CATEGORIES, FFID_INQUIRY_CATEGORIES_SITE_2026, cleanupStateStorage as clearState, computeEffectiveStatusFromSession, createFFIDAnnouncementsClient, createFFIDClient, createTokenStore, generateCodeChallenge, generateCodeVerifier, handleRedirectCallback, hasAccessFromUserinfo, isBlockedFromUserinfo, isFFIDInquiryCategorySite2026, normalizeRedirectUri, retrieveCodeVerifier, retrieveState, storeCodeVerifier, storeState, useFFID, useFFIDAnnouncements, useSubscription, withSubscription } from './chunk-XT4BAOKZ.js';
3
- export { ALL_DENIED_EXCEPT_NECESSARY, CONSENT_COOKIE_NAME, CONSENT_DISMISSAL_TIMESTAMP_KEY, COOKIE_VERSION, DEFAULT_CONSENT_ERROR_MESSAGES, FFIDAnalyticsProvider, FFIDConsentError, FFIDCookieBanner, FFIDCookieLink, FFIDCookieSettings, FFID_CONSENT_ERROR_CODES, clearConsentDismissalTimestamp, decodeConsentCookie, encodeConsentCookie, readConsentCookie, readConsentDismissalTimestamp, useFFIDConsent, useFFIDConsentPreferences, writeConsentCookie, writeConsentDismissalTimestamp } from './chunk-HAR75DTJ.js';
1
+ import { useFFIDContext, useSubscription } from './chunk-HLCHSKAF.js';
2
+ export { ACCESS_GRANTING_EFFECTIVE_STATUSES, BLOCKING_EFFECTIVE_STATUSES, DEFAULT_API_BASE_URL, DEFAULT_OAUTH_SCOPES, EFFECTIVE_SUBSCRIPTION_STATUSES, FFIDAnnouncementBadge, FFIDAnnouncementList, FFIDInquiryForm, FFIDLoginButton, FFIDOrganizationSwitcher, FFIDProvider, FFIDSDKError, FFIDSubscriptionBadge, FFIDUserMenu, FFID_ANNOUNCEMENTS_ERROR_CODES, FFID_INQUIRY_CATEGORIES, FFID_INQUIRY_CATEGORIES_SITE_2026, cleanupStateStorage as clearState, computeEffectiveStatusFromSession, createFFIDAnnouncementsClient, createFFIDClient, createTokenStore, generateCodeChallenge, generateCodeVerifier, handleRedirectCallback, hasAccessFromUserinfo, isBlockedFromUserinfo, isFFIDInquiryCategorySite2026, normalizeRedirectUri, retrieveCodeVerifier, retrieveState, storeCodeVerifier, storeState, useFFID, useFFIDAnnouncements, useSubscription, withSubscription } from './chunk-HLCHSKAF.js';
3
+ export { ALL_DENIED_EXCEPT_NECESSARY, CONSENT_COOKIE_NAME, CONSENT_DISMISSAL_TIMESTAMP_KEY, COOKIE_VERSION, DEFAULT_CONSENT_ERROR_MESSAGES, FFIDAnalyticsProvider, FFIDConsentError, FFIDCookieBanner, FFIDCookieLink, FFIDCookieSettings, FFID_CONSENT_ERROR_CODES, clearConsentDismissalTimestamp, decodeConsentCookie, encodeConsentCookie, readConsentCookie, readConsentDismissalTimestamp, useFFIDConsent, useFFIDConsentPreferences, writeConsentCookie, writeConsentDismissalTimestamp } from './chunk-G7VOX64X.js';
4
4
  import { useEffect, useRef } from 'react';
5
5
  import { jsx, Fragment } from 'react/jsx-runtime';
6
6
 
@@ -1090,7 +1090,7 @@ function createNonContractMethods(deps) {
1090
1090
  }
1091
1091
 
1092
1092
  // src/client/version-check.ts
1093
- var SDK_VERSION = "5.16.1";
1093
+ var SDK_VERSION = "5.17.0";
1094
1094
  var SDK_USER_AGENT = `FFID-SDK/${SDK_VERSION} (TypeScript)`;
1095
1095
  var SDK_VERSION_HEADER = "X-FFID-SDK-Version";
1096
1096
  function sdkHeaders() {
@@ -1841,6 +1841,9 @@ function createRedirectMethods(deps) {
1841
1841
  if (options?.screenHint === SCREEN_HINT_SIGNUP) {
1842
1842
  params.set(SCREEN_HINT_PARAM, SCREEN_HINT_SIGNUP);
1843
1843
  }
1844
+ if (options?.prompt) {
1845
+ params.set("prompt", options.prompt);
1846
+ }
1844
1847
  const authorizeUrl = `${baseUrl}${OAUTH_AUTHORIZE_ENDPOINT}?${params.toString()}`;
1845
1848
  logger.debug("Redirecting to authorize:", authorizeUrl);
1846
1849
  recordRedirectAttempt(authorizeKey, now, logger);
@@ -1860,12 +1863,12 @@ function createRedirectMethods(deps) {
1860
1863
  if (authMode === "token") {
1861
1864
  return redirectToAuthorize(options);
1862
1865
  }
1863
- const targetUrl = options?.screenHint === SCREEN_HINT_SIGNUP ? getSignupUrl() : getLoginUrl();
1866
+ const targetUrl = options?.screenHint === SCREEN_HINT_SIGNUP ? getSignupUrl() : getLoginUrl(void 0, options?.prompt ? { prompt: options.prompt } : void 0);
1864
1867
  logger.debug("Redirecting to auth page:", targetUrl);
1865
1868
  window.location.href = targetUrl;
1866
1869
  return { success: true };
1867
1870
  }
1868
- function getLoginUrl(redirectUrl) {
1871
+ function getLoginUrl(redirectUrl, options) {
1869
1872
  let redirect;
1870
1873
  if (redirectUrl != null) {
1871
1874
  redirect = redirectUrl;
@@ -1875,7 +1878,8 @@ function createRedirectMethods(deps) {
1875
1878
  logger.warn("getLoginUrl: SSR \u74B0\u5883\u3067 redirectUrl \u304C\u672A\u6307\u5B9A\u306E\u305F\u3081\u7A7A\u6587\u5B57\u306B\u30D5\u30A9\u30FC\u30EB\u30D0\u30C3\u30AF\u3057\u307E\u3059");
1876
1879
  redirect = "";
1877
1880
  }
1878
- return `${baseUrl}/login?redirect=${encodeURIComponent(redirect)}&service=${encodeURIComponent(serviceCode)}`;
1881
+ const promptSuffix = options?.prompt ? `&prompt=${encodeURIComponent(options.prompt)}` : "";
1882
+ return `${baseUrl}/login?redirect=${encodeURIComponent(redirect)}&service=${encodeURIComponent(serviceCode)}${promptSuffix}`;
1879
1883
  }
1880
1884
  function getSignupUrl(redirectUrl) {
1881
1885
  let redirect;
@@ -1907,7 +1911,10 @@ function createRedirectMethods(deps) {
1907
1911
  window.location.href = logoutUrl;
1908
1912
  return { success: true };
1909
1913
  }
1910
- return { redirectToLogin, redirectToAuthorize, getLoginUrl, getSignupUrl, getLogoutUrl, redirectToLogout };
1914
+ async function switchAccount(options) {
1915
+ return redirectToLogin({ ...options, prompt: "select_account" });
1916
+ }
1917
+ return { redirectToLogin, redirectToAuthorize, getLoginUrl, getSignupUrl, getLogoutUrl, redirectToLogout, switchAccount };
1911
1918
  }
1912
1919
 
1913
1920
  // src/client/redirect-uri.ts
@@ -2806,7 +2813,7 @@ function createFFIDClient(config) {
2806
2813
  }
2807
2814
  return signOutCookie();
2808
2815
  }
2809
- const { redirectToLogin, redirectToAuthorize, getLoginUrl, getSignupUrl, getLogoutUrl, redirectToLogout } = createRedirectMethods({
2816
+ const { redirectToLogin, redirectToAuthorize, getLoginUrl, getSignupUrl, getLogoutUrl, redirectToLogout, switchAccount } = createRedirectMethods({
2810
2817
  authMode,
2811
2818
  baseUrl,
2812
2819
  clientId,
@@ -3000,6 +3007,7 @@ function createFFIDClient(config) {
3000
3007
  redirectToLogin,
3001
3008
  redirectToAuthorize,
3002
3009
  redirectToLogout,
3010
+ switchAccount,
3003
3011
  getLoginUrl,
3004
3012
  getLogoutUrl,
3005
3013
  getSignupUrl,
@@ -1,5 +1,5 @@
1
- import { F as FFIDLogger, a as FFIDError, b as FFIDCacheAdapter, c as FFIDVerifyAccessTokenOptions, d as FFIDApiResponse, e as FFIDOAuthUserInfo } from '../ffid-client-CKFxY60u.cjs';
2
- export { f as FFIDAddMemberParams, g as FFIDAddMemberRequest, h as FFIDAddMemberResponse, i as FFIDAssignableMemberRole, j as FFIDCacheConfig, k as FFIDClient, l as FFIDConfig, m as FFIDListMembersResponse, n as FFIDMemberRole, o as FFIDOrganization, p as FFIDOrganizationMember, q as FFIDOtpSendResponse, r as FFIDOtpVerifyResponse, s as FFIDPasswordResetConfirmResponse, t as FFIDPasswordResetResponse, u as FFIDPasswordResetVerifyResponse, v as FFIDProfileCallOptions, w as FFIDRemoveMemberResponse, x as FFIDResetSessionResponse, y as FFIDSubscription, z as FFIDUpdateMemberRoleResponse, A as FFIDUpdateUserProfileRequest, B as FFIDUser, C as FFIDUserProfile, T as TokenData, D as TokenStore, E as createFFIDClient, G as createTokenStore } from '../ffid-client-CKFxY60u.cjs';
1
+ import { F as FFIDLogger, a as FFIDError, b as FFIDCacheAdapter, c as FFIDVerifyAccessTokenOptions, d as FFIDApiResponse, e as FFIDOAuthUserInfo } from '../ffid-client-DZEK3tkP.cjs';
2
+ export { f as FFIDAddMemberParams, g as FFIDAddMemberRequest, h as FFIDAddMemberResponse, i as FFIDAssignableMemberRole, j as FFIDCacheConfig, k as FFIDClient, l as FFIDConfig, m as FFIDListMembersResponse, n as FFIDMemberRole, o as FFIDOrganization, p as FFIDOrganizationMember, q as FFIDOtpSendResponse, r as FFIDOtpVerifyResponse, s as FFIDPasswordResetConfirmResponse, t as FFIDPasswordResetResponse, u as FFIDPasswordResetVerifyResponse, v as FFIDProfileCallOptions, w as FFIDRemoveMemberResponse, x as FFIDResetSessionResponse, y as FFIDSubscription, z as FFIDUpdateMemberRoleResponse, A as FFIDUpdateUserProfileRequest, B as FFIDUser, C as FFIDUserProfile, T as TokenData, D as TokenStore, E as createFFIDClient, G as createTokenStore } from '../ffid-client-DZEK3tkP.cjs';
3
3
  export { D as DEFAULT_API_BASE_URL, a as DEFAULT_OAUTH_SCOPES } from '../constants-D61jqRIO.cjs';
4
4
  import { z } from 'zod';
5
5
  import '../types-BeVl-z12.cjs';
@@ -1,5 +1,5 @@
1
- import { F as FFIDLogger, a as FFIDError, b as FFIDCacheAdapter, c as FFIDVerifyAccessTokenOptions, d as FFIDApiResponse, e as FFIDOAuthUserInfo } from '../ffid-client-9-lh0G_h.js';
2
- export { f as FFIDAddMemberParams, g as FFIDAddMemberRequest, h as FFIDAddMemberResponse, i as FFIDAssignableMemberRole, j as FFIDCacheConfig, k as FFIDClient, l as FFIDConfig, m as FFIDListMembersResponse, n as FFIDMemberRole, o as FFIDOrganization, p as FFIDOrganizationMember, q as FFIDOtpSendResponse, r as FFIDOtpVerifyResponse, s as FFIDPasswordResetConfirmResponse, t as FFIDPasswordResetResponse, u as FFIDPasswordResetVerifyResponse, v as FFIDProfileCallOptions, w as FFIDRemoveMemberResponse, x as FFIDResetSessionResponse, y as FFIDSubscription, z as FFIDUpdateMemberRoleResponse, A as FFIDUpdateUserProfileRequest, B as FFIDUser, C as FFIDUserProfile, T as TokenData, D as TokenStore, E as createFFIDClient, G as createTokenStore } from '../ffid-client-9-lh0G_h.js';
1
+ import { F as FFIDLogger, a as FFIDError, b as FFIDCacheAdapter, c as FFIDVerifyAccessTokenOptions, d as FFIDApiResponse, e as FFIDOAuthUserInfo } from '../ffid-client-BtS84epg.js';
2
+ export { f as FFIDAddMemberParams, g as FFIDAddMemberRequest, h as FFIDAddMemberResponse, i as FFIDAssignableMemberRole, j as FFIDCacheConfig, k as FFIDClient, l as FFIDConfig, m as FFIDListMembersResponse, n as FFIDMemberRole, o as FFIDOrganization, p as FFIDOrganizationMember, q as FFIDOtpSendResponse, r as FFIDOtpVerifyResponse, s as FFIDPasswordResetConfirmResponse, t as FFIDPasswordResetResponse, u as FFIDPasswordResetVerifyResponse, v as FFIDProfileCallOptions, w as FFIDRemoveMemberResponse, x as FFIDResetSessionResponse, y as FFIDSubscription, z as FFIDUpdateMemberRoleResponse, A as FFIDUpdateUserProfileRequest, B as FFIDUser, C as FFIDUserProfile, T as TokenData, D as TokenStore, E as createFFIDClient, G as createTokenStore } from '../ffid-client-BtS84epg.js';
3
3
  export { D as DEFAULT_API_BASE_URL, a as DEFAULT_OAUTH_SCOPES } from '../constants-D61jqRIO.js';
4
4
  import { z } from 'zod';
5
5
  import '../types-BeVl-z12.js';
@@ -1089,7 +1089,7 @@ function createNonContractMethods(deps) {
1089
1089
  }
1090
1090
 
1091
1091
  // src/client/version-check.ts
1092
- var SDK_VERSION = "5.16.1";
1092
+ var SDK_VERSION = "5.17.0";
1093
1093
  var SDK_USER_AGENT = `FFID-SDK/${SDK_VERSION} (TypeScript)`;
1094
1094
  var SDK_VERSION_HEADER = "X-FFID-SDK-Version";
1095
1095
  function sdkHeaders() {
@@ -1840,6 +1840,9 @@ function createRedirectMethods(deps) {
1840
1840
  if (options?.screenHint === SCREEN_HINT_SIGNUP) {
1841
1841
  params.set(SCREEN_HINT_PARAM, SCREEN_HINT_SIGNUP);
1842
1842
  }
1843
+ if (options?.prompt) {
1844
+ params.set("prompt", options.prompt);
1845
+ }
1843
1846
  const authorizeUrl = `${baseUrl}${OAUTH_AUTHORIZE_ENDPOINT}?${params.toString()}`;
1844
1847
  logger.debug("Redirecting to authorize:", authorizeUrl);
1845
1848
  recordRedirectAttempt(authorizeKey, now, logger);
@@ -1859,12 +1862,12 @@ function createRedirectMethods(deps) {
1859
1862
  if (authMode === "token") {
1860
1863
  return redirectToAuthorize(options);
1861
1864
  }
1862
- const targetUrl = options?.screenHint === SCREEN_HINT_SIGNUP ? getSignupUrl() : getLoginUrl();
1865
+ const targetUrl = options?.screenHint === SCREEN_HINT_SIGNUP ? getSignupUrl() : getLoginUrl(void 0, options?.prompt ? { prompt: options.prompt } : void 0);
1863
1866
  logger.debug("Redirecting to auth page:", targetUrl);
1864
1867
  window.location.href = targetUrl;
1865
1868
  return { success: true };
1866
1869
  }
1867
- function getLoginUrl(redirectUrl) {
1870
+ function getLoginUrl(redirectUrl, options) {
1868
1871
  let redirect;
1869
1872
  if (redirectUrl != null) {
1870
1873
  redirect = redirectUrl;
@@ -1874,7 +1877,8 @@ function createRedirectMethods(deps) {
1874
1877
  logger.warn("getLoginUrl: SSR \u74B0\u5883\u3067 redirectUrl \u304C\u672A\u6307\u5B9A\u306E\u305F\u3081\u7A7A\u6587\u5B57\u306B\u30D5\u30A9\u30FC\u30EB\u30D0\u30C3\u30AF\u3057\u307E\u3059");
1875
1878
  redirect = "";
1876
1879
  }
1877
- return `${baseUrl}/login?redirect=${encodeURIComponent(redirect)}&service=${encodeURIComponent(serviceCode)}`;
1880
+ const promptSuffix = options?.prompt ? `&prompt=${encodeURIComponent(options.prompt)}` : "";
1881
+ return `${baseUrl}/login?redirect=${encodeURIComponent(redirect)}&service=${encodeURIComponent(serviceCode)}${promptSuffix}`;
1878
1882
  }
1879
1883
  function getSignupUrl(redirectUrl) {
1880
1884
  let redirect;
@@ -1906,7 +1910,10 @@ function createRedirectMethods(deps) {
1906
1910
  window.location.href = logoutUrl;
1907
1911
  return { success: true };
1908
1912
  }
1909
- return { redirectToLogin, redirectToAuthorize, getLoginUrl, getSignupUrl, getLogoutUrl, redirectToLogout };
1913
+ async function switchAccount(options) {
1914
+ return redirectToLogin({ ...options, prompt: "select_account" });
1915
+ }
1916
+ return { redirectToLogin, redirectToAuthorize, getLoginUrl, getSignupUrl, getLogoutUrl, redirectToLogout, switchAccount };
1910
1917
  }
1911
1918
 
1912
1919
  // src/client/redirect-uri.ts
@@ -2805,7 +2812,7 @@ function createFFIDClient(config) {
2805
2812
  }
2806
2813
  return signOutCookie();
2807
2814
  }
2808
- const { redirectToLogin, redirectToAuthorize, getLoginUrl, getSignupUrl, getLogoutUrl, redirectToLogout } = createRedirectMethods({
2815
+ const { redirectToLogin, redirectToAuthorize, getLoginUrl, getSignupUrl, getLogoutUrl, redirectToLogout, switchAccount } = createRedirectMethods({
2809
2816
  authMode,
2810
2817
  baseUrl,
2811
2818
  clientId,
@@ -2999,6 +3006,7 @@ function createFFIDClient(config) {
2999
3006
  redirectToLogin,
3000
3007
  redirectToAuthorize,
3001
3008
  redirectToLogout,
3009
+ switchAccount,
3002
3010
  getLoginUrl,
3003
3011
  getLogoutUrl,
3004
3012
  getSignupUrl,
@@ -1,4 +1,4 @@
1
- import { k as FFIDClient, e as FFIDOAuthUserInfo } from '../../ffid-client-CKFxY60u.cjs';
1
+ import { k as FFIDClient, e as FFIDOAuthUserInfo } from '../../ffid-client-DZEK3tkP.cjs';
2
2
  import '../../types-BeVl-z12.cjs';
3
3
 
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { k as FFIDClient, e as FFIDOAuthUserInfo } from '../../ffid-client-9-lh0G_h.js';
1
+ import { k as FFIDClient, e as FFIDOAuthUserInfo } from '../../ffid-client-BtS84epg.js';
2
2
  import '../../types-BeVl-z12.js';
3
3
 
4
4
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@feelflow/ffid-sdk",
3
- "version": "5.16.1",
3
+ "version": "5.17.0",
4
4
  "description": "FeelFlow ID Platform SDK for React/Next.js applications",
5
5
  "keywords": [
6
6
  "feelflow",