@thunderid/react 1.10.1 → 1.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/components/account/UserProfile/BaseUserProfile.cjs +1 -1
- package/dist/cjs/components/auth/AcceptInvite/BaseAcceptInvite.cjs +1 -1
- package/dist/cjs/components/auth/DeviceGrant/BaseDeviceGrant.cjs +61 -0
- package/dist/cjs/components/auth/DeviceGrant/BaseDeviceGrant.cjs.map +1 -0
- package/dist/cjs/components/auth/DeviceGrant/BaseDeviceGrant.styles.cjs +26 -0
- package/dist/cjs/components/auth/DeviceGrant/BaseDeviceGrant.styles.cjs.map +1 -0
- package/dist/cjs/components/auth/DeviceGrant/DeviceGrant.cjs +192 -0
- package/dist/cjs/components/auth/DeviceGrant/DeviceGrant.cjs.map +1 -0
- package/dist/cjs/components/auth/InviteUser/BaseInviteUser.cjs +1 -1
- package/dist/cjs/components/auth/Recovery/BaseRecovery.cjs +2 -2
- package/dist/cjs/components/auth/SignIn/BaseSignIn.cjs +15 -4
- package/dist/cjs/components/auth/SignIn/BaseSignIn.cjs.map +1 -1
- package/dist/cjs/components/auth/SignUp/BaseSignUp.cjs +2 -2
- package/dist/cjs/components/auth/flow/AuthOptionFactory.cjs +17 -2
- package/dist/cjs/components/auth/flow/AuthOptionFactory.cjs.map +1 -1
- package/dist/cjs/components/auth/flow/Consent.cjs +1 -1
- package/dist/cjs/components/primitives/Alert/Alert.cjs +1 -1
- package/dist/cjs/components/primitives/Card/Card.cjs +1 -1
- package/dist/cjs/components/primitives/Typography/Typography.styles.cjs +3 -0
- package/dist/cjs/components/primitives/Typography/Typography.styles.cjs.map +1 -1
- package/dist/cjs/contexts/ThunderID/ThunderIDContext.cjs +1 -0
- package/dist/cjs/contexts/ThunderID/ThunderIDContext.cjs.map +1 -1
- package/dist/cjs/contexts/ThunderID/ThunderIDProvider.cjs +3 -0
- package/dist/cjs/contexts/ThunderID/ThunderIDProvider.cjs.map +1 -1
- package/dist/cjs/hooks/management/useGrantedPermissions.cjs +6 -5
- package/dist/cjs/hooks/management/useGrantedPermissions.cjs.map +1 -1
- package/dist/cjs/index.cjs +6 -2
- package/dist/components/account/UserProfile/BaseUserProfile.js +1 -1
- package/dist/components/auth/AcceptInvite/BaseAcceptInvite.js +1 -1
- package/dist/components/auth/DeviceGrant/BaseDeviceGrant.d.ts +17 -0
- package/dist/components/auth/DeviceGrant/BaseDeviceGrant.d.ts.map +1 -0
- package/dist/components/auth/DeviceGrant/BaseDeviceGrant.js +58 -0
- package/dist/components/auth/DeviceGrant/BaseDeviceGrant.js.map +1 -0
- package/dist/components/auth/DeviceGrant/BaseDeviceGrant.styles.d.ts +4 -0
- package/dist/components/auth/DeviceGrant/BaseDeviceGrant.styles.d.ts.map +1 -0
- package/dist/components/auth/DeviceGrant/BaseDeviceGrant.styles.js +24 -0
- package/dist/components/auth/DeviceGrant/BaseDeviceGrant.styles.js.map +1 -0
- package/dist/components/auth/DeviceGrant/DeviceGrant.d.ts +37 -0
- package/dist/components/auth/DeviceGrant/DeviceGrant.d.ts.map +1 -0
- package/dist/components/auth/DeviceGrant/DeviceGrant.js +188 -0
- package/dist/components/auth/DeviceGrant/DeviceGrant.js.map +1 -0
- package/dist/components/auth/InviteUser/BaseInviteUser.js +1 -1
- package/dist/components/auth/Recovery/BaseRecovery.js +2 -2
- package/dist/components/auth/SignIn/BaseSignIn.d.ts +4 -0
- package/dist/components/auth/SignIn/BaseSignIn.d.ts.map +1 -1
- package/dist/components/auth/SignIn/BaseSignIn.js +16 -5
- package/dist/components/auth/SignIn/BaseSignIn.js.map +1 -1
- package/dist/components/auth/SignUp/BaseSignUp.js +2 -2
- package/dist/components/auth/flow/AuthOptionFactory.d.ts.map +1 -1
- package/dist/components/auth/flow/AuthOptionFactory.js +17 -2
- package/dist/components/auth/flow/AuthOptionFactory.js.map +1 -1
- package/dist/components/auth/flow/Consent.js +1 -1
- package/dist/components/primitives/Alert/Alert.js +1 -1
- package/dist/components/primitives/Card/Card.js +1 -1
- package/dist/components/primitives/Typography/Typography.styles.d.ts.map +1 -1
- package/dist/components/primitives/Typography/Typography.styles.js +3 -0
- package/dist/components/primitives/Typography/Typography.styles.js.map +1 -1
- package/dist/contexts/ThunderID/ThunderIDContext.d.ts +6 -0
- package/dist/contexts/ThunderID/ThunderIDContext.d.ts.map +1 -1
- package/dist/contexts/ThunderID/ThunderIDContext.js +1 -0
- package/dist/contexts/ThunderID/ThunderIDContext.js.map +1 -1
- package/dist/contexts/ThunderID/ThunderIDProvider.d.ts.map +1 -1
- package/dist/contexts/ThunderID/ThunderIDProvider.js +3 -0
- package/dist/contexts/ThunderID/ThunderIDProvider.js.map +1 -1
- package/dist/hooks/management/useGrantedPermissions.d.ts +2 -1
- package/dist/hooks/management/useGrantedPermissions.d.ts.map +1 -1
- package/dist/hooks/management/useGrantedPermissions.js +7 -6
- package/dist/hooks/management/useGrantedPermissions.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -3
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ThunderIDProvider.cjs","names":["logger: ReturnType<typeof createPackageComponentLogger>","ThunderIDProvider: FC<PropsWithChildren<ThunderIDProviderProps>>","reRenderCheckRef: RefObject<boolean>","client: ThunderIDReactClient","ThunderIDReactClient","invalidator: ResourceInvalidator","storageManagerRef: any","useBrowserUrl","pendingSessionUpdateRef: RefObject<Promise<void> | null>","resolvedBaseUrl: string","decodedToken: IdToken","shouldFetchProfile: boolean","claims: User","currentSignInStatus: boolean","getUsersMe","getUsersMeMeta","arg1: any","isV2FlowRequest: boolean","ThunderIDRuntimeError","currentUrl: URL","urlParams: URLSearchParams","code: string | null","executionIdFromUrl: string | null","storedExecutionId: string | null","SPAUtils","interval: NodeJS.Timeout","status: boolean","getDecodedIdToken: () => Promise<IdToken>","getIdToken: () => Promise<string>","getAccessToken: () => Promise<string>","getStorageManager: ThunderIDContextProps['getStorageManager']","storageManager: Awaited<ReturnType<ThunderIDContextProps['getStorageManager']>>","request: (...args: any[]) => Promise<any>","requestAll: (...args: any[]) => Promise<any>","exchangeToken: (exchangeConfig: any) => Promise<any>","signOut: (...args: any[]) => Promise<any>","recover: ThunderIDContextProps['recover']","signUp: (...args: any[]) => Promise<any>","clearSession: (...args: any[]) => Promise<any>","reInitialize: (reInitConfig: any) => Promise<any>","result: any","reinitializedConfig: ThunderIDReactConfig","value: any","ThunderIDContext","I18nProvider","FlowMetaProvider","ThemeProvider","FlowProvider","UserProvider","ComponentRendererProvider"],"sources":["../../../../src/contexts/ThunderID/ThunderIDProvider.tsx"],"sourcesContent":["// Copyright 2025-2026 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\nimport {\n ResourceInvalidator,\n createResourceInvalidator,\n ThunderIDRuntimeError,\n generateFlattenedUserProfile,\n OIDCDiscoveryApiResponse,\n SignInOptions,\n User,\n UserProfile,\n IdToken,\n extractUserClaimsFromIdToken,\n EmbeddedSignInFlowResponse,\n EmbeddedRecoveryFlowRequest,\n EmbeddedRecoveryFlowResponse,\n createPackageComponentLogger,\n getVendorPrefix,\n resolveResourceEndpoint,\n AttributeSchema,\n SPAUtils,\n} from '@thunderid/browser';\nimport {FC, RefObject, PropsWithChildren, ReactElement, useEffect, useMemo, useRef, useState, useCallback} from 'react';\nimport ThunderIDContext, {ThunderIDContextProps} from './ThunderIDContext';\nimport getUsersMe from '../../api/account/getUsersMe';\nimport getUsersMeMeta from '../../api/account/getUsersMeMeta';\nimport useBrowserUrl from '../../hooks/useBrowserUrl';\nimport {ThunderIDReactConfig} from '../../models/config';\nimport {configureEmotionNonce} from '../../styles/emotion';\nimport ThunderIDReactClient from '../../ThunderIDReactClient';\nimport ComponentRendererProvider from '../ComponentRenderer/ComponentRendererProvider';\nimport FlowProvider from '../Flow/FlowProvider';\nimport FlowMetaProvider from '../FlowMeta/FlowMetaProvider';\nimport I18nProvider from '../I18n/I18nProvider';\nimport ThemeProvider from '../Theme/ThemeProvider';\nimport UserProvider from '../User/UserProvider';\n\nconst logger: ReturnType<typeof createPackageComponentLogger> = createPackageComponentLogger(\n '@thunderid/react',\n 'ThunderIDProvider',\n);\n\n/**\n * Props interface of {@link ThunderIDProvider}\n */\nexport type ThunderIDProviderProps = ThunderIDReactConfig;\n\nconst ThunderIDProvider: FC<PropsWithChildren<ThunderIDProviderProps>> = ({\n afterSignInUrl,\n afterSignOutUrl,\n baseUrl: initialBaseUrl,\n clientId,\n children,\n extensions,\n scopes,\n preferences,\n signInUrl,\n signUpUrl,\n organizationHandle,\n applicationId,\n signInOptions,\n tokenRequest,\n instanceId = 0,\n organizationChain,\n cspNonce,\n vendor,\n namespace,\n http: httpOptions,\n ...rest\n}: PropsWithChildren<ThunderIDProviderProps>): ReactElement => {\n // Must run synchronously here, in the render body, before any descendant's css()/cx()/\n // keyframes() calls execute during this same render pass - see the doc comment on\n // `configureEmotionNonce` for why a `useEffect` would be too late.\n configureEmotionNonce(cspNonce, vendor);\n\n const reRenderCheckRef: RefObject<boolean> = useRef(false);\n const client: ThunderIDReactClient = useMemo(() => new ThunderIDReactClient(instanceId), [instanceId]);\n const invalidator: ResourceInvalidator = useMemo(() => createResourceInvalidator(), []);\n const storageManagerRef: any = useRef<any>(null);\n const {hasAuthParams, hasCalledForThisInstance} = useBrowserUrl();\n const [user, setUser] = useState<User | null>(null);\n const [isSignedInSync, setIsSignedInSync] = useState<boolean>(false);\n const [isInitializedSync, setIsInitializedSync] = useState<boolean>(false);\n const [isLoadingSync, setIsLoadingSync] = useState<boolean>(true);\n\n const [userProfile, setUserProfile] = useState<UserProfile | null>(null);\n const [userSchema, setUserSchema] = useState<Record<string, AttributeSchema> | null>(null);\n const [baseUrl, setBaseUrl] = useState<string>(initialBaseUrl ?? '');\n const [config, setConfig] = useState<ThunderIDReactConfig>({\n afterSignInUrl: afterSignInUrl ?? window.location.origin,\n afterSignOutUrl: afterSignOutUrl ?? window.location.origin,\n applicationId,\n baseUrl,\n clientId,\n organizationChain,\n organizationHandle,\n scopes,\n signInOptions,\n tokenRequest,\n signInUrl,\n signUpUrl,\n vendor,\n ...rest,\n });\n\n const [isUpdatingSession, setIsUpdatingSession] = useState<boolean>(false);\n const [wellKnown, setWellKnown] = useState<OIDCDiscoveryApiResponse | null>(null);\n\n // Holds the in-flight `updateSession()` promise so concurrent callers coalesce onto a single\n // `/users/me` request instead of issuing one each.\n const pendingSessionUpdateRef: RefObject<Promise<void> | null> = useRef<Promise<void> | null>(null);\n\n useEffect(() => {\n setBaseUrl(initialBaseUrl ?? '');\n }, [initialBaseUrl]);\n\n useEffect(() => {\n (async (): Promise<void> => {\n await client.initialize(config);\n const initializedConfig: ThunderIDReactConfig = await client.getConfiguration();\n setConfig(initializedConfig);\n setWellKnown(await client.getDiscoveryResponse());\n })();\n }, []);\n\n async function performSessionUpdate(): Promise<void> {\n try {\n // Set flag to prevent loading state tracking from interfering\n setIsUpdatingSession(true);\n setIsLoadingSync(true);\n let resolvedBaseUrl: string = baseUrl;\n\n const decodedToken: IdToken = await client.getDecodedIdToken();\n\n // If there's a `user_org` claim in the ID token,\n // Treat this login as a organization login.\n if (decodedToken?.['user_org']) {\n resolvedBaseUrl = `${(await client.getConfiguration()).baseUrl}/o`;\n setBaseUrl(resolvedBaseUrl);\n }\n\n const shouldFetchProfile: boolean = preferences?.user?.fetchUserProfile !== false;\n const claims: User = extractUserClaimsFromIdToken(decodedToken) as User;\n let profileData = claims;\n const currentSignInStatus: boolean = await client.isSignedIn();\n\n if (currentSignInStatus && shouldFetchProfile) {\n try {\n const fetchedProfile = await getUsersMe({\n baseUrl: resolvedBaseUrl,\n url: resolveResourceEndpoint('usersMe', config),\n instanceId,\n });\n profileData = {...claims, ...fetchedProfile};\n } catch (err) {\n logger.warn('Failed to fetch user profile from /users/me:', err);\n }\n\n try {\n const metaRes = await getUsersMeMeta({\n baseUrl: resolvedBaseUrl,\n url: resolveResourceEndpoint('usersMeMeta', config),\n instanceId,\n });\n if (metaRes?.schema) {\n setUserSchema(metaRes.schema);\n } else {\n setUserSchema(null);\n }\n } catch (err) {\n setUserSchema(null);\n logger.warn('Failed to fetch user schema metadata from /users/me/meta:', err);\n }\n } else {\n setUserSchema(null);\n }\n\n setUser(profileData);\n setUserProfile({\n flattenedProfile: generateFlattenedUserProfile(profileData, []),\n profile: profileData,\n });\n\n // CRITICAL: Update sign-in status BEFORE setting loading to false\n // This prevents the race condition where ProtectedRoute sees isLoading=false but isSignedIn=false\n setIsSignedInSync(currentSignInStatus);\n } catch (error) {\n // TODO: Add an error log.\n } finally {\n // Clear the flag and set final loading state\n setIsUpdatingSession(false);\n setIsLoadingSync(client.isLoading());\n }\n }\n\n /**\n * Single-flight wrapper around {@link performSessionUpdate}.\n *\n * Concurrent callers share the in-flight request instead of each issuing their own `/users/me`.\n * This is not a cache: once the request settles the ref is cleared, so a later caller (e.g.\n * revalidation after a profile update) fetches again.\n */\n async function updateSession(): Promise<void> {\n if (pendingSessionUpdateRef.current) {\n return pendingSessionUpdateRef.current;\n }\n\n pendingSessionUpdateRef.current = performSessionUpdate().finally(() => {\n pendingSessionUpdateRef.current = null;\n });\n\n return pendingSessionUpdateRef.current;\n }\n\n async function signIn(...args: any): Promise<User | EmbeddedSignInFlowResponse> {\n // Check if this is a V2 embedded flow request BEFORE calling signIn\n // This allows us to skip session checks entirely for V2 flows\n const arg1: any = args[0];\n const isV2FlowRequest: boolean =\n typeof arg1 === 'object' && arg1 !== null && ('executionId' in arg1 || 'applicationId' in arg1);\n\n try {\n if (!isV2FlowRequest) {\n setIsUpdatingSession(true);\n setIsLoadingSync(true);\n }\n\n return await client.signIn(...args);\n } catch (error) {\n throw new ThunderIDRuntimeError(\n `Sign in failed: ${error instanceof Error ? error.message : String(JSON.stringify(error))}`,\n 'thunderid-signIn-Error',\n 'react',\n 'An error occurred while trying to sign in.',\n );\n } finally {\n if (!isV2FlowRequest) {\n setIsUpdatingSession(false);\n setIsLoadingSync(client.isLoading());\n }\n }\n }\n\n /**\n * Try signing in when the component is mounted.\n */\n useEffect(() => {\n // React 18.x Strict.Mode has a new check for `Ensuring reusable state` to facilitate an upcoming react feature.\n // https://reactjs.org/docs/strict-mode.html#ensuring-reusable-state\n // This will remount all the useEffects to ensure that there are no unexpected side effects.\n // When react remounts the signIn hook of the AuthProvider, it will cause a race condition. Hence, we have to\n // prevent the re-render of this hook as suggested in the following discussion.\n // https://github.com/reactwg/react-18/discussions/18#discussioncomment-795623\n if (reRenderCheckRef.current) {\n return;\n }\n\n reRenderCheckRef.current = true;\n\n (async (): Promise<void> => {\n // Sync session state whenever sign-in completes (both redirect and embedded V2 flows).\n // Pass the user returned by the SDK's sign-in flow so users/me result is not discarded.\n await client.on('sign-in', async () => {\n await updateSession();\n });\n\n // A session that ends elsewhere, such as a sign-out in another app, signs this app out too.\n await client.on('sign-out', () => {\n setUser(null);\n setUserProfile(null);\n setIsSignedInSync(false);\n });\n\n // Start auto-refresh with a soft failure. This also covers the case where the access token\n // expired while the refresh token is still valid — startAutoRefreshToken() calls\n // refreshAccessToken() immediately when timeUntilRefresh <= 0 — so the sign-in check below\n // sees the refreshed state.\n try {\n await client.startAutoRefreshToken();\n } catch (error) {\n logger.warn('Failed to schedule automatic token refresh.', error);\n }\n\n // User is already authenticated. Restore the session and skip the sign-in path.\n if (await client.isSignedIn()) {\n await updateSession();\n\n return;\n }\n\n const currentUrl: URL = new URL(window.location.href);\n const hasAuthParamsResult: boolean =\n hasAuthParams(currentUrl, config.afterSignInUrl!) && hasCalledForThisInstance(currentUrl, instanceId ?? 0);\n\n if (hasAuthParamsResult) {\n try {\n const urlParams: URLSearchParams = currentUrl.searchParams;\n const code: string | null = urlParams.get('code');\n const executionIdFromUrl: string | null = urlParams.get('executionId');\n const storedExecutionId: string | null = sessionStorage.getItem(\n `${getVendorPrefix(config.vendor)}_execution_id`,\n );\n\n // A silent sign-in response is handled even without a code: an error such as\n // login_required must still be relayed from the iframe to the waiting parent.\n if ((code || SPAUtils.isSilentStatePresentInURL()) && !executionIdFromUrl && !storedExecutionId) {\n await signIn();\n }\n } catch (error) {\n throw new ThunderIDRuntimeError(\n `Sign in failed: ${error instanceof Error ? error.message : String(JSON.stringify(error))}`,\n 'thunderid-signIn-Error',\n 'react',\n 'An error occurred while trying to sign in.',\n );\n }\n }\n })();\n }, []);\n\n /**\n * Check if the user is signed in and update the state accordingly.\n * This will also set an interval to check for the sign-in status every second\n * until the user is signed in.\n */\n useEffect(() => {\n let interval: NodeJS.Timeout;\n\n (async (): Promise<void> => {\n try {\n const status: boolean = await client.isSignedIn();\n\n setIsSignedInSync(status);\n\n if (!status) {\n interval = setInterval(async () => {\n const newStatus: boolean = await client.isSignedIn();\n\n if (newStatus) {\n setIsSignedInSync(true);\n clearInterval(interval);\n }\n }, 1000);\n } else {\n // TODO: Add a debug log to indicate that the user is already signed in.\n }\n } catch (error) {\n setIsSignedInSync(false);\n }\n })();\n\n return (): void => {\n if (interval) {\n clearInterval(interval);\n }\n };\n }, [client]);\n\n useEffect(() => {\n (async (): Promise<void> => {\n try {\n const status: boolean = await client.isInitialized();\n\n setIsInitializedSync(status);\n } catch (error) {\n setIsInitializedSync(false);\n }\n })();\n }, [client]);\n\n /**\n * Track loading state changes from the ThunderID client\n */\n useEffect(() => {\n const checkLoadingState = (): void => {\n // Don't override loading state during critical session updates\n if (isUpdatingSession) {\n return;\n }\n\n // Don't set loading=false while auth params are in the URL and user isn't signed in yet.\n // This prevents ProtectedRoute from redirecting before the sign-in effect processes the auth code.\n const currentUrl: URL = new URL(window.location.href);\n if (!isSignedInSync && hasAuthParams(currentUrl, config.afterSignInUrl!)) {\n return;\n }\n\n setIsLoadingSync(client.isLoading());\n };\n\n // Initial check\n checkLoadingState();\n\n // Set up an interval to check for loading state changes\n const interval: NodeJS.Timeout = setInterval(checkLoadingState, 100);\n\n return (): void => {\n clearInterval(interval);\n };\n }, [client, isLoadingSync, isSignedInSync, isUpdatingSession]);\n\n const signInSilently = async (options?: SignInOptions): Promise<User | boolean> => {\n try {\n setIsUpdatingSession(true);\n setIsLoadingSync(true);\n return await client.signInSilently(options);\n } catch (error) {\n throw new ThunderIDRuntimeError(\n `Error while signing in silently: ${error instanceof Error ? error.message : String(JSON.stringify(error))}`,\n 'thunderid-signInSilently-Error',\n 'react',\n 'An error occurred while trying to sign in silently.',\n );\n } finally {\n setIsUpdatingSession(false);\n setIsLoadingSync(client.isLoading());\n }\n };\n\n const handleProfileUpdate = (payload: User): void => {\n setUser(payload);\n setUserProfile((prev: UserProfile | null) => ({\n flattenedProfile: generateFlattenedUserProfile(payload),\n profile: payload,\n }));\n };\n\n const getDecodedIdToken: () => Promise<IdToken> = useCallback(\n async (): Promise<IdToken> => client.getDecodedIdToken(),\n [client],\n );\n\n const getIdToken: () => Promise<string> = useCallback(async (): Promise<string> => client.getIdToken(), [client]);\n\n const getAccessToken: () => Promise<string> = useCallback(\n async (): Promise<string> => client.getAccessToken(),\n [client],\n );\n\n const getStorageManager: ThunderIDContextProps['getStorageManager'] = useCallback(async () => {\n const storageManager: Awaited<ReturnType<ThunderIDContextProps['getStorageManager']>> =\n storageManagerRef.current ?? (await client.getStorageManager());\n if (storageManager) {\n storageManagerRef.current = storageManager;\n }\n return storageManager;\n }, [client]);\n\n const request: (...args: any[]) => Promise<any> = useCallback(\n async (...args: any[]): Promise<any> => client.request(...args),\n [client],\n );\n\n const requestAll: (...args: any[]) => Promise<any> = useCallback(\n async (...args: any[]): Promise<any> => client.requestAll(...args),\n [client],\n );\n\n const exchangeToken: (exchangeConfig: any) => Promise<any> = useCallback(\n async (exchangeConfig: any): Promise<any> => client.exchangeToken(exchangeConfig),\n [client],\n );\n\n const signOut: (...args: any[]) => Promise<any> = useCallback(\n async (...args: any[]): Promise<any> => client.signOut(...args),\n [client],\n );\n\n const recover: ThunderIDContextProps['recover'] = useCallback(\n async (payload?: EmbeddedRecoveryFlowRequest): Promise<EmbeddedRecoveryFlowResponse> =>\n (await client.recover(payload)) as EmbeddedRecoveryFlowResponse,\n [client],\n );\n\n const signUp: (...args: any[]) => Promise<any> = useCallback(\n async (...args: any[]): Promise<any> => client.signUp(...args),\n [client],\n );\n\n const clearSession: (...args: any[]) => Promise<any> = useCallback(\n async (...args: any[]): Promise<any> => client.clearSession(...args),\n [client],\n );\n\n const reInitialize: (reInitConfig: any) => Promise<any> = useCallback(\n async (reInitConfig: any): Promise<any> => {\n const result: any = await client.reInitialize(reInitConfig);\n\n // Refresh React state from the reinitialized client so the context (config.endpoints,\n // baseUrl, discovery) reflects the new configuration instead of the pre-reinitialization state.\n const reinitializedConfig: ThunderIDReactConfig = await client.getConfiguration();\n setConfig(reinitializedConfig);\n setBaseUrl(reinitializedConfig.baseUrl ?? '');\n setWellKnown(await client.getDiscoveryResponse());\n\n return result;\n },\n [client],\n );\n\n const value: any = useMemo(\n () => ({\n afterSignInUrl: config.afterSignInUrl,\n applicationId: config.applicationId,\n baseUrl,\n endpoints: config.endpoints,\n scopes: config.scopes,\n clearSession,\n clientId,\n discovery: {\n wellKnown,\n },\n exchangeToken,\n getAccessToken,\n getDecodedIdToken,\n getIdToken,\n getStorageManager,\n http: {\n fetcher: httpOptions?.fetcher,\n request,\n requestAll,\n },\n instanceId,\n invalidator,\n isInitialized: isInitializedSync,\n isLoading: isLoadingSync,\n isSignedIn: isSignedInSync,\n organizationChain,\n organizationHandle: config?.organizationHandle,\n preferences,\n reInitialize,\n recover,\n signIn,\n signInOptions,\n tokenRequest,\n signInSilently,\n signInUrl,\n signOut,\n signUp,\n signUpUrl,\n user,\n userSchema,\n vendor: getVendorPrefix(config.vendor),\n }),\n [\n applicationId,\n config?.organizationHandle,\n config.vendor,\n config.afterSignInUrl,\n config.endpoints,\n config.scopes,\n signInUrl,\n signUpUrl,\n baseUrl,\n clientId,\n wellKnown,\n isInitializedSync,\n isLoadingSync,\n isSignedInSync,\n signIn,\n signInSilently,\n user,\n userSchema,\n client,\n signInOptions,\n tokenRequest,\n getDecodedIdToken,\n clearSession,\n exchangeToken,\n httpOptions?.fetcher,\n getAccessToken,\n getStorageManager,\n instanceId,\n invalidator,\n organizationChain,\n preferences,\n recover,\n reInitialize,\n request,\n requestAll,\n signOut,\n signUp,\n ],\n );\n\n return (\n <ThunderIDContext.Provider value={value}>\n <I18nProvider preferences={preferences?.i18n} vendor={getVendorPrefix(config.vendor)}>\n <FlowMetaProvider enabled={preferences?.resolveFromMeta !== false} namespace={namespace}>\n <ThemeProvider\n theme={{\n ...preferences?.theme?.overrides,\n direction: preferences?.theme?.direction,\n }}\n >\n <FlowProvider>\n <UserProvider profile={userProfile!} userSchema={userSchema} onUpdateProfile={handleProfileUpdate}>\n <ComponentRendererProvider renderers={(extensions?.components?.renderers ?? {}) as any}>\n {children}\n </ComponentRendererProvider>\n </UserProvider>\n </FlowProvider>\n </ThemeProvider>\n </FlowMetaProvider>\n </I18nProvider>\n </ThunderIDContext.Provider>\n );\n};\n\nexport default ThunderIDProvider;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ThunderIDProvider.cjs","names":["logger: ReturnType<typeof createPackageComponentLogger>","ThunderIDProvider: FC<PropsWithChildren<ThunderIDProviderProps>>","reRenderCheckRef: RefObject<boolean>","client: ThunderIDReactClient","ThunderIDReactClient","invalidator: ResourceInvalidator","storageManagerRef: any","useBrowserUrl","pendingSessionUpdateRef: RefObject<Promise<void> | null>","resolvedBaseUrl: string","decodedToken: IdToken","shouldFetchProfile: boolean","claims: User","currentSignInStatus: boolean","getUsersMe","getUsersMeMeta","arg1: any","isV2FlowRequest: boolean","ThunderIDRuntimeError","currentUrl: URL","urlParams: URLSearchParams","code: string | null","executionIdFromUrl: string | null","storedExecutionId: string | null","SPAUtils","interval: NodeJS.Timeout","status: boolean","getDecodedIdToken: () => Promise<IdToken>","getIdToken: () => Promise<string>","getAccessToken: () => Promise<string>","getGrantedPermissions: () => Promise<string[]>","getStorageManager: ThunderIDContextProps['getStorageManager']","storageManager: Awaited<ReturnType<ThunderIDContextProps['getStorageManager']>>","request: (...args: any[]) => Promise<any>","requestAll: (...args: any[]) => Promise<any>","exchangeToken: (exchangeConfig: any) => Promise<any>","signOut: (...args: any[]) => Promise<any>","recover: ThunderIDContextProps['recover']","signUp: (...args: any[]) => Promise<any>","clearSession: (...args: any[]) => Promise<any>","reInitialize: (reInitConfig: any) => Promise<any>","result: any","reinitializedConfig: ThunderIDReactConfig","value: any","ThunderIDContext","I18nProvider","FlowMetaProvider","ThemeProvider","FlowProvider","UserProvider","ComponentRendererProvider"],"sources":["../../../../src/contexts/ThunderID/ThunderIDProvider.tsx"],"sourcesContent":["// Copyright 2025-2026 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\nimport {\n ResourceInvalidator,\n createResourceInvalidator,\n ThunderIDRuntimeError,\n generateFlattenedUserProfile,\n OIDCDiscoveryApiResponse,\n SignInOptions,\n User,\n UserProfile,\n IdToken,\n extractUserClaimsFromIdToken,\n EmbeddedSignInFlowResponse,\n EmbeddedRecoveryFlowRequest,\n EmbeddedRecoveryFlowResponse,\n createPackageComponentLogger,\n getVendorPrefix,\n resolveResourceEndpoint,\n AttributeSchema,\n SPAUtils,\n} from '@thunderid/browser';\nimport {FC, RefObject, PropsWithChildren, ReactElement, useEffect, useMemo, useRef, useState, useCallback} from 'react';\nimport ThunderIDContext, {ThunderIDContextProps} from './ThunderIDContext';\nimport getUsersMe from '../../api/account/getUsersMe';\nimport getUsersMeMeta from '../../api/account/getUsersMeMeta';\nimport useBrowserUrl from '../../hooks/useBrowserUrl';\nimport {ThunderIDReactConfig} from '../../models/config';\nimport {configureEmotionNonce} from '../../styles/emotion';\nimport ThunderIDReactClient from '../../ThunderIDReactClient';\nimport ComponentRendererProvider from '../ComponentRenderer/ComponentRendererProvider';\nimport FlowProvider from '../Flow/FlowProvider';\nimport FlowMetaProvider from '../FlowMeta/FlowMetaProvider';\nimport I18nProvider from '../I18n/I18nProvider';\nimport ThemeProvider from '../Theme/ThemeProvider';\nimport UserProvider from '../User/UserProvider';\n\nconst logger: ReturnType<typeof createPackageComponentLogger> = createPackageComponentLogger(\n '@thunderid/react',\n 'ThunderIDProvider',\n);\n\n/**\n * Props interface of {@link ThunderIDProvider}\n */\nexport type ThunderIDProviderProps = ThunderIDReactConfig;\n\nconst ThunderIDProvider: FC<PropsWithChildren<ThunderIDProviderProps>> = ({\n afterSignInUrl,\n afterSignOutUrl,\n baseUrl: initialBaseUrl,\n clientId,\n children,\n extensions,\n scopes,\n preferences,\n signInUrl,\n signUpUrl,\n organizationHandle,\n applicationId,\n signInOptions,\n tokenRequest,\n instanceId = 0,\n organizationChain,\n cspNonce,\n vendor,\n namespace,\n http: httpOptions,\n ...rest\n}: PropsWithChildren<ThunderIDProviderProps>): ReactElement => {\n // Must run synchronously here, in the render body, before any descendant's css()/cx()/\n // keyframes() calls execute during this same render pass - see the doc comment on\n // `configureEmotionNonce` for why a `useEffect` would be too late.\n configureEmotionNonce(cspNonce, vendor);\n\n const reRenderCheckRef: RefObject<boolean> = useRef(false);\n const client: ThunderIDReactClient = useMemo(() => new ThunderIDReactClient(instanceId), [instanceId]);\n const invalidator: ResourceInvalidator = useMemo(() => createResourceInvalidator(), []);\n const storageManagerRef: any = useRef<any>(null);\n const {hasAuthParams, hasCalledForThisInstance} = useBrowserUrl();\n const [user, setUser] = useState<User | null>(null);\n const [isSignedInSync, setIsSignedInSync] = useState<boolean>(false);\n const [isInitializedSync, setIsInitializedSync] = useState<boolean>(false);\n const [isLoadingSync, setIsLoadingSync] = useState<boolean>(true);\n\n const [userProfile, setUserProfile] = useState<UserProfile | null>(null);\n const [userSchema, setUserSchema] = useState<Record<string, AttributeSchema> | null>(null);\n const [baseUrl, setBaseUrl] = useState<string>(initialBaseUrl ?? '');\n const [config, setConfig] = useState<ThunderIDReactConfig>({\n afterSignInUrl: afterSignInUrl ?? window.location.origin,\n afterSignOutUrl: afterSignOutUrl ?? window.location.origin,\n applicationId,\n baseUrl,\n clientId,\n organizationChain,\n organizationHandle,\n scopes,\n signInOptions,\n tokenRequest,\n signInUrl,\n signUpUrl,\n vendor,\n ...rest,\n });\n\n const [isUpdatingSession, setIsUpdatingSession] = useState<boolean>(false);\n const [wellKnown, setWellKnown] = useState<OIDCDiscoveryApiResponse | null>(null);\n\n // Holds the in-flight `updateSession()` promise so concurrent callers coalesce onto a single\n // `/users/me` request instead of issuing one each.\n const pendingSessionUpdateRef: RefObject<Promise<void> | null> = useRef<Promise<void> | null>(null);\n\n useEffect(() => {\n setBaseUrl(initialBaseUrl ?? '');\n }, [initialBaseUrl]);\n\n useEffect(() => {\n (async (): Promise<void> => {\n await client.initialize(config);\n const initializedConfig: ThunderIDReactConfig = await client.getConfiguration();\n setConfig(initializedConfig);\n setWellKnown(await client.getDiscoveryResponse());\n })();\n }, []);\n\n async function performSessionUpdate(): Promise<void> {\n try {\n // Set flag to prevent loading state tracking from interfering\n setIsUpdatingSession(true);\n setIsLoadingSync(true);\n let resolvedBaseUrl: string = baseUrl;\n\n const decodedToken: IdToken = await client.getDecodedIdToken();\n\n // If there's a `user_org` claim in the ID token,\n // Treat this login as a organization login.\n if (decodedToken?.['user_org']) {\n resolvedBaseUrl = `${(await client.getConfiguration()).baseUrl}/o`;\n setBaseUrl(resolvedBaseUrl);\n }\n\n const shouldFetchProfile: boolean = preferences?.user?.fetchUserProfile !== false;\n const claims: User = extractUserClaimsFromIdToken(decodedToken) as User;\n let profileData = claims;\n const currentSignInStatus: boolean = await client.isSignedIn();\n\n if (currentSignInStatus && shouldFetchProfile) {\n try {\n const fetchedProfile = await getUsersMe({\n baseUrl: resolvedBaseUrl,\n url: resolveResourceEndpoint('usersMe', config),\n instanceId,\n });\n profileData = {...claims, ...fetchedProfile};\n } catch (err) {\n logger.warn('Failed to fetch user profile from /users/me:', err);\n }\n\n try {\n const metaRes = await getUsersMeMeta({\n baseUrl: resolvedBaseUrl,\n url: resolveResourceEndpoint('usersMeMeta', config),\n instanceId,\n });\n if (metaRes?.schema) {\n setUserSchema(metaRes.schema);\n } else {\n setUserSchema(null);\n }\n } catch (err) {\n setUserSchema(null);\n logger.warn('Failed to fetch user schema metadata from /users/me/meta:', err);\n }\n } else {\n setUserSchema(null);\n }\n\n setUser(profileData);\n setUserProfile({\n flattenedProfile: generateFlattenedUserProfile(profileData, []),\n profile: profileData,\n });\n\n // CRITICAL: Update sign-in status BEFORE setting loading to false\n // This prevents the race condition where ProtectedRoute sees isLoading=false but isSignedIn=false\n setIsSignedInSync(currentSignInStatus);\n } catch (error) {\n // TODO: Add an error log.\n } finally {\n // Clear the flag and set final loading state\n setIsUpdatingSession(false);\n setIsLoadingSync(client.isLoading());\n }\n }\n\n /**\n * Single-flight wrapper around {@link performSessionUpdate}.\n *\n * Concurrent callers share the in-flight request instead of each issuing their own `/users/me`.\n * This is not a cache: once the request settles the ref is cleared, so a later caller (e.g.\n * revalidation after a profile update) fetches again.\n */\n async function updateSession(): Promise<void> {\n if (pendingSessionUpdateRef.current) {\n return pendingSessionUpdateRef.current;\n }\n\n pendingSessionUpdateRef.current = performSessionUpdate().finally(() => {\n pendingSessionUpdateRef.current = null;\n });\n\n return pendingSessionUpdateRef.current;\n }\n\n async function signIn(...args: any): Promise<User | EmbeddedSignInFlowResponse> {\n // Check if this is a V2 embedded flow request BEFORE calling signIn\n // This allows us to skip session checks entirely for V2 flows\n const arg1: any = args[0];\n const isV2FlowRequest: boolean =\n typeof arg1 === 'object' && arg1 !== null && ('executionId' in arg1 || 'applicationId' in arg1);\n\n try {\n if (!isV2FlowRequest) {\n setIsUpdatingSession(true);\n setIsLoadingSync(true);\n }\n\n return await client.signIn(...args);\n } catch (error) {\n throw new ThunderIDRuntimeError(\n `Sign in failed: ${error instanceof Error ? error.message : String(JSON.stringify(error))}`,\n 'thunderid-signIn-Error',\n 'react',\n 'An error occurred while trying to sign in.',\n );\n } finally {\n if (!isV2FlowRequest) {\n setIsUpdatingSession(false);\n setIsLoadingSync(client.isLoading());\n }\n }\n }\n\n /**\n * Try signing in when the component is mounted.\n */\n useEffect(() => {\n // React 18.x Strict.Mode has a new check for `Ensuring reusable state` to facilitate an upcoming react feature.\n // https://reactjs.org/docs/strict-mode.html#ensuring-reusable-state\n // This will remount all the useEffects to ensure that there are no unexpected side effects.\n // When react remounts the signIn hook of the AuthProvider, it will cause a race condition. Hence, we have to\n // prevent the re-render of this hook as suggested in the following discussion.\n // https://github.com/reactwg/react-18/discussions/18#discussioncomment-795623\n if (reRenderCheckRef.current) {\n return;\n }\n\n reRenderCheckRef.current = true;\n\n (async (): Promise<void> => {\n // Sync session state whenever sign-in completes (both redirect and embedded V2 flows).\n // Pass the user returned by the SDK's sign-in flow so users/me result is not discarded.\n await client.on('sign-in', async () => {\n await updateSession();\n });\n\n // A session that ends elsewhere, such as a sign-out in another app, signs this app out too.\n await client.on('sign-out', () => {\n setUser(null);\n setUserProfile(null);\n setIsSignedInSync(false);\n });\n\n // Start auto-refresh with a soft failure. This also covers the case where the access token\n // expired while the refresh token is still valid — startAutoRefreshToken() calls\n // refreshAccessToken() immediately when timeUntilRefresh <= 0 — so the sign-in check below\n // sees the refreshed state.\n try {\n await client.startAutoRefreshToken();\n } catch (error) {\n logger.warn('Failed to schedule automatic token refresh.', error);\n }\n\n // User is already authenticated. Restore the session and skip the sign-in path.\n if (await client.isSignedIn()) {\n await updateSession();\n\n return;\n }\n\n const currentUrl: URL = new URL(window.location.href);\n const hasAuthParamsResult: boolean =\n hasAuthParams(currentUrl, config.afterSignInUrl!) && hasCalledForThisInstance(currentUrl, instanceId ?? 0);\n\n if (hasAuthParamsResult) {\n try {\n const urlParams: URLSearchParams = currentUrl.searchParams;\n const code: string | null = urlParams.get('code');\n const executionIdFromUrl: string | null = urlParams.get('executionId');\n const storedExecutionId: string | null = sessionStorage.getItem(\n `${getVendorPrefix(config.vendor)}_execution_id`,\n );\n\n // A silent sign-in response is handled even without a code: an error such as\n // login_required must still be relayed from the iframe to the waiting parent.\n if ((code || SPAUtils.isSilentStatePresentInURL()) && !executionIdFromUrl && !storedExecutionId) {\n await signIn();\n }\n } catch (error) {\n throw new ThunderIDRuntimeError(\n `Sign in failed: ${error instanceof Error ? error.message : String(JSON.stringify(error))}`,\n 'thunderid-signIn-Error',\n 'react',\n 'An error occurred while trying to sign in.',\n );\n }\n }\n })();\n }, []);\n\n /**\n * Check if the user is signed in and update the state accordingly.\n * This will also set an interval to check for the sign-in status every second\n * until the user is signed in.\n */\n useEffect(() => {\n let interval: NodeJS.Timeout;\n\n (async (): Promise<void> => {\n try {\n const status: boolean = await client.isSignedIn();\n\n setIsSignedInSync(status);\n\n if (!status) {\n interval = setInterval(async () => {\n const newStatus: boolean = await client.isSignedIn();\n\n if (newStatus) {\n setIsSignedInSync(true);\n clearInterval(interval);\n }\n }, 1000);\n } else {\n // TODO: Add a debug log to indicate that the user is already signed in.\n }\n } catch (error) {\n setIsSignedInSync(false);\n }\n })();\n\n return (): void => {\n if (interval) {\n clearInterval(interval);\n }\n };\n }, [client]);\n\n useEffect(() => {\n (async (): Promise<void> => {\n try {\n const status: boolean = await client.isInitialized();\n\n setIsInitializedSync(status);\n } catch (error) {\n setIsInitializedSync(false);\n }\n })();\n }, [client]);\n\n /**\n * Track loading state changes from the ThunderID client\n */\n useEffect(() => {\n const checkLoadingState = (): void => {\n // Don't override loading state during critical session updates\n if (isUpdatingSession) {\n return;\n }\n\n // Don't set loading=false while auth params are in the URL and user isn't signed in yet.\n // This prevents ProtectedRoute from redirecting before the sign-in effect processes the auth code.\n const currentUrl: URL = new URL(window.location.href);\n if (!isSignedInSync && hasAuthParams(currentUrl, config.afterSignInUrl!)) {\n return;\n }\n\n setIsLoadingSync(client.isLoading());\n };\n\n // Initial check\n checkLoadingState();\n\n // Set up an interval to check for loading state changes\n const interval: NodeJS.Timeout = setInterval(checkLoadingState, 100);\n\n return (): void => {\n clearInterval(interval);\n };\n }, [client, isLoadingSync, isSignedInSync, isUpdatingSession]);\n\n const signInSilently = async (options?: SignInOptions): Promise<User | boolean> => {\n try {\n setIsUpdatingSession(true);\n setIsLoadingSync(true);\n return await client.signInSilently(options);\n } catch (error) {\n throw new ThunderIDRuntimeError(\n `Error while signing in silently: ${error instanceof Error ? error.message : String(JSON.stringify(error))}`,\n 'thunderid-signInSilently-Error',\n 'react',\n 'An error occurred while trying to sign in silently.',\n );\n } finally {\n setIsUpdatingSession(false);\n setIsLoadingSync(client.isLoading());\n }\n };\n\n const handleProfileUpdate = (payload: User): void => {\n setUser(payload);\n setUserProfile((prev: UserProfile | null) => ({\n flattenedProfile: generateFlattenedUserProfile(payload),\n profile: payload,\n }));\n };\n\n const getDecodedIdToken: () => Promise<IdToken> = useCallback(\n async (): Promise<IdToken> => client.getDecodedIdToken(),\n [client],\n );\n\n const getIdToken: () => Promise<string> = useCallback(async (): Promise<string> => client.getIdToken(), [client]);\n\n const getAccessToken: () => Promise<string> = useCallback(\n async (): Promise<string> => client.getAccessToken(),\n [client],\n );\n\n const getGrantedPermissions: () => Promise<string[]> = useCallback(\n async (): Promise<string[]> => client.getGrantedPermissions(),\n [client],\n );\n\n const getStorageManager: ThunderIDContextProps['getStorageManager'] = useCallback(async () => {\n const storageManager: Awaited<ReturnType<ThunderIDContextProps['getStorageManager']>> =\n storageManagerRef.current ?? (await client.getStorageManager());\n if (storageManager) {\n storageManagerRef.current = storageManager;\n }\n return storageManager;\n }, [client]);\n\n const request: (...args: any[]) => Promise<any> = useCallback(\n async (...args: any[]): Promise<any> => client.request(...args),\n [client],\n );\n\n const requestAll: (...args: any[]) => Promise<any> = useCallback(\n async (...args: any[]): Promise<any> => client.requestAll(...args),\n [client],\n );\n\n const exchangeToken: (exchangeConfig: any) => Promise<any> = useCallback(\n async (exchangeConfig: any): Promise<any> => client.exchangeToken(exchangeConfig),\n [client],\n );\n\n const signOut: (...args: any[]) => Promise<any> = useCallback(\n async (...args: any[]): Promise<any> => client.signOut(...args),\n [client],\n );\n\n const recover: ThunderIDContextProps['recover'] = useCallback(\n async (payload?: EmbeddedRecoveryFlowRequest): Promise<EmbeddedRecoveryFlowResponse> =>\n (await client.recover(payload)) as EmbeddedRecoveryFlowResponse,\n [client],\n );\n\n const signUp: (...args: any[]) => Promise<any> = useCallback(\n async (...args: any[]): Promise<any> => client.signUp(...args),\n [client],\n );\n\n const clearSession: (...args: any[]) => Promise<any> = useCallback(\n async (...args: any[]): Promise<any> => client.clearSession(...args),\n [client],\n );\n\n const reInitialize: (reInitConfig: any) => Promise<any> = useCallback(\n async (reInitConfig: any): Promise<any> => {\n const result: any = await client.reInitialize(reInitConfig);\n\n // Refresh React state from the reinitialized client so the context (config.endpoints,\n // baseUrl, discovery) reflects the new configuration instead of the pre-reinitialization state.\n const reinitializedConfig: ThunderIDReactConfig = await client.getConfiguration();\n setConfig(reinitializedConfig);\n setBaseUrl(reinitializedConfig.baseUrl ?? '');\n setWellKnown(await client.getDiscoveryResponse());\n\n return result;\n },\n [client],\n );\n\n const value: any = useMemo(\n () => ({\n afterSignInUrl: config.afterSignInUrl,\n applicationId: config.applicationId,\n baseUrl,\n endpoints: config.endpoints,\n scopes: config.scopes,\n clearSession,\n clientId,\n discovery: {\n wellKnown,\n },\n exchangeToken,\n getAccessToken,\n getDecodedIdToken,\n getGrantedPermissions,\n getIdToken,\n getStorageManager,\n http: {\n fetcher: httpOptions?.fetcher,\n request,\n requestAll,\n },\n instanceId,\n invalidator,\n isInitialized: isInitializedSync,\n isLoading: isLoadingSync,\n isSignedIn: isSignedInSync,\n organizationChain,\n organizationHandle: config?.organizationHandle,\n preferences,\n reInitialize,\n recover,\n signIn,\n signInOptions,\n tokenRequest,\n signInSilently,\n signInUrl,\n signOut,\n signUp,\n signUpUrl,\n user,\n userSchema,\n vendor: getVendorPrefix(config.vendor),\n }),\n [\n applicationId,\n config?.organizationHandle,\n config.vendor,\n config.afterSignInUrl,\n config.endpoints,\n config.scopes,\n signInUrl,\n signUpUrl,\n baseUrl,\n clientId,\n wellKnown,\n isInitializedSync,\n isLoadingSync,\n isSignedInSync,\n signIn,\n signInSilently,\n user,\n userSchema,\n client,\n signInOptions,\n tokenRequest,\n getDecodedIdToken,\n clearSession,\n exchangeToken,\n httpOptions?.fetcher,\n getAccessToken,\n getGrantedPermissions,\n getStorageManager,\n instanceId,\n invalidator,\n organizationChain,\n preferences,\n recover,\n reInitialize,\n request,\n requestAll,\n signOut,\n signUp,\n ],\n );\n\n return (\n <ThunderIDContext.Provider value={value}>\n <I18nProvider preferences={preferences?.i18n} vendor={getVendorPrefix(config.vendor)}>\n <FlowMetaProvider enabled={preferences?.resolveFromMeta !== false} namespace={namespace}>\n <ThemeProvider\n theme={{\n ...preferences?.theme?.overrides,\n direction: preferences?.theme?.direction,\n }}\n >\n <FlowProvider>\n <UserProvider profile={userProfile!} userSchema={userSchema} onUpdateProfile={handleProfileUpdate}>\n <ComponentRendererProvider renderers={(extensions?.components?.renderers ?? {}) as any}>\n {children}\n </ComponentRendererProvider>\n </UserProvider>\n </FlowProvider>\n </ThemeProvider>\n </FlowMetaProvider>\n </I18nProvider>\n </ThunderIDContext.Provider>\n );\n};\n\nexport default ThunderIDProvider;\n"],"mappings":"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"}
|
|
@@ -8,7 +8,8 @@ react = require_rolldown_runtime.__toESM(react);
|
|
|
8
8
|
//#region src/hooks/management/useGrantedPermissions.ts
|
|
9
9
|
/**
|
|
10
10
|
* Reads the permissions the signed-in user's access token grants, for example to hide a page the
|
|
11
|
-
* user cannot use.
|
|
11
|
+
* user cannot use. In backend mode they come from the backend's session, so the token stays on the
|
|
12
|
+
* backend.
|
|
12
13
|
*
|
|
13
14
|
* @returns The granted permissions and a `can` check.
|
|
14
15
|
*
|
|
@@ -19,18 +20,18 @@ react = require_rolldown_runtime.__toESM(react);
|
|
|
19
20
|
* ```
|
|
20
21
|
*/
|
|
21
22
|
const useGrantedPermissions = () => {
|
|
22
|
-
const {
|
|
23
|
+
const { getGrantedPermissions, isSignedIn } = require_useThunderID.default();
|
|
23
24
|
const [granted, setGranted] = (0, react.useState)(null);
|
|
24
25
|
(0, react.useEffect)(() => {
|
|
25
26
|
if (!isSignedIn) return;
|
|
26
27
|
let active = true;
|
|
27
|
-
|
|
28
|
-
if (active) setGranted(
|
|
28
|
+
getGrantedPermissions().catch(() => []).then((grantedPermissions) => {
|
|
29
|
+
if (active) setGranted(grantedPermissions);
|
|
29
30
|
});
|
|
30
31
|
return () => {
|
|
31
32
|
active = false;
|
|
32
33
|
};
|
|
33
|
-
}, [
|
|
34
|
+
}, [getGrantedPermissions, isSignedIn]);
|
|
34
35
|
const permissions = (0, react.useMemo)(() => isSignedIn ? granted ?? [] : [], [granted, isSignedIn]);
|
|
35
36
|
const isLoading = isSignedIn && granted === null;
|
|
36
37
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useGrantedPermissions.cjs","names":["useThunderID","permissions: string[]","isLoading: boolean"],"sources":["../../../../src/hooks/management/useGrantedPermissions.ts"],"sourcesContent":["// Copyright 2026 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\nimport {
|
|
1
|
+
{"version":3,"file":"useGrantedPermissions.cjs","names":["useThunderID","permissions: string[]","isLoading: boolean"],"sources":["../../../../src/hooks/management/useGrantedPermissions.ts"],"sourcesContent":["// Copyright 2026 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\nimport {hasPermission} from '@thunderid/browser';\nimport {useCallback, useEffect, useMemo, useState} from 'react';\nimport useThunderID from '../../contexts/ThunderID/useThunderID';\n\n/**\n * The permissions the signed-in user's access token grants.\n */\nexport interface GrantedPermissions {\n /**\n * Whether the granted permissions cover a required one. A permission covers everything under it,\n * so `system:user` covers `system:user:view`. Use it to decide what to show; the server still\n * checks every request.\n */\n can: (required: string) => boolean;\n isLoading: boolean;\n permissions: string[];\n}\n\n/**\n * Reads the permissions the signed-in user's access token grants, for example to hide a page the\n * user cannot use. In backend mode they come from the backend's session, so the token stays on the\n * backend.\n *\n * @returns The granted permissions and a `can` check.\n *\n * @example\n * ```tsx\n * const {can} = useGrantedPermissions();\n * return can('system:group:view') ? <GroupList /> : null;\n * ```\n */\nconst useGrantedPermissions = (): GrantedPermissions => {\n const {getGrantedPermissions, isSignedIn} = useThunderID();\n const [granted, setGranted] = useState<string[] | null>(null);\n\n useEffect(() => {\n if (!isSignedIn) {\n return undefined;\n }\n\n let active = true;\n\n void getGrantedPermissions()\n .catch((): string[] => [])\n .then((grantedPermissions: string[]) => {\n if (active) {\n setGranted(grantedPermissions);\n }\n });\n\n return (): void => {\n active = false;\n };\n }, [getGrantedPermissions, isSignedIn]);\n\n const permissions: string[] = useMemo(() => (isSignedIn ? (granted ?? []) : []), [granted, isSignedIn]);\n const isLoading: boolean = isSignedIn && granted === null;\n\n const can: (required: string) => boolean = useCallback(\n (required: string): boolean => hasPermission(permissions, required),\n [permissions],\n );\n\n return {can, isLoading, permissions};\n};\n\nexport default useGrantedPermissions;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAkCA,MAAM,8BAAkD;CACtD,MAAM,EAAC,uBAAuB,eAAcA,8BAAc;CAC1D,MAAM,CAAC,SAAS,kCAAwC,KAAK;AAE7D,4BAAgB;AACd,MAAI,CAAC,WACH;EAGF,IAAI,SAAS;AAEb,EAAK,uBAAuB,CACzB,YAAsB,EAAE,CAAC,CACzB,MAAM,uBAAiC;AACtC,OAAI,OACF,YAAW,mBAAmB;IAEhC;AAEJ,eAAmB;AACjB,YAAS;;IAEV,CAAC,uBAAuB,WAAW,CAAC;CAEvC,MAAMC,uCAAuC,aAAc,WAAW,EAAE,GAAI,EAAE,EAAG,CAAC,SAAS,WAAW,CAAC;CACvG,MAAMC,YAAqB,cAAc,YAAY;AAOrD,QAAO;EAAC,6BAJL,oDAA4C,aAAa,SAAS,EACnE,CAAC,YAAY,CACd;EAEY;EAAW;EAAY;;AAGtC,oCAAe"}
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -38,13 +38,13 @@ const require_SignUpButton = require('./components/auth/buttons/SignUpButton/Sig
|
|
|
38
38
|
const require_SignedIn = require('./components/auth/guards/SignedIn.cjs');
|
|
39
39
|
const require_SignedOut = require('./components/auth/guards/SignedOut.cjs');
|
|
40
40
|
const require_Loading = require('./components/auth/guards/Loading.cjs');
|
|
41
|
+
const require_Typography = require('./components/primitives/Typography/Typography.cjs');
|
|
42
|
+
const require_Card = require('./components/primitives/Card/Card.cjs');
|
|
41
43
|
const require_CircleAlert = require('./components/primitives/Icons/CircleAlert.cjs');
|
|
42
44
|
const require_CircleCheck = require('./components/primitives/Icons/CircleCheck.cjs');
|
|
43
45
|
const require_Info = require('./components/primitives/Icons/Info.cjs');
|
|
44
46
|
const require_TriangleAlert = require('./components/primitives/Icons/TriangleAlert.cjs');
|
|
45
|
-
const require_Typography = require('./components/primitives/Typography/Typography.cjs');
|
|
46
47
|
const require_Alert = require('./components/primitives/Alert/Alert.cjs');
|
|
47
|
-
const require_Card = require('./components/primitives/Card/Card.cjs');
|
|
48
48
|
const require_FormControl = require('./components/primitives/FormControl/FormControl.cjs');
|
|
49
49
|
const require_InputLabel = require('./components/primitives/InputLabel/InputLabel.cjs');
|
|
50
50
|
const require_Toggle = require('./components/primitives/Toggle/Toggle.cjs');
|
|
@@ -82,6 +82,8 @@ const require_LinkedInButton = require('./components/auth/buttons/LinkedInButton
|
|
|
82
82
|
const require_MicrosoftButton = require('./components/auth/buttons/MicrosoftButton.cjs');
|
|
83
83
|
const require_SignInWithEthereumButton = require('./components/auth/buttons/SignInWithEthereumButton.cjs');
|
|
84
84
|
const require_BaseSignIn = require('./components/auth/SignIn/BaseSignIn.cjs');
|
|
85
|
+
const require_BaseDeviceGrant = require('./components/auth/DeviceGrant/BaseDeviceGrant.cjs');
|
|
86
|
+
const require_DeviceGrant = require('./components/auth/DeviceGrant/DeviceGrant.cjs');
|
|
85
87
|
const require_useOAuthCallback = require('./hooks/auth/useOAuthCallback.cjs');
|
|
86
88
|
const require_SignIn = require('./components/auth/SignIn/SignIn.cjs');
|
|
87
89
|
const require_Logo = require('./components/primitives/Logo/Logo.cjs');
|
|
@@ -250,6 +252,7 @@ exports.BaseApplicationDetails = require_BaseApplicationDetails.default;
|
|
|
250
252
|
exports.BaseApplicationList = require_BaseApplicationList.default;
|
|
251
253
|
exports.BaseAuthFlowSelect = require_BaseAuthFlowSelect.default;
|
|
252
254
|
exports.BaseChangeCredential = require_BaseChangeCredential.default;
|
|
255
|
+
exports.BaseDeviceGrant = require_BaseDeviceGrant.default;
|
|
253
256
|
exports.BaseGroupCreate = require_BaseGroupCreate.default;
|
|
254
257
|
exports.BaseGroupList = require_BaseGroupList.default;
|
|
255
258
|
exports.BaseGroupMembers = require_BaseGroupMembers.default;
|
|
@@ -301,6 +304,7 @@ exports.ConsentCheckboxList = require_ConsentCheckboxList.default;
|
|
|
301
304
|
exports.ConsentDetailField = require_ConsentDetailField.default;
|
|
302
305
|
exports.DataTable = require_DataTable.default;
|
|
303
306
|
exports.DatePicker = require_DatePicker.default;
|
|
307
|
+
exports.DeviceGrant = require_DeviceGrant.default;
|
|
304
308
|
exports.Divider = require_Divider.default;
|
|
305
309
|
Object.defineProperty(exports, 'EMOJI_URI_SCHEME', {
|
|
306
310
|
enumerable: true,
|
|
@@ -3,8 +3,8 @@ import useTheme_default from "../../../contexts/Theme/useTheme.js";
|
|
|
3
3
|
import useTranslation_default from "../../../hooks/useTranslation.js";
|
|
4
4
|
import Button_default from "../../primitives/Button/Button.js";
|
|
5
5
|
import Typography_default from "../../primitives/Typography/Typography.js";
|
|
6
|
-
import Alert_default from "../../primitives/Alert/Alert.js";
|
|
7
6
|
import Card_default from "../../primitives/Card/Card.js";
|
|
7
|
+
import Alert_default from "../../primitives/Alert/Alert.js";
|
|
8
8
|
import TextField_default from "../../primitives/TextField/TextField.js";
|
|
9
9
|
import Checkbox_default from "../../primitives/Checkbox/Checkbox.js";
|
|
10
10
|
import DatePicker_default from "../../primitives/DatePicker/DatePicker.js";
|
|
@@ -7,8 +7,8 @@ import { extractErrorMessage, normalizeFlowResponse } from "../../../utils/flowT
|
|
|
7
7
|
import Spinner_default from "../../primitives/Spinner/Spinner.js";
|
|
8
8
|
import Button_default from "../../primitives/Button/Button.js";
|
|
9
9
|
import Typography_default from "../../primitives/Typography/Typography.js";
|
|
10
|
-
import Alert_default from "../../primitives/Alert/Alert.js";
|
|
11
10
|
import Card_default from "../../primitives/Card/Card.js";
|
|
11
|
+
import Alert_default from "../../primitives/Alert/Alert.js";
|
|
12
12
|
import isConsentApprovalBlocked_default from "../../../utils/isConsentApprovalBlocked.js";
|
|
13
13
|
import { renderInviteUserComponents } from "../flow/AuthOptionFactory.js";
|
|
14
14
|
import { useOAuthCallback } from "../../../hooks/auth/useOAuthCallback.js";
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { EmbeddedFlowComponent } from '@thunderid/browser';
|
|
2
|
+
import { FC } from 'react';
|
|
3
|
+
import { type BaseSignInProps } from '../SignIn/BaseSignIn';
|
|
4
|
+
export type DeviceGrantResult = 'failure' | 'success' | null;
|
|
5
|
+
export interface BaseDeviceGrantProps extends Omit<BaseSignInProps, 'components' | 'onSubmit'> {
|
|
6
|
+
components: EmbeddedFlowComponent[];
|
|
7
|
+
completeMessage?: string;
|
|
8
|
+
completeDescription?: string;
|
|
9
|
+
failedMessage?: string;
|
|
10
|
+
failedDescription?: string;
|
|
11
|
+
onSubmit: NonNullable<BaseSignInProps['onSubmit']>;
|
|
12
|
+
result?: DeviceGrantResult;
|
|
13
|
+
}
|
|
14
|
+
/** Renders the server-described Device Grant prompt independently of SDK orchestration. */
|
|
15
|
+
declare const BaseDeviceGrant: FC<BaseDeviceGrantProps>;
|
|
16
|
+
export default BaseDeviceGrant;
|
|
17
|
+
//# sourceMappingURL=BaseDeviceGrant.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BaseDeviceGrant.d.ts","sourceRoot":"","sources":["../../../../src/components/auth/DeviceGrant/BaseDeviceGrant.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAC,qBAAqB,EAAC,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAAC,EAAE,EAAe,MAAM,OAAO,CAAC;AAMvC,OAAmB,EAAC,KAAK,eAAe,EAAC,MAAM,sBAAsB,CAAC;AAEtE,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,SAAS,GAAG,IAAI,CAAC;AAE7D,MAAM,WAAW,oBAAqB,SAAQ,IAAI,CAAC,eAAe,EAAE,YAAY,GAAG,UAAU,CAAC;IAC5F,UAAU,EAAE,qBAAqB,EAAE,CAAC;IACpC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,EAAE,WAAW,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC,CAAC;IACnD,MAAM,CAAC,EAAE,iBAAiB,CAAC;CAC5B;AAED,2FAA2F;AAC3F,QAAA,MAAM,eAAe,EAAE,EAAE,CAAC,oBAAoB,CAgE7C,CAAC;AAEF,eAAe,eAAe,CAAC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import useTheme_default from "../../../contexts/Theme/useTheme.js";
|
|
2
|
+
import useTranslation_default from "../../../hooks/useTranslation.js";
|
|
3
|
+
import BaseDeviceGrant_styles_default from "./BaseDeviceGrant.styles.js";
|
|
4
|
+
import Typography_default from "../../primitives/Typography/Typography.js";
|
|
5
|
+
import Card_default from "../../primitives/Card/Card.js";
|
|
6
|
+
import BaseSignIn_default from "../SignIn/BaseSignIn.js";
|
|
7
|
+
import { createElement } from "react";
|
|
8
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
9
|
+
|
|
10
|
+
//#region src/components/auth/DeviceGrant/BaseDeviceGrant.tsx
|
|
11
|
+
/** Renders the server-described Device Grant prompt independently of SDK orchestration. */
|
|
12
|
+
const BaseDeviceGrant = ({ components, className = "", completeMessage = void 0, completeDescription = void 0, failedMessage = void 0, failedDescription = void 0, error, isLoading, preferences, result = null, variant = "default",...signInProps }) => {
|
|
13
|
+
const { theme } = useTheme_default();
|
|
14
|
+
const { t } = useTranslation_default(preferences?.i18n);
|
|
15
|
+
const styles = BaseDeviceGrant_styles_default(theme);
|
|
16
|
+
if ((error || result) && components.length === 0) {
|
|
17
|
+
const isSuccess = result === "success" && !error;
|
|
18
|
+
const resolvedCompleteMessage = completeMessage ?? t("deviceGrant.messages.complete");
|
|
19
|
+
const resolvedCompleteDescription = completeDescription ?? t("deviceGrant.messages.completeDescription");
|
|
20
|
+
const resolvedFailedMessage = failedMessage ?? t("deviceGrant.messages.failed");
|
|
21
|
+
const resolvedFailedDescription = failedDescription ?? t("deviceGrant.messages.failedDescription");
|
|
22
|
+
const title = isSuccess ? resolvedCompleteMessage : resolvedFailedMessage;
|
|
23
|
+
const description = isSuccess ? resolvedCompleteDescription : !error || error.message === resolvedFailedMessage ? resolvedFailedDescription : error.message;
|
|
24
|
+
return /* @__PURE__ */ jsxs(Card_default, {
|
|
25
|
+
className: `${styles["terminalCard"]} ${className}`,
|
|
26
|
+
"data-testid": "device-grant-result",
|
|
27
|
+
variant,
|
|
28
|
+
children: [/* @__PURE__ */ jsx(Typography_default, {
|
|
29
|
+
className: styles["terminalTitle"],
|
|
30
|
+
color: isSuccess ? "success" : "error",
|
|
31
|
+
component: "h2",
|
|
32
|
+
fontWeight: 600,
|
|
33
|
+
variant: "h6",
|
|
34
|
+
children: title
|
|
35
|
+
}), /* @__PURE__ */ jsx(Typography_default, {
|
|
36
|
+
className: styles["terminalDescription"],
|
|
37
|
+
color: "textSecondary",
|
|
38
|
+
component: "p",
|
|
39
|
+
variant: "caption",
|
|
40
|
+
children: description
|
|
41
|
+
})]
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
return /* @__PURE__ */ createElement(BaseSignIn_default, {
|
|
45
|
+
...signInProps,
|
|
46
|
+
className,
|
|
47
|
+
key: components.map((component) => component.id).join("|"),
|
|
48
|
+
components,
|
|
49
|
+
error,
|
|
50
|
+
isLoading,
|
|
51
|
+
preferences
|
|
52
|
+
});
|
|
53
|
+
};
|
|
54
|
+
var BaseDeviceGrant_default = BaseDeviceGrant;
|
|
55
|
+
|
|
56
|
+
//#endregion
|
|
57
|
+
export { BaseDeviceGrant_default as default };
|
|
58
|
+
//# sourceMappingURL=BaseDeviceGrant.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BaseDeviceGrant.js","names":["BaseDeviceGrant: FC<BaseDeviceGrantProps>","useTheme","useTranslation","useStyles","CardPrimitive","Typography","BaseSignIn"],"sources":["../../../../src/components/auth/DeviceGrant/BaseDeviceGrant.tsx"],"sourcesContent":["// Copyright 2025-2026 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\nimport type {EmbeddedFlowComponent} from '@thunderid/browser';\nimport {FC, ReactElement} from 'react';\nimport useStyles from './BaseDeviceGrant.styles';\nimport useTheme from '../../../contexts/Theme/useTheme';\nimport useTranslation from '../../../hooks/useTranslation';\nimport CardPrimitive from '../../primitives/Card/Card';\nimport Typography from '../../primitives/Typography/Typography';\nimport BaseSignIn, {type BaseSignInProps} from '../SignIn/BaseSignIn';\n\nexport type DeviceGrantResult = 'failure' | 'success' | null;\n\nexport interface BaseDeviceGrantProps extends Omit<BaseSignInProps, 'components' | 'onSubmit'> {\n components: EmbeddedFlowComponent[];\n completeMessage?: string;\n completeDescription?: string;\n failedMessage?: string;\n failedDescription?: string;\n onSubmit: NonNullable<BaseSignInProps['onSubmit']>;\n result?: DeviceGrantResult;\n}\n\n/** Renders the server-described Device Grant prompt independently of SDK orchestration. */\nconst BaseDeviceGrant: FC<BaseDeviceGrantProps> = ({\n components,\n className = '',\n completeMessage = undefined,\n completeDescription = undefined,\n failedMessage = undefined,\n failedDescription = undefined,\n error,\n isLoading,\n preferences,\n result = null,\n variant = 'default',\n ...signInProps\n}: BaseDeviceGrantProps): ReactElement => {\n const {theme} = useTheme();\n const {t} = useTranslation(preferences?.i18n);\n const styles = useStyles(theme);\n\n if ((error || result) && components.length === 0) {\n const isSuccess = result === 'success' && !error;\n const resolvedCompleteMessage = completeMessage ?? t('deviceGrant.messages.complete');\n const resolvedCompleteDescription = completeDescription ?? t('deviceGrant.messages.completeDescription');\n const resolvedFailedMessage = failedMessage ?? t('deviceGrant.messages.failed');\n const resolvedFailedDescription = failedDescription ?? t('deviceGrant.messages.failedDescription');\n const title = isSuccess ? resolvedCompleteMessage : resolvedFailedMessage;\n const description = isSuccess\n ? resolvedCompleteDescription\n : !error || error.message === resolvedFailedMessage\n ? resolvedFailedDescription\n : error.message;\n\n return (\n <CardPrimitive\n className={`${styles['terminalCard']} ${className}`}\n data-testid=\"device-grant-result\"\n variant={variant}\n >\n <Typography\n className={styles['terminalTitle']}\n color={isSuccess ? 'success' : 'error'}\n component=\"h2\"\n fontWeight={600}\n variant=\"h6\"\n >\n {title}\n </Typography>\n <Typography className={styles['terminalDescription']} color=\"textSecondary\" component=\"p\" variant=\"caption\">\n {description}\n </Typography>\n </CardPrimitive>\n );\n }\n\n return (\n <BaseSignIn\n {...signInProps}\n className={className}\n key={components.map((component: EmbeddedFlowComponent) => component.id).join('|')}\n components={components}\n error={error}\n isLoading={isLoading}\n preferences={preferences}\n />\n );\n};\n\nexport default BaseDeviceGrant;\n"],"mappings":";;;;;;;;;;;AAyBA,MAAMA,mBAA6C,EACjD,YACA,YAAY,IACZ,kBAAkB,QAClB,sBAAsB,QACtB,gBAAgB,QAChB,oBAAoB,QACpB,OACA,WACA,aACA,SAAS,MACT,UAAU,UACV,GAAG,kBACqC;CACxC,MAAM,EAAC,UAASC,kBAAU;CAC1B,MAAM,EAAC,MAAKC,uBAAe,aAAa,KAAK;CAC7C,MAAM,SAASC,+BAAU,MAAM;AAE/B,MAAK,SAAS,WAAW,WAAW,WAAW,GAAG;EAChD,MAAM,YAAY,WAAW,aAAa,CAAC;EAC3C,MAAM,0BAA0B,mBAAmB,EAAE,gCAAgC;EACrF,MAAM,8BAA8B,uBAAuB,EAAE,2CAA2C;EACxG,MAAM,wBAAwB,iBAAiB,EAAE,8BAA8B;EAC/E,MAAM,4BAA4B,qBAAqB,EAAE,yCAAyC;EAClG,MAAM,QAAQ,YAAY,0BAA0B;EACpD,MAAM,cAAc,YAChB,8BACA,CAAC,SAAS,MAAM,YAAY,wBAC1B,4BACA,MAAM;AAEZ,SACE,qBAACC;GACC,WAAW,GAAG,OAAO,gBAAgB,GAAG;GACxC,eAAY;GACH;cAET,oBAACC;IACC,WAAW,OAAO;IAClB,OAAO,YAAY,YAAY;IAC/B,WAAU;IACV,YAAY;IACZ,SAAQ;cAEP;KACU,EACb,oBAACA;IAAW,WAAW,OAAO;IAAwB,OAAM;IAAgB,WAAU;IAAI,SAAQ;cAC/F;KACU;IACC;;AAIpB,QACE,8BAACC;EACC,GAAI;EACO;EACX,KAAK,WAAW,KAAK,cAAqC,UAAU,GAAG,CAAC,KAAK,IAAI;EACrE;EACL;EACI;EACE;GACb;;AAIN,8BAAe"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BaseDeviceGrant.styles.d.ts","sourceRoot":"","sources":["../../../../src/components/auth/DeviceGrant/BaseDeviceGrant.styles.ts"],"names":[],"mappings":"AAGA,OAAO,EAAC,KAAK,EAAC,MAAM,oBAAoB,CAAC;AAIzC,QAAA,MAAM,SAAS,GAAI,OAAO,KAAK,KAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAkBpD,CAAC;AAEJ,eAAe,SAAS,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { css } from "../../../styles/emotion.js";
|
|
2
|
+
import { useMemo } from "react";
|
|
3
|
+
|
|
4
|
+
//#region src/components/auth/DeviceGrant/BaseDeviceGrant.styles.ts
|
|
5
|
+
const useStyles = (theme) => useMemo(() => ({
|
|
6
|
+
terminalCard: css`
|
|
7
|
+
box-sizing: border-box;
|
|
8
|
+
width: 100%;
|
|
9
|
+
max-width: calc(${theme.vars.spacing.unit} * 60);
|
|
10
|
+
margin: 0 auto;
|
|
11
|
+
gap: ${theme.vars.spacing.unit};
|
|
12
|
+
`,
|
|
13
|
+
terminalDescription: css`
|
|
14
|
+
margin: 0;
|
|
15
|
+
`,
|
|
16
|
+
terminalTitle: css`
|
|
17
|
+
margin: 0;
|
|
18
|
+
`
|
|
19
|
+
}), [theme]);
|
|
20
|
+
var BaseDeviceGrant_styles_default = useStyles;
|
|
21
|
+
|
|
22
|
+
//#endregion
|
|
23
|
+
export { BaseDeviceGrant_styles_default as default };
|
|
24
|
+
//# sourceMappingURL=BaseDeviceGrant.styles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BaseDeviceGrant.styles.js","names":[],"sources":["../../../../src/components/auth/DeviceGrant/BaseDeviceGrant.styles.ts"],"sourcesContent":["// Copyright 2025-2026 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\nimport {Theme} from '@thunderid/browser';\nimport {useMemo} from 'react';\nimport {css} from '../../../styles/emotion';\n\nconst useStyles = (theme: Theme): Record<string, string> =>\n useMemo(\n () => ({\n terminalCard: css`\n box-sizing: border-box;\n width: 100%;\n max-width: calc(${theme.vars.spacing.unit} * 60);\n margin: 0 auto;\n gap: ${theme.vars.spacing.unit};\n `,\n terminalDescription: css`\n margin: 0;\n `,\n terminalTitle: css`\n margin: 0;\n `,\n }),\n [theme],\n );\n\nexport default useStyles;\n"],"mappings":";;;;AAOA,MAAM,aAAa,UACjB,eACS;CACL,cAAc,GAAG;;;0BAGG,MAAM,KAAK,QAAQ,KAAK;;eAEnC,MAAM,KAAK,QAAQ,KAAK;;CAEjC,qBAAqB,GAAG;;;CAGxB,eAAe,GAAG;;;CAGnB,GACD,CAAC,MAAM,CACR;AAEH,qCAAe"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { executeEmbeddedDeviceGrantFlow } from '@thunderid/browser';
|
|
2
|
+
import type { EmbeddedFlowComponent, EmbeddedSignInFlowRequest, FlowMetadataResponse } from '@thunderid/browser';
|
|
3
|
+
import type { FC, ReactNode } from 'react';
|
|
4
|
+
import { type BaseDeviceGrantProps, type DeviceGrantResult } from './BaseDeviceGrant';
|
|
5
|
+
type EmbeddedDeviceGrantFlowResponse = Awaited<ReturnType<typeof executeEmbeddedDeviceGrantFlow>>;
|
|
6
|
+
/** Values exposed to consumers that provide custom Device Grant UI. */
|
|
7
|
+
export interface DeviceGrantRenderProps {
|
|
8
|
+
/** Additional values returned for the active flow step. */
|
|
9
|
+
additionalData: Record<string, unknown>;
|
|
10
|
+
/** Components returned by the configured flow. */
|
|
11
|
+
components: EmbeddedFlowComponent[];
|
|
12
|
+
/** Current flow error, when one needs to be shown. */
|
|
13
|
+
error: Error | null;
|
|
14
|
+
/** First server validation message for each field. */
|
|
15
|
+
fieldErrors: Record<string, string>;
|
|
16
|
+
/** Values prefilled from the verification URI. */
|
|
17
|
+
initialValues: Record<string, string>;
|
|
18
|
+
/** Whether a flow request is in progress. */
|
|
19
|
+
isLoading: boolean;
|
|
20
|
+
/** Flow metadata used to resolve application-specific template values. */
|
|
21
|
+
meta: FlowMetadataResponse | null;
|
|
22
|
+
/** Submits user-code input or continues the active flow. */
|
|
23
|
+
onSubmit: (payload: EmbeddedSignInFlowRequest) => Promise<void>;
|
|
24
|
+
/** Terminal flow result when the flow has no configured prompt to render. */
|
|
25
|
+
result: DeviceGrantResult;
|
|
26
|
+
}
|
|
27
|
+
export type DeviceGrantProps = Omit<BaseDeviceGrantProps, 'children' | 'components' | 'error' | 'initialValues' | 'isLoading' | 'onSubmit' | 'result' | 'serverFieldErrors'> & {
|
|
28
|
+
/** Render props for Gate or other consumers that provide their own flow UI. */
|
|
29
|
+
children?: (props: DeviceGrantRenderProps) => ReactNode;
|
|
30
|
+
onComplete?: (response: EmbeddedDeviceGrantFlowResponse) => void;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Runs the application's configured Device Grant flow and exposes its state for custom renderers.
|
|
34
|
+
*/
|
|
35
|
+
declare const DeviceGrant: FC<DeviceGrantProps>;
|
|
36
|
+
export default DeviceGrant;
|
|
37
|
+
//# sourceMappingURL=DeviceGrant.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DeviceGrant.d.ts","sourceRoot":"","sources":["../../../../src/components/auth/DeviceGrant/DeviceGrant.tsx"],"names":[],"mappings":"AAGA,OAAO,EAA6C,8BAA8B,EAAC,MAAM,oBAAoB,CAAC;AAC9G,OAAO,KAAK,EAAC,qBAAqB,EAAE,yBAAyB,EAAE,oBAAoB,EAAC,MAAM,oBAAoB,CAAC;AAE/G,OAAO,KAAK,EAAC,EAAE,EAAgB,SAAS,EAAC,MAAM,OAAO,CAAC;AACvD,OAAwB,EAAC,KAAK,oBAAoB,EAAE,KAAK,iBAAiB,EAAC,MAAM,mBAAmB,CAAC;AAKrG,KAAK,+BAA+B,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,8BAA8B,CAAC,CAAC,CAAC;AAGlG,uEAAuE;AACvE,MAAM,WAAW,sBAAsB;IACrC,2DAA2D;IAC3D,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACxC,kDAAkD;IAClD,UAAU,EAAE,qBAAqB,EAAE,CAAC;IACpC,sDAAsD;IACtD,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,sDAAsD;IACtD,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,kDAAkD;IAClD,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,6CAA6C;IAC7C,SAAS,EAAE,OAAO,CAAC;IACnB,0EAA0E;IAC1E,IAAI,EAAE,oBAAoB,GAAG,IAAI,CAAC;IAClC,4DAA4D;IAC5D,QAAQ,EAAE,CAAC,OAAO,EAAE,yBAAyB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChE,6EAA6E;IAC7E,MAAM,EAAE,iBAAiB,CAAC;CAC3B;AAED,MAAM,MAAM,gBAAgB,GAAG,IAAI,CACjC,oBAAoB,EACpB,UAAU,GAAG,YAAY,GAAG,OAAO,GAAG,eAAe,GAAG,WAAW,GAAG,UAAU,GAAG,QAAQ,GAAG,mBAAmB,CAClH,GAAG;IACF,+EAA+E;IAC/E,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,sBAAsB,KAAK,SAAS,CAAC;IACxD,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,+BAA+B,KAAK,IAAI,CAAC;CAClE,CAAC;AAgBF;;GAEG;AACH,QAAA,MAAM,WAAW,EAAE,EAAE,CAAC,gBAAgB,CA0MrC,CAAC;AAEF,eAAe,WAAW,CAAC"}
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import useThunderID_default from "../../../contexts/ThunderID/useThunderID.js";
|
|
2
|
+
import useTranslation_default from "../../../hooks/useTranslation.js";
|
|
3
|
+
import { extractErrorMessage, normalizeFlowResponse } from "../../../utils/flowTransformer.js";
|
|
4
|
+
import BaseDeviceGrant_default from "./BaseDeviceGrant.js";
|
|
5
|
+
import { EmbeddedFlowType, EmbeddedSignInFlowStatus, executeEmbeddedDeviceGrantFlow } from "@thunderid/browser";
|
|
6
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
7
|
+
import { Fragment as Fragment$1, jsx } from "react/jsx-runtime";
|
|
8
|
+
|
|
9
|
+
//#region src/components/auth/DeviceGrant/DeviceGrant.tsx
|
|
10
|
+
const clearVerificationParameters = () => {
|
|
11
|
+
if (!window.location.href) return;
|
|
12
|
+
const url = new URL(window.location.href);
|
|
13
|
+
url.searchParams.delete("user_code");
|
|
14
|
+
url.searchParams.delete("applicationId");
|
|
15
|
+
window.history.replaceState(window.history.state, "", url.toString());
|
|
16
|
+
};
|
|
17
|
+
const hasUserCodeInput = (components) => components.some((component) => component.ref === "user_code" || Array.isArray(component.components) && hasUserCodeInput(component.components));
|
|
18
|
+
/**
|
|
19
|
+
* Runs the application's configured Device Grant flow and exposes its state for custom renderers.
|
|
20
|
+
*/
|
|
21
|
+
const DeviceGrant = ({ children = void 0, className = "", onComplete = void 0, onError = void 0, preferences = {}, size = "medium", variant = "default",...baseProps }) => {
|
|
22
|
+
const { applicationId, baseUrl, meta } = useThunderID_default();
|
|
23
|
+
const { t } = useTranslation_default(preferences?.i18n);
|
|
24
|
+
const [components, setComponents] = useState([]);
|
|
25
|
+
const [additionalData, setAdditionalData] = useState({});
|
|
26
|
+
const [initialValues, setInitialValues] = useState({});
|
|
27
|
+
const [serverFieldErrors, setServerFieldErrors] = useState(null);
|
|
28
|
+
const [executionId, setExecutionId] = useState("");
|
|
29
|
+
const [challengeToken, setChallengeToken] = useState("");
|
|
30
|
+
const [error, setError] = useState(null);
|
|
31
|
+
const [isLoading, setIsLoading] = useState(() => {
|
|
32
|
+
if (applicationId) return true;
|
|
33
|
+
return typeof window !== "undefined" && Boolean(new URL(window.location.href).searchParams.get("applicationId"));
|
|
34
|
+
});
|
|
35
|
+
const [result, setResult] = useState(null);
|
|
36
|
+
const flowStartAttempted = useRef(false);
|
|
37
|
+
const verificationParametersRead = useRef(false);
|
|
38
|
+
const handleError = useCallback((flowError) => {
|
|
39
|
+
setComponents([]);
|
|
40
|
+
setAdditionalData({});
|
|
41
|
+
setServerFieldErrors(null);
|
|
42
|
+
setError(flowError);
|
|
43
|
+
setResult("failure");
|
|
44
|
+
onError?.(flowError);
|
|
45
|
+
}, [onError]);
|
|
46
|
+
const applyResponse = useCallback((response) => {
|
|
47
|
+
const normalized = normalizeFlowResponse(response, t, {
|
|
48
|
+
throwOnError: false,
|
|
49
|
+
resolveTranslations: false
|
|
50
|
+
}, meta);
|
|
51
|
+
setExecutionId(response.executionId);
|
|
52
|
+
setChallengeToken(response.challengeToken ?? "");
|
|
53
|
+
setComponents(normalized.components);
|
|
54
|
+
setAdditionalData(normalized.additionalData);
|
|
55
|
+
setServerFieldErrors(response.data?.fieldErrors ?? null);
|
|
56
|
+
setError(response.error ? new Error(extractErrorMessage(response, t)) : null);
|
|
57
|
+
if (response.flowStatus === EmbeddedSignInFlowStatus.Complete) {
|
|
58
|
+
setResult("success");
|
|
59
|
+
onComplete?.(response);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
if (response.flowStatus === EmbeddedSignInFlowStatus.Error) {
|
|
63
|
+
const flowError = new Error(extractErrorMessage(response, t, "deviceGrant.messages.failed"));
|
|
64
|
+
setError(flowError);
|
|
65
|
+
setResult("failure");
|
|
66
|
+
onError?.(flowError);
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
setResult(null);
|
|
70
|
+
}, [
|
|
71
|
+
meta,
|
|
72
|
+
onComplete,
|
|
73
|
+
onError,
|
|
74
|
+
t
|
|
75
|
+
]);
|
|
76
|
+
const startFlow = useCallback(async (appId) => {
|
|
77
|
+
setIsLoading(true);
|
|
78
|
+
setError(null);
|
|
79
|
+
try {
|
|
80
|
+
const response = await executeEmbeddedDeviceGrantFlow({
|
|
81
|
+
baseUrl,
|
|
82
|
+
payload: {
|
|
83
|
+
applicationId: appId,
|
|
84
|
+
flowType: EmbeddedFlowType.DeviceGrant,
|
|
85
|
+
inputs: {}
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
clearVerificationParameters();
|
|
89
|
+
applyResponse(response);
|
|
90
|
+
} catch (flowError) {
|
|
91
|
+
handleError(flowError instanceof Error ? flowError : new Error(t("deviceGrant.errors.continue")));
|
|
92
|
+
} finally {
|
|
93
|
+
setIsLoading(false);
|
|
94
|
+
}
|
|
95
|
+
}, [
|
|
96
|
+
applyResponse,
|
|
97
|
+
baseUrl,
|
|
98
|
+
handleError,
|
|
99
|
+
t
|
|
100
|
+
]);
|
|
101
|
+
useEffect(() => {
|
|
102
|
+
const url = new URL(window.location.href);
|
|
103
|
+
if (!verificationParametersRead.current) {
|
|
104
|
+
verificationParametersRead.current = true;
|
|
105
|
+
const userCode = url.searchParams.get("user_code") ?? "";
|
|
106
|
+
if (userCode) setInitialValues({ user_code: userCode });
|
|
107
|
+
}
|
|
108
|
+
const applicationIdFromUrl = url.searchParams.get("applicationId");
|
|
109
|
+
const appId = applicationIdFromUrl?.trim() ? applicationIdFromUrl : applicationId;
|
|
110
|
+
if (flowStartAttempted.current) return;
|
|
111
|
+
if (!appId) {
|
|
112
|
+
flowStartAttempted.current = true;
|
|
113
|
+
handleError(new Error(t("deviceGrant.errors.start")));
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
flowStartAttempted.current = true;
|
|
117
|
+
startFlow(appId);
|
|
118
|
+
}, [
|
|
119
|
+
applicationId,
|
|
120
|
+
handleError,
|
|
121
|
+
startFlow,
|
|
122
|
+
t
|
|
123
|
+
]);
|
|
124
|
+
const submit = async (payload, actionId) => {
|
|
125
|
+
setIsLoading(true);
|
|
126
|
+
setError(null);
|
|
127
|
+
setResult(null);
|
|
128
|
+
try {
|
|
129
|
+
if (!executionId) return;
|
|
130
|
+
applyResponse(await executeEmbeddedDeviceGrantFlow({
|
|
131
|
+
baseUrl,
|
|
132
|
+
payload: {
|
|
133
|
+
action: payload.action ?? actionId,
|
|
134
|
+
challengeToken,
|
|
135
|
+
executionId,
|
|
136
|
+
inputs: {
|
|
137
|
+
...Object.fromEntries(Object.entries(payload.inputs ?? {}).filter(([key]) => !key.startsWith("__consent_opt__"))),
|
|
138
|
+
...!hasUserCodeInput(components) ? { user_code: void 0 } : {}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}));
|
|
142
|
+
} catch (flowError) {
|
|
143
|
+
handleError(flowError instanceof Error ? flowError : new Error(t("deviceGrant.errors.continue")));
|
|
144
|
+
} finally {
|
|
145
|
+
setIsLoading(false);
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
const handleBaseSubmit = (payload, component) => submit(payload, component.id);
|
|
149
|
+
const fieldErrors = useMemo(() => {
|
|
150
|
+
const errors = {};
|
|
151
|
+
(serverFieldErrors ?? []).forEach((fieldError) => {
|
|
152
|
+
if (!(fieldError.identifier in errors)) errors[fieldError.identifier] = fieldError.message;
|
|
153
|
+
});
|
|
154
|
+
return errors;
|
|
155
|
+
}, [serverFieldErrors]);
|
|
156
|
+
if (children) return /* @__PURE__ */ jsx(Fragment$1, { children: children({
|
|
157
|
+
additionalData,
|
|
158
|
+
components,
|
|
159
|
+
error,
|
|
160
|
+
fieldErrors,
|
|
161
|
+
initialValues,
|
|
162
|
+
isLoading,
|
|
163
|
+
meta,
|
|
164
|
+
onSubmit: submit,
|
|
165
|
+
result
|
|
166
|
+
}) });
|
|
167
|
+
return /* @__PURE__ */ jsx(BaseDeviceGrant_default, {
|
|
168
|
+
...baseProps,
|
|
169
|
+
className,
|
|
170
|
+
components,
|
|
171
|
+
additionalData,
|
|
172
|
+
error,
|
|
173
|
+
initialValues,
|
|
174
|
+
isLoading,
|
|
175
|
+
onError: handleError,
|
|
176
|
+
onSubmit: handleBaseSubmit,
|
|
177
|
+
preferences,
|
|
178
|
+
result,
|
|
179
|
+
serverFieldErrors,
|
|
180
|
+
size,
|
|
181
|
+
variant
|
|
182
|
+
});
|
|
183
|
+
};
|
|
184
|
+
var DeviceGrant_default = DeviceGrant;
|
|
185
|
+
|
|
186
|
+
//#endregion
|
|
187
|
+
export { DeviceGrant_default as default };
|
|
188
|
+
//# sourceMappingURL=DeviceGrant.js.map
|