@thunderid/nextjs 1.11.0 → 1.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ThunderIDNextClient.d.ts +8 -1
- package/dist/ThunderIDNextClient.d.ts.map +1 -1
- package/dist/ThunderIDNextClient.js +10 -0
- package/dist/ThunderIDNextClient.js.map +1 -1
- package/dist/cjs/ThunderIDNextClient.cjs +10 -0
- package/dist/cjs/ThunderIDNextClient.cjs.map +1 -1
- package/dist/cjs/client/components/account/UserProfile/UserProfile.cjs +11 -1
- package/dist/cjs/client/components/account/UserProfile/UserProfile.cjs.map +1 -1
- package/dist/cjs/client/components/account/VerifyAttribute/VerifyAttribute.cjs +80 -0
- package/dist/cjs/client/components/account/VerifyAttribute/VerifyAttribute.cjs.map +1 -0
- package/dist/cjs/client/contexts/ThunderID/ThunderIDProvider.cjs +12 -0
- 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/actions/auth/executeSelfFlowAction.cjs +47 -0
- package/dist/cjs/server/actions/auth/executeSelfFlowAction.cjs.map +1 -0
- package/dist/client/components/account/UserProfile/UserProfile.d.ts +7 -1
- package/dist/client/components/account/UserProfile/UserProfile.d.ts.map +1 -1
- package/dist/client/components/account/UserProfile/UserProfile.js +12 -2
- package/dist/client/components/account/UserProfile/UserProfile.js.map +1 -1
- package/dist/client/components/account/VerifyAttribute/VerifyAttribute.d.ts +41 -0
- package/dist/client/components/account/VerifyAttribute/VerifyAttribute.d.ts.map +1 -0
- package/dist/client/components/account/VerifyAttribute/VerifyAttribute.js +75 -0
- package/dist/client/components/account/VerifyAttribute/VerifyAttribute.js.map +1 -0
- package/dist/client/contexts/ThunderID/ThunderIDProvider.d.ts.map +1 -1
- package/dist/client/contexts/ThunderID/ThunderIDProvider.js +12 -0
- 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/actions/auth/executeSelfFlowAction.d.ts +20 -0
- package/dist/server/actions/auth/executeSelfFlowAction.d.ts.map +1 -0
- package/dist/server/actions/auth/executeSelfFlowAction.js +45 -0
- package/dist/server/actions/auth/executeSelfFlowAction.js.map +1 -0
- package/package.json +3 -3
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
'use server';
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
const require_rolldown_runtime = require('../../../_virtual/rolldown_runtime.cjs');
|
|
5
|
+
const require_getSessionId = require('../getSessionId.cjs');
|
|
6
|
+
const require_getClient = require('../../getClient.cjs');
|
|
7
|
+
let __thunderid_node = require("@thunderid/node");
|
|
8
|
+
__thunderid_node = require_rolldown_runtime.__toESM(__thunderid_node);
|
|
9
|
+
|
|
10
|
+
//#region src/server/actions/auth/executeSelfFlowAction.ts
|
|
11
|
+
/**
|
|
12
|
+
* Executes one step of a `SELF` flow, such as self attribute verification, for the signed-in
|
|
13
|
+
* user, with the access token of the server-held session. The request carries no session ID, token
|
|
14
|
+
* or user ID: the session comes from the request cookie, and only the fields of a step are forwarded.
|
|
15
|
+
* A new flow must be a `SELF` flow named by its handle.
|
|
16
|
+
*
|
|
17
|
+
* Never throws across the server action boundary. A failure carries only its HTTP status, never the
|
|
18
|
+
* reply of the server, which the browser reports as a refusal.
|
|
19
|
+
*/
|
|
20
|
+
const executeSelfFlowAction = async (request) => {
|
|
21
|
+
const sessionId = await require_getSessionId.default();
|
|
22
|
+
if (!sessionId) return {
|
|
23
|
+
statusCode: 401,
|
|
24
|
+
success: false
|
|
25
|
+
};
|
|
26
|
+
const checked = (0, __thunderid_node.parseSelfFlowRequest)(request);
|
|
27
|
+
if ("invalid" in checked) return {
|
|
28
|
+
statusCode: 400,
|
|
29
|
+
success: false
|
|
30
|
+
};
|
|
31
|
+
try {
|
|
32
|
+
return {
|
|
33
|
+
data: await require_getClient.default().executeEmbeddedSelfFlow(checked.request, sessionId),
|
|
34
|
+
success: true
|
|
35
|
+
};
|
|
36
|
+
} catch (error) {
|
|
37
|
+
return error instanceof __thunderid_node.ThunderIDAPIError && error.statusCode ? {
|
|
38
|
+
statusCode: error.statusCode,
|
|
39
|
+
success: false
|
|
40
|
+
} : { success: false };
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
var executeSelfFlowAction_default = executeSelfFlowAction;
|
|
44
|
+
|
|
45
|
+
//#endregion
|
|
46
|
+
exports.default = executeSelfFlowAction_default;
|
|
47
|
+
//# sourceMappingURL=executeSelfFlowAction.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executeSelfFlowAction.cjs","names":["sessionId: string | undefined","getSessionId","checked: SelfFlowRequestParseResult","getClient","ThunderIDAPIError"],"sources":["../../../../../src/server/actions/auth/executeSelfFlowAction.ts"],"sourcesContent":["// Copyright 2026 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\n'use server';\n\nimport {\n EmbeddedSelfFlowResponse,\n SelfFlowRequestParseResult,\n ThunderIDAPIError,\n parseSelfFlowRequest,\n} from '@thunderid/node';\nimport getClient from '../../getClient';\nimport getSessionId from '../getSessionId';\n\nexport type ExecuteSelfFlowActionResult =\n | {data: EmbeddedSelfFlowResponse; success: true}\n | {statusCode?: number; success: false};\n\n/**\n * Executes one step of a `SELF` flow, such as self attribute verification, for the signed-in\n * user, with the access token of the server-held session. The request carries no session ID, token\n * or user ID: the session comes from the request cookie, and only the fields of a step are forwarded.\n * A new flow must be a `SELF` flow named by its handle.\n *\n * Never throws across the server action boundary. A failure carries only its HTTP status, never the\n * reply of the server, which the browser reports as a refusal.\n */\nconst executeSelfFlowAction = async (request: unknown): Promise<ExecuteSelfFlowActionResult> => {\n const sessionId: string | undefined = await getSessionId();\n\n if (!sessionId) {\n return {statusCode: 401, success: false};\n }\n\n const checked: SelfFlowRequestParseResult = parseSelfFlowRequest(request);\n\n if ('invalid' in checked) {\n return {statusCode: 400, success: false};\n }\n\n try {\n const data: EmbeddedSelfFlowResponse = await getClient().executeEmbeddedSelfFlow(checked.request, sessionId);\n\n return {data, success: true};\n } catch (error) {\n return error instanceof ThunderIDAPIError && error.statusCode\n ? {statusCode: error.statusCode, success: false}\n : {success: false};\n }\n};\n\nexport default executeSelfFlowAction;\n"],"mappings":";;;;;;;;;;;;;;;;;;;AA2BA,MAAM,wBAAwB,OAAO,YAA2D;CAC9F,MAAMA,YAAgC,MAAMC,8BAAc;AAE1D,KAAI,CAAC,UACH,QAAO;EAAC,YAAY;EAAK,SAAS;EAAM;CAG1C,MAAMC,qDAA2D,QAAQ;AAEzE,KAAI,aAAa,QACf,QAAO;EAAC,YAAY;EAAK,SAAS;EAAM;AAG1C,KAAI;AAGF,SAAO;GAAC,MAF+B,MAAMC,2BAAW,CAAC,wBAAwB,QAAQ,SAAS,UAAU;GAE9F,SAAS;GAAK;UACrB,OAAO;AACd,SAAO,iBAAiBC,sCAAqB,MAAM,aAC/C;GAAC,YAAY,MAAM;GAAY,SAAS;GAAM,GAC9C,EAAC,SAAS,OAAM;;;AAIxB,oCAAe"}
|
|
@@ -4,7 +4,13 @@ import { FC } from 'react';
|
|
|
4
4
|
* Props for the UserProfile component.
|
|
5
5
|
* Extends BaseUserProfileProps but makes the user prop optional since it will be obtained from useThunderID
|
|
6
6
|
*/
|
|
7
|
-
export type UserProfileProps = Omit<BaseUserProfileProps, 'user' | 'profile' | 'flattenedProfile'
|
|
7
|
+
export type UserProfileProps = Omit<BaseUserProfileProps, 'user' | 'profile' | 'flattenedProfile'> & {
|
|
8
|
+
/**
|
|
9
|
+
* Handle of the `SELF` flow that verifies an attribute. Defaults to the server's shipped
|
|
10
|
+
* `default-self-attribute-verification-flow`.
|
|
11
|
+
*/
|
|
12
|
+
verificationFlowHandle?: string;
|
|
13
|
+
};
|
|
8
14
|
/**
|
|
9
15
|
* UserProfile component displays the authenticated user's profile information in a
|
|
10
16
|
* structured and styled format. It shows user details such as display name, email,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UserProfile.d.ts","sourceRoot":"","sources":["../../../../../src/client/components/account/UserProfile/UserProfile.tsx"],"names":[],"mappings":"AAMA,OAAO,
|
|
1
|
+
{"version":3,"file":"UserProfile.d.ts","sourceRoot":"","sources":["../../../../../src/client/components/account/UserProfile/UserProfile.tsx"],"names":[],"mappings":"AAMA,OAAO,EAEL,oBAAoB,EAIrB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAC,EAAE,EAAoC,MAAM,OAAO,CAAC;AAK5D;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GAAG,IAAI,CAAC,oBAAoB,EAAE,MAAM,GAAG,SAAS,GAAG,kBAAkB,CAAC,GAAG;IACnG;;;OAGG;IACH,sBAAsB,CAAC,EAAE,MAAM,CAAC;CACjC,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,QAAA,MAAM,WAAW,EAAE,EAAE,CAAC,gBAAgB,CAyErC,CAAC;AAEF,eAAe,WAAW,CAAC"}
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
|
|
4
4
|
import getSessionId_default from "../../../../server/actions/getSessionId.js";
|
|
5
5
|
import useThunderID_default from "../../../contexts/ThunderID/useThunderID.js";
|
|
6
|
-
import
|
|
6
|
+
import VerifyAttribute_default from "../VerifyAttribute/VerifyAttribute.js";
|
|
7
|
+
import { AttributeVerificationConstants, deepMerge } from "@thunderid/node";
|
|
7
8
|
import { BaseUserProfile, useTranslation, useUser } from "@thunderid/react";
|
|
8
9
|
import { useState } from "react";
|
|
9
10
|
import { jsx } from "react/jsx-runtime";
|
|
@@ -32,7 +33,7 @@ import { jsx } from "react/jsx-runtime";
|
|
|
32
33
|
* />
|
|
33
34
|
* ```
|
|
34
35
|
*/
|
|
35
|
-
const UserProfile = ({ preferences, editable = true,...rest }) => {
|
|
36
|
+
const UserProfile = ({ preferences, editable = true, verificationFlowHandle = AttributeVerificationConstants.DEFAULT_FLOW_HANDLE,...rest }) => {
|
|
36
37
|
const { preferences: contextPreferences } = useThunderID_default();
|
|
37
38
|
const { profile, flattenedProfile, onUpdateProfile, updateProfile, userSchema } = useUser();
|
|
38
39
|
const resolvedPreferences = {
|
|
@@ -56,7 +57,16 @@ const UserProfile = ({ preferences, editable = true,...rest }) => {
|
|
|
56
57
|
if (result.success) onUpdateProfile(result.data.user);
|
|
57
58
|
else setError(result.error || t("user.profile.update.generic.error"));
|
|
58
59
|
};
|
|
60
|
+
const renderVerification = ({ attribute, attributeDisplayName, onCancel }) => /* @__PURE__ */ jsx(VerifyAttribute_default, {
|
|
61
|
+
attribute,
|
|
62
|
+
attributeDisplayName,
|
|
63
|
+
flowHandle: verificationFlowHandle,
|
|
64
|
+
preferences: resolvedPreferences,
|
|
65
|
+
onCancel,
|
|
66
|
+
onDone: onCancel
|
|
67
|
+
}, attribute);
|
|
59
68
|
return /* @__PURE__ */ jsx(BaseUserProfile, {
|
|
69
|
+
renderVerification: isEditableProfile ? renderVerification : void 0,
|
|
60
70
|
profile,
|
|
61
71
|
flattenedProfile,
|
|
62
72
|
userSchema,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UserProfile.js","names":["UserProfile: FC<UserProfileProps>","useThunderID","isEditableProfile: boolean","result: {data: {user: User}; error: string; success: boolean}","getSessionId"],"sources":["../../../../../src/client/components/account/UserProfile/UserProfile.tsx"],"sourcesContent":["// Copyright 2025 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\n'use client';\n\nimport {deepMerge, User} from '@thunderid/node';\nimport {BaseUserProfile
|
|
1
|
+
{"version":3,"file":"UserProfile.js","names":["UserProfile: FC<UserProfileProps>","useThunderID","isEditableProfile: boolean","result: {data: {user: User}; error: string; success: boolean}","getSessionId","VerifyAttribute"],"sources":["../../../../../src/client/components/account/UserProfile/UserProfile.tsx"],"sourcesContent":["// Copyright 2025 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\n'use client';\n\nimport {AttributeVerificationConstants, deepMerge, User} from '@thunderid/node';\nimport {\n BaseUserProfile,\n BaseUserProfileProps,\n BaseUserProfileVerificationRenderProps,\n useUser,\n useTranslation,\n} from '@thunderid/react';\nimport {FC, ReactElement, ReactNode, useState} from 'react';\nimport useThunderID from '../../../contexts/ThunderID/useThunderID';\nimport getSessionId from '../../../../server/actions/getSessionId';\nimport VerifyAttribute from '../VerifyAttribute/VerifyAttribute';\n\n/**\n * Props for the UserProfile component.\n * Extends BaseUserProfileProps but makes the user prop optional since it will be obtained from useThunderID\n */\nexport type UserProfileProps = Omit<BaseUserProfileProps, 'user' | 'profile' | 'flattenedProfile'> & {\n /**\n * Handle of the `SELF` flow that verifies an attribute. Defaults to the server's shipped\n * `default-self-attribute-verification-flow`.\n */\n verificationFlowHandle?: string;\n};\n\n/**\n * UserProfile component displays the authenticated user's profile information in a\n * structured and styled format. It shows user details such as display name, email,\n * username, and other available profile information from ThunderID.\n *\n * This component is the React-specific implementation that uses the BaseUserProfile\n * and automatically retrieves the user data from ThunderID context if not provided.\n *\n * @example\n * ```tsx\n * // Basic usage - will use user from ThunderID context\n * <UserProfile />\n *\n * // With explicit user data\n * <UserProfile user={specificUser} />\n *\n * // With card layout and custom fallback\n * <UserProfile\n * cardLayout={true}\n * fallback={<div>Please sign in to view your profile</div>}\n * />\n * ```\n */\nconst UserProfile: FC<UserProfileProps> = ({\n preferences,\n editable = true,\n verificationFlowHandle = AttributeVerificationConstants.DEFAULT_FLOW_HANDLE,\n ...rest\n}: UserProfileProps): ReactElement => {\n const {preferences: contextPreferences} = useThunderID();\n const {profile, flattenedProfile, onUpdateProfile, updateProfile, userSchema} = useUser();\n const resolvedPreferences = {\n ...contextPreferences,\n ...preferences,\n user: {\n ...contextPreferences?.user,\n ...preferences?.user,\n },\n };\n const {t} = useTranslation(resolvedPreferences?.i18n);\n const isEditableProfile: boolean = resolvedPreferences?.user?.fetchUserProfile === false ? false : editable;\n\n const [error, setError] = useState<string | null>(null);\n\n const handleProfileUpdate = async (payload: any): Promise<void> => {\n setError(null);\n\n const updatedAttributes = deepMerge((profile?.['attributes'] as Record<string, unknown>) ?? {}, payload);\n\n Object.keys(updatedAttributes).forEach((key) => {\n if (updatedAttributes[key] === undefined || updatedAttributes[key] === null) {\n delete updatedAttributes[key];\n }\n });\n\n const result: {data: {user: User}; error: string; success: boolean} = await updateProfile(\n {payload: updatedAttributes},\n await getSessionId(),\n );\n\n if (result.success) {\n onUpdateProfile(result.data.user);\n } else {\n setError(result.error || t('user.profile.update.generic.error'));\n }\n };\n\n const renderVerification = ({\n attribute,\n attributeDisplayName,\n onCancel,\n }: BaseUserProfileVerificationRenderProps): ReactNode => (\n <VerifyAttribute\n key={attribute}\n attribute={attribute}\n attributeDisplayName={attributeDisplayName}\n flowHandle={verificationFlowHandle}\n preferences={resolvedPreferences}\n onCancel={onCancel}\n onDone={onCancel}\n />\n );\n\n return (\n <BaseUserProfile\n renderVerification={isEditableProfile ? renderVerification : undefined}\n profile={profile!}\n flattenedProfile={flattenedProfile!}\n userSchema={userSchema}\n editable={isEditableProfile}\n onUpdate={isEditableProfile ? handleProfileUpdate : undefined}\n error={error}\n preferences={resolvedPreferences}\n {...rest}\n />\n );\n};\n\nexport default UserProfile;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqDA,MAAMA,eAAqC,EACzC,aACA,WAAW,MACX,yBAAyB,+BAA+B,oBACxD,GAAG,WACiC;CACpC,MAAM,EAAC,aAAa,uBAAsBC,sBAAc;CACxD,MAAM,EAAC,SAAS,kBAAkB,iBAAiB,eAAe,eAAc,SAAS;CACzF,MAAM,sBAAsB;EAC1B,GAAG;EACH,GAAG;EACH,MAAM;GACJ,GAAG,oBAAoB;GACvB,GAAG,aAAa;GACjB;EACF;CACD,MAAM,EAAC,MAAK,eAAe,qBAAqB,KAAK;CACrD,MAAMC,oBAA6B,qBAAqB,MAAM,qBAAqB,QAAQ,QAAQ;CAEnG,MAAM,CAAC,OAAO,YAAY,SAAwB,KAAK;CAEvD,MAAM,sBAAsB,OAAO,YAAgC;AACjE,WAAS,KAAK;EAEd,MAAM,oBAAoB,UAAW,UAAU,iBAA6C,EAAE,EAAE,QAAQ;AAExG,SAAO,KAAK,kBAAkB,CAAC,SAAS,QAAQ;AAC9C,OAAI,kBAAkB,SAAS,UAAa,kBAAkB,SAAS,KACrE,QAAO,kBAAkB;IAE3B;EAEF,MAAMC,SAAgE,MAAM,cAC1E,EAAC,SAAS,mBAAkB,EAC5B,MAAMC,sBAAc,CACrB;AAED,MAAI,OAAO,QACT,iBAAgB,OAAO,KAAK,KAAK;MAEjC,UAAS,OAAO,SAAS,EAAE,oCAAoC,CAAC;;CAIpE,MAAM,sBAAsB,EAC1B,WACA,sBACA,eAEA,oBAACC;EAEY;EACW;EACtB,YAAY;EACZ,aAAa;EACH;EACV,QAAQ;IANH,UAOL;AAGJ,QACE,oBAAC;EACC,oBAAoB,oBAAoB,qBAAqB;EACpD;EACS;EACN;EACZ,UAAU;EACV,UAAU,oBAAoB,sBAAsB;EAC7C;EACP,aAAa;EACb,GAAI;GACJ;;AAIN,0BAAe"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { BaseVerifyAttributeProps } from '@thunderid/react';
|
|
2
|
+
import { FC } from 'react';
|
|
3
|
+
/**
|
|
4
|
+
* Props for the VerifyAttribute component.
|
|
5
|
+
* Mirrors `@thunderid/react`'s `VerifyAttributeProps`, so a consumer moving between the React and
|
|
6
|
+
* Next.js SDKs doesn't need to change how they call it.
|
|
7
|
+
*/
|
|
8
|
+
export type VerifyAttributeProps = Omit<BaseVerifyAttributeProps, 'onInitialize' | 'onSubmit' | 'isInitialized'> & {
|
|
9
|
+
/**
|
|
10
|
+
* Name of the signed-in user's attribute to verify, such as `email`. Only a top-level, single-valued
|
|
11
|
+
* `email` or `mobile` property of the user's schema can be verified; any other is refused without a
|
|
12
|
+
* request, through `onError`, with `VerifyAttribute-handleInitialize-RuntimeError-001`.
|
|
13
|
+
*/
|
|
14
|
+
attribute: string;
|
|
15
|
+
/**
|
|
16
|
+
* Handle of the `SELF` flow to run. Defaults to the server's shipped
|
|
17
|
+
* `default-self-attribute-verification-flow`.
|
|
18
|
+
*/
|
|
19
|
+
flowHandle?: string;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* VerifyAttribute verifies one of the signed-in user's attributes, such as their email address, by
|
|
23
|
+
* running a self attribute verification flow named by `flowHandle`.
|
|
24
|
+
*
|
|
25
|
+
* This is the Next.js-specific implementation: it renders `BaseVerifyAttribute` from
|
|
26
|
+
* `@thunderid/react`, but runs every step through `executeSelfFlowAction` (a server action that
|
|
27
|
+
* attaches the server-held session's access token) instead of calling the ThunderID server from the
|
|
28
|
+
* browser. Once the server records the verification, and when the user selects Done after a link is
|
|
29
|
+
* sent, it re-reads the user's profile.
|
|
30
|
+
*
|
|
31
|
+
* Mount it with a `key` per attribute: each mount starts a new verification and sends a new code or
|
|
32
|
+
* link.
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```tsx
|
|
36
|
+
* <VerifyAttribute attribute="email" onComplete={() => setOpen(false)} onCancel={() => setOpen(false)} />
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
declare const VerifyAttribute: FC<VerifyAttributeProps>;
|
|
40
|
+
export default VerifyAttribute;
|
|
41
|
+
//# sourceMappingURL=VerifyAttribute.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VerifyAttribute.d.ts","sourceRoot":"","sources":["../../../../../src/client/components/account/VerifyAttribute/VerifyAttribute.tsx"],"names":[],"mappings":"AAeA,OAAO,EAAsB,wBAAwB,EAAU,MAAM,kBAAkB,CAAC;AACxF,OAAO,EAAC,EAAE,EAA4B,MAAM,OAAO,CAAC;AAMpD;;;;GAIG;AACH,MAAM,MAAM,oBAAoB,GAAG,IAAI,CAAC,wBAAwB,EAAE,cAAc,GAAG,UAAU,GAAG,eAAe,CAAC,GAAG;IACjH;;;;OAIG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAmBF;;;;;;;;;;;;;;;;;GAiBG;AACH,QAAA,MAAM,eAAe,EAAE,EAAE,CAAC,oBAAoB,CAyD7C,CAAC;AAEF,eAAe,eAAe,CAAC"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
import useThunderID_default from "../../../contexts/ThunderID/useThunderID.js";
|
|
5
|
+
import executeSelfFlowAction_default from "../../../../server/actions/auth/executeSelfFlowAction.js";
|
|
6
|
+
import { AttributeVerificationConstants, EmbeddedFlowType, ThunderIDAPIError, ThunderIDRuntimeError, isVerifiableAttribute, startCase } from "@thunderid/node";
|
|
7
|
+
import { BaseVerifyAttribute, useUser } from "@thunderid/react";
|
|
8
|
+
import { useCallback } from "react";
|
|
9
|
+
import { jsx } from "react/jsx-runtime";
|
|
10
|
+
|
|
11
|
+
//#region src/client/components/account/VerifyAttribute/VerifyAttribute.tsx
|
|
12
|
+
const execute = async (payload) => {
|
|
13
|
+
const result = await executeSelfFlowAction_default(payload);
|
|
14
|
+
if (!result.success) throw new ThunderIDAPIError("SELF flow request failed", "VerifyAttribute-execute-ResponseError-001", "nextjs", result.statusCode);
|
|
15
|
+
return result.data;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* VerifyAttribute verifies one of the signed-in user's attributes, such as their email address, by
|
|
19
|
+
* running a self attribute verification flow named by `flowHandle`.
|
|
20
|
+
*
|
|
21
|
+
* This is the Next.js-specific implementation: it renders `BaseVerifyAttribute` from
|
|
22
|
+
* `@thunderid/react`, but runs every step through `executeSelfFlowAction` (a server action that
|
|
23
|
+
* attaches the server-held session's access token) instead of calling the ThunderID server from the
|
|
24
|
+
* browser. Once the server records the verification, and when the user selects Done after a link is
|
|
25
|
+
* sent, it re-reads the user's profile.
|
|
26
|
+
*
|
|
27
|
+
* Mount it with a `key` per attribute: each mount starts a new verification and sends a new code or
|
|
28
|
+
* link.
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```tsx
|
|
32
|
+
* <VerifyAttribute attribute="email" onComplete={() => setOpen(false)} onCancel={() => setOpen(false)} />
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
const VerifyAttribute = ({ attribute, attributeDisplayName, flowHandle = AttributeVerificationConstants.DEFAULT_FLOW_HANDLE, onComplete, onDone,...rest }) => {
|
|
36
|
+
const { isLoading } = useThunderID_default();
|
|
37
|
+
const { revalidateProfile, userSchema } = useUser();
|
|
38
|
+
const refreshProfile = useCallback(async () => {
|
|
39
|
+
try {
|
|
40
|
+
await revalidateProfile?.();
|
|
41
|
+
} catch {}
|
|
42
|
+
}, [revalidateProfile]);
|
|
43
|
+
const handleInitialize = useCallback(() => {
|
|
44
|
+
if (!isVerifiableAttribute(userSchema, attribute)) return Promise.reject(new ThunderIDRuntimeError(`Attribute "${attribute}" is not a verifiable email or mobile attribute.`, "VerifyAttribute-handleInitialize-RuntimeError-001", "nextjs", "Only a top-level, single-valued email or mobile attribute of the user schema can be verified."));
|
|
45
|
+
return execute({
|
|
46
|
+
flowType: EmbeddedFlowType.Self,
|
|
47
|
+
handle: flowHandle,
|
|
48
|
+
inputs: { [AttributeVerificationConstants.ATTRIBUTE_INPUT]: attribute }
|
|
49
|
+
});
|
|
50
|
+
}, [
|
|
51
|
+
attribute,
|
|
52
|
+
flowHandle,
|
|
53
|
+
userSchema
|
|
54
|
+
]);
|
|
55
|
+
return /* @__PURE__ */ jsx(BaseVerifyAttribute, {
|
|
56
|
+
...rest,
|
|
57
|
+
attributeDisplayName: attributeDisplayName ?? userSchema?.[attribute]?.displayName ?? startCase(attribute),
|
|
58
|
+
isInitialized: !isLoading,
|
|
59
|
+
onInitialize: handleInitialize,
|
|
60
|
+
onSubmit: execute,
|
|
61
|
+
onComplete: (response) => {
|
|
62
|
+
refreshProfile();
|
|
63
|
+
onComplete?.(response);
|
|
64
|
+
},
|
|
65
|
+
onDone: () => {
|
|
66
|
+
refreshProfile();
|
|
67
|
+
onDone?.();
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
};
|
|
71
|
+
var VerifyAttribute_default = VerifyAttribute;
|
|
72
|
+
|
|
73
|
+
//#endregion
|
|
74
|
+
export { VerifyAttribute_default as default };
|
|
75
|
+
//# sourceMappingURL=VerifyAttribute.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VerifyAttribute.js","names":["result: ExecuteSelfFlowActionResult","executeSelfFlowAction","VerifyAttribute: FC<VerifyAttributeProps>","useThunderID"],"sources":["../../../../../src/client/components/account/VerifyAttribute/VerifyAttribute.tsx"],"sourcesContent":["// Copyright 2026 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\n'use client';\n\nimport {\n AttributeVerificationConstants,\n EmbeddedFlowType,\n EmbeddedSelfFlowRequest,\n EmbeddedSelfFlowResponse,\n ThunderIDAPIError,\n ThunderIDRuntimeError,\n isVerifiableAttribute,\n startCase,\n} from '@thunderid/node';\nimport {BaseVerifyAttribute, BaseVerifyAttributeProps, useUser} from '@thunderid/react';\nimport {FC, ReactElement, useCallback} from 'react';\nimport executeSelfFlowAction, {\n ExecuteSelfFlowActionResult,\n} from '../../../../server/actions/auth/executeSelfFlowAction';\nimport useThunderID from '../../../contexts/ThunderID/useThunderID';\n\n/**\n * Props for the VerifyAttribute component.\n * Mirrors `@thunderid/react`'s `VerifyAttributeProps`, so a consumer moving between the React and\n * Next.js SDKs doesn't need to change how they call it.\n */\nexport type VerifyAttributeProps = Omit<BaseVerifyAttributeProps, 'onInitialize' | 'onSubmit' | 'isInitialized'> & {\n /**\n * Name of the signed-in user's attribute to verify, such as `email`. Only a top-level, single-valued\n * `email` or `mobile` property of the user's schema can be verified; any other is refused without a\n * request, through `onError`, with `VerifyAttribute-handleInitialize-RuntimeError-001`.\n */\n attribute: string;\n /**\n * Handle of the `SELF` flow to run. Defaults to the server's shipped\n * `default-self-attribute-verification-flow`.\n */\n flowHandle?: string;\n};\n\n// Runs one step through the server action, which attaches the session's access token. A failure\n// raises `VerifyAttribute-execute-ResponseError-001` with the refusal's status, never the server's reply.\nconst execute = async (payload: EmbeddedSelfFlowRequest): Promise<EmbeddedSelfFlowResponse> => {\n const result: ExecuteSelfFlowActionResult = await executeSelfFlowAction(payload);\n\n if (!result.success) {\n throw new ThunderIDAPIError(\n 'SELF flow request failed',\n 'VerifyAttribute-execute-ResponseError-001',\n 'nextjs',\n result.statusCode,\n );\n }\n\n return result.data;\n};\n\n/**\n * VerifyAttribute verifies one of the signed-in user's attributes, such as their email address, by\n * running a self attribute verification flow named by `flowHandle`.\n *\n * This is the Next.js-specific implementation: it renders `BaseVerifyAttribute` from\n * `@thunderid/react`, but runs every step through `executeSelfFlowAction` (a server action that\n * attaches the server-held session's access token) instead of calling the ThunderID server from the\n * browser. Once the server records the verification, and when the user selects Done after a link is\n * sent, it re-reads the user's profile.\n *\n * Mount it with a `key` per attribute: each mount starts a new verification and sends a new code or\n * link.\n *\n * @example\n * ```tsx\n * <VerifyAttribute attribute=\"email\" onComplete={() => setOpen(false)} onCancel={() => setOpen(false)} />\n * ```\n */\nconst VerifyAttribute: FC<VerifyAttributeProps> = ({\n attribute,\n attributeDisplayName,\n flowHandle = AttributeVerificationConstants.DEFAULT_FLOW_HANDLE,\n onComplete,\n onDone,\n ...rest\n}: VerifyAttributeProps): ReactElement => {\n const {isLoading} = useThunderID();\n const {revalidateProfile, userSchema} = useUser();\n\n // Re-reads the profile so the recorded verification shows; a failure leaves it stale, not broken.\n const refreshProfile = useCallback(async (): Promise<void> => {\n try {\n await revalidateProfile?.();\n } catch {\n // Non-fatal: the profile stays stale until the next re-read.\n }\n }, [revalidateProfile]);\n\n const handleInitialize = useCallback((): Promise<EmbeddedSelfFlowResponse> => {\n if (!isVerifiableAttribute(userSchema, attribute)) {\n return Promise.reject(\n new ThunderIDRuntimeError(\n `Attribute \"${attribute}\" is not a verifiable email or mobile attribute.`,\n 'VerifyAttribute-handleInitialize-RuntimeError-001',\n 'nextjs',\n 'Only a top-level, single-valued email or mobile attribute of the user schema can be verified.',\n ),\n );\n }\n\n return execute({\n flowType: EmbeddedFlowType.Self,\n handle: flowHandle,\n inputs: {[AttributeVerificationConstants.ATTRIBUTE_INPUT]: attribute},\n });\n }, [attribute, flowHandle, userSchema]);\n\n return (\n <BaseVerifyAttribute\n {...rest}\n attributeDisplayName={attributeDisplayName ?? userSchema?.[attribute]?.displayName ?? startCase(attribute)}\n // The schema decides whether the attribute can be verified, so wait for the session to load.\n isInitialized={!isLoading}\n onInitialize={handleInitialize}\n onSubmit={execute}\n onComplete={(response: EmbeddedSelfFlowResponse): void => {\n void refreshProfile();\n onComplete?.(response);\n }}\n onDone={(): void => {\n void refreshProfile();\n onDone?.();\n }}\n />\n );\n};\n\nexport default VerifyAttribute;\n"],"mappings":";;;;;;;;;;;AA2CA,MAAM,UAAU,OAAO,YAAwE;CAC7F,MAAMA,SAAsC,MAAMC,8BAAsB,QAAQ;AAEhF,KAAI,CAAC,OAAO,QACV,OAAM,IAAI,kBACR,4BACA,6CACA,UACA,OAAO,WACR;AAGH,QAAO,OAAO;;;;;;;;;;;;;;;;;;;;AAqBhB,MAAMC,mBAA6C,EACjD,WACA,sBACA,aAAa,+BAA+B,qBAC5C,YACA,OACA,GAAG,WACqC;CACxC,MAAM,EAAC,cAAaC,sBAAc;CAClC,MAAM,EAAC,mBAAmB,eAAc,SAAS;CAGjD,MAAM,iBAAiB,YAAY,YAA2B;AAC5D,MAAI;AACF,SAAM,qBAAqB;UACrB;IAGP,CAAC,kBAAkB,CAAC;CAEvB,MAAM,mBAAmB,kBAAqD;AAC5E,MAAI,CAAC,sBAAsB,YAAY,UAAU,CAC/C,QAAO,QAAQ,OACb,IAAI,sBACF,cAAc,UAAU,mDACxB,qDACA,UACA,gGACD,CACF;AAGH,SAAO,QAAQ;GACb,UAAU,iBAAiB;GAC3B,QAAQ;GACR,QAAQ,GAAE,+BAA+B,kBAAkB,WAAU;GACtE,CAAC;IACD;EAAC;EAAW;EAAY;EAAW,CAAC;AAEvC,QACE,oBAAC;EACC,GAAI;EACJ,sBAAsB,wBAAwB,aAAa,YAAY,eAAe,UAAU,UAAU;EAE1G,eAAe,CAAC;EAChB,cAAc;EACd,UAAU;EACV,aAAa,aAA6C;AACxD,GAAK,gBAAgB;AACrB,gBAAa,SAAS;;EAExB,cAAoB;AAClB,GAAK,gBAAgB;AACrB,aAAU;;GAEZ;;AAIN,8BAAe"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ThunderIDProvider.d.ts","sourceRoot":"","sources":["../../../../src/client/contexts/ThunderID/ThunderIDProvider.tsx"],"names":[],"mappings":"AAKA,OAAO,EACL,eAAe,EAEf,oBAAoB,EAEpB,qBAAqB,EACrB,IAAI,EACJ,WAAW,EAGZ,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAQL,sBAAsB,EACvB,MAAM,kBAAkB,CAAC;AAI1B,OAAO,EAAC,EAAE,EAAE,iBAAiB,EAAkD,MAAM,OAAO,CAAC;AAC7F,OAAyB,EAAC,qBAAqB,EAAC,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"ThunderIDProvider.d.ts","sourceRoot":"","sources":["../../../../src/client/contexts/ThunderID/ThunderIDProvider.tsx"],"names":[],"mappings":"AAKA,OAAO,EACL,eAAe,EAEf,oBAAoB,EAEpB,qBAAqB,EACrB,IAAI,EACJ,WAAW,EAGZ,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAQL,sBAAsB,EACvB,MAAM,kBAAkB,CAAC;AAI1B,OAAO,EAAC,EAAE,EAAE,iBAAiB,EAAkD,MAAM,OAAO,CAAC;AAC7F,OAAyB,EAAC,qBAAqB,EAAC,MAAM,oBAAoB,CAAC;AAG3E,OAAO,EAAC,aAAa,EAAC,MAAM,sCAAsC,CAAC;AAKnE;;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,KACV,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;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,GAAG,IAAI,CAAC;CACrD,CAAC;AAEJ,QAAA,MAAM,uBAAuB,EAAE,EAAE,CAAC,iBAAiB,CAAC,4BAA4B,CAAC,CAqXhF,CAAC;AAEF,eAAe,uBAAuB,CAAC"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
import getSessionId_default from "../../../server/actions/getSessionId.js";
|
|
5
|
+
import getUserProfileAction_default from "../../../server/actions/account/getUserProfileAction.js";
|
|
4
6
|
import logger_default from "../../../utils/logger.js";
|
|
5
7
|
import ThunderIDContext_default from "./ThunderIDContext.js";
|
|
6
8
|
import fetchFlowMetaFromServer_default from "../../fetchFlowMetaFromServer.js";
|
|
@@ -139,6 +141,15 @@ const ThunderIDClientProvider = ({ baseUrl, children, endpoints, signIn, clearSe
|
|
|
139
141
|
profile: payload
|
|
140
142
|
}));
|
|
141
143
|
};
|
|
144
|
+
/**
|
|
145
|
+
* Re-reads `/users/me` through the server-held session, so a change made outside the profile API,
|
|
146
|
+
* such as a recorded verification, shows.
|
|
147
|
+
*/
|
|
148
|
+
const revalidateProfile = async () => {
|
|
149
|
+
if (preferences?.user?.fetchUserProfile === false) return;
|
|
150
|
+
const result = await getUserProfileAction_default(await getSessionId_default() ?? "");
|
|
151
|
+
if (result.success) handleProfileUpdate(result.data.userProfile.profile);
|
|
152
|
+
};
|
|
142
153
|
const unsupported = (name) => {
|
|
143
154
|
return () => Promise.reject(new ThunderIDRuntimeError(`\`${name}\` is not supported in @thunderid/nextjs.`, `ThunderIDClientProvider-${name}-NotSupportedError-001`, "nextjs"));
|
|
144
155
|
};
|
|
@@ -214,6 +225,7 @@ const ThunderIDClientProvider = ({ baseUrl, children, endpoints, signIn, clearSe
|
|
|
214
225
|
profile: userProfile,
|
|
215
226
|
userSchema,
|
|
216
227
|
onUpdateProfile: handleProfileUpdate,
|
|
228
|
+
revalidateProfile,
|
|
217
229
|
updateProfile,
|
|
218
230
|
children
|
|
219
231
|
}) })
|
|
@@ -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","result: {error?: string; redirectUrl?: string; success: boolean}","result: any","contextValue: ThunderIDContextProps","reactContextValue: ReactThunderIDContextProps","fetchManagementFromServer","ThunderIDContext","ReactThunderIDContext","fetchFlowMetaFromServer"],"sources":["../../../../src/client/contexts/ThunderID/ThunderIDProvider.tsx"],"sourcesContent":["// Copyright 2025 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\n'use client';\n\nimport {\n AttributeSchema,\n EmbeddedFlowExecuteRequestConfig,\n FlowMetadataResponse,\n generateFlattenedUserProfile,\n UpdateMeProfileConfig,\n User,\n UserProfile,\n ThunderIDRuntimeError,\n getVendorPrefix,\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} 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';\nimport fetchFlowMetaFromServer from '../../fetchFlowMetaFromServer';\nimport fetchManagementFromServer from '../../fetchManagementFromServer';\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 ) => 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 userSchema?: Record<string, AttributeSchema> | null;\n };\n\nconst ThunderIDClientProvider: FC<PropsWithChildren<ThunderIDClientProviderProps>> = ({\n baseUrl,\n children,\n endpoints,\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 userSchema: _userSchema = null,\n updateProfile,\n applicationId,\n organizationHandle,\n scopes,\n vendor,\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 const [userSchema, setUserSchema] = useState<Record<string, AttributeSchema> | null>(_userSchema);\n\n useEffect(() => {\n setUserProfile(_userProfile);\n }, [_userProfile]);\n\n useEffect(() => {\n setUserSchema(_userSchema);\n }, [_userSchema]);\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 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 );\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 preferences,\n refreshToken,\n scopes,\n signIn: handleSignIn,\n signInUrl,\n signOut: handleSignOut,\n signUp: handleSignUp,\n signUpUrl,\n user,\n }),\n [\n baseUrl,\n user,\n isSignedIn,\n isLoading,\n signInUrl,\n signUpUrl,\n applicationId,\n organizationHandle,\n scopes,\n preferences,\n ],\n );\n\n const handleProfileUpdate = (payload: User): void => {\n setUser(payload);\n setUserProfile((prev: UserProfile) => ({\n ...prev,\n flattenedProfile: generateFlattenedUserProfile(payload),\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 // Only the management collection overrides arrive here, so the admin hooks build the URLs the\n // management server action accepts.\n endpoints,\n exchangeToken: unsupported('exchangeToken'),\n getAccessToken: unsupported('getAccessToken'),\n getDecodedIdToken: unsupported('getDecodedIdToken'),\n // The Next.js useGrantedPermissions reads them through a server action instead.\n getGrantedPermissions: unsupported('getGrantedPermissions'),\n getIdToken: unsupported('getIdToken'),\n getStorageManager: () => Promise.resolve(null),\n http: {\n // The admin components and hooks send management requests through a server action that adds\n // the server-held access token, so the token never reaches the browser.\n fetcher: fetchManagementFromServer,\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 userSchema,\n vendor: getVendorPrefix(vendor),\n }),\n [\n applicationId,\n baseUrl,\n clearSession,\n endpoints,\n isLoading,\n isSignedIn,\n organizationHandle,\n scopes,\n signInUrl,\n signUpUrl,\n user,\n userSchema,\n initialMeta,\n vendor,\n ],\n );\n\n return (\n <ThunderIDContext.Provider value={contextValue}>\n <ReactThunderIDContext.Provider value={reactContextValue}>\n <I18nProvider preferences={preferences?.i18n}>\n <FlowMetaProvider\n enabled={preferences?.resolveFromMeta !== false}\n initialMeta={initialMeta}\n fetchMeta={fetchFlowMetaFromServer}\n >\n <ThemeProvider theme={preferences?.theme?.overrides} mode={preferences?.theme?.mode}>\n <FlowProvider>\n <UserProvider\n profile={userProfile}\n userSchema={userSchema}\n onUpdateProfile={handleProfileUpdate}\n updateProfile={updateProfile}\n >\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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"}
|
|
1
|
+
{"version":3,"file":"ThunderIDProvider.js","names":["ThunderIDClientProvider: FC<PropsWithChildren<ThunderIDClientProviderProps>>","reRenderCheckRef: RefObject<boolean>","router: AppRouterInstance","searchParams: ReadonlyURLSearchParams","code: string | null","state: string | null","result: {error?: string; redirectUrl?: string; success: boolean}","result: any","contextValue: ThunderIDContextProps","result: Awaited<ReturnType<typeof getUserProfileAction>>","getUserProfileAction","getSessionId","reactContextValue: ReactThunderIDContextProps","fetchManagementFromServer","ThunderIDContext","ReactThunderIDContext","fetchFlowMetaFromServer"],"sources":["../../../../src/client/contexts/ThunderID/ThunderIDProvider.tsx"],"sourcesContent":["// Copyright 2025 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\n'use client';\n\nimport {\n AttributeSchema,\n EmbeddedFlowExecuteRequestConfig,\n FlowMetadataResponse,\n generateFlattenedUserProfile,\n UpdateMeProfileConfig,\n User,\n UserProfile,\n ThunderIDRuntimeError,\n getVendorPrefix,\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} 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 getUserProfileAction from '../../../server/actions/account/getUserProfileAction';\nimport getSessionId from '../../../server/actions/getSessionId';\nimport {RefreshResult} from '../../../server/actions/refreshToken';\nimport logger from '../../../utils/logger';\nimport fetchFlowMetaFromServer from '../../fetchFlowMetaFromServer';\nimport fetchManagementFromServer from '../../fetchManagementFromServer';\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 ) => 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 userSchema?: Record<string, AttributeSchema> | null;\n };\n\nconst ThunderIDClientProvider: FC<PropsWithChildren<ThunderIDClientProviderProps>> = ({\n baseUrl,\n children,\n endpoints,\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 userSchema: _userSchema = null,\n updateProfile,\n applicationId,\n organizationHandle,\n scopes,\n vendor,\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 const [userSchema, setUserSchema] = useState<Record<string, AttributeSchema> | null>(_userSchema);\n\n useEffect(() => {\n setUserProfile(_userProfile);\n }, [_userProfile]);\n\n useEffect(() => {\n setUserSchema(_userSchema);\n }, [_userSchema]);\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 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 );\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 preferences,\n refreshToken,\n scopes,\n signIn: handleSignIn,\n signInUrl,\n signOut: handleSignOut,\n signUp: handleSignUp,\n signUpUrl,\n user,\n }),\n [\n baseUrl,\n user,\n isSignedIn,\n isLoading,\n signInUrl,\n signUpUrl,\n applicationId,\n organizationHandle,\n scopes,\n preferences,\n ],\n );\n\n const handleProfileUpdate = (payload: User): void => {\n setUser(payload);\n setUserProfile((prev: UserProfile) => ({\n ...prev,\n flattenedProfile: generateFlattenedUserProfile(payload),\n profile: payload,\n }));\n };\n\n /**\n * Re-reads `/users/me` through the server-held session, so a change made outside the profile API,\n * such as a recorded verification, shows.\n */\n const revalidateProfile = async (): Promise<void> => {\n if (preferences?.user?.fetchUserProfile === false) return;\n\n const result: Awaited<ReturnType<typeof getUserProfileAction>> = await getUserProfileAction(\n (await getSessionId()) ?? '',\n );\n\n if (result.success) {\n handleProfileUpdate(result.data.userProfile.profile);\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 // Only the management collection overrides arrive here, so the admin hooks build the URLs the\n // management server action accepts.\n endpoints,\n exchangeToken: unsupported('exchangeToken'),\n getAccessToken: unsupported('getAccessToken'),\n getDecodedIdToken: unsupported('getDecodedIdToken'),\n // The Next.js useGrantedPermissions reads them through a server action instead.\n getGrantedPermissions: unsupported('getGrantedPermissions'),\n getIdToken: unsupported('getIdToken'),\n getStorageManager: () => Promise.resolve(null),\n http: {\n // The admin components and hooks send management requests through a server action that adds\n // the server-held access token, so the token never reaches the browser.\n fetcher: fetchManagementFromServer,\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 userSchema,\n vendor: getVendorPrefix(vendor),\n }),\n [\n applicationId,\n baseUrl,\n clearSession,\n endpoints,\n isLoading,\n isSignedIn,\n organizationHandle,\n scopes,\n signInUrl,\n signUpUrl,\n user,\n userSchema,\n initialMeta,\n vendor,\n ],\n );\n\n return (\n <ThunderIDContext.Provider value={contextValue}>\n <ReactThunderIDContext.Provider value={reactContextValue}>\n <I18nProvider preferences={preferences?.i18n}>\n <FlowMetaProvider\n enabled={preferences?.resolveFromMeta !== false}\n initialMeta={initialMeta}\n fetchMeta={fetchFlowMetaFromServer}\n >\n <ThemeProvider theme={preferences?.theme?.overrides} mode={preferences?.theme?.mode}>\n <FlowProvider>\n <UserProvider\n profile={userProfile}\n userSchema={userSchema}\n onUpdateProfile={handleProfileUpdate}\n revalidateProfile={revalidateProfile}\n updateProfile={updateProfile}\n >\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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"}
|
package/dist/client/index.d.ts
CHANGED
|
@@ -25,6 +25,8 @@ export { default as UserProfile } from './components/account/UserProfile/UserPro
|
|
|
25
25
|
export type { UserProfileProps } from './components/account/UserProfile/UserProfile';
|
|
26
26
|
export { default as ChangeCredential } from './components/account/ChangeCredential/ChangeCredential';
|
|
27
27
|
export type { ChangeCredentialProps } from './components/account/ChangeCredential/ChangeCredential';
|
|
28
|
+
export { default as VerifyAttribute } from './components/account/VerifyAttribute/VerifyAttribute';
|
|
29
|
+
export type { VerifyAttributeProps } from './components/account/VerifyAttribute/VerifyAttribute';
|
|
28
30
|
export { default as UserSelect } from './components/primitives/UserSelect/UserSelect';
|
|
29
31
|
export type { UserSelectProps } from './components/primitives/UserSelect/UserSelect';
|
|
30
32
|
export { default as AuthFlowSelect } from './components/primitives/AuthFlowSelect/AuthFlowSelect';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"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"}
|
package/dist/client/index.js
CHANGED
|
@@ -8,6 +8,7 @@ import DeviceGrant_default from "./components/auth/DeviceGrant/DeviceGrant.js";
|
|
|
8
8
|
import SignOutButton_default from "./components/auth/buttons/SignOutButton/SignOutButton.js";
|
|
9
9
|
import User_default from "./components/account/User/User.js";
|
|
10
10
|
import SignUp_default from "./components/auth/SignUp/SignUp.js";
|
|
11
|
+
import VerifyAttribute_default from "./components/account/VerifyAttribute/VerifyAttribute.js";
|
|
11
12
|
import UserProfile_default from "./components/account/UserProfile/UserProfile.js";
|
|
12
13
|
import UserDropdown_default from "./components/account/UserDropdown/UserDropdown.js";
|
|
13
14
|
import UserAvatar_default from "./components/account/UserAvatar/UserAvatar.js";
|
package/dist/index.js
CHANGED
|
@@ -15,6 +15,7 @@ import DeviceGrant_default from "./client/components/auth/DeviceGrant/DeviceGran
|
|
|
15
15
|
import SignOutButton_default from "./client/components/auth/buttons/SignOutButton/SignOutButton.js";
|
|
16
16
|
import User_default from "./client/components/account/User/User.js";
|
|
17
17
|
import SignUp_default from "./client/components/auth/SignUp/SignUp.js";
|
|
18
|
+
import VerifyAttribute_default from "./client/components/account/VerifyAttribute/VerifyAttribute.js";
|
|
18
19
|
import UserProfile_default from "./client/components/account/UserProfile/UserProfile.js";
|
|
19
20
|
import UserDropdown_default from "./client/components/account/UserDropdown/UserDropdown.js";
|
|
20
21
|
import UserAvatar_default from "./client/components/account/UserAvatar/UserAvatar.js";
|
|
@@ -42,4 +43,4 @@ import useGrantedPermissions_default from "./client/hooks/management/useGrantedP
|
|
|
42
43
|
import { BaseAgentCreate, BaseAgentDetails, BaseAgentList, BaseApplicationCreate, BaseApplicationDetails, BaseApplicationList, BaseGroupCreate, BaseGroupList, BaseGroupMembers, BaseRoleAssignments, BaseRoleCreate, BaseRoleList, BaseRolePermissions, BaseUserCreate, BaseUserDetails, BaseUserList, useManagementRequestConfig } from "./client/admin.js";
|
|
43
44
|
import "./client/index.js";
|
|
44
45
|
|
|
45
|
-
export { AgentCreate_default as AgentCreate, AgentDetails_default as AgentDetails, AgentList_default as AgentList, ApplicationCreate_default as ApplicationCreate, ApplicationDetails_default as ApplicationDetails, ApplicationList_default as ApplicationList, AuthFlowSelect_default as AuthFlowSelect, BaseAgentCreate, BaseAgentDetails, BaseAgentList, BaseApplicationCreate, BaseApplicationDetails, BaseApplicationList, BaseGroupCreate, BaseGroupList, BaseGroupMembers, BaseRoleAssignments, BaseRoleCreate, BaseRoleList, BaseRolePermissions, BaseUserCreate, BaseUserDetails, BaseUserList, ChangeCredential_default as ChangeCredential, DeviceGrant_default as DeviceGrant, GroupCreate_default as GroupCreate, GroupList_default as GroupList, GroupMembers_default as GroupMembers, RoleAssignments_default as RoleAssignments, RoleCreate_default as RoleCreate, RoleList_default as RoleList, RolePermissions_default as RolePermissions, 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, UserCreate_default as UserCreate, UserDetails_default as UserDetails, UserDropdown_default as UserDropdown, UserList_default as UserList, UserProfile_default as UserProfile, UserSelect_default as UserSelect, UserTypeSelect_default as UserTypeSelect, backchannelLogout_default as backchannelLogout, createRouteMatcher_default as createRouteMatcher, removeChunkedCookieFromHeader, replaceChunkedCookieInHeader, thunderIDProxy_default as thunderIDProxy, thunderid_default as thunderid, useGrantedPermissions_default as useGrantedPermissions, useManagementRequestConfig, useThunderID_default as useThunderID };
|
|
46
|
+
export { AgentCreate_default as AgentCreate, AgentDetails_default as AgentDetails, AgentList_default as AgentList, ApplicationCreate_default as ApplicationCreate, ApplicationDetails_default as ApplicationDetails, ApplicationList_default as ApplicationList, AuthFlowSelect_default as AuthFlowSelect, BaseAgentCreate, BaseAgentDetails, BaseAgentList, BaseApplicationCreate, BaseApplicationDetails, BaseApplicationList, BaseGroupCreate, BaseGroupList, BaseGroupMembers, BaseRoleAssignments, BaseRoleCreate, BaseRoleList, BaseRolePermissions, BaseUserCreate, BaseUserDetails, BaseUserList, ChangeCredential_default as ChangeCredential, DeviceGrant_default as DeviceGrant, GroupCreate_default as GroupCreate, GroupList_default as GroupList, GroupMembers_default as GroupMembers, RoleAssignments_default as RoleAssignments, RoleCreate_default as RoleCreate, RoleList_default as RoleList, RolePermissions_default as RolePermissions, 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, UserCreate_default as UserCreate, UserDetails_default as UserDetails, UserDropdown_default as UserDropdown, UserList_default as UserList, UserProfile_default as UserProfile, UserSelect_default as UserSelect, UserTypeSelect_default as UserTypeSelect, VerifyAttribute_default as VerifyAttribute, backchannelLogout_default as backchannelLogout, createRouteMatcher_default as createRouteMatcher, removeChunkedCookieFromHeader, replaceChunkedCookieInHeader, thunderIDProxy_default as thunderIDProxy, thunderid_default as thunderid, useGrantedPermissions_default as useGrantedPermissions, useManagementRequestConfig, useThunderID_default as useThunderID };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { EmbeddedSelfFlowResponse } from '@thunderid/node';
|
|
2
|
+
export type ExecuteSelfFlowActionResult = {
|
|
3
|
+
data: EmbeddedSelfFlowResponse;
|
|
4
|
+
success: true;
|
|
5
|
+
} | {
|
|
6
|
+
statusCode?: number;
|
|
7
|
+
success: false;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Executes one step of a `SELF` flow, such as self attribute verification, for the signed-in
|
|
11
|
+
* user, with the access token of the server-held session. The request carries no session ID, token
|
|
12
|
+
* or user ID: the session comes from the request cookie, and only the fields of a step are forwarded.
|
|
13
|
+
* A new flow must be a `SELF` flow named by its handle.
|
|
14
|
+
*
|
|
15
|
+
* Never throws across the server action boundary. A failure carries only its HTTP status, never the
|
|
16
|
+
* reply of the server, which the browser reports as a refusal.
|
|
17
|
+
*/
|
|
18
|
+
declare const executeSelfFlowAction: (request: unknown) => Promise<ExecuteSelfFlowActionResult>;
|
|
19
|
+
export default executeSelfFlowAction;
|
|
20
|
+
//# sourceMappingURL=executeSelfFlowAction.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executeSelfFlowAction.d.ts","sourceRoot":"","sources":["../../../../src/server/actions/auth/executeSelfFlowAction.ts"],"names":[],"mappings":"AAKA,OAAO,EACL,wBAAwB,EAIzB,MAAM,iBAAiB,CAAC;AAIzB,MAAM,MAAM,2BAA2B,GACnC;IAAC,IAAI,EAAE,wBAAwB,CAAC;IAAC,OAAO,EAAE,IAAI,CAAA;CAAC,GAC/C;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,KAAK,CAAA;CAAC,CAAC;AAE1C;;;;;;;;GAQG;AACH,QAAA,MAAM,qBAAqB,GAAU,SAAS,OAAO,KAAG,OAAO,CAAC,2BAA2B,CAsB1F,CAAC;AAEF,eAAe,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
'use server';
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
import getSessionId_default from "../getSessionId.js";
|
|
5
|
+
import getClient_default from "../../getClient.js";
|
|
6
|
+
import { ThunderIDAPIError, parseSelfFlowRequest } from "@thunderid/node";
|
|
7
|
+
|
|
8
|
+
//#region src/server/actions/auth/executeSelfFlowAction.ts
|
|
9
|
+
/**
|
|
10
|
+
* Executes one step of a `SELF` flow, such as self attribute verification, for the signed-in
|
|
11
|
+
* user, with the access token of the server-held session. The request carries no session ID, token
|
|
12
|
+
* or user ID: the session comes from the request cookie, and only the fields of a step are forwarded.
|
|
13
|
+
* A new flow must be a `SELF` flow named by its handle.
|
|
14
|
+
*
|
|
15
|
+
* Never throws across the server action boundary. A failure carries only its HTTP status, never the
|
|
16
|
+
* reply of the server, which the browser reports as a refusal.
|
|
17
|
+
*/
|
|
18
|
+
const executeSelfFlowAction = async (request) => {
|
|
19
|
+
const sessionId = await getSessionId_default();
|
|
20
|
+
if (!sessionId) return {
|
|
21
|
+
statusCode: 401,
|
|
22
|
+
success: false
|
|
23
|
+
};
|
|
24
|
+
const checked = parseSelfFlowRequest(request);
|
|
25
|
+
if ("invalid" in checked) return {
|
|
26
|
+
statusCode: 400,
|
|
27
|
+
success: false
|
|
28
|
+
};
|
|
29
|
+
try {
|
|
30
|
+
return {
|
|
31
|
+
data: await getClient_default().executeEmbeddedSelfFlow(checked.request, sessionId),
|
|
32
|
+
success: true
|
|
33
|
+
};
|
|
34
|
+
} catch (error) {
|
|
35
|
+
return error instanceof ThunderIDAPIError && error.statusCode ? {
|
|
36
|
+
statusCode: error.statusCode,
|
|
37
|
+
success: false
|
|
38
|
+
} : { success: false };
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
var executeSelfFlowAction_default = executeSelfFlowAction;
|
|
42
|
+
|
|
43
|
+
//#endregion
|
|
44
|
+
export { executeSelfFlowAction_default as default };
|
|
45
|
+
//# sourceMappingURL=executeSelfFlowAction.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executeSelfFlowAction.js","names":["sessionId: string | undefined","getSessionId","checked: SelfFlowRequestParseResult","getClient"],"sources":["../../../../src/server/actions/auth/executeSelfFlowAction.ts"],"sourcesContent":["// Copyright 2026 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\n'use server';\n\nimport {\n EmbeddedSelfFlowResponse,\n SelfFlowRequestParseResult,\n ThunderIDAPIError,\n parseSelfFlowRequest,\n} from '@thunderid/node';\nimport getClient from '../../getClient';\nimport getSessionId from '../getSessionId';\n\nexport type ExecuteSelfFlowActionResult =\n | {data: EmbeddedSelfFlowResponse; success: true}\n | {statusCode?: number; success: false};\n\n/**\n * Executes one step of a `SELF` flow, such as self attribute verification, for the signed-in\n * user, with the access token of the server-held session. The request carries no session ID, token\n * or user ID: the session comes from the request cookie, and only the fields of a step are forwarded.\n * A new flow must be a `SELF` flow named by its handle.\n *\n * Never throws across the server action boundary. A failure carries only its HTTP status, never the\n * reply of the server, which the browser reports as a refusal.\n */\nconst executeSelfFlowAction = async (request: unknown): Promise<ExecuteSelfFlowActionResult> => {\n const sessionId: string | undefined = await getSessionId();\n\n if (!sessionId) {\n return {statusCode: 401, success: false};\n }\n\n const checked: SelfFlowRequestParseResult = parseSelfFlowRequest(request);\n\n if ('invalid' in checked) {\n return {statusCode: 400, success: false};\n }\n\n try {\n const data: EmbeddedSelfFlowResponse = await getClient().executeEmbeddedSelfFlow(checked.request, sessionId);\n\n return {data, success: true};\n } catch (error) {\n return error instanceof ThunderIDAPIError && error.statusCode\n ? {statusCode: error.statusCode, success: false}\n : {success: false};\n }\n};\n\nexport default executeSelfFlowAction;\n"],"mappings":";;;;;;;;;;;;;;;;;AA2BA,MAAM,wBAAwB,OAAO,YAA2D;CAC9F,MAAMA,YAAgC,MAAMC,sBAAc;AAE1D,KAAI,CAAC,UACH,QAAO;EAAC,YAAY;EAAK,SAAS;EAAM;CAG1C,MAAMC,UAAsC,qBAAqB,QAAQ;AAEzE,KAAI,aAAa,QACf,QAAO;EAAC,YAAY;EAAK,SAAS;EAAM;AAG1C,KAAI;AAGF,SAAO;GAAC,MAF+B,MAAMC,mBAAW,CAAC,wBAAwB,QAAQ,SAAS,UAAU;GAE9F,SAAS;GAAK;UACrB,OAAO;AACd,SAAO,iBAAiB,qBAAqB,MAAM,aAC/C;GAAC,YAAY,MAAM;GAAY,SAAS;GAAM,GAC9C,EAAC,SAAS,OAAM;;;AAIxB,oCAAe"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thunderid/nextjs",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.13.0",
|
|
4
4
|
"description": "Next.js SDK for ThunderID",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"thunderid",
|
|
@@ -37,8 +37,8 @@
|
|
|
37
37
|
"directory": "packages/nextjs"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@thunderid/node": "^1.
|
|
41
|
-
"@thunderid/react": "^1.
|
|
40
|
+
"@thunderid/node": "^1.11.0",
|
|
41
|
+
"@thunderid/react": "^1.14.0",
|
|
42
42
|
"@types/react": "19.2.14",
|
|
43
43
|
"jose": "6.2.3",
|
|
44
44
|
"tslib": "2.8.1"
|