Skip to content

Commit fea939d

Browse files
authored
Merge pull request #79 from brionmario/next
feat: `SignUp` component for `@asgardeo/next`
2 parents 9bd7a1c + 8ba9f1a commit fea939d

File tree

75 files changed

+3131
-1368
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

75 files changed

+3131
-1368
lines changed

.changeset/metal-colts-lose.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
---
2-
'@asgardeo/nextjs': patch
2+
'@asgardeo/nextjs': minor
3+
'@asgardeo/react': patch
34
---
45

56
Stabilize the SDK

packages/javascript/src/__legacy__/client.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -237,13 +237,14 @@ export class AsgardeoAuthClient<T> {
237237
await this._storageManager.setTemporaryDataParameter(pkceKey, codeVerifier, userId);
238238
}
239239

240-
console.log('[AsgardeoAuthClient] configData:', configData);
240+
if (authRequestConfig['client_secret']) {
241+
authRequestConfig['client_secret'] = configData.clientSecret;
242+
}
241243

242244
const authorizeRequestParams: Map<string, string> = getAuthorizeRequestUrlParams(
243245
{
244246
redirectUri: configData.afterSignInUrl,
245247
clientId: configData.clientId,
246-
clientSecret: configData.clientSecret,
247248
scopes: processOpenIDScopes(configData.scopes),
248249
responseMode: configData.responseMode,
249250
codeChallengeMethod: PKCEConstants.DEFAULT_CODE_CHALLENGE_METHOD,
Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
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 {Organization} from '../models/organization';
20+
import AsgardeoAPIError from '../errors/AsgardeoAPIError';
21+
22+
/**
23+
* Interface for organization creation payload.
24+
*/
25+
export interface CreateOrganizationPayload {
26+
/**
27+
* Organization description.
28+
*/
29+
description: string;
30+
/**
31+
* Organization handle/slug.
32+
*/
33+
orgHandle?: string;
34+
/**
35+
* Organization name.
36+
*/
37+
name: string;
38+
/**
39+
* Parent organization ID.
40+
*/
41+
parentId: string;
42+
/**
43+
* Organization type.
44+
*/
45+
type: 'TENANT';
46+
}
47+
48+
/**
49+
* Configuration for the createOrganization request
50+
*/
51+
export interface CreateOrganizationConfig extends Omit<RequestInit, 'method' | 'body'> {
52+
/**
53+
* The base URL for the API endpoint.
54+
*/
55+
baseUrl: string;
56+
/**
57+
* Organization creation payload
58+
*/
59+
payload: CreateOrganizationPayload;
60+
/**
61+
* Optional custom fetcher function.
62+
* If not provided, native fetch will be used
63+
*/
64+
fetcher?: (url: string, config: RequestInit) => Promise<Response>;
65+
}
66+
67+
/**
68+
* Creates a new organization.
69+
*
70+
* @param config - Configuration object containing baseUrl, payload and optional request config.
71+
* @returns A promise that resolves with the created organization information.
72+
* @example
73+
* ```typescript
74+
* // Using default fetch
75+
* try {
76+
* const organization = await createOrganization({
77+
* baseUrl: "https://api.asgardeo.io/t/<ORGANIZATION>",
78+
* payload: {
79+
* description: "Share your screens",
80+
* name: "Team Viewer",
81+
* orgHandle: "team-viewer",
82+
* parentId: "f4825104-4948-40d9-ab65-a960eee3e3d5",
83+
* type: "TENANT"
84+
* }
85+
* });
86+
* console.log(organization);
87+
* } catch (error) {
88+
* if (error instanceof AsgardeoAPIError) {
89+
* console.error('Failed to create organization:', error.message);
90+
* }
91+
* }
92+
* ```
93+
*
94+
* @example
95+
* ```typescript
96+
* // Using custom fetcher (e.g., axios-based httpClient)
97+
* try {
98+
* const organization = await createOrganization({
99+
* baseUrl: "https://api.asgardeo.io/t/<ORGANIZATION>",
100+
* payload: {
101+
* description: "Share your screens",
102+
* name: "Team Viewer",
103+
* orgHandle: "team-viewer",
104+
* parentId: "f4825104-4948-40d9-ab65-a960eee3e3d5",
105+
* type: "TENANT"
106+
* },
107+
* fetcher: async (url, config) => {
108+
* const response = await httpClient({
109+
* url,
110+
* method: config.method,
111+
* headers: config.headers,
112+
* data: config.body,
113+
* ...config
114+
* });
115+
* // Convert axios-like response to fetch-like Response
116+
* return {
117+
* ok: response.status >= 200 && response.status < 300,
118+
* status: response.status,
119+
* statusText: response.statusText,
120+
* json: () => Promise.resolve(response.data),
121+
* text: () => Promise.resolve(typeof response.data === 'string' ? response.data : JSON.stringify(response.data))
122+
* } as Response;
123+
* }
124+
* });
125+
* console.log(organization);
126+
* } catch (error) {
127+
* if (error instanceof AsgardeoAPIError) {
128+
* console.error('Failed to create organization:', error.message);
129+
* }
130+
* }
131+
* ```
132+
*/
133+
const createOrganization = async ({
134+
baseUrl,
135+
payload,
136+
fetcher,
137+
...requestConfig
138+
}: CreateOrganizationConfig): Promise<Organization> => {
139+
try {
140+
new URL(baseUrl);
141+
} catch (error) {
142+
throw new AsgardeoAPIError(
143+
`Invalid base URL provided. ${error?.toString()}`,
144+
'createOrganization-ValidationError-001',
145+
'javascript',
146+
400,
147+
'The provided `baseUrl` does not adhere to the URL schema.',
148+
);
149+
}
150+
151+
if (!payload) {
152+
throw new AsgardeoAPIError(
153+
'Organization payload is required',
154+
'createOrganization-ValidationError-002',
155+
'javascript',
156+
400,
157+
'Invalid Request',
158+
);
159+
}
160+
161+
// Always set type to TENANT for now
162+
const organizationPayload = {
163+
...payload,
164+
type: 'TENANT' as const,
165+
};
166+
167+
const fetchFn = fetcher || fetch;
168+
const resolvedUrl = `${baseUrl}/api/server/v1/organizations`;
169+
170+
const requestInit: RequestInit = {
171+
method: 'POST',
172+
headers: {
173+
'Content-Type': 'application/json',
174+
Accept: 'application/json',
175+
...requestConfig.headers,
176+
},
177+
body: JSON.stringify(organizationPayload),
178+
...requestConfig,
179+
};
180+
181+
try {
182+
const response: Response = await fetchFn(resolvedUrl, requestInit);
183+
184+
if (!response?.ok) {
185+
const errorText = await response.text();
186+
187+
throw new AsgardeoAPIError(
188+
`Failed to create organization: ${errorText}`,
189+
'createOrganization-ResponseError-001',
190+
'javascript',
191+
response.status,
192+
response.statusText,
193+
);
194+
}
195+
196+
return (await response.json()) as Organization;
197+
} catch (error) {
198+
if (error instanceof AsgardeoAPIError) {
199+
throw error;
200+
}
201+
202+
throw new AsgardeoAPIError(
203+
`Network or parsing error: ${error instanceof Error ? error.message : 'Unknown error'}`,
204+
'createOrganization-NetworkError-001',
205+
'javascript',
206+
0,
207+
'Network Error',
208+
);
209+
}
210+
};
211+
212+
export default createOrganization;

0 commit comments

Comments
 (0)