Skip to content

Commit 6f6325f

Browse files
committed
feat(nextjs): expose token APIs via AsgardeoContext
expose getIdToken, getDecodedIdToken, getAccessToken, and exchangeToken methods through AsgardeoContext in the Next.js SDK.
1 parent dc99542 commit 6f6325f

File tree

7 files changed

+157
-7
lines changed

7 files changed

+157
-7
lines changed

packages/nextjs/src/client/contexts/Asgardeo/AsgardeoContext.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
'use client';
2020

2121
import {AsgardeoContextProps as AsgardeoReactContextProps} from '@asgardeo/react';
22-
import {EmbeddedFlowExecuteRequestConfig, EmbeddedSignInFlowHandleRequestPayload, User} from '@asgardeo/node';
22+
import {EmbeddedFlowExecuteRequestConfig, EmbeddedSignInFlowHandleRequestPayload, User, TokenExchangeRequestConfig, TokenResponse, IdToken} from '@asgardeo/node';
2323
import {Context, createContext} from 'react';
2424

2525
/**
@@ -44,6 +44,10 @@ const AsgardeoContext: Context<AsgardeoContextProps | null> = createContext<null
4444
signOut: () => Promise.resolve({} as any),
4545
signUp: () => Promise.resolve({} as any),
4646
user: null,
47+
getDecodedIdToken: async (sessionId?:string) => Promise.resolve({} as IdToken),
48+
getIdToken: async () => Promise.resolve(undefined),
49+
getAccessToken: async (sessionId?:string) => Promise.resolve(undefined),
50+
exchangeToken: async (config: TokenExchangeRequestConfig, sessionId?:string) => Promise.resolve({} as TokenResponse | Response),
4751
});
4852

4953
AsgardeoContext.displayName = 'AsgardeoContext';

packages/nextjs/src/client/contexts/Asgardeo/AsgardeoProvider.tsx

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@ export type AsgardeoClientProviderProps = Partial<Omit<AsgardeoProviderProps, 'b
7777
) => Promise<{data: {user: User}; error: string; success: boolean}>;
7878
user: User | null;
7979
userProfile: UserProfile;
80+
getIdToken: AsgardeoContextProps['getIdToken'];
81+
getDecodedIdToken: AsgardeoContextProps['getDecodedIdToken'];
82+
getAccessToken: AsgardeoContextProps['getAccessToken'];
83+
exchangeToken: AsgardeoContextProps['exchangeToken'];
8084
};
8185

8286
const AsgardeoClientProvider: FC<PropsWithChildren<AsgardeoClientProviderProps>> = ({
@@ -102,6 +106,10 @@ const AsgardeoClientProvider: FC<PropsWithChildren<AsgardeoClientProviderProps>>
102106
getAllOrganizations,
103107
switchOrganization,
104108
brandingPreference,
109+
getIdToken,
110+
getDecodedIdToken,
111+
getAccessToken,
112+
exchangeToken,
105113
}: PropsWithChildren<AsgardeoClientProviderProps>) => {
106114
const reRenderCheckRef: RefObject<boolean> = useRef(false);
107115
const router = useRouter();
@@ -309,8 +317,12 @@ const AsgardeoClientProvider: FC<PropsWithChildren<AsgardeoClientProviderProps>>
309317
signUpUrl,
310318
applicationId,
311319
organizationHandle,
320+
getIdToken,
321+
getDecodedIdToken,
322+
getAccessToken,
323+
exchangeToken,
312324
}),
313-
[baseUrl, user, isSignedIn, isLoading, signInUrl, signUpUrl, applicationId, organizationHandle],
325+
[baseUrl, user, isSignedIn, isLoading, signInUrl, signUpUrl, applicationId, organizationHandle, getIdToken, getDecodedIdToken, getAccessToken, exchangeToken],
314326
);
315327

316328
const handleProfileUpdate = (payload: User): void => {

packages/nextjs/src/server/AsgardeoProvider.tsx

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
'use server';
2020

21-
import {BrandingPreference, AsgardeoRuntimeError, Organization, User, UserProfile} from '@asgardeo/node';
21+
import {BrandingPreference, AsgardeoRuntimeError, Organization, User, UserProfile, TokenExchangeRequestConfig} from '@asgardeo/node';
2222
import {AsgardeoProviderProps} from '@asgardeo/react';
2323
import {FC, PropsWithChildren, ReactElement} from 'react';
2424
import createOrganization from './actions/createOrganization';
@@ -41,6 +41,10 @@ import AsgardeoNextClient from '../AsgardeoNextClient';
4141
import AsgardeoClientProvider from '../client/contexts/Asgardeo/AsgardeoProvider';
4242
import {AsgardeoNextConfig} from '../models/config';
4343
import logger from '../utils/logger';
44+
import getAccessToken from './actions/getAccessToken';
45+
import getIdToken from './actions/getIdToken';
46+
import getDecodedIdToken from './actions/getDecodedIdToken';
47+
import exchangeToken from './actions/exchangeToken';
4448

4549
/**
4650
* Props interface of {@link AsgardeoServerProvider}
@@ -194,6 +198,12 @@ const AsgardeoServerProvider: FC<PropsWithChildren<AsgardeoServerProviderProps>>
194198
switchOrganization={switchOrganization}
195199
brandingPreference={brandingPreference}
196200
createOrganization={createOrganization}
201+
getAccessToken={async () => await getAccessToken()}
202+
getIdToken={async () => await getIdToken(sessionId)}
203+
exchangeToken={async (exchangeConfig: TokenExchangeRequestConfig) =>
204+
await exchangeToken(exchangeConfig, sessionId)
205+
}
206+
getDecodedIdToken={async () => await getDecodedIdToken(sessionId)}
197207
>
198208
{children}
199209
</AsgardeoClientProvider>
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/**
2+
* Copyright (c) 2026, 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+
'use server';
20+
21+
import {TokenExchangeRequestConfig, TokenResponse} from '@asgardeo/node';
22+
import AsgardeoNextClient from '../../AsgardeoNextClient';
23+
24+
/**
25+
* Exchange tokens based on the provided configuration.
26+
* This supports various token exchange grant types like organization switching.
27+
*
28+
* @param config - Token exchange request configuration
29+
* @param sessionId - Optional session ID for the exchange
30+
* @returns The token response from the exchange operation
31+
* @throws {AsgardeoRuntimeError} If the token exchange fails
32+
*/
33+
const exchangeToken = async (
34+
config: TokenExchangeRequestConfig,
35+
sessionId?: string,
36+
): Promise<TokenResponse | Response> => {
37+
const client = AsgardeoNextClient.getInstance();
38+
return client.exchangeToken(config, sessionId);
39+
};
40+
41+
export default exchangeToken;
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/**
2+
* Copyright (c) 2026, 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+
'use server';
20+
21+
import {IdToken} from '@asgardeo/node';
22+
import AsgardeoNextClient from '../../AsgardeoNextClient';
23+
24+
/**
25+
* Get the decoded ID token from the current session.
26+
*
27+
* @param sessionId - Optional session ID to retrieve the decoded ID token for
28+
* @returns The decoded ID token payload
29+
* @throws {AsgardeoRuntimeError} If the decoded ID token cannot be retrieved
30+
*/
31+
const getDecodedIdToken = async (sessionId?: string): Promise<IdToken> => {
32+
const client = AsgardeoNextClient.getInstance();
33+
return client.getDecodedIdToken(sessionId);
34+
};
35+
36+
export default getDecodedIdToken;
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/**
2+
* Copyright (c) 2026, 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+
'use server';
20+
21+
import {ReadonlyRequestCookies} from 'next/dist/server/web/spec-extension/adapters/request-cookies';
22+
import {cookies} from 'next/headers';
23+
import SessionManager from '../../utils/SessionManager';
24+
25+
/**
26+
* Get the ID token from the session cookie.
27+
*
28+
* @returns The ID token if it exists, undefined otherwise
29+
*/
30+
const getIdToken = async (sessionId?: string): Promise<string | undefined> => {
31+
const cookieStore: ReadonlyRequestCookies = await cookies();
32+
33+
const idToken = cookieStore.get(SessionManager.getSessionCookieName())?.value;
34+
35+
if (idToken) {
36+
try {
37+
const sessionPayload = await SessionManager.verifySessionToken(idToken);
38+
return sessionPayload['idToken'] as string;
39+
} catch (error) {
40+
return undefined;
41+
}
42+
}
43+
44+
return undefined;
45+
};
46+
47+
export default getIdToken;

packages/react/src/contexts/Asgardeo/AsgardeoContext.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -111,23 +111,23 @@ export type AsgardeoContextProps = {
111111
*
112112
* @returns A promise that resolves to the decoded ID token payload.
113113
*/
114-
getDecodedIdToken: () => Promise<IdToken>;
114+
getDecodedIdToken: () => Promise<IdToken | undefined>;
115115

116116
/**
117117
* Function to retrieve the ID token.
118118
* This function retrieves the ID token and returns it.
119119
*
120120
* @returns A promise that resolves to the ID token.
121121
*/
122-
getIdToken: () => Promise<string>;
122+
getIdToken: () => Promise<string | undefined>;
123123

124124
/**
125125
* Retrieves the access token stored in the storage.
126126
* This function retrieves the access token and returns it.
127127
* @remarks This does not work in the `webWorker` or any other worker environment.
128-
* @returns A promise that resolves to the access token.
128+
* @returns A promise that resolves to the access token, or undefined if not available.
129129
*/
130-
getAccessToken: () => Promise<string>;
130+
getAccessToken: () => Promise<string | undefined>;
131131

132132
/**
133133
* Swaps the current access token with a new one based on the provided configuration (with a grant type).

0 commit comments

Comments
 (0)