@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.
- package/dist/ThunderIDNextClient.d.ts.map +1 -1
- package/dist/ThunderIDNextClient.js +11 -2
- package/dist/ThunderIDNextClient.js.map +1 -1
- package/dist/cjs/ThunderIDNextClient.cjs +10 -1
- package/dist/cjs/ThunderIDNextClient.cjs.map +1 -1
- package/dist/cjs/client/components/presentation/SignIn/SignIn.cjs +57 -6
- package/dist/cjs/client/components/presentation/SignIn/SignIn.cjs.map +1 -1
- package/dist/cjs/client/components/presentation/SignUp/SignUp.cjs +3 -2
- package/dist/cjs/client/components/presentation/SignUp/SignUp.cjs.map +1 -1
- package/dist/cjs/client/components/presentation/UserAvatar/UserAvatar.cjs +33 -0
- package/dist/cjs/client/components/presentation/UserAvatar/UserAvatar.cjs.map +1 -0
- package/dist/cjs/client/contexts/ThunderID/ThunderIDProvider.cjs +68 -14
- package/dist/cjs/client/contexts/ThunderID/ThunderIDProvider.cjs.map +1 -1
- package/dist/cjs/client/index.cjs +1 -0
- package/dist/cjs/index.cjs +2 -0
- package/dist/cjs/server/ThunderIDProvider.cjs +13 -0
- package/dist/cjs/server/ThunderIDProvider.cjs.map +1 -1
- package/dist/cjs/server/actions/signInAction.cjs +13 -21
- package/dist/cjs/server/actions/signInAction.cjs.map +1 -1
- package/dist/client/components/presentation/SignIn/SignIn.d.ts +3 -2
- package/dist/client/components/presentation/SignIn/SignIn.d.ts.map +1 -1
- package/dist/client/components/presentation/SignIn/SignIn.js +58 -8
- package/dist/client/components/presentation/SignIn/SignIn.js.map +1 -1
- package/dist/client/components/presentation/SignUp/SignUp.d.ts.map +1 -1
- package/dist/client/components/presentation/SignUp/SignUp.js +3 -2
- package/dist/client/components/presentation/SignUp/SignUp.js.map +1 -1
- package/dist/client/components/presentation/UserAvatar/UserAvatar.d.ts +33 -0
- package/dist/client/components/presentation/UserAvatar/UserAvatar.d.ts.map +1 -0
- package/dist/client/components/presentation/UserAvatar/UserAvatar.js +30 -0
- package/dist/client/components/presentation/UserAvatar/UserAvatar.js.map +1 -0
- package/dist/client/contexts/ThunderID/ThunderIDProvider.d.ts +6 -1
- package/dist/client/contexts/ThunderID/ThunderIDProvider.d.ts.map +1 -1
- package/dist/client/contexts/ThunderID/ThunderIDProvider.js +69 -15
- package/dist/client/contexts/ThunderID/ThunderIDProvider.js.map +1 -1
- package/dist/client/index.d.ts +2 -0
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +1 -0
- package/dist/index.js +2 -1
- package/dist/server/ThunderIDProvider.d.ts.map +1 -1
- package/dist/server/ThunderIDProvider.js +14 -1
- package/dist/server/ThunderIDProvider.js.map +1 -1
- package/dist/server/actions/signInAction.d.ts.map +1 -1
- package/dist/server/actions/signInAction.js +13 -21
- package/dist/server/actions/signInAction.js.map +1 -1
- package/package.json +2 -2
|
@@ -51,6 +51,18 @@ const ThunderIDServerProvider = async ({ children, afterSignInUrl, afterSignOutU
|
|
|
51
51
|
throw new __thunderid_node.ThunderIDRuntimeError(`Failed to initialize ThunderID client: ${error?.toString()}`, "next-ConfigurationError-001", "next", "An error occurred while initializing the ThunderID client. Please check your configuration.");
|
|
52
52
|
}
|
|
53
53
|
if (!thunderIDClient.isInitialized) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, {});
|
|
54
|
+
let flowMeta = null;
|
|
55
|
+
try {
|
|
56
|
+
flowMeta = await (0, __thunderid_node.getFlowMeta)({
|
|
57
|
+
baseUrl: config?.baseUrl,
|
|
58
|
+
...config?.applicationId ? {
|
|
59
|
+
id: config.applicationId,
|
|
60
|
+
type: __thunderid_node.FlowMetaType.App
|
|
61
|
+
} : {}
|
|
62
|
+
});
|
|
63
|
+
} catch (error) {
|
|
64
|
+
require_logger.default.warn("[ThunderIDServerProvider] Failed to fetch flow metadata:", error?.toString());
|
|
65
|
+
}
|
|
54
66
|
const sessionPayload = await require_getSessionPayload.default();
|
|
55
67
|
const sessionId = sessionPayload?.sessionId || await require_getSessionId.default() || "";
|
|
56
68
|
const signedIn = await require_isSignedIn.default(sessionId);
|
|
@@ -90,6 +102,7 @@ const ThunderIDServerProvider = async ({ children, afterSignInUrl, afterSignOutU
|
|
|
90
102
|
organizationHandle: config?.organizationHandle,
|
|
91
103
|
applicationId: config?.applicationId,
|
|
92
104
|
baseUrl: config?.baseUrl,
|
|
105
|
+
initialMeta: flowMeta,
|
|
93
106
|
signIn: require_signInAction.default,
|
|
94
107
|
clearSession: require_clearSession.default,
|
|
95
108
|
refreshToken: require_refreshToken.default,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ThunderIDProvider.cjs","names":["ThunderIDServerProvider: FC<PropsWithChildren<ThunderIDServerProviderProps>>","getClient","config: Partial<ThunderIDNextConfig>","ThunderIDRuntimeError","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,2BAAW;CACnC,IAAIC,SAAuC,EAAE;AAE7C,KAAI;AACF,QAAM,gBAAgB,WAAW,QAA+B;AAEhE,yBAAO,MAAM,uEAAuE;AAEpF,WAAS,MAAM,gBAAgB,kBAAkB;UAC1C,OAAO;AACd,yBAAO,MAAM,oEAAoE,OAAO,UAAU,CAAC;AAEnG,QAAM,IAAIC,uCACR,0CAA0C,OAAO,UAAU,IAC3D,+BACA,QACA,8FACD;;AAGH,KAAI,CAAC,gBAAgB,cACnB,QAAO,0EAAK;CAId,MAAMC,iBAAkD,MAAMC,mCAAmB;CACjF,MAAMC,YAAoB,gBAAgB,aAAc,MAAMC,8BAAc,IAAK;CACjF,MAAMC,WAAoB,MAAMC,2BAAW,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,8BAAc,UAAU;GAClC,MAAMC,sBAIF,MAAMC,qCAAqB,UAAU;AAEzC,UAAO,aAAa,MAAM,QAAQ,EAAE;AACpC,iBAAc,oBAAoB,MAAM,eAAe;WAChD,OAAO;AACd,0BAAO,KAAK,sEAAsE,OAAO,UAAU,CAAC;;;AAK1G,QACE,2CAACC;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.cjs","names":["ThunderIDServerProvider: FC<PropsWithChildren<ThunderIDServerProviderProps>>","getClient","config: Partial<ThunderIDNextConfig>","ThunderIDRuntimeError","flowMeta: FlowMetadataResponse | null","FlowMetaType","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,2BAAW;CACnC,IAAIC,SAAuC,EAAE;AAE7C,KAAI;AACF,QAAM,gBAAgB,WAAW,QAA+B;AAEhE,yBAAO,MAAM,uEAAuE;AAEpF,WAAS,MAAM,gBAAgB,kBAAkB;UAC1C,OAAO;AACd,yBAAO,MAAM,oEAAoE,OAAO,UAAU,CAAC;AAEnG,QAAM,IAAIC,uCACR,0CAA0C,OAAO,UAAU,IAC3D,+BACA,QACA,8FACD;;AAGH,KAAI,CAAC,gBAAgB,cACnB,QAAO,0EAAK;CAMd,IAAIC,WAAwC;AAC5C,KAAI;AACF,aAAW,wCAAkB;GAC3B,SAAS,QAAQ;GACjB,GAAI,QAAQ,gBAAgB;IAAC,IAAI,OAAO;IAAe,MAAMC,8BAAa;IAAI,GAAG,EAAE;GACpF,CAAC;UACK,OAAO;AACd,yBAAO,KAAK,4DAA4D,OAAO,UAAU,CAAC;;CAI5F,MAAMC,iBAAkD,MAAMC,mCAAmB;CACjF,MAAMC,YAAoB,gBAAgB,aAAc,MAAMC,8BAAc,IAAK;CACjF,MAAMC,WAAoB,MAAMC,2BAAW,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,8BAAc,UAAU;GAClC,MAAMC,sBAIF,MAAMC,qCAAqB,UAAU;AAEzC,UAAO,aAAa,MAAM,QAAQ,EAAE;AACpC,iBAAc,oBAAoB,MAAM,eAAe;WAChD,OAAO;AACd,0BAAO,KAAK,sEAAsE,OAAO,UAAU,CAAC;;;AAK1G,QACE,2CAACC;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"}
|
|
@@ -48,27 +48,19 @@ const signInAction = async (payload, request) => {
|
|
|
48
48
|
}
|
|
49
49
|
const response = await client.signIn(payload, request, sessionId);
|
|
50
50
|
if (response.flowStatus === __thunderid_node.EmbeddedSignInFlowStatus.Complete) {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
const expiresIn = Number(rawExpiresIn);
|
|
65
|
-
if (Number.isNaN(expiresIn)) throw new Error(`[signInAction] Invalid expiresIn value received: ${rawExpiresIn}`);
|
|
66
|
-
const config = await client.getConfiguration();
|
|
67
|
-
const sessionCookieExpiryTime = require_SessionManager.default.resolveSessionCookieExpiry(config.sessionCookie?.expiryTime);
|
|
68
|
-
const sessionToken = await require_SessionManager.default.createSessionToken(accessToken, userIdFromToken, sessionId, scopes, expiresIn, refreshToken, organizationId);
|
|
69
|
-
cookieStore.set(require_SessionManager.default.getSessionCookieName(), sessionToken, require_SessionManager.default.getSessionCookieOptions(sessionCookieExpiryTime));
|
|
70
|
-
cookieStore.delete(require_SessionManager.default.getTempSessionCookieName());
|
|
71
|
-
}
|
|
51
|
+
if (!response.assertion) throw new Error("[signInAction] Flow completed without an assertion.");
|
|
52
|
+
const idToken = await client.getDecodedIdToken(sessionId, response.assertion);
|
|
53
|
+
const userIdFromToken = idToken.sub ?? sessionId;
|
|
54
|
+
const organizationId = idToken["user_org"] || idToken["organization_id"];
|
|
55
|
+
const scopes = idToken["scope"] ?? "";
|
|
56
|
+
const iat = idToken["iat"] ?? Math.floor(Date.now() / 1e3);
|
|
57
|
+
const exp = idToken["exp"] ?? iat + 3600;
|
|
58
|
+
const expiresIn = Math.max(exp - iat, 0);
|
|
59
|
+
const config = await client.getConfiguration();
|
|
60
|
+
const sessionCookieExpiryTime = require_SessionManager.default.resolveSessionCookieExpiry(config.sessionCookie?.expiryTime);
|
|
61
|
+
const sessionToken = await require_SessionManager.default.createSessionToken(response.assertion, userIdFromToken, sessionId, scopes, expiresIn, "", organizationId);
|
|
62
|
+
cookieStore.set(require_SessionManager.default.getSessionCookieName(), sessionToken, require_SessionManager.default.getSessionCookieOptions(sessionCookieExpiryTime));
|
|
63
|
+
cookieStore.delete(require_SessionManager.default.getTempSessionCookieName());
|
|
72
64
|
const afterSignInUrl = await (await client.getStorageManager()).getConfigDataParameter("afterSignInUrl");
|
|
73
65
|
return {
|
|
74
66
|
data: { afterSignInUrl: String(afterSignInUrl) },
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"signInAction.cjs","names":["getClient","cookieStore: RequestCookies","sessionId: string | undefined","existingSessionToken: string | undefined","SessionManager","tempSessionToken: string | undefined","tempSessionToken: string","defaultSignInUrl: string","response: any","EmbeddedSignInFlowStatus","
|
|
1
|
+
{"version":3,"file":"signInAction.cjs","names":["getClient","cookieStore: RequestCookies","sessionId: string | undefined","existingSessionToken: string | undefined","SessionManager","tempSessionToken: string | undefined","tempSessionToken: string","defaultSignInUrl: string","response: any","EmbeddedSignInFlowStatus","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,2BAAW;EAC1B,MAAMC,cAA8B,iCAAe;EAEnD,IAAIC;EAEJ,MAAMC,uBAA2C,YAAY,IAAIC,+BAAe,sBAAsB,CAAC,EAAE;AAEzG,MAAI,qBACF,KAAI;AAEF,gBAD4C,MAAMA,+BAAe,mBAAmB,qBAAqB,EAC9E;UACrB;AAKV,MAAI,CAAC,WAAW;GACd,MAAMC,mBAAuC,YAAY,IAAID,+BAAe,0BAA0B,CAAC,EAAE;AAEzG,OAAI,iBACF,KAAI;AAEF,iBADyC,MAAMA,+BAAe,kBAAkB,iBAAiB,EACzE;WAClB;;AAMZ,MAAI,CAAC,WAAW;AACd,wDAA+B;GAE/B,MAAME,mBAA2B,MAAMF,+BAAe,kBAAkB,UAAU;AAElF,eAAY,IACVA,+BAAe,0BAA0B,EACzC,kBACAA,+BAAe,6BAA6B,CAC7C;;AAIH,MAAI,CAAC,yCAAmB,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,eAAeC,0CAAyB,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,0BAAkCd,+BAAe,2BACrD,OAAO,eAAe,WACvB;GAED,MAAMe,eAAuB,MAAMf,+BAAe,mBAChD,SAAS,WACT,iBACA,WACA,QACA,WACA,IACA,eACD;AAED,eAAY,IACVA,+BAAe,sBAAsB,EACrC,cACAA,+BAAe,wBAAwB,wBAAwB,CAChE;AAED,eAAY,OAAOA,+BAAe,0BAA0B,CAAC;GAE7D,MAAMgB,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,yBAAO,MAAM,wCAAwC,UAAU;AAC/D,SAAO;GAAC,OAAO;GAAS,SAAS;GAAM;;;AAI3C,2BAAe"}
|
|
@@ -24,8 +24,9 @@ import { FC } from 'react';
|
|
|
24
24
|
export type SignInProps = Pick<BaseSignInProps, 'className' | 'onSuccess' | 'onError' | 'variant' | 'size'>;
|
|
25
25
|
/**
|
|
26
26
|
* A SignIn component for Next.js that provides native authentication flow.
|
|
27
|
-
* This component delegates to the BaseSignIn from @thunderid/react
|
|
28
|
-
*
|
|
27
|
+
* This component delegates to the BaseSignIn from @thunderid/react. Unlike BaseSignUp,
|
|
28
|
+
* BaseSignIn does not manage its own flow state, so this component initiates the flow
|
|
29
|
+
* (using the server-action-backed `signIn`) and tracks `components`/`executionId` itself.
|
|
29
30
|
*/
|
|
30
31
|
declare const SignIn: FC<SignInProps>;
|
|
31
32
|
export default SignIn;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SignIn.d.ts","sourceRoot":"","sources":["../../../../../src/client/components/presentation/SignIn/SignIn.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAKH,OAAO,EAAa,eAAe,
|
|
1
|
+
{"version":3,"file":"SignIn.d.ts","sourceRoot":"","sources":["../../../../../src/client/components/presentation/SignIn/SignIn.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAKH,OAAO,EAAa,eAAe,EAAwC,MAAM,kBAAkB,CAAC;AACpG,OAAO,EAAC,EAAE,EAA8B,MAAM,OAAO,CAAC;AAGtD;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG,IAAI,CAAC,eAAe,EAAE,WAAW,GAAG,WAAW,GAAG,SAAS,GAAG,SAAS,GAAG,MAAM,CAAC,CAAC;AAE5G;;;;;GAKG;AACH,QAAA,MAAM,MAAM,EAAE,EAAE,CAAC,WAAW,CAmG3B,CAAC;AAIF,eAAe,MAAM,CAAC"}
|
|
@@ -2,23 +2,73 @@
|
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
import useThunderID_default from "../../../contexts/ThunderID/useThunderID.js";
|
|
5
|
-
import { ThunderIDRuntimeError } from "@thunderid/node";
|
|
6
|
-
import { BaseSignIn } from "@thunderid/react";
|
|
5
|
+
import { EmbeddedFlowType, ThunderIDRuntimeError } from "@thunderid/node";
|
|
6
|
+
import { BaseSignIn, normalizeFlowResponse, useTranslation } from "@thunderid/react";
|
|
7
|
+
import { useEffect, useRef, useState } from "react";
|
|
7
8
|
import { jsx } from "react/jsx-runtime";
|
|
8
9
|
|
|
9
10
|
//#region src/client/components/presentation/SignIn/SignIn.tsx
|
|
10
11
|
/**
|
|
11
12
|
* A SignIn component for Next.js that provides native authentication flow.
|
|
12
|
-
* This component delegates to the BaseSignIn from @thunderid/react
|
|
13
|
-
*
|
|
13
|
+
* This component delegates to the BaseSignIn from @thunderid/react. Unlike BaseSignUp,
|
|
14
|
+
* BaseSignIn does not manage its own flow state, so this component initiates the flow
|
|
15
|
+
* (using the server-action-backed `signIn`) and tracks `components`/`executionId` itself.
|
|
14
16
|
*/
|
|
15
|
-
const SignIn = ({ size = "medium", variant = "outlined",...rest }) => {
|
|
16
|
-
const { signIn } = useThunderID_default();
|
|
17
|
-
const
|
|
17
|
+
const SignIn = ({ size = "medium", variant = "outlined", onError,...rest }) => {
|
|
18
|
+
const { signIn, applicationId, scopes } = useThunderID_default();
|
|
19
|
+
const { t } = useTranslation();
|
|
20
|
+
const [components, setComponents] = useState([]);
|
|
21
|
+
const [additionalData, setAdditionalData] = useState({});
|
|
22
|
+
const [executionId, setExecutionId] = useState(void 0);
|
|
23
|
+
const [isFlowInitialized, setIsFlowInitialized] = useState(false);
|
|
24
|
+
const [flowError, setFlowError] = useState(null);
|
|
25
|
+
const initializationAttemptedRef = useRef(false);
|
|
26
|
+
const challengeTokenRef = useRef(void 0);
|
|
27
|
+
const applyFlowResponse = (response) => {
|
|
28
|
+
const normalized = normalizeFlowResponse(response, t, { resolveTranslations: false });
|
|
29
|
+
challengeTokenRef.current = response?.challengeToken ?? void 0;
|
|
30
|
+
setExecutionId(normalized.executionId ?? void 0);
|
|
31
|
+
setComponents(normalized.components);
|
|
32
|
+
setAdditionalData(normalized.additionalData);
|
|
33
|
+
};
|
|
34
|
+
const handleFlowError = (error) => {
|
|
35
|
+
const normalizedError = error instanceof Error ? error : new Error(String(error));
|
|
36
|
+
setFlowError(normalizedError);
|
|
37
|
+
onError?.(normalizedError);
|
|
38
|
+
};
|
|
39
|
+
useEffect(() => {
|
|
40
|
+
if (initializationAttemptedRef.current || !signIn) return;
|
|
41
|
+
initializationAttemptedRef.current = true;
|
|
42
|
+
(async () => {
|
|
43
|
+
try {
|
|
44
|
+
const response = await signIn({
|
|
45
|
+
applicationId,
|
|
46
|
+
flowType: EmbeddedFlowType.Authentication,
|
|
47
|
+
...scopes && { scopes }
|
|
48
|
+
}, {});
|
|
49
|
+
if (response) applyFlowResponse(response);
|
|
50
|
+
} catch (error) {
|
|
51
|
+
handleFlowError(error);
|
|
52
|
+
} finally {
|
|
53
|
+
setIsFlowInitialized(true);
|
|
54
|
+
}
|
|
55
|
+
})();
|
|
56
|
+
}, [signIn]);
|
|
57
|
+
const handleOnSubmit = async (payload) => {
|
|
18
58
|
if (!signIn) throw new ThunderIDRuntimeError("`signIn` function is not available.", "SignIn-handleOnSubmit-RuntimeError-001", "nextjs");
|
|
19
|
-
await signIn(
|
|
59
|
+
const response = await signIn({
|
|
60
|
+
...payload,
|
|
61
|
+
executionId,
|
|
62
|
+
...challengeTokenRef.current ? { challengeToken: challengeTokenRef.current } : {}
|
|
63
|
+
}, {});
|
|
64
|
+
if (response) applyFlowResponse(response);
|
|
20
65
|
};
|
|
21
66
|
return /* @__PURE__ */ jsx(BaseSignIn, {
|
|
67
|
+
additionalData,
|
|
68
|
+
components,
|
|
69
|
+
error: flowError,
|
|
70
|
+
isLoading: !isFlowInitialized,
|
|
71
|
+
onError,
|
|
22
72
|
onSubmit: handleOnSubmit,
|
|
23
73
|
size,
|
|
24
74
|
variant,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SignIn.js","names":["SignIn: FC<SignInProps>","useThunderID"],"sources":["../../../../../src/client/components/presentation/SignIn/SignIn.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 {ThunderIDRuntimeError} from '@thunderid/node';\nimport {BaseSignIn, BaseSignInProps} from '@thunderid/react';\nimport {FC} from 'react';\nimport useThunderID from '../../../contexts/ThunderID/useThunderID';\n\n/**\n * Props for the SignIn component.\n * Extends BaseSignInProps for full compatibility with the React BaseSignIn component\n */\nexport type SignInProps = Pick<BaseSignInProps, 'className' | 'onSuccess' | 'onError' | 'variant' | 'size'>;\n\n/**\n * A SignIn component for Next.js that provides native authentication flow.\n * This component delegates to the BaseSignIn from @thunderid/react
|
|
1
|
+
{"version":3,"file":"SignIn.js","names":["SignIn: FC<SignInProps>","useThunderID","normalizedError: Error","response: any"],"sources":["../../../../../src/client/components/presentation/SignIn/SignIn.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 {EmbeddedFlowComponent, EmbeddedFlowType, ThunderIDRuntimeError} from '@thunderid/node';\nimport {BaseSignIn, BaseSignInProps, normalizeFlowResponse, useTranslation} from '@thunderid/react';\nimport {FC, useEffect, useRef, useState} from 'react';\nimport useThunderID from '../../../contexts/ThunderID/useThunderID';\n\n/**\n * Props for the SignIn component.\n * Extends BaseSignInProps for full compatibility with the React BaseSignIn component\n */\nexport type SignInProps = Pick<BaseSignInProps, 'className' | 'onSuccess' | 'onError' | 'variant' | 'size'>;\n\n/**\n * A SignIn component for Next.js that provides native authentication flow.\n * This component delegates to the BaseSignIn from @thunderid/react. Unlike BaseSignUp,\n * BaseSignIn does not manage its own flow state, so this component initiates the flow\n * (using the server-action-backed `signIn`) and tracks `components`/`executionId` itself.\n */\nconst SignIn: FC<SignInProps> = ({size = 'medium', variant = 'outlined', onError, ...rest}: SignInProps) => {\n const {signIn, applicationId, scopes} = useThunderID();\n const {t} = useTranslation();\n\n const [components, setComponents] = useState<EmbeddedFlowComponent[]>([]);\n const [additionalData, setAdditionalData] = useState<Record<string, any>>({});\n const [executionId, setExecutionId] = useState<string | undefined>(undefined);\n const [isFlowInitialized, setIsFlowInitialized] = useState(false);\n const [flowError, setFlowError] = useState<Error | null>(null);\n const initializationAttemptedRef = useRef(false);\n // A fresh challenge token is required on every step to prevent replay attacks; the server\n // rotates it on each response, so it's tracked in a ref (not state) to avoid a stale value\n // from a closure captured before the previous response's state update committed.\n const challengeTokenRef = useRef<string | undefined>(undefined);\n\n const applyFlowResponse = (response: any): void => {\n const normalized = normalizeFlowResponse(response, t, {resolveTranslations: false});\n\n challengeTokenRef.current = response?.challengeToken ?? undefined;\n setExecutionId(normalized.executionId ?? undefined);\n setComponents(normalized.components);\n setAdditionalData(normalized.additionalData);\n };\n\n const handleFlowError = (error: unknown): void => {\n const normalizedError: Error = error instanceof Error ? error : new Error(String(error));\n\n setFlowError(normalizedError);\n onError?.(normalizedError);\n };\n\n useEffect(() => {\n if (initializationAttemptedRef.current || !signIn) {\n return;\n }\n\n initializationAttemptedRef.current = true;\n\n (async (): Promise<void> => {\n try {\n const response: any = await signIn(\n {\n applicationId,\n flowType: EmbeddedFlowType.Authentication,\n ...(scopes && {scopes}),\n },\n {},\n );\n\n // `response` is undefined when the provider already redirected\n // (OAuth-redirect or completed flows are handled there directly).\n if (response) {\n applyFlowResponse(response);\n }\n } catch (error) {\n handleFlowError(error);\n } finally {\n setIsFlowInitialized(true);\n }\n })();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [signIn]);\n\n const handleOnSubmit = async (payload: any): Promise<void> => {\n if (!signIn) {\n throw new ThunderIDRuntimeError(\n '`signIn` function is not available.',\n 'SignIn-handleOnSubmit-RuntimeError-001',\n 'nextjs',\n );\n }\n\n const response: any = await signIn(\n {\n ...payload,\n executionId,\n ...(challengeTokenRef.current ? {challengeToken: challengeTokenRef.current} : {}),\n },\n {},\n );\n\n if (response) {\n applyFlowResponse(response);\n }\n };\n\n return (\n <BaseSignIn\n additionalData={additionalData}\n components={components}\n error={flowError}\n isLoading={!isFlowInitialized}\n onError={onError}\n onSubmit={handleOnSubmit}\n size={size}\n variant={variant}\n {...rest}\n />\n );\n};\n\nSignIn.displayName = 'SignIn';\n\nexport default SignIn;\n"],"mappings":";;;;;;;;;;;;;;;;AAqCA,MAAMA,UAA2B,EAAC,OAAO,UAAU,UAAU,YAAY,QAAS,GAAG,WAAuB;CAC1G,MAAM,EAAC,QAAQ,eAAe,WAAUC,sBAAc;CACtD,MAAM,EAAC,MAAK,gBAAgB;CAE5B,MAAM,CAAC,YAAY,iBAAiB,SAAkC,EAAE,CAAC;CACzE,MAAM,CAAC,gBAAgB,qBAAqB,SAA8B,EAAE,CAAC;CAC7E,MAAM,CAAC,aAAa,kBAAkB,SAA6B,OAAU;CAC7E,MAAM,CAAC,mBAAmB,wBAAwB,SAAS,MAAM;CACjE,MAAM,CAAC,WAAW,gBAAgB,SAAuB,KAAK;CAC9D,MAAM,6BAA6B,OAAO,MAAM;CAIhD,MAAM,oBAAoB,OAA2B,OAAU;CAE/D,MAAM,qBAAqB,aAAwB;EACjD,MAAM,aAAa,sBAAsB,UAAU,GAAG,EAAC,qBAAqB,OAAM,CAAC;AAEnF,oBAAkB,UAAU,UAAU,kBAAkB;AACxD,iBAAe,WAAW,eAAe,OAAU;AACnD,gBAAc,WAAW,WAAW;AACpC,oBAAkB,WAAW,eAAe;;CAG9C,MAAM,mBAAmB,UAAyB;EAChD,MAAMC,kBAAyB,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,MAAM,CAAC;AAExF,eAAa,gBAAgB;AAC7B,YAAU,gBAAgB;;AAG5B,iBAAgB;AACd,MAAI,2BAA2B,WAAW,CAAC,OACzC;AAGF,6BAA2B,UAAU;AAErC,GAAC,YAA2B;AAC1B,OAAI;IACF,MAAMC,WAAgB,MAAM,OAC1B;KACE;KACA,UAAU,iBAAiB;KAC3B,GAAI,UAAU,EAAC,QAAO;KACvB,EACD,EAAE,CACH;AAID,QAAI,SACF,mBAAkB,SAAS;YAEtB,OAAO;AACd,oBAAgB,MAAM;aACd;AACR,yBAAqB,KAAK;;MAE1B;IAEH,CAAC,OAAO,CAAC;CAEZ,MAAM,iBAAiB,OAAO,YAAgC;AAC5D,MAAI,CAAC,OACH,OAAM,IAAI,sBACR,uCACA,0CACA,SACD;EAGH,MAAMA,WAAgB,MAAM,OAC1B;GACE,GAAG;GACH;GACA,GAAI,kBAAkB,UAAU,EAAC,gBAAgB,kBAAkB,SAAQ,GAAG,EAAE;GACjF,EACD,EAAE,CACH;AAED,MAAI,SACF,mBAAkB,SAAS;;AAI/B,QACE,oBAAC;EACiB;EACJ;EACZ,OAAO;EACP,WAAW,CAAC;EACH;EACT,UAAU;EACJ;EACG;EACT,GAAI;GACJ;;AAIN,OAAO,cAAc;AAErB,qBAAe"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SignUp.d.ts","sourceRoot":"","sources":["../../../../../src/client/components/presentation/SignUp/SignUp.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAKH,OAAO,EAAa,eAAe,EAAC,MAAM,kBAAkB,CAAC;AAC7D,OAAO,EAAC,EAAE,EAAC,MAAM,OAAO,CAAC;AAGzB;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,eAAe,CAAC;AAE1C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,QAAA,MAAM,MAAM,EAAE,EAAE,CAAC,WAAW,
|
|
1
|
+
{"version":3,"file":"SignUp.d.ts","sourceRoot":"","sources":["../../../../../src/client/components/presentation/SignUp/SignUp.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAKH,OAAO,EAAa,eAAe,EAAC,MAAM,kBAAkB,CAAC;AAC7D,OAAO,EAAC,EAAE,EAAC,MAAM,OAAO,CAAC;AAGzB;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,eAAe,CAAC;AAE1C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,QAAA,MAAM,MAAM,EAAE,EAAE,CAAC,WAAW,CAwD3B,CAAC;AAEF,eAAe,MAAM,CAAC"}
|
|
@@ -44,10 +44,11 @@ const SignUp = ({ className, size = "medium", variant = "outlined", afterSignUpU
|
|
|
44
44
|
*/
|
|
45
45
|
const handleInitialize = async (payload) => {
|
|
46
46
|
if (!signUp) throw new ThunderIDRuntimeError("`signUp` function is not available.", "SignUp-handleInitialize-RuntimeError-001", "nextjs");
|
|
47
|
-
return await signUp(
|
|
47
|
+
return await signUp({
|
|
48
48
|
flowType: EmbeddedFlowType.Registration,
|
|
49
49
|
...contextApplicationId && { applicationId: contextApplicationId },
|
|
50
|
-
...scopes && { scopes }
|
|
50
|
+
...scopes && { scopes },
|
|
51
|
+
...payload
|
|
51
52
|
});
|
|
52
53
|
};
|
|
53
54
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SignUp.js","names":["SignUp: FC<SignUpProps>","useThunderID"],"sources":["../../../../../src/client/components/presentation/SignUp/SignUp.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 {ThunderIDRuntimeError, EmbeddedFlowType} from '@thunderid/node';\nimport {BaseSignUp, BaseSignUpProps} from '@thunderid/react';\nimport {FC} from 'react';\nimport useThunderID from '../../../contexts/ThunderID/useThunderID';\n\n/**\n * Props for the SignUp component.\n */\nexport type SignUpProps = BaseSignUpProps;\n\n/**\n * A styled SignUp component that provides embedded sign-up flow with pre-built styling.\n * This component handles the API calls for sign-up and delegates UI logic to BaseSignUp.\n *\n * @example\n * ```tsx\n * import { SignUp } from '@thunderid/react';\n *\n * const App = () => {\n * return (\n * <SignUp\n * onSuccess={(response) => {\n * console.log('Sign-up successful:', response);\n * // Handle successful sign-up (e.g., redirect, show confirmation)\n * }}\n * onError={(error) => {\n * console.error('Sign-up failed:', error);\n * }}\n * onComplete={(redirectUrl) => {\n * // Platform-specific redirect handling (e.g., Next.js router.push)\n * router.push(redirectUrl); // or window.location.href = redirectUrl\n * }}\n * size=\"medium\"\n * variant=\"outlined\"\n * afterSignUpUrl=\"/welcome\"\n * />\n * );\n * };\n * ```\n */\nconst SignUp: FC<SignUpProps> = ({\n className,\n size = 'medium',\n variant = 'outlined',\n afterSignUpUrl,\n onError,\n}: SignUpProps) => {\n const {signUp, applicationId: contextApplicationId, scopes} = useThunderID();\n\n /**\n * Initialize the sign-up flow.\n */\n const handleInitialize = async (payload?: any): Promise<any> => {\n if (!signUp) {\n throw new ThunderIDRuntimeError(\n '`signUp` function is not available.',\n 'SignUp-handleInitialize-RuntimeError-001',\n 'nextjs',\n );\n }\n\n return (await signUp(\n
|
|
1
|
+
{"version":3,"file":"SignUp.js","names":["SignUp: FC<SignUpProps>","useThunderID"],"sources":["../../../../../src/client/components/presentation/SignUp/SignUp.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 {ThunderIDRuntimeError, EmbeddedFlowType} from '@thunderid/node';\nimport {BaseSignUp, BaseSignUpProps} from '@thunderid/react';\nimport {FC} from 'react';\nimport useThunderID from '../../../contexts/ThunderID/useThunderID';\n\n/**\n * Props for the SignUp component.\n */\nexport type SignUpProps = BaseSignUpProps;\n\n/**\n * A styled SignUp component that provides embedded sign-up flow with pre-built styling.\n * This component handles the API calls for sign-up and delegates UI logic to BaseSignUp.\n *\n * @example\n * ```tsx\n * import { SignUp } from '@thunderid/react';\n *\n * const App = () => {\n * return (\n * <SignUp\n * onSuccess={(response) => {\n * console.log('Sign-up successful:', response);\n * // Handle successful sign-up (e.g., redirect, show confirmation)\n * }}\n * onError={(error) => {\n * console.error('Sign-up failed:', error);\n * }}\n * onComplete={(redirectUrl) => {\n * // Platform-specific redirect handling (e.g., Next.js router.push)\n * router.push(redirectUrl); // or window.location.href = redirectUrl\n * }}\n * size=\"medium\"\n * variant=\"outlined\"\n * afterSignUpUrl=\"/welcome\"\n * />\n * );\n * };\n * ```\n */\nconst SignUp: FC<SignUpProps> = ({\n className,\n size = 'medium',\n variant = 'outlined',\n afterSignUpUrl,\n onError,\n}: SignUpProps) => {\n const {signUp, applicationId: contextApplicationId, scopes} = useThunderID();\n\n /**\n * Initialize the sign-up flow.\n */\n const handleInitialize = async (payload?: any): Promise<any> => {\n if (!signUp) {\n throw new ThunderIDRuntimeError(\n '`signUp` function is not available.',\n 'SignUp-handleInitialize-RuntimeError-001',\n 'nextjs',\n );\n }\n\n return (await signUp({\n flowType: EmbeddedFlowType.Registration,\n ...(contextApplicationId && {applicationId: contextApplicationId}),\n ...(scopes && {scopes}),\n ...payload,\n })) as unknown as Promise<any>;\n };\n\n /**\n * Handle sign-up steps.\n */\n const handleOnSubmit = async (payload: any): Promise<any> => {\n if (!signUp) {\n throw new ThunderIDRuntimeError(\n '`signUp` function is not available.',\n 'SignUp-handleOnSubmit-RuntimeError-001',\n 'nextjs',\n );\n }\n\n return (await signUp(payload)) as unknown as Promise<any>;\n };\n\n return (\n <BaseSignUp\n afterSignUpUrl={afterSignUpUrl}\n onInitialize={handleInitialize}\n onSubmit={handleOnSubmit}\n onError={onError}\n className={className}\n size={size}\n variant={variant}\n isInitialized={true}\n />\n );\n};\n\nexport default SignUp;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4DA,MAAMA,UAA2B,EAC/B,WACA,OAAO,UACP,UAAU,YACV,gBACA,cACiB;CACjB,MAAM,EAAC,QAAQ,eAAe,sBAAsB,WAAUC,sBAAc;;;;CAK5E,MAAM,mBAAmB,OAAO,YAAgC;AAC9D,MAAI,CAAC,OACH,OAAM,IAAI,sBACR,uCACA,4CACA,SACD;AAGH,SAAQ,MAAM,OAAO;GACnB,UAAU,iBAAiB;GAC3B,GAAI,wBAAwB,EAAC,eAAe,sBAAqB;GACjE,GAAI,UAAU,EAAC,QAAO;GACtB,GAAG;GACJ,CAAC;;;;;CAMJ,MAAM,iBAAiB,OAAO,YAA+B;AAC3D,MAAI,CAAC,OACH,OAAM,IAAI,sBACR,uCACA,0CACA,SACD;AAGH,SAAQ,MAAM,OAAO,QAAQ;;AAG/B,QACE,oBAAC;EACiB;EAChB,cAAc;EACd,UAAU;EACD;EACE;EACL;EACG;EACT,eAAe;GACf;;AAIN,qBAAe"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026, WSO2 LLC. (https://www.wso2.com).
|
|
3
|
+
*
|
|
4
|
+
* WSO2 LLC. licenses this file to you under the Apache License,
|
|
5
|
+
* Version 2.0 (the "License"); you may not use this file except
|
|
6
|
+
* in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing,
|
|
12
|
+
* software distributed under the License is distributed on an
|
|
13
|
+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
14
|
+
* KIND, either express or implied. See the License for the
|
|
15
|
+
* specific language governing permissions and limitations
|
|
16
|
+
* under the License.
|
|
17
|
+
*/
|
|
18
|
+
import { BaseUserAvatarProps } from '@thunderid/react';
|
|
19
|
+
import { FC } from 'react';
|
|
20
|
+
export type UserAvatarProps = Omit<BaseUserAvatarProps, 'user'>;
|
|
21
|
+
/**
|
|
22
|
+
* UserAvatar component renders an avatar for the currently signed-in user.
|
|
23
|
+
* This component is the Next.js-specific implementation that uses BaseUserAvatar
|
|
24
|
+
* and automatically retrieves the user data from ThunderID context.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```tsx
|
|
28
|
+
* <UserAvatar size={48} />
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
declare const UserAvatar: FC<UserAvatarProps>;
|
|
32
|
+
export default UserAvatar;
|
|
33
|
+
//# sourceMappingURL=UserAvatar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UserAvatar.d.ts","sourceRoot":"","sources":["../../../../../src/client/components/presentation/UserAvatar/UserAvatar.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH,OAAO,EAAiB,mBAAmB,EAAC,MAAM,kBAAkB,CAAC;AACrE,OAAO,EAAC,EAAE,EAAe,MAAM,OAAO,CAAC;AAGvC,MAAM,MAAM,eAAe,GAAG,IAAI,CAAC,mBAAmB,EAAE,MAAM,CAAC,CAAC;AAEhE;;;;;;;;;GASG;AACH,QAAA,MAAM,UAAU,EAAE,EAAE,CAAC,eAAe,CAInC,CAAC;AAEF,eAAe,UAAU,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
import useThunderID_default from "../../../contexts/ThunderID/useThunderID.js";
|
|
5
|
+
import { BaseUserAvatar } from "@thunderid/react";
|
|
6
|
+
import { jsx } from "react/jsx-runtime";
|
|
7
|
+
|
|
8
|
+
//#region src/client/components/presentation/UserAvatar/UserAvatar.tsx
|
|
9
|
+
/**
|
|
10
|
+
* UserAvatar component renders an avatar for the currently signed-in user.
|
|
11
|
+
* This component is the Next.js-specific implementation that uses BaseUserAvatar
|
|
12
|
+
* and automatically retrieves the user data from ThunderID context.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```tsx
|
|
16
|
+
* <UserAvatar size={48} />
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
const UserAvatar = (props) => {
|
|
20
|
+
const { user } = useThunderID_default();
|
|
21
|
+
return /* @__PURE__ */ jsx(BaseUserAvatar, {
|
|
22
|
+
user,
|
|
23
|
+
...props
|
|
24
|
+
});
|
|
25
|
+
};
|
|
26
|
+
var UserAvatar_default = UserAvatar;
|
|
27
|
+
|
|
28
|
+
//#endregion
|
|
29
|
+
export { UserAvatar_default as default };
|
|
30
|
+
//# sourceMappingURL=UserAvatar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UserAvatar.js","names":["UserAvatar: FC<UserAvatarProps>","useThunderID"],"sources":["../../../../../src/client/components/presentation/UserAvatar/UserAvatar.tsx"],"sourcesContent":["/**\n * Copyright (c) 2026, 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 {BaseUserAvatar, BaseUserAvatarProps} from '@thunderid/react';\nimport {FC, ReactElement} from 'react';\nimport useThunderID from '../../../contexts/ThunderID/useThunderID';\n\nexport type UserAvatarProps = Omit<BaseUserAvatarProps, 'user'>;\n\n/**\n * UserAvatar component renders an avatar for the currently signed-in user.\n * This component is the Next.js-specific implementation that uses BaseUserAvatar\n * and automatically retrieves the user data from ThunderID context.\n *\n * @example\n * ```tsx\n * <UserAvatar size={48} />\n * ```\n */\nconst UserAvatar: FC<UserAvatarProps> = (props: UserAvatarProps): ReactElement => {\n const {user} = useThunderID();\n\n return <BaseUserAvatar user={user} {...props} />;\n};\n\nexport default UserAvatar;\n"],"mappings":";;;;;;;;;;;;;;;;;;AAoCA,MAAMA,cAAmC,UAAyC;CAChF,MAAM,EAAC,SAAQC,sBAAc;AAE7B,QAAO,oBAAC;EAAqB;EAAM,GAAI;GAAS;;AAGlD,yBAAe"}
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* specific language governing permissions and limitations
|
|
16
16
|
* under the License.
|
|
17
17
|
*/
|
|
18
|
-
import { UpdateMeProfileConfig, User, UserProfile } from '@thunderid/node';
|
|
18
|
+
import { FlowMetadataResponse, UpdateMeProfileConfig, User, UserProfile } from '@thunderid/node';
|
|
19
19
|
import { ThunderIDProviderProps } from '@thunderid/react';
|
|
20
20
|
import { FC, PropsWithChildren } from 'react';
|
|
21
21
|
import { ThunderIDContextProps } from './ThunderIDContext';
|
|
@@ -31,6 +31,11 @@ export type ThunderIDClientProviderProps = Partial<Omit<ThunderIDProviderProps,
|
|
|
31
31
|
redirectUrl?: string;
|
|
32
32
|
success: boolean;
|
|
33
33
|
}>;
|
|
34
|
+
/**
|
|
35
|
+
* Flow metadata fetched server-side ahead of time, seeding `FlowMetaProvider` so it can skip
|
|
36
|
+
* its own initial client-side fetch (avoiding a flash of untranslated i18n keys).
|
|
37
|
+
*/
|
|
38
|
+
initialMeta?: FlowMetadataResponse | null;
|
|
34
39
|
isSignedIn: boolean;
|
|
35
40
|
organizationHandle: ThunderIDContextProps['organizationHandle'];
|
|
36
41
|
refreshToken: () => Promise<RefreshResult>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ThunderIDProvider.d.ts","sourceRoot":"","sources":["../../../../src/client/contexts/ThunderID/ThunderIDProvider.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH,OAAO,
|
|
1
|
+
{"version":3,"file":"ThunderIDProvider.d.ts","sourceRoot":"","sources":["../../../../src/client/contexts/ThunderID/ThunderIDProvider.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH,OAAO,EAEL,oBAAoB,EAEpB,qBAAqB,EACrB,IAAI,EACJ,WAAW,EAEZ,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAQL,sBAAsB,EAEvB,MAAM,kBAAkB,CAAC;AAI1B,OAAO,EAAC,EAAE,EAAE,iBAAiB,EAAkD,MAAM,OAAO,CAAC;AAC7F,OAAyB,EAAC,qBAAqB,EAAC,MAAM,oBAAoB,CAAC;AAC3E,OAAO,EAAC,aAAa,EAAC,MAAM,sCAAsC,CAAC;AAGnE;;GAEG;AACH,MAAM,MAAM,4BAA4B,GAAG,OAAO,CAAC,IAAI,CAAC,sBAAsB,EAAE,SAAS,GAAG,UAAU,CAAC,CAAC,GACtG,IAAI,CAAC,sBAAsB,EAAE,SAAS,GAAG,UAAU,CAAC,GAAG;IACrD,aAAa,EAAE,qBAAqB,CAAC,eAAe,CAAC,CAAC;IACtD,YAAY,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAClC,mBAAmB,EAAE,CACnB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,YAAY,CAAC,EAAE,MAAM,KAClB,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAC,CAAC,CAAC;IACvE;;;OAGG;IACH,WAAW,CAAC,EAAE,oBAAoB,GAAG,IAAI,CAAC;IAC1C,UAAU,EAAE,OAAO,CAAC;IACpB,kBAAkB,EAAE,qBAAqB,CAAC,oBAAoB,CAAC,CAAC;IAChE,YAAY,EAAE,MAAM,OAAO,CAAC,aAAa,CAAC,CAAC;IAC3C,MAAM,EAAE,qBAAqB,CAAC,QAAQ,CAAC,CAAC;IACxC,OAAO,EAAE,qBAAqB,CAAC,SAAS,CAAC,CAAC;IAC1C,MAAM,EAAE,qBAAqB,CAAC,QAAQ,CAAC,CAAC;IACxC,aAAa,EAAE,CACb,aAAa,EAAE,qBAAqB,EACpC,SAAS,CAAC,EAAE,MAAM,KACf,OAAO,CAAC;QAAC,IAAI,EAAE;YAAC,IAAI,EAAE,IAAI,CAAA;SAAC,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAC,CAAC,CAAC;IACpE,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;IAClB,WAAW,EAAE,WAAW,CAAC;CAC1B,CAAC;AAEJ,QAAA,MAAM,uBAAuB,EAAE,EAAE,CAAC,iBAAiB,CAAC,4BAA4B,CAAC,CA4ThF,CAAC;AAEF,eAAe,uBAAuB,CAAC"}
|
|
@@ -4,13 +4,13 @@
|
|
|
4
4
|
import logger_default from "../../../utils/logger.js";
|
|
5
5
|
import ThunderIDContext_default from "./ThunderIDContext.js";
|
|
6
6
|
import { ThunderIDRuntimeError, generateFlattenedUserProfile } from "@thunderid/node";
|
|
7
|
-
import { FlowMetaProvider, FlowProvider, I18nProvider, ThemeProvider, UserProvider, getActiveTheme } from "@thunderid/react";
|
|
7
|
+
import { FlowMetaProvider, FlowProvider, I18nProvider, ThemeProvider, ThunderIDContext, UserProvider, getActiveTheme } from "@thunderid/react";
|
|
8
8
|
import { useRouter, useSearchParams } from "next/navigation";
|
|
9
9
|
import { useEffect, useMemo, useRef, useState } from "react";
|
|
10
10
|
import { jsx } from "react/jsx-runtime";
|
|
11
11
|
|
|
12
12
|
//#region src/client/contexts/ThunderID/ThunderIDProvider.tsx
|
|
13
|
-
const ThunderIDClientProvider = ({ baseUrl, children, signIn, clearSession, refreshToken, signOut, signUp, handleOAuthCallback, preferences, isSignedIn, signInUrl, signUpUrl, user: _user, userProfile: _userProfile, updateProfile, applicationId, organizationHandle, scopes }) => {
|
|
13
|
+
const ThunderIDClientProvider = ({ baseUrl, children, signIn, clearSession, refreshToken, signOut, signUp, handleOAuthCallback, preferences, isSignedIn, signInUrl, signUpUrl, user: _user, userProfile: _userProfile, updateProfile, applicationId, organizationHandle, scopes, initialMeta = null }) => {
|
|
14
14
|
const reRenderCheckRef = useRef(false);
|
|
15
15
|
const router = useRouter();
|
|
16
16
|
const searchParams = useSearchParams();
|
|
@@ -132,21 +132,75 @@ const ThunderIDClientProvider = ({ baseUrl, children, signIn, clearSession, refr
|
|
|
132
132
|
profile: payload
|
|
133
133
|
}));
|
|
134
134
|
};
|
|
135
|
+
const unsupported = (name) => {
|
|
136
|
+
return () => Promise.reject(new ThunderIDRuntimeError(`\`${name}\` is not supported in @thunderid/nextjs.`, `ThunderIDClientProvider-${name}-NotSupportedError-001`, "nextjs"));
|
|
137
|
+
};
|
|
138
|
+
const reactContextValue = useMemo(() => ({
|
|
139
|
+
afterSignInUrl: void 0,
|
|
140
|
+
applicationId,
|
|
141
|
+
baseUrl,
|
|
142
|
+
clearSession,
|
|
143
|
+
clientId: void 0,
|
|
144
|
+
discovery: { wellKnown: null },
|
|
145
|
+
exchangeToken: unsupported("exchangeToken"),
|
|
146
|
+
getAccessToken: unsupported("getAccessToken"),
|
|
147
|
+
getDecodedIdToken: unsupported("getDecodedIdToken"),
|
|
148
|
+
getIdToken: unsupported("getIdToken"),
|
|
149
|
+
getStorageManager: () => Promise.resolve(null),
|
|
150
|
+
http: {
|
|
151
|
+
request: unsupported("http.request"),
|
|
152
|
+
requestAll: unsupported("http.requestAll")
|
|
153
|
+
},
|
|
154
|
+
instanceId: 0,
|
|
155
|
+
isInitialized: !isLoading,
|
|
156
|
+
isLoading,
|
|
157
|
+
isMetaLoading: false,
|
|
158
|
+
isSignedIn,
|
|
159
|
+
meta: initialMeta ?? null,
|
|
160
|
+
organizationHandle,
|
|
161
|
+
reInitialize: unsupported("reInitialize"),
|
|
162
|
+
recover: unsupported("recover"),
|
|
163
|
+
resolveFlowTemplateLiterals: (text) => text ?? "",
|
|
164
|
+
scopes,
|
|
165
|
+
signIn: handleSignIn,
|
|
166
|
+
signInSilently: unsupported("signInSilently"),
|
|
167
|
+
signInUrl,
|
|
168
|
+
signOut: handleSignOut,
|
|
169
|
+
signUp: handleSignUp,
|
|
170
|
+
signUpUrl,
|
|
171
|
+
user
|
|
172
|
+
}), [
|
|
173
|
+
applicationId,
|
|
174
|
+
baseUrl,
|
|
175
|
+
clearSession,
|
|
176
|
+
isLoading,
|
|
177
|
+
isSignedIn,
|
|
178
|
+
organizationHandle,
|
|
179
|
+
scopes,
|
|
180
|
+
signInUrl,
|
|
181
|
+
signUpUrl,
|
|
182
|
+
user,
|
|
183
|
+
initialMeta
|
|
184
|
+
]);
|
|
135
185
|
return /* @__PURE__ */ jsx(ThunderIDContext_default.Provider, {
|
|
136
186
|
value: contextValue,
|
|
137
|
-
children: /* @__PURE__ */ jsx(
|
|
138
|
-
|
|
139
|
-
children: /* @__PURE__ */ jsx(
|
|
140
|
-
|
|
141
|
-
children: /* @__PURE__ */ jsx(
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
children: /* @__PURE__ */ jsx(
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
187
|
+
children: /* @__PURE__ */ jsx(ThunderIDContext.Provider, {
|
|
188
|
+
value: reactContextValue,
|
|
189
|
+
children: /* @__PURE__ */ jsx(I18nProvider, {
|
|
190
|
+
preferences: preferences?.i18n,
|
|
191
|
+
children: /* @__PURE__ */ jsx(FlowMetaProvider, {
|
|
192
|
+
enabled: preferences?.resolveFromMeta !== false,
|
|
193
|
+
initialMeta,
|
|
194
|
+
children: /* @__PURE__ */ jsx(ThemeProvider, {
|
|
195
|
+
theme: preferences?.theme?.overrides,
|
|
196
|
+
mode: getActiveTheme(preferences?.theme?.mode),
|
|
197
|
+
children: /* @__PURE__ */ jsx(FlowProvider, { children: /* @__PURE__ */ jsx(UserProvider, {
|
|
198
|
+
profile: userProfile,
|
|
199
|
+
onUpdateProfile: handleProfileUpdate,
|
|
200
|
+
updateProfile,
|
|
201
|
+
children
|
|
202
|
+
}) })
|
|
203
|
+
})
|
|
150
204
|
})
|
|
151
205
|
})
|
|
152
206
|
})
|