Skip to content

Commit e16d876

Browse files
authored
Merge pull request #232 from brionmario/thunder
feat: add ⚡️ Thunder support for `SignUp` component
2 parents 77c88b9 + 2a85043 commit e16d876

File tree

8 files changed

+689
-23
lines changed

8 files changed

+689
-23
lines changed

.changeset/brave-waves-stick.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'@asgardeo/javascript': minor
3+
'@asgardeo/react': minor
4+
---
5+
6+
Add ⚡️ Thunder support for `SignUp` component.
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
/**
2+
* Copyright (c) 2025, 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+
19+
import {
20+
EmbeddedFlowExecuteRequestConfigV2,
21+
EmbeddedSignUpFlowResponseV2,
22+
EmbeddedSignUpFlowStatusV2,
23+
} from '../../models/v2/embedded-signup-flow-v2';
24+
import AsgardeoAPIError from '../../errors/AsgardeoAPIError';
25+
26+
const executeEmbeddedSignUpFlowV2 = async ({
27+
url,
28+
baseUrl,
29+
payload,
30+
sessionDataKey,
31+
...requestConfig
32+
}: EmbeddedFlowExecuteRequestConfigV2): Promise<EmbeddedSignUpFlowResponseV2> => {
33+
if (!payload) {
34+
throw new AsgardeoAPIError(
35+
'Registration payload is required',
36+
'executeEmbeddedSignUpFlow-ValidationError-002',
37+
'javascript',
38+
400,
39+
'If a registration payload is not provided, the request cannot be constructed correctly.',
40+
);
41+
}
42+
43+
let endpoint: string = url ?? `${baseUrl}/flow/execute`;
44+
45+
const response: Response = await fetch(endpoint, {
46+
...requestConfig,
47+
method: requestConfig.method || 'POST',
48+
headers: {
49+
'Content-Type': 'application/json',
50+
Accept: 'application/json',
51+
...requestConfig.headers,
52+
},
53+
body: JSON.stringify(payload),
54+
});
55+
56+
if (!response.ok) {
57+
const errorText = await response.text();
58+
59+
throw new AsgardeoAPIError(
60+
`Registration request failed: ${errorText}`,
61+
'executeEmbeddedSignUpFlow-ResponseError-001',
62+
'javascript',
63+
response.status,
64+
response.statusText,
65+
);
66+
}
67+
68+
const flowResponse: EmbeddedSignUpFlowResponseV2 = await response.json();
69+
70+
// IMPORTANT: Only applicable for Asgardeo V2 platform.
71+
// Check if the flow is complete and has an assertion and sessionDataKey is provided, then call OAuth2 authorize.
72+
if (
73+
flowResponse.flowStatus === EmbeddedSignUpFlowStatusV2.Complete &&
74+
(flowResponse as any).assertion &&
75+
sessionDataKey
76+
) {
77+
try {
78+
const oauth2Response: Response = await fetch(`${baseUrl}/oauth2/authorize`, {
79+
method: 'POST',
80+
headers: {
81+
'Content-Type': 'application/json',
82+
Accept: 'application/json',
83+
...requestConfig.headers,
84+
},
85+
body: JSON.stringify({
86+
assertion: (flowResponse as any).assertion,
87+
sessionDataKey,
88+
}),
89+
credentials: 'include',
90+
});
91+
92+
if (!oauth2Response.ok) {
93+
const oauth2ErrorText: string = await oauth2Response.text();
94+
95+
throw new AsgardeoAPIError(
96+
`OAuth2 authorization failed: ${oauth2ErrorText}`,
97+
'executeEmbeddedSignUpFlow-OAuth2Error-002',
98+
'javascript',
99+
oauth2Response.status,
100+
oauth2Response.statusText,
101+
);
102+
}
103+
104+
const oauth2Result = await oauth2Response.json();
105+
106+
return {
107+
flowStatus: flowResponse.flowStatus,
108+
redirectUrl: oauth2Result.redirect_uri,
109+
} as any;
110+
} catch (authError) {
111+
throw new AsgardeoAPIError(
112+
`OAuth2 authorization failed: ${authError instanceof Error ? authError.message : 'Unknown error'}`,
113+
'executeEmbeddedSignUpFlow-OAuth2Error-001',
114+
'javascript',
115+
500,
116+
'Failed to complete OAuth2 authorization after successful embedded sign-up flow.',
117+
);
118+
}
119+
}
120+
121+
return flowResponse;
122+
};
123+
124+
export default executeEmbeddedSignUpFlowV2;

packages/javascript/src/index.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ export {default as updateOrganization, createPatchOperations, UpdateOrganization
4646
export {default as updateMeProfile, UpdateMeProfileConfig} from './api/updateMeProfile';
4747
export {default as getBrandingPreference, GetBrandingPreferenceConfig} from './api/getBrandingPreference';
4848
export {default as executeEmbeddedSignInFlowV2} from './api/v2/executeEmbeddedSignInFlowV2';
49+
export {default as executeEmbeddedSignUpFlowV2} from './api/v2/executeEmbeddedSignUpFlowV2';
4950

5051
export {default as ApplicationNativeAuthenticationConstants} from './constants/ApplicationNativeAuthenticationConstants';
5152
export {default as TokenConstants} from './constants/TokenConstants';
@@ -90,6 +91,16 @@ export {
9091
EmbeddedFlowExecuteRequestPayload,
9192
EmbeddedFlowExecuteRequestConfig,
9293
} from './models/embedded-flow';
94+
export {
95+
EmbeddedSignUpFlowStatusV2,
96+
EmbeddedSignUpFlowInitiateRequestV2,
97+
EmbeddedSignUpFlowRequestV2,
98+
EmbeddedSignUpFlowCompleteResponse,
99+
EmbeddedSignUpFlowResponseV2,
100+
ExtendedEmbeddedSignUpFlowResponseV2,
101+
EmbeddedSignUpFlowTypeV2,
102+
EmbeddedFlowExecuteRequestConfigV2,
103+
} from './models/v2/embedded-signup-flow-v2';
93104
export {FlowMode} from './models/flow';
94105
export {AsgardeoClient} from './models/client';
95106
export {
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
/**
2+
* Copyright (c) 2025, 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+
19+
import {EmbeddedFlowExecuteRequestConfig, EmbeddedFlowResponseType, EmbeddedFlowType} from '../embedded-flow';
20+
21+
export enum EmbeddedSignUpFlowStatusV2 {
22+
Complete = 'COMPLETE',
23+
Incomplete = 'INCOMPLETE',
24+
Error = 'ERROR',
25+
}
26+
27+
export enum EmbeddedSignUpFlowTypeV2 {
28+
Redirection = 'REDIRECTION',
29+
View = 'VIEW',
30+
}
31+
32+
/**
33+
* Extended response structure for the embedded sign-up flow V2.
34+
* @remarks This response is only done from the SDK level.
35+
* @experimental
36+
*/
37+
export interface ExtendedEmbeddedSignUpFlowResponseV2 {
38+
/**
39+
* The URL to redirect the user after completing the sign-up flow.
40+
*/
41+
redirectUrl?: string;
42+
}
43+
44+
/**
45+
* Response structure for the new Asgardeo V2 embedded sign-up flow.
46+
* @experimental
47+
*/
48+
export interface EmbeddedSignUpFlowResponseV2 extends ExtendedEmbeddedSignUpFlowResponseV2 {
49+
flowId: string;
50+
flowStatus: EmbeddedSignUpFlowStatusV2;
51+
type: EmbeddedSignUpFlowTypeV2;
52+
data: {
53+
actions?: {
54+
type: EmbeddedFlowResponseType;
55+
id: string;
56+
}[];
57+
inputs?: {
58+
name: string;
59+
type: string;
60+
required: boolean;
61+
}[];
62+
};
63+
}
64+
65+
/**
66+
* Response structure for the new Asgardeo V2 embedded sign-up flow when the flow is complete.
67+
* @experimental
68+
*/
69+
export interface EmbeddedSignUpFlowCompleteResponse {
70+
redirect_uri: string;
71+
}
72+
73+
/**
74+
* Request payload for initiating the new Asgardeo V2 embedded sign-up flow.
75+
* @experimental
76+
*/
77+
export type EmbeddedSignUpFlowInitiateRequestV2 = {
78+
applicationId: string;
79+
flowType: EmbeddedFlowType;
80+
};
81+
82+
/**
83+
* Request payload for executing steps in the new Asgardeo V2 embedded sign-up flow.
84+
* @experimental
85+
*/
86+
export interface EmbeddedSignUpFlowRequestV2 extends Partial<EmbeddedSignUpFlowInitiateRequestV2> {
87+
flowId?: string;
88+
actionId?: string;
89+
inputs?: Record<string, any>;
90+
}
91+
92+
/**
93+
* Request config for executing the new Asgardeo V2 embedded sign-up flow.
94+
* @experimental
95+
*/
96+
export interface EmbeddedFlowExecuteRequestConfigV2<T = any> extends EmbeddedFlowExecuteRequestConfig<T> {
97+
sessionDataKey?: string;
98+
}

packages/react/src/AsgardeoReactClient.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ import {
5050
Platform,
5151
isEmpty,
5252
EmbeddedSignInFlowResponseV2,
53+
executeEmbeddedSignUpFlowV2,
5354
} from '@asgardeo/browser';
5455
import AuthAPI from './__temp__/api';
5556
import getMeOrganizations from './api/getMeOrganizations';
@@ -399,19 +400,25 @@ class AsgardeoReactClient<T extends AsgardeoReactConfig = AsgardeoReactConfig> e
399400
override async signUp(options?: SignUpOptions): Promise<void>;
400401
override async signUp(payload: EmbeddedFlowExecuteRequestPayload): Promise<EmbeddedFlowExecuteResponse>;
401402
override async signUp(...args: any[]): Promise<void | EmbeddedFlowExecuteResponse> {
402-
const configData = await this.asgardeo.getConfigData();
403+
const config: AsgardeoReactConfig = (await this.asgardeo.getConfigData()) as AsgardeoReactConfig;
403404
const firstArg = args[0];
405+
const baseUrl: string = config?.baseUrl;
404406

405-
if (typeof firstArg === 'object' && 'flowType' in firstArg) {
406-
const baseUrl: string = configData?.baseUrl;
407+
if (config.platform === Platform.AsgardeoV2) {
408+
return executeEmbeddedSignUpFlowV2({
409+
baseUrl,
410+
payload: firstArg as EmbeddedFlowExecuteRequestPayload,
411+
}) as any;
412+
}
407413

414+
if (typeof firstArg === 'object' && 'flowType' in firstArg) {
408415
return executeEmbeddedSignUpFlow({
409416
baseUrl,
410417
payload: firstArg as EmbeddedFlowExecuteRequestPayload,
411418
});
412419
}
413420

414-
navigate(getRedirectBasedSignUpUrl(configData as Config));
421+
navigate(getRedirectBasedSignUpUrl(config as Config));
415422
}
416423

417424
async request(requestConfig?: HttpRequestConfig): Promise<HttpResponse<any>> {

0 commit comments

Comments
 (0)