@thunderid/nextjs 0.2.3 → 0.2.4

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.
Files changed (45) hide show
  1. package/dist/ThunderIDNextClient.d.ts.map +1 -1
  2. package/dist/ThunderIDNextClient.js +11 -2
  3. package/dist/ThunderIDNextClient.js.map +1 -1
  4. package/dist/cjs/ThunderIDNextClient.cjs +10 -1
  5. package/dist/cjs/ThunderIDNextClient.cjs.map +1 -1
  6. package/dist/cjs/client/components/presentation/SignIn/SignIn.cjs +57 -6
  7. package/dist/cjs/client/components/presentation/SignIn/SignIn.cjs.map +1 -1
  8. package/dist/cjs/client/components/presentation/SignUp/SignUp.cjs +3 -2
  9. package/dist/cjs/client/components/presentation/SignUp/SignUp.cjs.map +1 -1
  10. package/dist/cjs/client/components/presentation/UserAvatar/UserAvatar.cjs +33 -0
  11. package/dist/cjs/client/components/presentation/UserAvatar/UserAvatar.cjs.map +1 -0
  12. package/dist/cjs/client/contexts/ThunderID/ThunderIDProvider.cjs +68 -14
  13. package/dist/cjs/client/contexts/ThunderID/ThunderIDProvider.cjs.map +1 -1
  14. package/dist/cjs/client/index.cjs +1 -0
  15. package/dist/cjs/index.cjs +2 -0
  16. package/dist/cjs/server/ThunderIDProvider.cjs +13 -0
  17. package/dist/cjs/server/ThunderIDProvider.cjs.map +1 -1
  18. package/dist/cjs/server/actions/signInAction.cjs +13 -21
  19. package/dist/cjs/server/actions/signInAction.cjs.map +1 -1
  20. package/dist/client/components/presentation/SignIn/SignIn.d.ts +3 -2
  21. package/dist/client/components/presentation/SignIn/SignIn.d.ts.map +1 -1
  22. package/dist/client/components/presentation/SignIn/SignIn.js +58 -8
  23. package/dist/client/components/presentation/SignIn/SignIn.js.map +1 -1
  24. package/dist/client/components/presentation/SignUp/SignUp.d.ts.map +1 -1
  25. package/dist/client/components/presentation/SignUp/SignUp.js +3 -2
  26. package/dist/client/components/presentation/SignUp/SignUp.js.map +1 -1
  27. package/dist/client/components/presentation/UserAvatar/UserAvatar.d.ts +33 -0
  28. package/dist/client/components/presentation/UserAvatar/UserAvatar.d.ts.map +1 -0
  29. package/dist/client/components/presentation/UserAvatar/UserAvatar.js +30 -0
  30. package/dist/client/components/presentation/UserAvatar/UserAvatar.js.map +1 -0
  31. package/dist/client/contexts/ThunderID/ThunderIDProvider.d.ts +6 -1
  32. package/dist/client/contexts/ThunderID/ThunderIDProvider.d.ts.map +1 -1
  33. package/dist/client/contexts/ThunderID/ThunderIDProvider.js +69 -15
  34. package/dist/client/contexts/ThunderID/ThunderIDProvider.js.map +1 -1
  35. package/dist/client/index.d.ts +2 -0
  36. package/dist/client/index.d.ts.map +1 -1
  37. package/dist/client/index.js +1 -0
  38. package/dist/index.js +2 -1
  39. package/dist/server/ThunderIDProvider.d.ts.map +1 -1
  40. package/dist/server/ThunderIDProvider.js +14 -1
  41. package/dist/server/ThunderIDProvider.js.map +1 -1
  42. package/dist/server/actions/signInAction.d.ts.map +1 -1
  43. package/dist/server/actions/signInAction.js +13 -21
  44. package/dist/server/actions/signInAction.js.map +1 -1
  45. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"ThunderIDProvider.js","names":["ThunderIDClientProvider: FC<PropsWithChildren<ThunderIDClientProviderProps>>","reRenderCheckRef: RefObject<boolean>","router: AppRouterInstance","searchParams: ReadonlyURLSearchParams","code: string | null","state: string | null","sessionState: string | null","result: {error?: string; redirectUrl?: string; success: boolean}","result: any","contextValue: ThunderIDContextProps","ThunderIDContext"],"sources":["../../../../src/client/contexts/ThunderID/ThunderIDProvider.tsx"],"sourcesContent":["/**\n * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com).\n *\n * WSO2 LLC. licenses this file to you under the Apache License,\n * Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied. See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\n\n'use client';\n\nimport {\n EmbeddedFlowExecuteRequestConfig,\n generateFlattenedUserProfile,\n UpdateMeProfileConfig,\n User,\n UserProfile,\n ThunderIDRuntimeError,\n} from '@thunderid/node';\nimport {\n I18nProvider,\n FlowMetaProvider,\n FlowProvider,\n UserProvider,\n ThemeProvider,\n ThunderIDProviderProps,\n getActiveTheme,\n} from '@thunderid/react';\nimport {ReadonlyURLSearchParams} from 'next/dist/client/components/navigation.react-server';\nimport {AppRouterInstance} from 'next/dist/shared/lib/app-router-context.shared-runtime';\nimport {useRouter, useSearchParams} from 'next/navigation';\nimport {FC, PropsWithChildren, RefObject, useEffect, useMemo, useRef, useState} from 'react';\nimport ThunderIDContext, {ThunderIDContextProps} from './ThunderIDContext';\nimport {RefreshResult} from '../../../server/actions/refreshToken';\nimport logger from '../../../utils/logger';\n\n/**\n * Props interface of {@link ThunderIDClientProvider}\n */\nexport type ThunderIDClientProviderProps = Partial<Omit<ThunderIDProviderProps, 'baseUrl' | 'clientId'>> &\n Pick<ThunderIDProviderProps, 'baseUrl' | 'clientId'> & {\n applicationId: ThunderIDContextProps['applicationId'];\n clearSession: () => Promise<void>;\n handleOAuthCallback: (\n code: string,\n state: string,\n sessionState?: string,\n ) => Promise<{error?: string; redirectUrl?: string; success: boolean}>;\n isSignedIn: boolean;\n organizationHandle: ThunderIDContextProps['organizationHandle'];\n refreshToken: () => Promise<RefreshResult>;\n signIn: ThunderIDContextProps['signIn'];\n signOut: ThunderIDContextProps['signOut'];\n signUp: ThunderIDContextProps['signUp'];\n updateProfile: (\n requestConfig: UpdateMeProfileConfig,\n sessionId?: string,\n ) => Promise<{data: {user: User}; error: string; success: boolean}>;\n user: User | null;\n userProfile: UserProfile;\n };\n\nconst ThunderIDClientProvider: FC<PropsWithChildren<ThunderIDClientProviderProps>> = ({\n baseUrl,\n children,\n signIn,\n clearSession,\n refreshToken,\n signOut,\n signUp,\n handleOAuthCallback,\n preferences,\n isSignedIn,\n signInUrl,\n signUpUrl,\n user: _user,\n userProfile: _userProfile,\n updateProfile,\n applicationId,\n organizationHandle,\n scopes,\n}: PropsWithChildren<ThunderIDClientProviderProps>) => {\n const reRenderCheckRef: RefObject<boolean> = useRef(false);\n const router: AppRouterInstance = useRouter();\n const searchParams: ReadonlyURLSearchParams = useSearchParams();\n const [isLoading, setIsLoading] = useState<boolean>(true);\n const [user, setUser] = useState<User | null>(_user);\n const [userProfile, setUserProfile] = useState<UserProfile>(_userProfile);\n\n useEffect(() => {\n setUserProfile(_userProfile);\n }, [_userProfile]);\n\n useEffect(() => {\n setUser(_user);\n }, [_user]);\n\n // Handle OAuth callback automatically\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 // Don't handle callback if already signed in\n if (isSignedIn) return;\n\n (async (): Promise<void> => {\n try {\n const code: string | null = searchParams.get('code');\n const state: string | null = searchParams.get('state');\n const sessionState: string | null = searchParams.get('session_state');\n const error: string | null = searchParams.get('error');\n\n // Check for OAuth errors first\n if (error) {\n logger.error('[ThunderIDClientProvider] An error was received for the initiated sign-in request.');\n\n return;\n }\n\n // Handle OAuth callback if code and state are present\n if (code && state) {\n setIsLoading(true);\n\n const result: {error?: string; redirectUrl?: string; success: boolean} = await handleOAuthCallback(\n code,\n state,\n sessionState || undefined,\n );\n\n if (result.success) {\n // Redirect to the success URL\n if (result.redirectUrl) {\n router.push(result.redirectUrl);\n } else {\n // Refresh the page to update authentication state\n window.location.reload();\n }\n } else {\n logger.error(\n `[ThunderIDClientProvider] An error occurred while signing in: ${result.error || 'Authentication failed'}`,\n );\n }\n }\n } catch (error) {\n logger.error('[ThunderIDClientProvider] Failed to handle OAuth callback:', error);\n }\n })();\n }, []);\n\n useEffect(() => {\n // Set loading to false when server has resolved authentication state\n setIsLoading(false);\n }, [isSignedIn, user]);\n\n const handleSignIn = async (payload: any, request: EmbeddedFlowExecuteRequestConfig): Promise<any> => {\n if (!signIn) {\n throw new ThunderIDRuntimeError(\n '`signIn` function is not available.',\n 'ThunderIDClientProvider-handleSignIn-RuntimeError-001',\n 'nextjs',\n );\n }\n\n const result: any = await signIn(payload, request);\n\n // Redirect based flow URL is sent as `signInUrl` in the response.\n // Use window.location.href instead of router.push() — the OAuth authorization\n // endpoint is on an external server, and router.push() would send RSC fetch\n // headers that the identity provider doesn't understand, causing a CORS error.\n if (result?.data?.signInUrl) {\n window.location.href = result.data.signInUrl;\n\n return undefined;\n }\n\n // After the Embedded flow is successful, the URL to navigate next is sent as `afterSignInUrl` in the response.\n if (result?.data?.afterSignInUrl) {\n router.push(result.data.afterSignInUrl);\n\n return undefined;\n }\n\n if (result?.error) {\n throw new Error(result.error);\n }\n\n return result?.data ?? result;\n };\n\n const handleSignUp = async (payload: any, request: EmbeddedFlowExecuteRequestConfig): Promise<any> => {\n if (!signUp) {\n throw new ThunderIDRuntimeError(\n '`signUp` function is not available.',\n 'ThunderIDClientProvider-handleSignUp-RuntimeError-001',\n 'nextjs',\n );\n }\n\n const result: any = await signUp(payload, request);\n\n // Redirect based flow URL is sent as `signUpUrl` in the response.\n if (result?.data?.signUpUrl) {\n router.push(result.data.signUpUrl);\n\n return undefined;\n }\n\n // After the Embedded flow is successful, the URL to navigate next is sent as `afterSignUpUrl` in the response.\n if (result?.data?.afterSignUpUrl) {\n router.push(result.data.afterSignUpUrl);\n\n return undefined;\n }\n\n if (result?.error) {\n throw new Error(result.error);\n }\n\n return result?.data ?? result;\n };\n\n const handleSignOut = async (): Promise<any> => {\n logger.debug('[ThunderIDClientProvider][handleSignOut] `handleSignOut` called.');\n\n try {\n const result: any = await signOut();\n\n logger.debug('[ThunderIDClientProvider][handleSignOut] Sign out result:', result);\n\n if (result?.data?.afterSignOutUrl) {\n router.push(result.data.afterSignOutUrl);\n\n return {location: result.data.afterSignOutUrl, redirected: true};\n }\n\n if (result?.error) {\n logger.error(\n '[ThunderIDClientProvider][handleSignOut] Error result was returned during signing the user out with a button click:',\n result.error,\n );\n }\n\n return result?.data ?? result;\n } catch (error) {\n logger.error(\n '[ThunderIDClientProvider][handleSignOut] Error occurred during signing the user out with a button click:',\n error,\n );\n\n return undefined;\n }\n };\n\n const contextValue: ThunderIDContextProps = useMemo(\n () => ({\n applicationId,\n baseUrl,\n clearSession,\n isLoading,\n isSignedIn,\n organizationHandle,\n refreshToken,\n scopes,\n signIn: handleSignIn,\n signInUrl,\n signOut: handleSignOut,\n signUp: handleSignUp,\n signUpUrl,\n user,\n }),\n [baseUrl, user, isSignedIn, isLoading, signInUrl, signUpUrl, applicationId, organizationHandle, scopes],\n );\n\n const handleProfileUpdate = (payload: User): void => {\n setUser(payload);\n setUserProfile((prev: UserProfile) => ({\n ...prev,\n flattenedProfile: generateFlattenedUserProfile(payload, prev?.schemas),\n profile: payload,\n }));\n };\n\n return (\n <ThunderIDContext.Provider value={contextValue}>\n <I18nProvider preferences={preferences?.i18n}>\n <FlowMetaProvider enabled={preferences?.resolveFromMeta !== false}>\n <ThemeProvider theme={preferences?.theme?.overrides} mode={getActiveTheme(preferences?.theme?.mode as any)}>\n <FlowProvider>\n <UserProvider profile={userProfile} onUpdateProfile={handleProfileUpdate} updateProfile={updateProfile}>\n {children}\n </UserProvider>\n </FlowProvider>\n </ThemeProvider>\n </FlowMetaProvider>\n </I18nProvider>\n </ThunderIDContext.Provider>\n );\n};\n\nexport default ThunderIDClientProvider;\n"],"mappings":"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"}
1
+ {"version":3,"file":"ThunderIDProvider.js","names":["ThunderIDClientProvider: FC<PropsWithChildren<ThunderIDClientProviderProps>>","reRenderCheckRef: RefObject<boolean>","router: AppRouterInstance","searchParams: ReadonlyURLSearchParams","code: string | null","state: string | null","sessionState: string | null","result: {error?: string; redirectUrl?: string; success: boolean}","result: any","contextValue: ThunderIDContextProps","reactContextValue: ReactThunderIDContextProps","ThunderIDContext","ReactThunderIDContext"],"sources":["../../../../src/client/contexts/ThunderID/ThunderIDProvider.tsx"],"sourcesContent":["/**\n * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com).\n *\n * WSO2 LLC. licenses this file to you under the Apache License,\n * Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied. See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\n\n'use client';\n\nimport {\n EmbeddedFlowExecuteRequestConfig,\n FlowMetadataResponse,\n generateFlattenedUserProfile,\n UpdateMeProfileConfig,\n User,\n UserProfile,\n ThunderIDRuntimeError,\n} from '@thunderid/node';\nimport {\n I18nProvider,\n FlowMetaProvider,\n FlowProvider,\n UserProvider,\n ThemeProvider,\n ThunderIDContext as ReactThunderIDContext,\n ThunderIDContextProps as ReactThunderIDContextProps,\n ThunderIDProviderProps,\n getActiveTheme,\n} from '@thunderid/react';\nimport {ReadonlyURLSearchParams} from 'next/dist/client/components/navigation.react-server';\nimport {AppRouterInstance} from 'next/dist/shared/lib/app-router-context.shared-runtime';\nimport {useRouter, useSearchParams} from 'next/navigation';\nimport {FC, PropsWithChildren, RefObject, useEffect, useMemo, useRef, useState} from 'react';\nimport ThunderIDContext, {ThunderIDContextProps} from './ThunderIDContext';\nimport {RefreshResult} from '../../../server/actions/refreshToken';\nimport logger from '../../../utils/logger';\n\n/**\n * Props interface of {@link ThunderIDClientProvider}\n */\nexport type ThunderIDClientProviderProps = Partial<Omit<ThunderIDProviderProps, 'baseUrl' | 'clientId'>> &\n Pick<ThunderIDProviderProps, 'baseUrl' | 'clientId'> & {\n applicationId: ThunderIDContextProps['applicationId'];\n clearSession: () => Promise<void>;\n handleOAuthCallback: (\n code: string,\n state: string,\n sessionState?: string,\n ) => Promise<{error?: string; redirectUrl?: string; success: boolean}>;\n /**\n * Flow metadata fetched server-side ahead of time, seeding `FlowMetaProvider` so it can skip\n * its own initial client-side fetch (avoiding a flash of untranslated i18n keys).\n */\n initialMeta?: FlowMetadataResponse | null;\n isSignedIn: boolean;\n organizationHandle: ThunderIDContextProps['organizationHandle'];\n refreshToken: () => Promise<RefreshResult>;\n signIn: ThunderIDContextProps['signIn'];\n signOut: ThunderIDContextProps['signOut'];\n signUp: ThunderIDContextProps['signUp'];\n updateProfile: (\n requestConfig: UpdateMeProfileConfig,\n sessionId?: string,\n ) => Promise<{data: {user: User}; error: string; success: boolean}>;\n user: User | null;\n userProfile: UserProfile;\n };\n\nconst ThunderIDClientProvider: FC<PropsWithChildren<ThunderIDClientProviderProps>> = ({\n baseUrl,\n children,\n signIn,\n clearSession,\n refreshToken,\n signOut,\n signUp,\n handleOAuthCallback,\n preferences,\n isSignedIn,\n signInUrl,\n signUpUrl,\n user: _user,\n userProfile: _userProfile,\n updateProfile,\n applicationId,\n organizationHandle,\n scopes,\n initialMeta = null,\n}: PropsWithChildren<ThunderIDClientProviderProps>) => {\n const reRenderCheckRef: RefObject<boolean> = useRef(false);\n const router: AppRouterInstance = useRouter();\n const searchParams: ReadonlyURLSearchParams = useSearchParams();\n const [isLoading, setIsLoading] = useState<boolean>(true);\n const [user, setUser] = useState<User | null>(_user);\n const [userProfile, setUserProfile] = useState<UserProfile>(_userProfile);\n\n useEffect(() => {\n setUserProfile(_userProfile);\n }, [_userProfile]);\n\n useEffect(() => {\n setUser(_user);\n }, [_user]);\n\n // Handle OAuth callback automatically\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 // Don't handle callback if already signed in\n if (isSignedIn) return;\n\n (async (): Promise<void> => {\n try {\n const code: string | null = searchParams.get('code');\n const state: string | null = searchParams.get('state');\n const sessionState: string | null = searchParams.get('session_state');\n const error: string | null = searchParams.get('error');\n\n // Check for OAuth errors first\n if (error) {\n logger.error('[ThunderIDClientProvider] An error was received for the initiated sign-in request.');\n\n return;\n }\n\n // Handle OAuth callback if code and state are present\n if (code && state) {\n setIsLoading(true);\n\n const result: {error?: string; redirectUrl?: string; success: boolean} = await handleOAuthCallback(\n code,\n state,\n sessionState || undefined,\n );\n\n if (result.success) {\n // Redirect to the success URL\n if (result.redirectUrl) {\n router.push(result.redirectUrl);\n } else {\n // Refresh the page to update authentication state\n window.location.reload();\n }\n } else {\n logger.error(\n `[ThunderIDClientProvider] An error occurred while signing in: ${result.error || 'Authentication failed'}`,\n );\n }\n }\n } catch (error) {\n logger.error('[ThunderIDClientProvider] Failed to handle OAuth callback:', error);\n }\n })();\n }, []);\n\n useEffect(() => {\n // Set loading to false when server has resolved authentication state\n setIsLoading(false);\n }, [isSignedIn, user]);\n\n const handleSignIn = async (payload: any, request: EmbeddedFlowExecuteRequestConfig): Promise<any> => {\n if (!signIn) {\n throw new ThunderIDRuntimeError(\n '`signIn` function is not available.',\n 'ThunderIDClientProvider-handleSignIn-RuntimeError-001',\n 'nextjs',\n );\n }\n\n const result: any = await signIn(payload, request);\n\n // Redirect based flow URL is sent as `signInUrl` in the response.\n // Use window.location.href instead of router.push() — the OAuth authorization\n // endpoint is on an external server, and router.push() would send RSC fetch\n // headers that the identity provider doesn't understand, causing a CORS error.\n if (result?.data?.signInUrl) {\n window.location.href = result.data.signInUrl;\n\n return undefined;\n }\n\n // After the Embedded flow is successful, the URL to navigate next is sent as `afterSignInUrl` in the response.\n if (result?.data?.afterSignInUrl) {\n router.push(result.data.afterSignInUrl);\n\n return undefined;\n }\n\n if (result?.error) {\n throw new Error(result.error);\n }\n\n return result?.data ?? result;\n };\n\n const handleSignUp = async (payload: any, request: EmbeddedFlowExecuteRequestConfig): Promise<any> => {\n if (!signUp) {\n throw new ThunderIDRuntimeError(\n '`signUp` function is not available.',\n 'ThunderIDClientProvider-handleSignUp-RuntimeError-001',\n 'nextjs',\n );\n }\n\n const result: any = await signUp(payload, request);\n\n // Redirect based flow URL is sent as `signUpUrl` in the response.\n if (result?.data?.signUpUrl) {\n router.push(result.data.signUpUrl);\n\n return undefined;\n }\n\n // After the Embedded flow is successful, the URL to navigate next is sent as `afterSignUpUrl` in the response.\n if (result?.data?.afterSignUpUrl) {\n router.push(result.data.afterSignUpUrl);\n\n return undefined;\n }\n\n if (result?.error) {\n throw new Error(result.error);\n }\n\n return result?.data ?? result;\n };\n\n const handleSignOut = async (): Promise<any> => {\n logger.debug('[ThunderIDClientProvider][handleSignOut] `handleSignOut` called.');\n\n try {\n const result: any = await signOut();\n\n logger.debug('[ThunderIDClientProvider][handleSignOut] Sign out result:', result);\n\n if (result?.data?.afterSignOutUrl) {\n router.push(result.data.afterSignOutUrl);\n\n return {location: result.data.afterSignOutUrl, redirected: true};\n }\n\n if (result?.error) {\n logger.error(\n '[ThunderIDClientProvider][handleSignOut] Error result was returned during signing the user out with a button click:',\n result.error,\n );\n }\n\n return result?.data ?? result;\n } catch (error) {\n logger.error(\n '[ThunderIDClientProvider][handleSignOut] Error occurred during signing the user out with a button click:',\n error,\n );\n\n return undefined;\n }\n };\n\n const contextValue: ThunderIDContextProps = useMemo(\n () => ({\n applicationId,\n baseUrl,\n clearSession,\n isLoading,\n isSignedIn,\n organizationHandle,\n refreshToken,\n scopes,\n signIn: handleSignIn,\n signInUrl,\n signOut: handleSignOut,\n signUp: handleSignUp,\n signUpUrl,\n user,\n }),\n [baseUrl, user, isSignedIn, isLoading, signInUrl, signUpUrl, applicationId, organizationHandle, scopes],\n );\n\n const handleProfileUpdate = (payload: User): void => {\n setUser(payload);\n setUserProfile((prev: UserProfile) => ({\n ...prev,\n flattenedProfile: generateFlattenedUserProfile(payload, prev?.schemas),\n profile: payload,\n }));\n };\n\n // Bridge into @thunderid/react's own ThunderIDContext. Internal react components rendered by\n // BaseSignIn/BaseSignUp — most notably FlowMetaProvider, which fetches `/flow/meta` and injects\n // its i18n bundle — call react's `useThunderID()` directly. Without this bridge they'd only see\n // react's context default (applicationId/baseUrl undefined, isInitialized false), so the meta\n // fetch would never fire and flow labels would render as untranslated i18n keys. Fields with no\n // nextjs equivalent (token/http helpers meant for direct browser API calls) are stubbed out,\n // since nextjs routes those operations through server actions instead.\n const unsupported = (name: string): (() => Promise<never>) => {\n return () =>\n Promise.reject(\n new ThunderIDRuntimeError(\n `\\`${name}\\` is not supported in @thunderid/nextjs.`,\n `ThunderIDClientProvider-${name}-NotSupportedError-001`,\n 'nextjs',\n ),\n );\n };\n\n const reactContextValue: ReactThunderIDContextProps = useMemo(\n () => ({\n afterSignInUrl: undefined,\n applicationId,\n baseUrl,\n clearSession,\n clientId: undefined,\n discovery: {wellKnown: null},\n exchangeToken: unsupported('exchangeToken'),\n getAccessToken: unsupported('getAccessToken'),\n getDecodedIdToken: unsupported('getDecodedIdToken'),\n getIdToken: unsupported('getIdToken'),\n getStorageManager: () => Promise.resolve(null),\n http: {\n request: unsupported('http.request'),\n requestAll: unsupported('http.requestAll'),\n },\n instanceId: 0,\n isInitialized: !isLoading,\n isLoading,\n isMetaLoading: false,\n isSignedIn,\n meta: initialMeta ?? null,\n organizationHandle,\n reInitialize: unsupported('reInitialize'),\n recover: unsupported('recover'),\n resolveFlowTemplateLiterals: (text: string | undefined): string => text ?? '',\n scopes,\n signIn: handleSignIn,\n signInSilently: unsupported('signInSilently'),\n signInUrl,\n signOut: handleSignOut,\n signUp: handleSignUp,\n signUpUrl,\n user,\n }),\n [\n applicationId,\n baseUrl,\n clearSession,\n isLoading,\n isSignedIn,\n organizationHandle,\n scopes,\n signInUrl,\n signUpUrl,\n user,\n initialMeta,\n ],\n );\n\n return (\n <ThunderIDContext.Provider value={contextValue}>\n <ReactThunderIDContext.Provider value={reactContextValue}>\n <I18nProvider preferences={preferences?.i18n}>\n <FlowMetaProvider enabled={preferences?.resolveFromMeta !== false} initialMeta={initialMeta}>\n <ThemeProvider theme={preferences?.theme?.overrides} mode={getActiveTheme(preferences?.theme?.mode as any)}>\n <FlowProvider>\n <UserProvider profile={userProfile} onUpdateProfile={handleProfileUpdate} updateProfile={updateProfile}>\n {children}\n </UserProvider>\n </FlowProvider>\n </ThemeProvider>\n </FlowMetaProvider>\n </I18nProvider>\n </ReactThunderIDContext.Provider>\n </ThunderIDContext.Provider>\n );\n};\n\nexport default ThunderIDClientProvider;\n"],"mappings":"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"}
@@ -34,6 +34,8 @@ export { default as SignUp } from './components/presentation/SignUp/SignUp';
34
34
  export type { SignUpProps } from './components/presentation/SignUp/SignUp';
35
35
  export { default as UserDropdown } from './components/presentation/UserDropdown/UserDropdown';
36
36
  export type { UserDropdownProps } from './components/presentation/UserDropdown/UserDropdown';
37
+ export { default as UserAvatar } from './components/presentation/UserAvatar/UserAvatar';
38
+ export type { UserAvatarProps } from './components/presentation/UserAvatar/UserAvatar';
37
39
  export { default as UserProfile } from './components/presentation/UserProfile/UserProfile';
38
40
  export type { UserProfileProps } from './components/presentation/UserProfile/UserProfile';
39
41
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAC,OAAO,IAAI,YAAY,EAAC,MAAM,mCAAmC,CAAC;AAE1E,OAAO,EAAC,OAAO,IAAI,QAAQ,EAAC,MAAM,wCAAwC,CAAC;AAC3E,YAAY,EAAC,aAAa,EAAC,MAAM,wCAAwC,CAAC;AAE1E,OAAO,EAAC,OAAO,IAAI,SAAS,EAAC,MAAM,0CAA0C,CAAC;AAC9E,YAAY,EAAC,cAAc,EAAC,MAAM,0CAA0C,CAAC;AAE7E,OAAO,EAAC,OAAO,IAAI,YAAY,EAAC,MAAM,gDAAgD,CAAC;AACvF,YAAY,EAAC,iBAAiB,EAAC,MAAM,gDAAgD,CAAC;AAEtF,OAAO,EAAC,OAAO,IAAI,YAAY,EAAC,MAAM,gDAAgD,CAAC;AACvF,YAAY,EAAC,iBAAiB,EAAC,MAAM,gDAAgD,CAAC;AAEtF,OAAO,EAAC,OAAO,IAAI,MAAM,EAAC,MAAM,yCAAyC,CAAC;AAC1E,YAAY,EAAC,WAAW,EAAC,MAAM,yCAAyC,CAAC;AAEzE,OAAO,EAAC,OAAO,IAAI,aAAa,EAAC,MAAM,kDAAkD,CAAC;AAC1F,YAAY,EAAC,kBAAkB,EAAC,MAAM,kDAAkD,CAAC;AAEzF,OAAO,EAAC,OAAO,IAAI,IAAI,EAAC,MAAM,qCAAqC,CAAC;AACpE,YAAY,EAAC,SAAS,EAAC,MAAM,qCAAqC,CAAC;AAEnE,OAAO,EAAC,OAAO,IAAI,MAAM,EAAC,MAAM,yCAAyC,CAAC;AAC1E,YAAY,EAAC,WAAW,EAAC,MAAM,yCAAyC,CAAC;AAEzE,OAAO,EAAC,OAAO,IAAI,YAAY,EAAC,MAAM,qDAAqD,CAAC;AAC5F,YAAY,EAAC,iBAAiB,EAAC,MAAM,qDAAqD,CAAC;AAE3F,OAAO,EAAC,OAAO,IAAI,WAAW,EAAC,MAAM,mDAAmD,CAAC;AACzF,YAAY,EAAC,gBAAgB,EAAC,MAAM,mDAAmD,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAC,OAAO,IAAI,YAAY,EAAC,MAAM,mCAAmC,CAAC;AAE1E,OAAO,EAAC,OAAO,IAAI,QAAQ,EAAC,MAAM,wCAAwC,CAAC;AAC3E,YAAY,EAAC,aAAa,EAAC,MAAM,wCAAwC,CAAC;AAE1E,OAAO,EAAC,OAAO,IAAI,SAAS,EAAC,MAAM,0CAA0C,CAAC;AAC9E,YAAY,EAAC,cAAc,EAAC,MAAM,0CAA0C,CAAC;AAE7E,OAAO,EAAC,OAAO,IAAI,YAAY,EAAC,MAAM,gDAAgD,CAAC;AACvF,YAAY,EAAC,iBAAiB,EAAC,MAAM,gDAAgD,CAAC;AAEtF,OAAO,EAAC,OAAO,IAAI,YAAY,EAAC,MAAM,gDAAgD,CAAC;AACvF,YAAY,EAAC,iBAAiB,EAAC,MAAM,gDAAgD,CAAC;AAEtF,OAAO,EAAC,OAAO,IAAI,MAAM,EAAC,MAAM,yCAAyC,CAAC;AAC1E,YAAY,EAAC,WAAW,EAAC,MAAM,yCAAyC,CAAC;AAEzE,OAAO,EAAC,OAAO,IAAI,aAAa,EAAC,MAAM,kDAAkD,CAAC;AAC1F,YAAY,EAAC,kBAAkB,EAAC,MAAM,kDAAkD,CAAC;AAEzF,OAAO,EAAC,OAAO,IAAI,IAAI,EAAC,MAAM,qCAAqC,CAAC;AACpE,YAAY,EAAC,SAAS,EAAC,MAAM,qCAAqC,CAAC;AAEnE,OAAO,EAAC,OAAO,IAAI,MAAM,EAAC,MAAM,yCAAyC,CAAC;AAC1E,YAAY,EAAC,WAAW,EAAC,MAAM,yCAAyC,CAAC;AAEzE,OAAO,EAAC,OAAO,IAAI,YAAY,EAAC,MAAM,qDAAqD,CAAC;AAC5F,YAAY,EAAC,iBAAiB,EAAC,MAAM,qDAAqD,CAAC;AAE3F,OAAO,EAAC,OAAO,IAAI,UAAU,EAAC,MAAM,iDAAiD,CAAC;AACtF,YAAY,EAAC,eAAe,EAAC,MAAM,iDAAiD,CAAC;AAErF,OAAO,EAAC,OAAO,IAAI,WAAW,EAAC,MAAM,mDAAmD,CAAC;AACzF,YAAY,EAAC,gBAAgB,EAAC,MAAM,mDAAmD,CAAC"}
@@ -9,5 +9,6 @@ import User_default from "./components/presentation/User/User.js";
9
9
  import SignUp_default from "./components/presentation/SignUp/SignUp.js";
10
10
  import UserProfile_default from "./components/presentation/UserProfile/UserProfile.js";
11
11
  import UserDropdown_default from "./components/presentation/UserDropdown/UserDropdown.js";
12
+ import UserAvatar_default from "./components/presentation/UserAvatar/UserAvatar.js";
12
13
 
13
14
  export { };
package/dist/index.js CHANGED
@@ -15,6 +15,7 @@ import User_default from "./client/components/presentation/User/User.js";
15
15
  import SignUp_default from "./client/components/presentation/SignUp/SignUp.js";
16
16
  import UserProfile_default from "./client/components/presentation/UserProfile/UserProfile.js";
17
17
  import UserDropdown_default from "./client/components/presentation/UserDropdown/UserDropdown.js";
18
+ import UserAvatar_default from "./client/components/presentation/UserAvatar/UserAvatar.js";
18
19
  import "./client/index.js";
19
20
 
20
- export { SignIn_default as SignIn, SignInButton_default as SignInButton, SignOutButton_default as SignOutButton, SignUp_default as SignUp, SignUpButton_default as SignUpButton, SignedIn_default as SignedIn, SignedOut_default as SignedOut, ThunderIDNextClient_default as ThunderIDNext, ThunderIDProvider_default as ThunderIDProvider, User_default as User, UserDropdown_default as UserDropdown, UserProfile_default as UserProfile, createRouteMatcher_default as createRouteMatcher, thunderIDProxy_default as thunderIDProxy, thunderid_default as thunderid, useThunderID_default as useThunderID };
21
+ export { SignIn_default as SignIn, SignInButton_default as SignInButton, SignOutButton_default as SignOutButton, SignUp_default as SignUp, SignUpButton_default as SignUpButton, SignedIn_default as SignedIn, SignedOut_default as SignedOut, ThunderIDNextClient_default as ThunderIDNext, ThunderIDProvider_default as ThunderIDProvider, User_default as User, UserAvatar_default as UserAvatar, UserDropdown_default as UserDropdown, UserProfile_default as UserProfile, createRouteMatcher_default as createRouteMatcher, thunderIDProxy_default as thunderIDProxy, thunderid_default as thunderid, useThunderID_default as useThunderID };
@@ -1 +1 @@
1
- {"version":3,"file":"ThunderIDProvider.d.ts","sourceRoot":"","sources":["../../src/server/ThunderIDProvider.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAKH,OAAO,EAAC,sBAAsB,EAAC,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAC,EAAE,EAAE,iBAAiB,EAAe,MAAM,OAAO,CAAC;AAmB1D;;GAEG;AACH,MAAM,MAAM,4BAA4B,GAAG,OAAO,CAAC,sBAAsB,CAAC,GAAG;IAC3E,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;;;;;;;;;OAYG;IACH,uBAAuB,CAAC,EAAE,MAAM,CAAC;CAClC,CAAC;AAEF;;;;;;;;;;;;;;;GAeG;AACH,QAAA,MAAM,uBAAuB,EAAE,EAAE,CAAC,iBAAiB,CAAC,4BAA4B,CAAC,CA0GhF,CAAC;AAEF,eAAe,uBAAuB,CAAC"}
1
+ {"version":3,"file":"ThunderIDProvider.d.ts","sourceRoot":"","sources":["../../src/server/ThunderIDProvider.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAaH,OAAO,EAAC,sBAAsB,EAAC,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAC,EAAE,EAAE,iBAAiB,EAAe,MAAM,OAAO,CAAC;AAmB1D;;GAEG;AACH,MAAM,MAAM,4BAA4B,GAAG,OAAO,CAAC,sBAAsB,CAAC,GAAG;IAC3E,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;;;;;;;;;OAYG;IACH,uBAAuB,CAAC,EAAE,MAAM,CAAC;CAClC,CAAC;AAEF;;;;;;;;;;;;;;;GAeG;AACH,QAAA,MAAM,uBAAuB,EAAE,EAAE,CAAC,iBAAiB,CAAC,4BAA4B,CAAC,CAwHhF,CAAC;AAEF,eAAe,uBAAuB,CAAC"}
@@ -16,7 +16,7 @@ import signOutAction_default from "./actions/signOutAction.js";
16
16
  import signUpAction_default from "./actions/signUpAction.js";
17
17
  import updateUserProfileAction_default from "./actions/updateUserProfileAction.js";
18
18
  import ThunderIDProvider_default from "../client/contexts/ThunderID/ThunderIDProvider.js";
19
- import { ThunderIDRuntimeError } from "@thunderid/node";
19
+ import { FlowMetaType, ThunderIDRuntimeError, getFlowMeta } from "@thunderid/node";
20
20
  import { Fragment, jsx } from "react/jsx-runtime";
21
21
 
22
22
  //#region src/server/ThunderIDProvider.tsx
@@ -48,6 +48,18 @@ const ThunderIDServerProvider = async ({ children, afterSignInUrl, afterSignOutU
48
48
  throw new ThunderIDRuntimeError(`Failed to initialize ThunderID client: ${error?.toString()}`, "next-ConfigurationError-001", "next", "An error occurred while initializing the ThunderID client. Please check your configuration.");
49
49
  }
50
50
  if (!thunderIDClient.isInitialized) return /* @__PURE__ */ jsx(Fragment, {});
51
+ let flowMeta = null;
52
+ try {
53
+ flowMeta = await getFlowMeta({
54
+ baseUrl: config?.baseUrl,
55
+ ...config?.applicationId ? {
56
+ id: config.applicationId,
57
+ type: FlowMetaType.App
58
+ } : {}
59
+ });
60
+ } catch (error) {
61
+ logger_default.warn("[ThunderIDServerProvider] Failed to fetch flow metadata:", error?.toString());
62
+ }
51
63
  const sessionPayload = await getSessionPayload_default();
52
64
  const sessionId = sessionPayload?.sessionId || await getSessionId_default() || "";
53
65
  const signedIn = await isSignedIn_default(sessionId);
@@ -87,6 +99,7 @@ const ThunderIDServerProvider = async ({ children, afterSignInUrl, afterSignOutU
87
99
  organizationHandle: config?.organizationHandle,
88
100
  applicationId: config?.applicationId,
89
101
  baseUrl: config?.baseUrl,
102
+ initialMeta: flowMeta,
90
103
  signIn: signInAction_default,
91
104
  clearSession: clearSession_default,
92
105
  refreshToken: refreshToken_default,
@@ -1 +1 @@
1
- {"version":3,"file":"ThunderIDProvider.js","names":["ThunderIDServerProvider: FC<PropsWithChildren<ThunderIDServerProviderProps>>","getClient","config: Partial<ThunderIDNextConfig>","sessionPayload: SessionTokenPayload | undefined","getSessionPayload","sessionId: string","getSessionId","signedIn: boolean","isSignedIn","user: User","userProfile: UserProfile","updatedBaseUrl: string | undefined","userResponse: {\n data: {user: User | null};\n error: string | null;\n success: boolean;\n }","getUserAction","userProfileResponse: {\n data: {userProfile: UserProfile};\n error: string | null;\n success: boolean;\n }","getUserProfileAction","ThunderIDClientProvider","signInAction","clearSession","refreshToken","signOutAction","signUpAction","handleOAuthCallbackAction","updateUserProfileAction"],"sources":["../../src/server/ThunderIDProvider.tsx"],"sourcesContent":["/**\n * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com).\n *\n * WSO2 LLC. licenses this file to you under the Apache License,\n * Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied. See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\n\n'use server';\n\nimport {ThunderIDRuntimeError, IdToken, User, UserProfile} from '@thunderid/node';\nimport {ThunderIDProviderProps} from '@thunderid/react';\nimport {FC, PropsWithChildren, ReactElement} from 'react';\nimport clearSession from './actions/clearSession';\nimport getSessionId from './actions/getSessionId';\nimport getSessionPayload from './actions/getSessionPayload';\nimport getUserAction from './actions/getUserAction';\nimport getUserProfileAction from './actions/getUserProfileAction';\nimport handleOAuthCallbackAction from './actions/handleOAuthCallbackAction';\nimport isSignedIn from './actions/isSignedIn';\nimport refreshToken from './actions/refreshToken';\nimport signInAction from './actions/signInAction';\nimport signOutAction from './actions/signOutAction';\nimport signUpAction from './actions/signUpAction';\nimport updateUserProfileAction from './actions/updateUserProfileAction';\nimport getClient from './getClient';\nimport ThunderIDClientProvider from '../client/contexts/ThunderID/ThunderIDProvider.js';\nimport {ThunderIDNextConfig} from '../models/config';\nimport logger from '../utils/logger';\nimport {SessionTokenPayload} from '../utils/SessionManager';\n\n/**\n * Props interface of {@link ThunderIDServerProvider}\n */\nexport type ThunderIDServerProviderProps = Partial<ThunderIDProviderProps> & {\n clientSecret?: string;\n /**\n * Session cookie lifetime in seconds. Determines how long the session cookie\n * remains valid in the browser after sign-in.\n *\n * Resolution order (first defined value wins):\n * 1. This prop — set here when mounting the provider.\n * 2. `THUNDERID_SESSION_COOKIE_EXPIRY_TIME` environment variable.\n * 3. Built-in default of 86400 seconds (24 hours).\n *\n * @example\n * // 8-hour session cookie\n * <ThunderIDServerProvider sessionCookieExpiryTime={28800} ... />\n */\n sessionCookieExpiryTime?: number;\n};\n\n/**\n * Server-side provider component for ThunderID authentication.\n * Wraps the client-side provider and handles server-side authentication logic.\n * Uses the singleton ThunderIDNextClient instance for consistent authentication state.\n *\n * @param props - Props injected into the component.\n *\n * @example\n * ```tsx\n * <ThunderIDServerProvider config={thunderidConfig}>\n * <YourApp />\n * </ThunderIDServerProvider>\n * ```\n *\n * @returns ThunderIDServerProvider component.\n */\nconst ThunderIDServerProvider: FC<PropsWithChildren<ThunderIDServerProviderProps>> = async ({\n children,\n afterSignInUrl,\n afterSignOutUrl,\n ..._config\n}: PropsWithChildren<ThunderIDServerProviderProps>): Promise<ReactElement> => {\n const thunderIDClient = getClient();\n let config: Partial<ThunderIDNextConfig> = {};\n\n try {\n await thunderIDClient.initialize(_config as ThunderIDNextConfig);\n\n logger.debug('[ThunderIDServerProvider] ThunderID client initialized successfully.');\n\n config = await thunderIDClient.getConfiguration();\n } catch (error) {\n logger.error('[ThunderIDServerProvider] Failed to initialize ThunderID client:', error?.toString());\n\n throw new ThunderIDRuntimeError(\n `Failed to initialize ThunderID client: ${error?.toString()}`,\n 'next-ConfigurationError-001',\n 'next',\n 'An error occurred while initializing the ThunderID client. Please check your configuration.',\n );\n }\n\n if (!thunderIDClient.isInitialized) {\n return <></>;\n }\n\n // Try to get session information from JWT first, then fall back to legacy\n const sessionPayload: SessionTokenPayload | undefined = await getSessionPayload();\n const sessionId: string = sessionPayload?.sessionId || (await getSessionId()) || '';\n const signedIn: boolean = await isSignedIn(sessionId);\n\n let user: User = {};\n let userProfile: UserProfile = {\n flattenedProfile: {},\n profile: {},\n schemas: [],\n };\n if (signedIn) {\n let updatedBaseUrl: string | undefined = config?.baseUrl;\n\n if (sessionPayload?.organizationId) {\n updatedBaseUrl = `${config?.baseUrl}/o`;\n config = {...config, baseUrl: updatedBaseUrl};\n } else if (sessionId) {\n try {\n const idToken: IdToken = await thunderIDClient.getDecodedIdToken(sessionId);\n if (idToken?.['user_org']) {\n updatedBaseUrl = `${config?.baseUrl}/o`;\n config = {...config, baseUrl: updatedBaseUrl};\n }\n } catch {\n // Continue without organization info\n }\n }\n\n // Check if user profile fetching is enabled (default: true)\n const shouldFetchUserProfile: boolean = config?.preferences?.user?.fetchUserProfile !== false;\n\n if (shouldFetchUserProfile) {\n try {\n const userResponse: {\n data: {user: User | null};\n error: string | null;\n success: boolean;\n } = await getUserAction(sessionId);\n const userProfileResponse: {\n data: {userProfile: UserProfile};\n error: string | null;\n success: boolean;\n } = await getUserProfileAction(sessionId);\n\n user = userResponse.data?.user || {};\n userProfile = userProfileResponse.data?.userProfile ?? userProfile;\n } catch (error) {\n logger.warn('[ThunderIDServerProvider] Failed to fetch user profile from SCIM2:', error?.toString());\n }\n }\n }\n\n return (\n <ThunderIDClientProvider\n organizationHandle={config?.organizationHandle}\n applicationId={config?.applicationId}\n baseUrl={config?.baseUrl}\n signIn={signInAction}\n clearSession={clearSession}\n refreshToken={refreshToken}\n signOut={signOutAction}\n signUp={signUpAction}\n handleOAuthCallback={handleOAuthCallbackAction}\n signInUrl={config?.signInUrl}\n signUpUrl={config?.signUpUrl}\n preferences={config?.preferences}\n clientId={config?.clientId}\n user={user}\n userProfile={userProfile}\n updateProfile={updateUserProfileAction}\n isSignedIn={signedIn}\n >\n {children}\n </ThunderIDClientProvider>\n );\n};\n\nexport default ThunderIDServerProvider;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8EA,MAAMA,0BAA+E,OAAO,EAC1F,UACA,gBACA,gBACA,GAAG,cACyE;CAC5E,MAAM,kBAAkBC,mBAAW;CACnC,IAAIC,SAAuC,EAAE;AAE7C,KAAI;AACF,QAAM,gBAAgB,WAAW,QAA+B;AAEhE,iBAAO,MAAM,uEAAuE;AAEpF,WAAS,MAAM,gBAAgB,kBAAkB;UAC1C,OAAO;AACd,iBAAO,MAAM,oEAAoE,OAAO,UAAU,CAAC;AAEnG,QAAM,IAAI,sBACR,0CAA0C,OAAO,UAAU,IAC3D,+BACA,QACA,8FACD;;AAGH,KAAI,CAAC,gBAAgB,cACnB,QAAO,iCAAK;CAId,MAAMC,iBAAkD,MAAMC,2BAAmB;CACjF,MAAMC,YAAoB,gBAAgB,aAAc,MAAMC,sBAAc,IAAK;CACjF,MAAMC,WAAoB,MAAMC,mBAAW,UAAU;CAErD,IAAIC,OAAa,EAAE;CACnB,IAAIC,cAA2B;EAC7B,kBAAkB,EAAE;EACpB,SAAS,EAAE;EACX,SAAS,EAAE;EACZ;AACD,KAAI,UAAU;EACZ,IAAIC,iBAAqC,QAAQ;AAEjD,MAAI,gBAAgB,gBAAgB;AAClC,oBAAiB,GAAG,QAAQ,QAAQ;AACpC,YAAS;IAAC,GAAG;IAAQ,SAAS;IAAe;aACpC,UACT,KAAI;AAEF,QADyB,MAAM,gBAAgB,kBAAkB,UAAU,IAC7D,aAAa;AACzB,qBAAiB,GAAG,QAAQ,QAAQ;AACpC,aAAS;KAAC,GAAG;KAAQ,SAAS;KAAe;;UAEzC;AAQV,MAFwC,QAAQ,aAAa,MAAM,qBAAqB,MAGtF,KAAI;GACF,MAAMC,eAIF,MAAMC,sBAAc,UAAU;GAClC,MAAMC,sBAIF,MAAMC,6BAAqB,UAAU;AAEzC,UAAO,aAAa,MAAM,QAAQ,EAAE;AACpC,iBAAc,oBAAoB,MAAM,eAAe;WAChD,OAAO;AACd,kBAAO,KAAK,sEAAsE,OAAO,UAAU,CAAC;;;AAK1G,QACE,oBAACC;EACC,oBAAoB,QAAQ;EAC5B,eAAe,QAAQ;EACvB,SAAS,QAAQ;EACjB,QAAQC;EACR,cAAcC;EACd,cAAcC;EACd,SAASC;EACT,QAAQC;EACR,qBAAqBC;EACrB,WAAW,QAAQ;EACnB,WAAW,QAAQ;EACnB,aAAa,QAAQ;EACrB,UAAU,QAAQ;EACZ;EACO;EACb,eAAeC;EACf,YAAY;EAEX;GACuB;;AAI9B,kCAAe"}
1
+ {"version":3,"file":"ThunderIDProvider.js","names":["ThunderIDServerProvider: FC<PropsWithChildren<ThunderIDServerProviderProps>>","getClient","config: Partial<ThunderIDNextConfig>","flowMeta: FlowMetadataResponse | null","sessionPayload: SessionTokenPayload | undefined","getSessionPayload","sessionId: string","getSessionId","signedIn: boolean","isSignedIn","user: User","userProfile: UserProfile","updatedBaseUrl: string | undefined","userResponse: {\n data: {user: User | null};\n error: string | null;\n success: boolean;\n }","getUserAction","userProfileResponse: {\n data: {userProfile: UserProfile};\n error: string | null;\n success: boolean;\n }","getUserProfileAction","ThunderIDClientProvider","signInAction","clearSession","refreshToken","signOutAction","signUpAction","handleOAuthCallbackAction","updateUserProfileAction"],"sources":["../../src/server/ThunderIDProvider.tsx"],"sourcesContent":["/**\n * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com).\n *\n * WSO2 LLC. licenses this file to you under the Apache License,\n * Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied. See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\n\n'use server';\n\nimport {\n ThunderIDRuntimeError,\n FlowMetadataResponse,\n FlowMetaType,\n IdToken,\n User,\n UserProfile,\n getFlowMeta,\n} from '@thunderid/node';\nimport {ThunderIDProviderProps} from '@thunderid/react';\nimport {FC, PropsWithChildren, ReactElement} from 'react';\nimport clearSession from './actions/clearSession';\nimport getSessionId from './actions/getSessionId';\nimport getSessionPayload from './actions/getSessionPayload';\nimport getUserAction from './actions/getUserAction';\nimport getUserProfileAction from './actions/getUserProfileAction';\nimport handleOAuthCallbackAction from './actions/handleOAuthCallbackAction';\nimport isSignedIn from './actions/isSignedIn';\nimport refreshToken from './actions/refreshToken';\nimport signInAction from './actions/signInAction';\nimport signOutAction from './actions/signOutAction';\nimport signUpAction from './actions/signUpAction';\nimport updateUserProfileAction from './actions/updateUserProfileAction';\nimport getClient from './getClient';\nimport ThunderIDClientProvider from '../client/contexts/ThunderID/ThunderIDProvider.js';\nimport {ThunderIDNextConfig} from '../models/config';\nimport logger from '../utils/logger';\nimport {SessionTokenPayload} from '../utils/SessionManager';\n\n/**\n * Props interface of {@link ThunderIDServerProvider}\n */\nexport type ThunderIDServerProviderProps = Partial<ThunderIDProviderProps> & {\n clientSecret?: string;\n /**\n * Session cookie lifetime in seconds. Determines how long the session cookie\n * remains valid in the browser after sign-in.\n *\n * Resolution order (first defined value wins):\n * 1. This prop — set here when mounting the provider.\n * 2. `THUNDERID_SESSION_COOKIE_EXPIRY_TIME` environment variable.\n * 3. Built-in default of 86400 seconds (24 hours).\n *\n * @example\n * // 8-hour session cookie\n * <ThunderIDServerProvider sessionCookieExpiryTime={28800} ... />\n */\n sessionCookieExpiryTime?: number;\n};\n\n/**\n * Server-side provider component for ThunderID authentication.\n * Wraps the client-side provider and handles server-side authentication logic.\n * Uses the singleton ThunderIDNextClient instance for consistent authentication state.\n *\n * @param props - Props injected into the component.\n *\n * @example\n * ```tsx\n * <ThunderIDServerProvider config={thunderidConfig}>\n * <YourApp />\n * </ThunderIDServerProvider>\n * ```\n *\n * @returns ThunderIDServerProvider component.\n */\nconst ThunderIDServerProvider: FC<PropsWithChildren<ThunderIDServerProviderProps>> = async ({\n children,\n afterSignInUrl,\n afterSignOutUrl,\n ..._config\n}: PropsWithChildren<ThunderIDServerProviderProps>): Promise<ReactElement> => {\n const thunderIDClient = getClient();\n let config: Partial<ThunderIDNextConfig> = {};\n\n try {\n await thunderIDClient.initialize(_config as ThunderIDNextConfig);\n\n logger.debug('[ThunderIDServerProvider] ThunderID client initialized successfully.');\n\n config = await thunderIDClient.getConfiguration();\n } catch (error) {\n logger.error('[ThunderIDServerProvider] Failed to initialize ThunderID client:', error?.toString());\n\n throw new ThunderIDRuntimeError(\n `Failed to initialize ThunderID client: ${error?.toString()}`,\n 'next-ConfigurationError-001',\n 'next',\n 'An error occurred while initializing the ThunderID client. Please check your configuration.',\n );\n }\n\n if (!thunderIDClient.isInitialized) {\n return <></>;\n }\n\n // Fetch flow metadata (design config + i18n bundle) server-side so `FlowMetaProvider` can seed\n // its state and skip a redundant client-side fetch — avoiding a flash of untranslated i18n keys\n // (e.g. raw `signin.forms.credentials.title`) while embedded flow components first render.\n let flowMeta: FlowMetadataResponse | null = null;\n try {\n flowMeta = await getFlowMeta({\n baseUrl: config?.baseUrl,\n ...(config?.applicationId ? {id: config.applicationId, type: FlowMetaType.App} : {}),\n });\n } catch (error) {\n logger.warn('[ThunderIDServerProvider] Failed to fetch flow metadata:', error?.toString());\n }\n\n // Try to get session information from JWT first, then fall back to legacy\n const sessionPayload: SessionTokenPayload | undefined = await getSessionPayload();\n const sessionId: string = sessionPayload?.sessionId || (await getSessionId()) || '';\n const signedIn: boolean = await isSignedIn(sessionId);\n\n let user: User = {};\n let userProfile: UserProfile = {\n flattenedProfile: {},\n profile: {},\n schemas: [],\n };\n if (signedIn) {\n let updatedBaseUrl: string | undefined = config?.baseUrl;\n\n if (sessionPayload?.organizationId) {\n updatedBaseUrl = `${config?.baseUrl}/o`;\n config = {...config, baseUrl: updatedBaseUrl};\n } else if (sessionId) {\n try {\n const idToken: IdToken = await thunderIDClient.getDecodedIdToken(sessionId);\n if (idToken?.['user_org']) {\n updatedBaseUrl = `${config?.baseUrl}/o`;\n config = {...config, baseUrl: updatedBaseUrl};\n }\n } catch {\n // Continue without organization info\n }\n }\n\n // Check if user profile fetching is enabled (default: true)\n const shouldFetchUserProfile: boolean = config?.preferences?.user?.fetchUserProfile !== false;\n\n if (shouldFetchUserProfile) {\n try {\n const userResponse: {\n data: {user: User | null};\n error: string | null;\n success: boolean;\n } = await getUserAction(sessionId);\n const userProfileResponse: {\n data: {userProfile: UserProfile};\n error: string | null;\n success: boolean;\n } = await getUserProfileAction(sessionId);\n\n user = userResponse.data?.user || {};\n userProfile = userProfileResponse.data?.userProfile ?? userProfile;\n } catch (error) {\n logger.warn('[ThunderIDServerProvider] Failed to fetch user profile from SCIM2:', error?.toString());\n }\n }\n }\n\n return (\n <ThunderIDClientProvider\n organizationHandle={config?.organizationHandle}\n applicationId={config?.applicationId}\n baseUrl={config?.baseUrl}\n initialMeta={flowMeta}\n signIn={signInAction}\n clearSession={clearSession}\n refreshToken={refreshToken}\n signOut={signOutAction}\n signUp={signUpAction}\n handleOAuthCallback={handleOAuthCallbackAction}\n signInUrl={config?.signInUrl}\n signUpUrl={config?.signUpUrl}\n preferences={config?.preferences}\n clientId={config?.clientId}\n user={user}\n userProfile={userProfile}\n updateProfile={updateUserProfileAction}\n isSignedIn={signedIn}\n >\n {children}\n </ThunderIDClientProvider>\n );\n};\n\nexport default ThunderIDServerProvider;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsFA,MAAMA,0BAA+E,OAAO,EAC1F,UACA,gBACA,gBACA,GAAG,cACyE;CAC5E,MAAM,kBAAkBC,mBAAW;CACnC,IAAIC,SAAuC,EAAE;AAE7C,KAAI;AACF,QAAM,gBAAgB,WAAW,QAA+B;AAEhE,iBAAO,MAAM,uEAAuE;AAEpF,WAAS,MAAM,gBAAgB,kBAAkB;UAC1C,OAAO;AACd,iBAAO,MAAM,oEAAoE,OAAO,UAAU,CAAC;AAEnG,QAAM,IAAI,sBACR,0CAA0C,OAAO,UAAU,IAC3D,+BACA,QACA,8FACD;;AAGH,KAAI,CAAC,gBAAgB,cACnB,QAAO,iCAAK;CAMd,IAAIC,WAAwC;AAC5C,KAAI;AACF,aAAW,MAAM,YAAY;GAC3B,SAAS,QAAQ;GACjB,GAAI,QAAQ,gBAAgB;IAAC,IAAI,OAAO;IAAe,MAAM,aAAa;IAAI,GAAG,EAAE;GACpF,CAAC;UACK,OAAO;AACd,iBAAO,KAAK,4DAA4D,OAAO,UAAU,CAAC;;CAI5F,MAAMC,iBAAkD,MAAMC,2BAAmB;CACjF,MAAMC,YAAoB,gBAAgB,aAAc,MAAMC,sBAAc,IAAK;CACjF,MAAMC,WAAoB,MAAMC,mBAAW,UAAU;CAErD,IAAIC,OAAa,EAAE;CACnB,IAAIC,cAA2B;EAC7B,kBAAkB,EAAE;EACpB,SAAS,EAAE;EACX,SAAS,EAAE;EACZ;AACD,KAAI,UAAU;EACZ,IAAIC,iBAAqC,QAAQ;AAEjD,MAAI,gBAAgB,gBAAgB;AAClC,oBAAiB,GAAG,QAAQ,QAAQ;AACpC,YAAS;IAAC,GAAG;IAAQ,SAAS;IAAe;aACpC,UACT,KAAI;AAEF,QADyB,MAAM,gBAAgB,kBAAkB,UAAU,IAC7D,aAAa;AACzB,qBAAiB,GAAG,QAAQ,QAAQ;AACpC,aAAS;KAAC,GAAG;KAAQ,SAAS;KAAe;;UAEzC;AAQV,MAFwC,QAAQ,aAAa,MAAM,qBAAqB,MAGtF,KAAI;GACF,MAAMC,eAIF,MAAMC,sBAAc,UAAU;GAClC,MAAMC,sBAIF,MAAMC,6BAAqB,UAAU;AAEzC,UAAO,aAAa,MAAM,QAAQ,EAAE;AACpC,iBAAc,oBAAoB,MAAM,eAAe;WAChD,OAAO;AACd,kBAAO,KAAK,sEAAsE,OAAO,UAAU,CAAC;;;AAK1G,QACE,oBAACC;EACC,oBAAoB,QAAQ;EAC5B,eAAe,QAAQ;EACvB,SAAS,QAAQ;EACjB,aAAa;EACb,QAAQC;EACR,cAAcC;EACd,cAAcC;EACd,SAASC;EACT,QAAQC;EACR,qBAAqBC;EACrB,WAAW,QAAQ;EACnB,WAAW,QAAQ;EACnB,aAAa,QAAQ;EACrB,UAAU,QAAQ;EACZ;EACO;EACb,eAAeC;EACf,YAAY;EAEX;GACuB;;AAI9B,kCAAe"}
@@ -1 +1 @@
1
- {"version":3,"file":"signInAction.d.ts","sourceRoot":"","sources":["../../../src/server/actions/signInAction.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH,OAAO,EAGL,gCAAgC,EAGjC,MAAM,iBAAiB,CAAC;AASzB;;;;;;;GAOG;AACH,QAAA,MAAM,YAAY,GAChB,UAAU,GAAG,EACb,UAAU,gCAAgC,KACzC,OAAO,CAAC;IACT,IAAI,CAAC,EACD;QACE,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,GACD,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;CAClB,CAuHA,CAAC;AAEF,eAAe,YAAY,CAAC"}
1
+ {"version":3,"file":"signInAction.d.ts","sourceRoot":"","sources":["../../../src/server/actions/signInAction.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH,OAAO,EAGL,gCAAgC,EAGjC,MAAM,iBAAiB,CAAC;AASzB;;;;;;;GAOG;AACH,QAAA,MAAM,YAAY,GAChB,UAAU,GAAG,EACb,UAAU,gCAAgC,KACzC,OAAO,CAAC;IACT,IAAI,CAAC,EACD;QACE,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,GACD,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;CAClB,CA6GA,CAAC;AAEF,eAAe,YAAY,CAAC"}
@@ -45,27 +45,19 @@ const signInAction = async (payload, request) => {
45
45
  }
46
46
  const response = await client.signIn(payload, request, sessionId);
47
47
  if (response.flowStatus === EmbeddedSignInFlowStatus.Complete) {
48
- const signInResult = await client.signIn({
49
- code: response?.authData?.code,
50
- session_state: response?.authData?.session_state,
51
- state: response?.authData?.state
52
- }, {}, sessionId);
53
- if (signInResult) {
54
- const idToken = await client.getDecodedIdToken(sessionId, signInResult["idToken"] || signInResult["id_token"]);
55
- const userIdFromToken = idToken.sub || signInResult["sub"] || sessionId;
56
- const { accessToken } = signInResult;
57
- const refreshToken = signInResult["refreshToken"] ?? "";
58
- const scopes = signInResult["scope"];
59
- const organizationId = idToken["user_org"] || idToken["organization_id"];
60
- const rawExpiresIn = signInResult["expiresIn"] ?? signInResult["expires_in"];
61
- const expiresIn = Number(rawExpiresIn);
62
- if (Number.isNaN(expiresIn)) throw new Error(`[signInAction] Invalid expiresIn value received: ${rawExpiresIn}`);
63
- const config = await client.getConfiguration();
64
- const sessionCookieExpiryTime = SessionManager_default.resolveSessionCookieExpiry(config.sessionCookie?.expiryTime);
65
- const sessionToken = await SessionManager_default.createSessionToken(accessToken, userIdFromToken, sessionId, scopes, expiresIn, refreshToken, organizationId);
66
- cookieStore.set(SessionManager_default.getSessionCookieName(), sessionToken, SessionManager_default.getSessionCookieOptions(sessionCookieExpiryTime));
67
- cookieStore.delete(SessionManager_default.getTempSessionCookieName());
68
- }
48
+ if (!response.assertion) throw new Error("[signInAction] Flow completed without an assertion.");
49
+ const idToken = await client.getDecodedIdToken(sessionId, response.assertion);
50
+ const userIdFromToken = idToken.sub ?? sessionId;
51
+ const organizationId = idToken["user_org"] || idToken["organization_id"];
52
+ const scopes = idToken["scope"] ?? "";
53
+ const iat = idToken["iat"] ?? Math.floor(Date.now() / 1e3);
54
+ const exp = idToken["exp"] ?? iat + 3600;
55
+ const expiresIn = Math.max(exp - iat, 0);
56
+ const config = await client.getConfiguration();
57
+ const sessionCookieExpiryTime = SessionManager_default.resolveSessionCookieExpiry(config.sessionCookie?.expiryTime);
58
+ const sessionToken = await SessionManager_default.createSessionToken(response.assertion, userIdFromToken, sessionId, scopes, expiresIn, "", organizationId);
59
+ cookieStore.set(SessionManager_default.getSessionCookieName(), sessionToken, SessionManager_default.getSessionCookieOptions(sessionCookieExpiryTime));
60
+ cookieStore.delete(SessionManager_default.getTempSessionCookieName());
69
61
  const afterSignInUrl = await (await client.getStorageManager()).getConfigDataParameter("afterSignInUrl");
70
62
  return {
71
63
  data: { afterSignInUrl: String(afterSignInUrl) },
@@ -1 +1 @@
1
- {"version":3,"file":"signInAction.js","names":["getClient","cookieStore: RequestCookies","sessionId: string | undefined","existingSessionToken: string | undefined","SessionManager","tempSessionToken: string | undefined","tempSessionToken: string","defaultSignInUrl: string","response: any","signInResult: Record<string, unknown>","idToken: IdToken","userIdFromToken: string","refreshToken: string","scopes: string","organizationId: string | undefined","rawExpiresIn: unknown","config: ThunderIDNextConfig","sessionCookieExpiryTime: number","sessionToken: string","afterSignInUrl: string"],"sources":["../../../src/server/actions/signInAction.ts"],"sourcesContent":["/**\n * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com).\n *\n * WSO2 LLC. licenses this file to you under the Apache License,\n * Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied. See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\n\n'use server';\n\nimport {\n generateSessionId,\n EmbeddedSignInFlowStatus,\n EmbeddedFlowExecuteRequestConfig,\n IdToken,\n isEmpty,\n} from '@thunderid/node';\nimport {cookies} from 'next/headers';\nimport {ThunderIDNextConfig} from '../../models/config';\nimport logger from '../../utils/logger';\nimport SessionManager, {SessionTokenPayload} from '../../utils/SessionManager';\nimport getClient from '../getClient';\n\ntype RequestCookies = Awaited<ReturnType<typeof cookies>>;\n\n/**\n * Server action for signing in a user.\n * Handles the embedded sign-in flow and manages session cookies.\n *\n * @param payload - The embedded sign-in flow payload\n * @param request - The embedded flow execute request config\n * @returns Promise that resolves when sign-in is complete\n */\nconst signInAction = async (\n payload?: any,\n request?: EmbeddedFlowExecuteRequestConfig,\n): Promise<{\n data?:\n | {\n afterSignInUrl?: string;\n signInUrl?: string;\n }\n | Record<string, unknown>;\n error?: string;\n success: boolean;\n}> => {\n try {\n const client = getClient();\n const cookieStore: RequestCookies = await cookies();\n\n let sessionId: string | undefined;\n\n const existingSessionToken: string | undefined = cookieStore.get(SessionManager.getSessionCookieName())?.value;\n\n if (existingSessionToken) {\n try {\n const sessionPayload: SessionTokenPayload = await SessionManager.verifySessionToken(existingSessionToken);\n sessionId = sessionPayload.sessionId;\n } catch {\n // Invalid session token, will create new temp session\n }\n }\n\n if (!sessionId) {\n const tempSessionToken: string | undefined = cookieStore.get(SessionManager.getTempSessionCookieName())?.value;\n\n if (tempSessionToken) {\n try {\n const tempSession: {sessionId: string} = await SessionManager.verifyTempSession(tempSessionToken);\n sessionId = tempSession.sessionId;\n } catch {\n // Invalid temp session, will create new one\n }\n }\n }\n\n if (!sessionId) {\n sessionId = generateSessionId();\n\n const tempSessionToken: string = await SessionManager.createTempSession(sessionId);\n\n cookieStore.set(\n SessionManager.getTempSessionCookieName(),\n tempSessionToken,\n SessionManager.getTempSessionCookieOptions(),\n );\n }\n\n // If no payload provided, redirect to sign-in URL for redirect-based sign-in.\n if (!payload || isEmpty(payload)) {\n const defaultSignInUrl: string = await client.getAuthorizeRequestUrl({}, sessionId);\n return {data: {signInUrl: String(defaultSignInUrl)}, success: true};\n }\n\n // Handle embedded sign-in flow\n const response: any = await client.signIn(payload, request!, sessionId);\n\n if (response.flowStatus === EmbeddedSignInFlowStatus.Complete) {\n const signInResult: Record<string, unknown> = await client.signIn(\n {\n code: response?.authData?.code,\n session_state: response?.authData?.session_state,\n state: response?.authData?.state,\n } as any,\n {},\n sessionId,\n );\n\n if (signInResult) {\n const idToken: IdToken = await client.getDecodedIdToken(\n sessionId,\n (signInResult['idToken'] || signInResult['id_token']) as string,\n );\n const userIdFromToken: string = (idToken.sub || signInResult['sub'] || sessionId) as string;\n const {accessToken}: {accessToken: string} = signInResult as {accessToken: string};\n const refreshToken: string = (signInResult['refreshToken'] as string | undefined) ?? '';\n const scopes: string = signInResult['scope'] as string;\n const organizationId: string | undefined = (idToken['user_org'] || idToken['organization_id']) as\n | string\n | undefined;\n const rawExpiresIn: unknown = signInResult['expiresIn'] ?? signInResult['expires_in'];\n const expiresIn = Number(rawExpiresIn);\n if (Number.isNaN(expiresIn)) {\n throw new Error(`[signInAction] Invalid expiresIn value received: ${rawExpiresIn}`);\n }\n const config: ThunderIDNextConfig = await client.getConfiguration();\n const sessionCookieExpiryTime: number = SessionManager.resolveSessionCookieExpiry(\n config.sessionCookie?.expiryTime,\n );\n\n const sessionToken: string = await SessionManager.createSessionToken(\n accessToken,\n userIdFromToken,\n sessionId,\n scopes,\n expiresIn,\n refreshToken,\n organizationId,\n );\n\n cookieStore.set(\n SessionManager.getSessionCookieName(),\n sessionToken,\n SessionManager.getSessionCookieOptions(sessionCookieExpiryTime),\n );\n\n cookieStore.delete(SessionManager.getTempSessionCookieName());\n }\n\n const afterSignInUrl: string = await (await client.getStorageManager()).getConfigDataParameter('afterSignInUrl');\n return {data: {afterSignInUrl: String(afterSignInUrl)}, success: true};\n }\n\n return {data: response as Record<string, unknown>, success: true};\n } catch (error) {\n const message =\n error instanceof Error\n ? error.message\n : typeof (error as any)?.message === 'string'\n ? (error as any).message\n : String(error);\n logger.error(`[signInAction] Error during sign-in: ${message}`);\n return {error: message, success: false};\n }\n};\n\nexport default signInAction;\n"],"mappings":";;;;;;;;;;;;;;;;;;AA2CA,MAAM,eAAe,OACnB,SACA,YAUI;AACJ,KAAI;EACF,MAAM,SAASA,mBAAW;EAC1B,MAAMC,cAA8B,MAAM,SAAS;EAEnD,IAAIC;EAEJ,MAAMC,uBAA2C,YAAY,IAAIC,uBAAe,sBAAsB,CAAC,EAAE;AAEzG,MAAI,qBACF,KAAI;AAEF,gBAD4C,MAAMA,uBAAe,mBAAmB,qBAAqB,EAC9E;UACrB;AAKV,MAAI,CAAC,WAAW;GACd,MAAMC,mBAAuC,YAAY,IAAID,uBAAe,0BAA0B,CAAC,EAAE;AAEzG,OAAI,iBACF,KAAI;AAEF,iBADyC,MAAMA,uBAAe,kBAAkB,iBAAiB,EACzE;WAClB;;AAMZ,MAAI,CAAC,WAAW;AACd,eAAY,mBAAmB;GAE/B,MAAME,mBAA2B,MAAMF,uBAAe,kBAAkB,UAAU;AAElF,eAAY,IACVA,uBAAe,0BAA0B,EACzC,kBACAA,uBAAe,6BAA6B,CAC7C;;AAIH,MAAI,CAAC,WAAW,QAAQ,QAAQ,EAAE;GAChC,MAAMG,mBAA2B,MAAM,OAAO,uBAAuB,EAAE,EAAE,UAAU;AACnF,UAAO;IAAC,MAAM,EAAC,WAAW,OAAO,iBAAiB,EAAC;IAAE,SAAS;IAAK;;EAIrE,MAAMC,WAAgB,MAAM,OAAO,OAAO,SAAS,SAAU,UAAU;AAEvE,MAAI,SAAS,eAAe,yBAAyB,UAAU;GAC7D,MAAMC,eAAwC,MAAM,OAAO,OACzD;IACE,MAAM,UAAU,UAAU;IAC1B,eAAe,UAAU,UAAU;IACnC,OAAO,UAAU,UAAU;IAC5B,EACD,EAAE,EACF,UACD;AAED,OAAI,cAAc;IAChB,MAAMC,UAAmB,MAAM,OAAO,kBACpC,WACC,aAAa,cAAc,aAAa,YAC1C;IACD,MAAMC,kBAA2B,QAAQ,OAAO,aAAa,UAAU;IACvE,MAAM,EAAC,gBAAsC;IAC7C,MAAMC,eAAwB,aAAa,mBAA0C;IACrF,MAAMC,SAAiB,aAAa;IACpC,MAAMC,iBAAsC,QAAQ,eAAe,QAAQ;IAG3E,MAAMC,eAAwB,aAAa,gBAAgB,aAAa;IACxE,MAAM,YAAY,OAAO,aAAa;AACtC,QAAI,OAAO,MAAM,UAAU,CACzB,OAAM,IAAI,MAAM,oDAAoD,eAAe;IAErF,MAAMC,SAA8B,MAAM,OAAO,kBAAkB;IACnE,MAAMC,0BAAkCb,uBAAe,2BACrD,OAAO,eAAe,WACvB;IAED,MAAMc,eAAuB,MAAMd,uBAAe,mBAChD,aACA,iBACA,WACA,QACA,WACA,cACA,eACD;AAED,gBAAY,IACVA,uBAAe,sBAAsB,EACrC,cACAA,uBAAe,wBAAwB,wBAAwB,CAChE;AAED,gBAAY,OAAOA,uBAAe,0BAA0B,CAAC;;GAG/D,MAAMe,iBAAyB,OAAO,MAAM,OAAO,mBAAmB,EAAE,uBAAuB,iBAAiB;AAChH,UAAO;IAAC,MAAM,EAAC,gBAAgB,OAAO,eAAe,EAAC;IAAE,SAAS;IAAK;;AAGxE,SAAO;GAAC,MAAM;GAAqC,SAAS;GAAK;UAC1D,OAAO;EACd,MAAM,UACJ,iBAAiB,QACb,MAAM,UACN,OAAQ,OAAe,YAAY,WAChC,MAAc,UACf,OAAO,MAAM;AACrB,iBAAO,MAAM,wCAAwC,UAAU;AAC/D,SAAO;GAAC,OAAO;GAAS,SAAS;GAAM;;;AAI3C,2BAAe"}
1
+ {"version":3,"file":"signInAction.js","names":["getClient","cookieStore: RequestCookies","sessionId: string | undefined","existingSessionToken: string | undefined","SessionManager","tempSessionToken: string | undefined","tempSessionToken: string","defaultSignInUrl: string","response: any","idToken: IdToken","userIdFromToken: string","organizationId: string | undefined","scopes: string","iat: number","exp: number","expiresIn: number","config: ThunderIDNextConfig","sessionCookieExpiryTime: number","sessionToken: string","afterSignInUrl: string"],"sources":["../../../src/server/actions/signInAction.ts"],"sourcesContent":["/**\n * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com).\n *\n * WSO2 LLC. licenses this file to you under the Apache License,\n * Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied. See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\n\n'use server';\n\nimport {\n generateSessionId,\n EmbeddedSignInFlowStatus,\n EmbeddedFlowExecuteRequestConfig,\n IdToken,\n isEmpty,\n} from '@thunderid/node';\nimport {cookies} from 'next/headers';\nimport {ThunderIDNextConfig} from '../../models/config';\nimport logger from '../../utils/logger';\nimport SessionManager, {SessionTokenPayload} from '../../utils/SessionManager';\nimport getClient from '../getClient';\n\ntype RequestCookies = Awaited<ReturnType<typeof cookies>>;\n\n/**\n * Server action for signing in a user.\n * Handles the embedded sign-in flow and manages session cookies.\n *\n * @param payload - The embedded sign-in flow payload\n * @param request - The embedded flow execute request config\n * @returns Promise that resolves when sign-in is complete\n */\nconst signInAction = async (\n payload?: any,\n request?: EmbeddedFlowExecuteRequestConfig,\n): Promise<{\n data?:\n | {\n afterSignInUrl?: string;\n signInUrl?: string;\n }\n | Record<string, unknown>;\n error?: string;\n success: boolean;\n}> => {\n try {\n const client = getClient();\n const cookieStore: RequestCookies = await cookies();\n\n let sessionId: string | undefined;\n\n const existingSessionToken: string | undefined = cookieStore.get(SessionManager.getSessionCookieName())?.value;\n\n if (existingSessionToken) {\n try {\n const sessionPayload: SessionTokenPayload = await SessionManager.verifySessionToken(existingSessionToken);\n sessionId = sessionPayload.sessionId;\n } catch {\n // Invalid session token, will create new temp session\n }\n }\n\n if (!sessionId) {\n const tempSessionToken: string | undefined = cookieStore.get(SessionManager.getTempSessionCookieName())?.value;\n\n if (tempSessionToken) {\n try {\n const tempSession: {sessionId: string} = await SessionManager.verifyTempSession(tempSessionToken);\n sessionId = tempSession.sessionId;\n } catch {\n // Invalid temp session, will create new one\n }\n }\n }\n\n if (!sessionId) {\n sessionId = generateSessionId();\n\n const tempSessionToken: string = await SessionManager.createTempSession(sessionId);\n\n cookieStore.set(\n SessionManager.getTempSessionCookieName(),\n tempSessionToken,\n SessionManager.getTempSessionCookieOptions(),\n );\n }\n\n // If no payload provided, redirect to sign-in URL for redirect-based sign-in.\n if (!payload || isEmpty(payload)) {\n const defaultSignInUrl: string = await client.getAuthorizeRequestUrl({}, sessionId);\n return {data: {signInUrl: String(defaultSignInUrl)}, success: true};\n }\n\n // Handle embedded sign-in flow\n const response: any = await client.signIn(payload, request!, sessionId);\n\n if (response.flowStatus === EmbeddedSignInFlowStatus.Complete) {\n // On the V2 platform, a completed embedded flow (without a preceding `/authorize` redirect,\n // i.e. no `authId`) returns a self-contained JWT `assertion` rather than an authorization\n // code to exchange. This mirrors how @thunderid/react and @thunderid/vue treat it: the\n // assertion is used directly as the bearer session token.\n if (!response.assertion) {\n throw new Error('[signInAction] Flow completed without an assertion.');\n }\n\n const idToken: IdToken = await client.getDecodedIdToken(sessionId, response.assertion);\n const userIdFromToken: string = (idToken.sub as string | undefined) ?? sessionId;\n const organizationId: string | undefined = (idToken['user_org'] || idToken['organization_id']) as\n | string\n | undefined;\n const scopes: string = (idToken['scope'] as string | undefined) ?? '';\n const iat: number = (idToken['iat'] as number | undefined) ?? Math.floor(Date.now() / 1000);\n const exp: number = (idToken['exp'] as number | undefined) ?? iat + 3600;\n const expiresIn: number = Math.max(exp - iat, 0);\n\n const config: ThunderIDNextConfig = await client.getConfiguration();\n const sessionCookieExpiryTime: number = SessionManager.resolveSessionCookieExpiry(\n config.sessionCookie?.expiryTime,\n );\n\n const sessionToken: string = await SessionManager.createSessionToken(\n response.assertion,\n userIdFromToken,\n sessionId,\n scopes,\n expiresIn,\n '',\n organizationId,\n );\n\n cookieStore.set(\n SessionManager.getSessionCookieName(),\n sessionToken,\n SessionManager.getSessionCookieOptions(sessionCookieExpiryTime),\n );\n\n cookieStore.delete(SessionManager.getTempSessionCookieName());\n\n const afterSignInUrl: string = await (await client.getStorageManager()).getConfigDataParameter('afterSignInUrl');\n return {data: {afterSignInUrl: String(afterSignInUrl)}, success: true};\n }\n\n return {data: response as Record<string, unknown>, success: true};\n } catch (error) {\n const message =\n error instanceof Error\n ? error.message\n : typeof (error as any)?.message === 'string'\n ? (error as any).message\n : String(error);\n logger.error(`[signInAction] Error during sign-in: ${message}`);\n return {error: message, success: false};\n }\n};\n\nexport default signInAction;\n"],"mappings":";;;;;;;;;;;;;;;;;;AA2CA,MAAM,eAAe,OACnB,SACA,YAUI;AACJ,KAAI;EACF,MAAM,SAASA,mBAAW;EAC1B,MAAMC,cAA8B,MAAM,SAAS;EAEnD,IAAIC;EAEJ,MAAMC,uBAA2C,YAAY,IAAIC,uBAAe,sBAAsB,CAAC,EAAE;AAEzG,MAAI,qBACF,KAAI;AAEF,gBAD4C,MAAMA,uBAAe,mBAAmB,qBAAqB,EAC9E;UACrB;AAKV,MAAI,CAAC,WAAW;GACd,MAAMC,mBAAuC,YAAY,IAAID,uBAAe,0BAA0B,CAAC,EAAE;AAEzG,OAAI,iBACF,KAAI;AAEF,iBADyC,MAAMA,uBAAe,kBAAkB,iBAAiB,EACzE;WAClB;;AAMZ,MAAI,CAAC,WAAW;AACd,eAAY,mBAAmB;GAE/B,MAAME,mBAA2B,MAAMF,uBAAe,kBAAkB,UAAU;AAElF,eAAY,IACVA,uBAAe,0BAA0B,EACzC,kBACAA,uBAAe,6BAA6B,CAC7C;;AAIH,MAAI,CAAC,WAAW,QAAQ,QAAQ,EAAE;GAChC,MAAMG,mBAA2B,MAAM,OAAO,uBAAuB,EAAE,EAAE,UAAU;AACnF,UAAO;IAAC,MAAM,EAAC,WAAW,OAAO,iBAAiB,EAAC;IAAE,SAAS;IAAK;;EAIrE,MAAMC,WAAgB,MAAM,OAAO,OAAO,SAAS,SAAU,UAAU;AAEvE,MAAI,SAAS,eAAe,yBAAyB,UAAU;AAK7D,OAAI,CAAC,SAAS,UACZ,OAAM,IAAI,MAAM,sDAAsD;GAGxE,MAAMC,UAAmB,MAAM,OAAO,kBAAkB,WAAW,SAAS,UAAU;GACtF,MAAMC,kBAA2B,QAAQ,OAA8B;GACvE,MAAMC,iBAAsC,QAAQ,eAAe,QAAQ;GAG3E,MAAMC,SAAkB,QAAQ,YAAmC;GACnE,MAAMC,MAAe,QAAQ,UAAiC,KAAK,MAAM,KAAK,KAAK,GAAG,IAAK;GAC3F,MAAMC,MAAe,QAAQ,UAAiC,MAAM;GACpE,MAAMC,YAAoB,KAAK,IAAI,MAAM,KAAK,EAAE;GAEhD,MAAMC,SAA8B,MAAM,OAAO,kBAAkB;GACnE,MAAMC,0BAAkCb,uBAAe,2BACrD,OAAO,eAAe,WACvB;GAED,MAAMc,eAAuB,MAAMd,uBAAe,mBAChD,SAAS,WACT,iBACA,WACA,QACA,WACA,IACA,eACD;AAED,eAAY,IACVA,uBAAe,sBAAsB,EACrC,cACAA,uBAAe,wBAAwB,wBAAwB,CAChE;AAED,eAAY,OAAOA,uBAAe,0BAA0B,CAAC;GAE7D,MAAMe,iBAAyB,OAAO,MAAM,OAAO,mBAAmB,EAAE,uBAAuB,iBAAiB;AAChH,UAAO;IAAC,MAAM,EAAC,gBAAgB,OAAO,eAAe,EAAC;IAAE,SAAS;IAAK;;AAGxE,SAAO;GAAC,MAAM;GAAqC,SAAS;GAAK;UAC1D,OAAO;EACd,MAAM,UACJ,iBAAiB,QACb,MAAM,UACN,OAAQ,OAAe,YAAY,WAChC,MAAc,UACf,OAAO,MAAM;AACrB,iBAAO,MAAM,wCAAwC,UAAU;AAC/D,SAAO;GAAC,OAAO;GAAS,SAAS;GAAM;;;AAI3C,2BAAe"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thunderid/nextjs",
3
- "version": "0.2.3",
3
+ "version": "0.2.4",
4
4
  "description": "Next.js SDK for ThunderID",
5
5
  "keywords": [
6
6
  "thunderid",
@@ -41,7 +41,7 @@
41
41
  "jose": "5.2.0",
42
42
  "tslib": "2.8.1",
43
43
  "@thunderid/node": "^0.2.3",
44
- "@thunderid/react": "^0.3.5"
44
+ "@thunderid/react": "^0.3.7"
45
45
  },
46
46
  "devDependencies": {
47
47
  "@thunderid/eslint-plugin": "0.0.2",