From 0a9e0de2354b4d342f12bbc9c89efe97a93cb4e8 Mon Sep 17 00:00:00 2001 From: Pavindu Lakshan Date: Mon, 11 May 2026 12:08:07 +0530 Subject: [PATCH 1/2] fix(nextjs): generate redirect signup URL in signUpAction --- .../actions/__tests__/signUpAction.test.ts | 96 +++++++++++++++++++ .../nextjs/src/server/actions/signUpAction.ts | 30 +++--- 2 files changed, 115 insertions(+), 11 deletions(-) create mode 100644 packages/nextjs/src/server/actions/__tests__/signUpAction.test.ts diff --git a/packages/nextjs/src/server/actions/__tests__/signUpAction.test.ts b/packages/nextjs/src/server/actions/__tests__/signUpAction.test.ts new file mode 100644 index 000000000..3a14d4335 --- /dev/null +++ b/packages/nextjs/src/server/actions/__tests__/signUpAction.test.ts @@ -0,0 +1,96 @@ +/** + * 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 {EmbeddedFlowExecuteRequestPayload} from '@asgardeo/node'; +import {describe, it, expect, vi, beforeEach, afterEach, type Mock} from 'vitest'; +import AsgardeoNextClient from '../../../AsgardeoNextClient'; +import signUpAction from '../signUpAction'; + +vi.mock('../../../AsgardeoNextClient', () => ({ + default: { + getInstance: vi.fn(), + }, +})); + +describe('signUpAction', () => { + const mockStorageManager: {getConfigData: ReturnType} = { + getConfigData: vi.fn(), + }; + + const mockClient: {getStorageManager: ReturnType; signUp: ReturnType} = { + getStorageManager: vi.fn(), + signUp: vi.fn(), + }; + + beforeEach(() => { + vi.resetAllMocks(); + + mockClient.getStorageManager.mockResolvedValue(mockStorageManager); + mockStorageManager.getConfigData.mockResolvedValue({ + applicationId: 'app-123', + baseUrl: 'https://api.asgardeo.io/t/test-org', + clientId: 'client-123', + }); + (AsgardeoNextClient.getInstance as unknown as Mock).mockReturnValue(mockClient); + }); + + afterEach(() => { + vi.restoreAllMocks(); + }); + + it('should return the configured sign-up URL for redirect-based sign-up', async () => { + mockStorageManager.getConfigData.mockResolvedValueOnce({ + baseUrl: 'https://api.asgardeo.io/t/test-org', + signUpUrl: 'https://accounts.example.com/register', + }); + + const result: Awaited> = await signUpAction(); + + expect(mockClient.getStorageManager).toHaveBeenCalledTimes(1); + expect(mockStorageManager.getConfigData).toHaveBeenCalledTimes(1); + expect(mockClient.signUp).not.toHaveBeenCalled(); + expect(result).toEqual({ + data: {signUpUrl: 'https://accounts.example.com/register'}, + success: true, + }); + }); + + it('should generate the Asgardeo sign-up URL for redirect-based sign-up', async () => { + const result: Awaited> = await signUpAction({}); + + expect(result).toEqual({ + data: { + signUpUrl: + 'https://accounts.asgardeo.io/t/test-org/accountrecoveryendpoint/register.do?client_id=client-123&spId=app-123', + }, + success: true, + }); + }); + + it('should execute embedded sign-up when a payload is provided', async () => { + const payload: EmbeddedFlowExecuteRequestPayload = {flowType: 'REGISTRATION'} as EmbeddedFlowExecuteRequestPayload; + const response: Record = {flowStatus: 'INCOMPLETE', flowId: 'flow-123'}; + + mockClient.signUp.mockResolvedValueOnce(response); + + const result: Awaited> = await signUpAction(payload); + + expect(mockClient.signUp).toHaveBeenCalledWith(payload); + expect(result).toEqual({data: response, success: true}); + }); +}); diff --git a/packages/nextjs/src/server/actions/signUpAction.ts b/packages/nextjs/src/server/actions/signUpAction.ts index febd32c03..2eceaadf6 100644 --- a/packages/nextjs/src/server/actions/signUpAction.ts +++ b/packages/nextjs/src/server/actions/signUpAction.ts @@ -18,16 +18,22 @@ 'use server'; -import {EmbeddedFlowExecuteRequestPayload, EmbeddedFlowExecuteResponse, EmbeddedFlowStatus} from '@asgardeo/node'; +import { + Config, + EmbeddedFlowExecuteRequestPayload, + EmbeddedFlowExecuteResponse, + EmbeddedFlowStatus, + getRedirectBasedSignUpUrl, + isEmpty, +} from '@asgardeo/node'; import AsgardeoNextClient from '../../AsgardeoNextClient'; /** - * Server action for signing in a user. - * Handles the embedded sign-in flow and manages session cookies. + * Server action for signing up a user. + * Handles the embedded sign-up flow. * - * @param payload - The embedded sign-in flow payload - * @param request - The embedded flow execute request config - * @returns Promise that resolves when sign-in is complete + * @param payload - The embedded sign-up flow payload + * @returns Promise that resolves when sign-up is complete */ const signUpAction = async ( payload?: EmbeddedFlowExecuteRequestPayload, @@ -44,12 +50,14 @@ const signUpAction = async ( try { const client: AsgardeoNextClient = AsgardeoNextClient.getInstance(); - // If no payload provided, redirect to sign-in URL for redirect-based sign-in. - // If there's a payload, handle the embedded sign-in flow. - if (!payload) { - const defaultSignUpUrl: string = ''; + // If no payload provided, redirect to sign-up URL for redirect-based sign-up. + // If there's a payload, handle the embedded sign-up flow. + if (!payload || isEmpty(payload)) { + const storageManager: any = await client.getStorageManager(); + const config: Config = (await storageManager.getConfigData()) as Config; + const signUpUrl: string = config.signUpUrl || getRedirectBasedSignUpUrl(config); - return {data: {signUpUrl: String(defaultSignUpUrl)}, success: true}; + return {data: {signUpUrl}, success: true}; } const response: any = await client.signUp(payload); From 8c45474a80a935ba696b9e823f02aa7f9594a92a Mon Sep 17 00:00:00 2001 From: Pavindu Lakshan Date: Mon, 11 May 2026 12:09:01 +0530 Subject: [PATCH 2/2] Fix copyright year --- .../nextjs/src/server/actions/__tests__/signUpAction.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/nextjs/src/server/actions/__tests__/signUpAction.test.ts b/packages/nextjs/src/server/actions/__tests__/signUpAction.test.ts index 3a14d4335..eb6eb2c65 100644 --- a/packages/nextjs/src/server/actions/__tests__/signUpAction.test.ts +++ b/packages/nextjs/src/server/actions/__tests__/signUpAction.test.ts @@ -1,5 +1,5 @@ /** - * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * Copyright (c) 2026, 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