Skip to content

Commit 6bc940b

Browse files
committed
feat: add exchangeToken method for token exchange functionality across clients
1 parent 2852163 commit 6bc940b

File tree

7 files changed

+54
-6
lines changed

7 files changed

+54
-6
lines changed

packages/javascript/src/AsgardeoJavaScriptClient.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import {Config, SignInOptions, SignOutOptions, SignUpOptions} from './models/con
2222
import {Storage} from './models/store';
2323
import {EmbeddedFlowExecuteRequestPayload, EmbeddedFlowExecuteResponse} from './models/embedded-flow';
2424
import {EmbeddedSignInFlowHandleRequestPayload} from './models/embedded-signin-flow';
25-
import {TokenResponse} from './models/token';
25+
import {TokenExchangeRequestConfig, TokenResponse} from './models/token';
2626
import {Organization} from './models/organization';
2727
import {User, UserProfile} from './models/user';
2828

@@ -55,6 +55,8 @@ abstract class AsgardeoJavaScriptClient<T = Config> implements AsgardeoClient<T>
5555

5656
abstract getConfiguration(): T;
5757

58+
abstract exchangeToken(config: TokenExchangeRequestConfig, sessionId?: string): Promise<TokenResponse | Response>;
59+
5860
abstract signIn(
5961
options?: SignInOptions,
6062
sessionId?: string,

packages/javascript/src/models/client.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import {
2525
import {EmbeddedSignInFlowHandleRequestPayload} from './embedded-signin-flow';
2626
import {Organization} from './organization';
2727
import {User, UserProfile} from './user';
28-
import {TokenResponse} from './token';
28+
import {TokenExchangeRequestConfig, TokenResponse} from './token';
2929
import {Storage} from './store';
3030
import {SignInOptions, SignOutOptions, SignUpOptions} from './config';
3131

@@ -65,6 +65,13 @@ export interface AsgardeoClient<T> {
6565

6666
getConfiguration(): T;
6767

68+
/**
69+
* Swaps the current access token with a new one based on the provided configuration (with a grant type).
70+
* @param config - Configuration for the token exchange request.
71+
* @param sessionId - Optional session ID to be used for the token exchange.
72+
*/
73+
exchangeToken(config: TokenExchangeRequestConfig, sessionId?: string): Promise<TokenResponse | Response>;
74+
6875
updateUserProfile(payload: any, userId?: string): Promise<User>;
6976

7077
/**

packages/nextjs/src/AsgardeoNextClient.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ import {
5252
extractUserClaimsFromIdToken,
5353
TokenResponse,
5454
Storage,
55+
TokenExchangeRequestConfig,
5556
} from '@asgardeo/node';
5657
import {AsgardeoNextConfig} from './models/config';
5758
import getSessionId from './server/actions/getSessionId';
@@ -381,6 +382,10 @@ class AsgardeoNextClient<T extends AsgardeoNextConfig = AsgardeoNextConfig> exte
381382
return this.asgardeo.isSignedIn(sessionId as string);
382383
}
383384

385+
override exchangeToken(config: TokenExchangeRequestConfig, sessionId?: string): Promise<TokenResponse | Response> {
386+
return this.asgardeo.exchangeToken(config, sessionId);
387+
}
388+
384389
/**
385390
* Gets the access token from the session cookie if no sessionId is provided,
386391
* otherwise falls back to legacy client method.

packages/nextjs/src/server/asgardeo.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,29 @@
1616
* under the License.
1717
*/
1818

19+
import {TokenExchangeRequestConfig} from '@asgardeo/node';
1920
import AsgardeoNextClient from '../AsgardeoNextClient';
2021
import getSessionIdAction from './actions/getSessionId';
2122

2223
const asgardeo = async () => {
23-
const getAccessToken = async (id: string) => {
24+
const getAccessToken = async (sessionId: string) => {
2425
const client: AsgardeoNextClient = AsgardeoNextClient.getInstance();
25-
return await client.getAccessToken(id);
26+
return await client.getAccessToken(sessionId);
2627
};
2728

2829
const getSessionId = async () => {
2930
return await getSessionIdAction();
3031
};
3132

33+
const exchangeToken = async (config: TokenExchangeRequestConfig, sessionId: string) => {
34+
const client: AsgardeoNextClient = AsgardeoNextClient.getInstance();
35+
return await client.exchangeToken(config, sessionId);
36+
};
37+
3238
return {
3339
getAccessToken,
3440
getSessionId,
41+
exchangeToken,
3542
};
3643
};
3744

packages/react/src/AsgardeoReactClient.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ import {
4242
HttpRequestConfig,
4343
HttpResponse,
4444
Storage,
45+
TokenExchangeRequestConfig,
4546
} from '@asgardeo/browser';
4647
import AuthAPI from './__temp__/api';
4748
import getMeOrganizations from './api/getMeOrganizations';
@@ -271,6 +272,15 @@ class AsgardeoReactClient<T extends AsgardeoReactConfig = AsgardeoReactConfig> e
271272
return this.asgardeo.getConfigData() as unknown as T;
272273
}
273274

275+
override async exchangeToken(
276+
config: TokenExchangeRequestConfig,
277+
sessionId?: string,
278+
): Promise<TokenResponse | Response> {
279+
return this.withLoading(async () => {
280+
return this.asgardeo.exchangeToken(config, (user: User) => {}) as unknown as TokenResponse | Response;
281+
});
282+
}
283+
274284
override signIn(
275285
options?: SignInOptions,
276286
sessionId?: string,

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

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,15 @@
1717
*/
1818

1919
import {Context, createContext} from 'react';
20-
import {HttpRequestConfig, HttpResponse, IdToken, Organization, SignInOptions} from '@asgardeo/browser';
20+
import {
21+
HttpRequestConfig,
22+
HttpResponse,
23+
IdToken,
24+
Organization,
25+
SignInOptions,
26+
TokenExchangeRequestConfig,
27+
TokenResponse,
28+
} from '@asgardeo/browser';
2129
import AsgardeoReactClient from '../../AsgardeoReactClient';
2230

2331
/**
@@ -99,12 +107,19 @@ export type AsgardeoContextProps = {
99107
getDecodedIdToken?: () => Promise<IdToken>;
100108

101109
/**
102-
* Function to retrieve the access token.
110+
* Retrieves the access token stored in the storage.
103111
* This function retrieves the access token and returns it.
104112
* @remarks This does not work in the `webWorker` or any other worker environment.
105113
* @returns A promise that resolves to the access token.
106114
*/
107115
getAccessToken?: () => Promise<string>;
116+
117+
/**
118+
* Swaps the current access token with a new one based on the provided configuration (with a grant type).
119+
* @param config - Configuration for the token exchange request.
120+
* @returns A promise that resolves to the token response or the raw response.
121+
*/
122+
exchangeToken?: (config: TokenExchangeRequestConfig) => Promise<TokenResponse | Response>;
108123
};
109124

110125
/**
@@ -133,6 +148,7 @@ const AsgardeoContext: Context<AsgardeoContextProps | null> = createContext<null
133148
signInOptions: {},
134149
getDecodedIdToken: null,
135150
getAccessToken: null,
151+
exchangeToken: null,
136152
});
137153

138154
AsgardeoContext.displayName = 'AsgardeoContext';

packages/react/src/contexts/Asgardeo/AsgardeoProvider.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,7 @@ const AsgardeoProvider: FC<PropsWithChildren<AsgardeoProviderProps>> = ({
438438
},
439439
signInOptions,
440440
getDecodedIdToken: asgardeo.getDecodedIdToken.bind(asgardeo),
441+
exchangeToken: asgardeo.exchangeToken.bind(asgardeo),
441442
syncSession,
442443
}),
443444
[

0 commit comments

Comments
 (0)