Skip to content

Commit 75b9840

Browse files
Refactor token request and exchange logic for improved clarity and error handling
1 parent 78c943a commit 75b9840

2 files changed

Lines changed: 135 additions & 143 deletions

File tree

packages/javascript/src/__legacy__/client.ts

Lines changed: 134 additions & 142 deletions
Original file line numberDiff line numberDiff line change
@@ -317,97 +317,93 @@ export class AsgardeoAuthClient<T> {
317317
params: Record<string, unknown>;
318318
},
319319
): Promise<TokenResponse> {
320-
const performTokenRequest = async (): Promise<TokenResponse> => {
321-
const tokenEndpoint: string | undefined = (await this.oidcProviderMetaDataProvider()).token_endpoint;
322-
const configData: StrictAuthClientConfig = await this.configProvider();
323-
324-
if (!tokenEndpoint || tokenEndpoint.trim().length === 0) {
325-
throw new AsgardeoAuthException(
326-
'JS-AUTH_CORE-RAT1-NF01',
327-
'Token endpoint not found.',
328-
'No token endpoint was found in the OIDC provider meta data returned by the well-known endpoint ' +
329-
'or the token endpoint passed to the SDK is empty.',
330-
);
331-
}
320+
if (
321+
!(await this.storageManager.getTemporaryDataParameter(
322+
OIDCDiscoveryConstants.Storage.StorageKeys.OPENID_PROVIDER_CONFIG_INITIATED,
323+
))
324+
) {
325+
await this.loadOpenIDProviderConfiguration(false);
326+
}
332327

333-
if (sessionState) {
334-
await this.storageManager.setSessionDataParameter(
335-
OIDCRequestConstants.Params.SESSION_STATE as keyof SessionData,
336-
sessionState,
337-
userId,
338-
);
339-
}
328+
const tokenEndpoint: string | undefined = (await this.oidcProviderMetaDataProvider()).token_endpoint;
329+
const configData: StrictAuthClientConfig = await this.configProvider();
340330

341-
const body: URLSearchParams = new URLSearchParams();
331+
if (!tokenEndpoint || tokenEndpoint.trim().length === 0) {
332+
throw new AsgardeoAuthException(
333+
'JS-AUTH_CORE-RAT1-NF01',
334+
'Token endpoint not found.',
335+
'No token endpoint was found in the OIDC provider meta data returned by the well-known endpoint ' +
336+
'or the token endpoint passed to the SDK is empty.',
337+
);
338+
}
342339

343-
body.set('client_id', configData.clientId);
340+
if (sessionState) {
341+
await this.storageManager.setSessionDataParameter(
342+
OIDCRequestConstants.Params.SESSION_STATE as keyof SessionData,
343+
sessionState,
344+
userId,
345+
);
346+
}
344347

345-
if (configData.clientSecret && configData.clientSecret.trim().length > 0) {
346-
body.set('client_secret', configData.clientSecret);
347-
}
348+
const body: URLSearchParams = new URLSearchParams();
348349

349-
const code: string = authorizationCode;
350+
body.set('client_id', configData.clientId);
350351

351-
body.set('code', code);
352+
if (configData.clientSecret && configData.clientSecret.trim().length > 0) {
353+
body.set('client_secret', configData.clientSecret);
354+
}
352355

353-
body.set('grant_type', 'authorization_code');
354-
body.set('redirect_uri', configData.afterSignInUrl);
356+
const code: string = authorizationCode;
355357

356-
if (tokenRequestConfig?.params) {
357-
Object.entries(tokenRequestConfig.params).forEach(([key, value]: [key: string, value: unknown]) => {
358-
body.append(key, value as string);
359-
});
360-
}
358+
body.set('code', code);
361359

362-
if (configData.enablePKCE) {
363-
body.set(
364-
'code_verifier',
365-
`${await this.storageManager.getTemporaryDataParameter(extractPkceStorageKeyFromState(state), userId)}`,
366-
);
360+
body.set('grant_type', 'authorization_code');
361+
body.set('redirect_uri', configData.afterSignInUrl);
367362

368-
await this.storageManager.removeTemporaryDataParameter(extractPkceStorageKeyFromState(state), userId);
369-
}
363+
if (tokenRequestConfig?.params) {
364+
Object.entries(tokenRequestConfig.params).forEach(([key, value]: [key: string, value: unknown]) => {
365+
body.append(key, value as string);
366+
});
367+
}
370368

371-
let tokenResponse: Response;
369+
if (configData.enablePKCE) {
370+
body.set(
371+
'code_verifier',
372+
`${await this.storageManager.getTemporaryDataParameter(extractPkceStorageKeyFromState(state), userId)}`,
373+
);
372374

373-
try {
374-
tokenResponse = await fetch(tokenEndpoint, {
375-
body,
376-
credentials: configData.sendCookiesInRequests ? 'include' : 'same-origin',
377-
headers: {
378-
Accept: 'application/json',
379-
'Content-Type': 'application/x-www-form-urlencoded',
380-
},
381-
method: 'POST',
382-
});
383-
} catch (error: any) {
384-
throw new AsgardeoAuthException(
385-
'JS-AUTH_CORE-RAT1-NE02',
386-
'Requesting access token failed',
387-
error ?? 'The request to get the access token from the server failed.',
388-
);
389-
}
375+
await this.storageManager.removeTemporaryDataParameter(extractPkceStorageKeyFromState(state), userId);
376+
}
390377

391-
if (!tokenResponse.ok) {
392-
throw new AsgardeoAuthException(
393-
'JS-AUTH_CORE-RAT1-HE03',
394-
`Requesting access token failed with ${tokenResponse.statusText}`,
395-
(await tokenResponse.json()) as string,
396-
);
397-
}
378+
let tokenResponse: Response;
398379

399-
return this.authHelper.handleTokenResponse(tokenResponse, userId);
400-
};
380+
try {
381+
tokenResponse = await fetch(tokenEndpoint, {
382+
body,
383+
credentials: configData.sendCookiesInRequests ? 'include' : 'same-origin',
384+
headers: {
385+
Accept: 'application/json',
386+
'Content-Type': 'application/x-www-form-urlencoded',
387+
},
388+
method: 'POST',
389+
});
390+
} catch (error: any) {
391+
throw new AsgardeoAuthException(
392+
'JS-AUTH_CORE-RAT1-NE02',
393+
'Requesting access token failed',
394+
error ?? 'The request to get the access token from the server failed.',
395+
);
396+
}
401397

402-
if (
403-
await this.storageManager.getTemporaryDataParameter(
404-
OIDCDiscoveryConstants.Storage.StorageKeys.OPENID_PROVIDER_CONFIG_INITIATED,
405-
)
406-
) {
407-
return performTokenRequest();
398+
if (!tokenResponse.ok) {
399+
throw new AsgardeoAuthException(
400+
'JS-AUTH_CORE-RAT1-HE03',
401+
`Requesting access token failed with ${tokenResponse.statusText}`,
402+
(await tokenResponse.json()) as string,
403+
);
408404
}
409405

410-
return this.loadOpenIDProviderConfiguration(false).then(() => performTokenRequest());
406+
return this.authHelper.handleTokenResponse(tokenResponse, userId);
411407
}
412408

413409
public async loadOpenIDProviderConfiguration(forceInit: boolean): Promise<void> {
@@ -914,89 +910,85 @@ export class AsgardeoAuthClient<T> {
914910
* @preserve
915911
*/
916912
public async exchangeToken(config: TokenExchangeRequestConfig, userId?: string): Promise<TokenResponse | Response> {
917-
const executeTokenExchange = async (): Promise<TokenResponse | Response> => {
918-
const oidcProviderMetadata: OIDCDiscoveryApiResponse = await this.oidcProviderMetaDataProvider();
919-
const configData: StrictAuthClientConfig = await this.configProvider();
920-
921-
let tokenEndpoint: string | undefined;
913+
if (
914+
!(await this.storageManager.getTemporaryDataParameter(
915+
OIDCDiscoveryConstants.Storage.StorageKeys.OPENID_PROVIDER_CONFIG_INITIATED,
916+
))
917+
) {
918+
await this.loadOpenIDProviderConfiguration(false);
919+
}
922920

923-
if (config.tokenEndpoint && config.tokenEndpoint.trim().length !== 0) {
924-
tokenEndpoint = config.tokenEndpoint;
925-
} else {
926-
tokenEndpoint = oidcProviderMetadata.token_endpoint;
927-
}
921+
const oidcProviderMetadata: OIDCDiscoveryApiResponse = await this.oidcProviderMetaDataProvider();
922+
const configData: StrictAuthClientConfig = await this.configProvider();
928923

929-
if (!tokenEndpoint || tokenEndpoint.trim().length === 0) {
930-
throw new AsgardeoAuthException(
931-
'JS-AUTH_CORE-RCG-NF01',
932-
'Token endpoint not found.',
933-
'No token endpoint was found in the OIDC provider meta data returned by the well-known endpoint ' +
934-
'or the token endpoint passed to the SDK is empty.',
935-
);
936-
}
924+
let tokenEndpoint: string | undefined;
937925

938-
const data: string[] = await Promise.all(
939-
Object.entries(config.data).map(async ([key, value]: [key: string, value: any]) => {
940-
const newValue: string = await this.authHelper.replaceCustomGrantTemplateTags(value as string, userId);
926+
if (config.tokenEndpoint && config.tokenEndpoint.trim().length !== 0) {
927+
tokenEndpoint = config.tokenEndpoint;
928+
} else {
929+
tokenEndpoint = oidcProviderMetadata.token_endpoint;
930+
}
941931

942-
return `${key}=${newValue}`;
943-
}),
932+
if (!tokenEndpoint || tokenEndpoint.trim().length === 0) {
933+
throw new AsgardeoAuthException(
934+
'JS-AUTH_CORE-RCG-NF01',
935+
'Token endpoint not found.',
936+
'No token endpoint was found in the OIDC provider meta data returned by the well-known endpoint ' +
937+
'or the token endpoint passed to the SDK is empty.',
944938
);
939+
}
945940

946-
let requestHeaders: Record<string, any> = {
947-
Accept: 'application/json',
948-
'Content-Type': 'application/x-www-form-urlencoded',
949-
};
941+
const data: string[] = await Promise.all(
942+
Object.entries(config.data).map(async ([key, value]: [key: string, value: any]) => {
943+
const newValue: string = await this.authHelper.replaceCustomGrantTemplateTags(value as string, userId);
950944

951-
if (config.attachToken) {
952-
requestHeaders = {
953-
...requestHeaders,
954-
Authorization: `Bearer ${(await this.storageManager.getSessionData(userId)).access_token}`,
955-
};
956-
}
945+
return `${key}=${newValue}`;
946+
}),
947+
);
957948

958-
const requestConfig: RequestInit = {
959-
body: data.join('&'),
960-
credentials: configData.sendCookiesInRequests ? 'include' : 'same-origin',
961-
headers: new Headers(requestHeaders),
962-
method: 'POST',
963-
};
949+
let requestHeaders: Record<string, any> = {
950+
Accept: 'application/json',
951+
'Content-Type': 'application/x-www-form-urlencoded',
952+
};
964953

965-
let response: Response;
954+
if (config.attachToken) {
955+
requestHeaders = {
956+
...requestHeaders,
957+
Authorization: `Bearer ${(await this.storageManager.getSessionData(userId)).access_token}`,
958+
};
959+
}
966960

967-
try {
968-
response = await fetch(tokenEndpoint, requestConfig);
969-
} catch (error: any) {
970-
throw new AsgardeoAuthException(
971-
'JS-AUTH_CORE-RCG-NE02',
972-
'The custom grant request failed.',
973-
error ?? 'The request sent to get the custom grant failed.',
974-
);
975-
}
961+
const requestConfig: RequestInit = {
962+
body: data.join('&'),
963+
credentials: configData.sendCookiesInRequests ? 'include' : 'same-origin',
964+
headers: new Headers(requestHeaders),
965+
method: 'POST',
966+
};
976967

977-
if (response.status !== 200 || !response.ok) {
978-
throw new AsgardeoAuthException(
979-
'JS-AUTH_CORE-RCG-HE03',
980-
`Invalid response status received for the custom grant request. (${response.statusText})`,
981-
(await response.json()) as string,
982-
);
983-
}
968+
let response: Response;
984969

985-
if (config.returnsSession) {
986-
return this.authHelper.handleTokenResponse(response, userId);
987-
}
988-
return Promise.resolve((await response.json()) as TokenResponse | Response);
989-
};
970+
try {
971+
response = await fetch(tokenEndpoint, requestConfig);
972+
} catch (error: any) {
973+
throw new AsgardeoAuthException(
974+
'JS-AUTH_CORE-RCG-NE02',
975+
'The custom grant request failed.',
976+
error ?? 'The request sent to get the custom grant failed.',
977+
);
978+
}
990979

991-
if (
992-
await this.storageManager.getTemporaryDataParameter(
993-
OIDCDiscoveryConstants.Storage.StorageKeys.OPENID_PROVIDER_CONFIG_INITIATED,
994-
)
995-
) {
996-
return executeTokenExchange();
980+
if (response.status !== 200 || !response.ok) {
981+
throw new AsgardeoAuthException(
982+
'JS-AUTH_CORE-RCG-HE03',
983+
`Invalid response status received for the custom grant request. (${response.statusText})`,
984+
(await response.json()) as string,
985+
);
997986
}
998987

999-
return this.loadOpenIDProviderConfiguration(false).then(() => executeTokenExchange());
988+
if (config.returnsSession) {
989+
return this.authHelper.handleTokenResponse(response, userId);
990+
}
991+
return Promise.resolve((await response.json()) as TokenResponse | Response);
1000992
}
1001993

1002994
/**

packages/javascript/src/__legacy__/helpers/authentication-helper.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ export class AuthenticationHelper<T> {
253253
}
254254
sessionData = await this.storageManager.getSessionData(userId, instanceKey);
255255

256-
if (!sessionData.access_token) {
256+
if (!sessionData || !sessionData.access_token) {
257257
throw new AsgardeoAuthException(
258258
'JS-AUTH_HELPER-RCGTT-NE01',
259259
'No session data found for source instance.',

0 commit comments

Comments
 (0)