Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/brave-waves-stick.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@asgardeo/javascript': minor
'@asgardeo/react': minor
---

Add ⚡️ Thunder support for `SignUp` component.
124 changes: 124 additions & 0 deletions packages/javascript/src/api/v2/executeEmbeddedSignUpFlowV2.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
/**
* Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com).
*
* WSO2 LLC. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import {
EmbeddedFlowExecuteRequestConfigV2,
EmbeddedSignUpFlowResponseV2,
EmbeddedSignUpFlowStatusV2,
} from '../../models/v2/embedded-signup-flow-v2';
import AsgardeoAPIError from '../../errors/AsgardeoAPIError';

const executeEmbeddedSignUpFlowV2 = async ({
url,
baseUrl,
payload,
sessionDataKey,
...requestConfig
}: EmbeddedFlowExecuteRequestConfigV2): Promise<EmbeddedSignUpFlowResponseV2> => {
if (!payload) {
throw new AsgardeoAPIError(
'Registration payload is required',
'executeEmbeddedSignUpFlow-ValidationError-002',
'javascript',
400,
'If a registration payload is not provided, the request cannot be constructed correctly.',
);
}

let endpoint: string = url ?? `${baseUrl}/flow/execute`;

const response: Response = await fetch(endpoint, {
...requestConfig,
method: requestConfig.method || 'POST',
headers: {
'Content-Type': 'application/json',
Accept: 'application/json',
...requestConfig.headers,
},
body: JSON.stringify(payload),
});

if (!response.ok) {
const errorText = await response.text();

throw new AsgardeoAPIError(
`Registration request failed: ${errorText}`,
'executeEmbeddedSignUpFlow-ResponseError-001',
'javascript',
response.status,
response.statusText,
);
}

const flowResponse: EmbeddedSignUpFlowResponseV2 = await response.json();

// IMPORTANT: Only applicable for Asgardeo V2 platform.
// Check if the flow is complete and has an assertion and sessionDataKey is provided, then call OAuth2 authorize.
if (
flowResponse.flowStatus === EmbeddedSignUpFlowStatusV2.Complete &&
(flowResponse as any).assertion &&
sessionDataKey
) {
try {
const oauth2Response: Response = await fetch(`${baseUrl}/oauth2/authorize`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Accept: 'application/json',
...requestConfig.headers,
},
body: JSON.stringify({
assertion: (flowResponse as any).assertion,
sessionDataKey,
}),
credentials: 'include',
});

if (!oauth2Response.ok) {
const oauth2ErrorText: string = await oauth2Response.text();

throw new AsgardeoAPIError(
`OAuth2 authorization failed: ${oauth2ErrorText}`,
'executeEmbeddedSignUpFlow-OAuth2Error-002',
'javascript',
oauth2Response.status,
oauth2Response.statusText,
);
}

const oauth2Result = await oauth2Response.json();

return {
flowStatus: flowResponse.flowStatus,
redirectUrl: oauth2Result.redirect_uri,
} as any;
} catch (authError) {
throw new AsgardeoAPIError(
`OAuth2 authorization failed: ${authError instanceof Error ? authError.message : 'Unknown error'}`,
'executeEmbeddedSignUpFlow-OAuth2Error-001',
'javascript',
500,
'Failed to complete OAuth2 authorization after successful embedded sign-up flow.',
);
}
}

return flowResponse;
};

export default executeEmbeddedSignUpFlowV2;
11 changes: 11 additions & 0 deletions packages/javascript/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export {default as updateOrganization, createPatchOperations, UpdateOrganization
export {default as updateMeProfile, UpdateMeProfileConfig} from './api/updateMeProfile';
export {default as getBrandingPreference, GetBrandingPreferenceConfig} from './api/getBrandingPreference';
export {default as executeEmbeddedSignInFlowV2} from './api/v2/executeEmbeddedSignInFlowV2';
export {default as executeEmbeddedSignUpFlowV2} from './api/v2/executeEmbeddedSignUpFlowV2';

export {default as ApplicationNativeAuthenticationConstants} from './constants/ApplicationNativeAuthenticationConstants';
export {default as TokenConstants} from './constants/TokenConstants';
Expand Down Expand Up @@ -90,6 +91,16 @@ export {
EmbeddedFlowExecuteRequestPayload,
EmbeddedFlowExecuteRequestConfig,
} from './models/embedded-flow';
export {
EmbeddedSignUpFlowStatusV2,
EmbeddedSignUpFlowInitiateRequestV2,
EmbeddedSignUpFlowRequestV2,
EmbeddedSignUpFlowCompleteResponse,
EmbeddedSignUpFlowResponseV2,
ExtendedEmbeddedSignUpFlowResponseV2,
EmbeddedSignUpFlowTypeV2,
EmbeddedFlowExecuteRequestConfigV2,
} from './models/v2/embedded-signup-flow-v2';
export {FlowMode} from './models/flow';
export {AsgardeoClient} from './models/client';
export {
Expand Down
98 changes: 98 additions & 0 deletions packages/javascript/src/models/v2/embedded-signup-flow-v2.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/**
* Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com).
*
* WSO2 LLC. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import {EmbeddedFlowExecuteRequestConfig, EmbeddedFlowResponseType, EmbeddedFlowType} from '../embedded-flow';

export enum EmbeddedSignUpFlowStatusV2 {
Complete = 'COMPLETE',
Incomplete = 'INCOMPLETE',
Error = 'ERROR',
}

export enum EmbeddedSignUpFlowTypeV2 {
Redirection = 'REDIRECTION',
View = 'VIEW',
}

/**
* Extended response structure for the embedded sign-up flow V2.
* @remarks This response is only done from the SDK level.
* @experimental
*/
export interface ExtendedEmbeddedSignUpFlowResponseV2 {
/**
* The URL to redirect the user after completing the sign-up flow.
*/
redirectUrl?: string;
}

/**
* Response structure for the new Asgardeo V2 embedded sign-up flow.
* @experimental
*/
export interface EmbeddedSignUpFlowResponseV2 extends ExtendedEmbeddedSignUpFlowResponseV2 {
flowId: string;
flowStatus: EmbeddedSignUpFlowStatusV2;
type: EmbeddedSignUpFlowTypeV2;
data: {
actions?: {
type: EmbeddedFlowResponseType;
id: string;
}[];
inputs?: {
name: string;
type: string;
required: boolean;
}[];
};
}

/**
* Response structure for the new Asgardeo V2 embedded sign-up flow when the flow is complete.
* @experimental
*/
export interface EmbeddedSignUpFlowCompleteResponse {
redirect_uri: string;
}

/**
* Request payload for initiating the new Asgardeo V2 embedded sign-up flow.
* @experimental
*/
export type EmbeddedSignUpFlowInitiateRequestV2 = {
applicationId: string;
flowType: EmbeddedFlowType;
};

/**
* Request payload for executing steps in the new Asgardeo V2 embedded sign-up flow.
* @experimental
*/
export interface EmbeddedSignUpFlowRequestV2 extends Partial<EmbeddedSignUpFlowInitiateRequestV2> {
flowId?: string;
actionId?: string;
inputs?: Record<string, any>;
}

/**
* Request config for executing the new Asgardeo V2 embedded sign-up flow.
* @experimental
*/
export interface EmbeddedFlowExecuteRequestConfigV2<T = any> extends EmbeddedFlowExecuteRequestConfig<T> {
sessionDataKey?: string;
}
15 changes: 11 additions & 4 deletions packages/react/src/AsgardeoReactClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ import {
Platform,
isEmpty,
EmbeddedSignInFlowResponseV2,
executeEmbeddedSignUpFlowV2,
} from '@asgardeo/browser';
import AuthAPI from './__temp__/api';
import getMeOrganizations from './api/getMeOrganizations';
Expand Down Expand Up @@ -399,19 +400,25 @@ class AsgardeoReactClient<T extends AsgardeoReactConfig = AsgardeoReactConfig> e
override async signUp(options?: SignUpOptions): Promise<void>;
override async signUp(payload: EmbeddedFlowExecuteRequestPayload): Promise<EmbeddedFlowExecuteResponse>;
override async signUp(...args: any[]): Promise<void | EmbeddedFlowExecuteResponse> {
const configData = await this.asgardeo.getConfigData();
const config: AsgardeoReactConfig = (await this.asgardeo.getConfigData()) as AsgardeoReactConfig;
const firstArg = args[0];
const baseUrl: string = config?.baseUrl;

if (typeof firstArg === 'object' && 'flowType' in firstArg) {
const baseUrl: string = configData?.baseUrl;
if (config.platform === Platform.AsgardeoV2) {
return executeEmbeddedSignUpFlowV2({
baseUrl,
payload: firstArg as EmbeddedFlowExecuteRequestPayload,
}) as any;
}

if (typeof firstArg === 'object' && 'flowType' in firstArg) {
return executeEmbeddedSignUpFlow({
baseUrl,
payload: firstArg as EmbeddedFlowExecuteRequestPayload,
});
}

navigate(getRedirectBasedSignUpUrl(configData as Config));
navigate(getRedirectBasedSignUpUrl(config as Config));
}

async request(requestConfig?: HttpRequestConfig): Promise<HttpResponse<any>> {
Expand Down
Loading
Loading