Skip to content

Commit

Permalink
Correctly handle error from par endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
ewanharris committed Dec 6, 2023
1 parent 0f2aabc commit 3a5c2c4
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 10 deletions.
12 changes: 10 additions & 2 deletions src/auth0-session/client/edge-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,16 @@ export class EdgeClient extends AbstractClient {

if (this.config.pushedAuthorizationRequests) {
const response = await oauth.pushedAuthorizationRequest(as, client, parameters as Record<string, string>);
const body = await response.json();
parameters = { request_uri: body.request_uri };
const result = await oauth.processPushedAuthorizationResponse(as, client, response);
if (oauth.isOAuth2Error(result)) {
throw new IdentityProviderError({
message: result.error_description || result.error,
error: result.error,
error_description: result.error_description
});
}

parameters = { request_uri: result.request_uri };
}

const authorizationUrl = new URL(as.authorization_endpoint as string);
Expand Down
8 changes: 6 additions & 2 deletions tests/fixtures/app-router-helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ export type GetResponseOpts = {
clearNock?: boolean;
auth0Instance?: Auth0Server;
reqInit?: RequestInit;
parStatus?: number;
parPayload?: Record<string, unknown>;
};

export type LoginOpts = Omit<GetResponseOpts, 'url'>;
Expand All @@ -81,11 +83,13 @@ export const getResponse = async ({
extraHandlers,
clearNock = true,
auth0Instance,
reqInit
reqInit,
parStatus,
parPayload
}: GetResponseOpts) => {
const opts = { ...withApi, ...config };
clearNock && nock.cleanAll();
await setupNock(opts, { idTokenClaims, discoveryOptions, userInfoPayload, userInfoToken });
await setupNock(opts, { idTokenClaims, discoveryOptions, userInfoPayload, userInfoToken, parPayload, parStatus });
const auth0 = url.split('?')[0].split('/').slice(3);
const instance = auth0Instance || initAuth0(opts);
const handleAuth = instance.handleAuth({
Expand Down
4 changes: 2 additions & 2 deletions tests/fixtures/oidc-nocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,6 @@ export function userInfo(params: ConfigParameters, token: string, payload: Recor
.reply(200, payload);
}

export function par(params: ConfigParameters): nock.Scope {
return nock(`${params.issuerBaseURL}`).post('/oauth/par').reply(201, { request_uri: 'foo', expires_in: 100 });
export function par(params: ConfigParameters, status = 201, payload: Record<string, unknown>): nock.Scope {
return nock(`${params.issuerBaseURL}`).post('/oauth/par').reply(status, payload);
}
13 changes: 10 additions & 3 deletions tests/fixtures/setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ export type SetupOptions = {
userInfoPayload?: Record<string, string>;
userInfoToken?: string;
asyncProps?: boolean;
parStatus?: number;
parPayload?: Record<string, unknown>;
};

export const defaultOnError: PageRouterOnError = (_req, res, error) => {
Expand All @@ -56,14 +58,19 @@ export const setupNock = async (
idTokenClaims,
discoveryOptions,
userInfoPayload = {},
userInfoToken = 'eyJz93a...k4laUWw'
}: Pick<SetupOptions, 'idTokenClaims' | 'discoveryOptions' | 'userInfoPayload' | 'userInfoToken'> = {}
userInfoToken = 'eyJz93a...k4laUWw',
parStatus = 201,
parPayload = { request_uri: 'foo', expires_in: 100 }
}: Pick<
SetupOptions,
'idTokenClaims' | 'discoveryOptions' | 'userInfoPayload' | 'userInfoToken' | 'parStatus' | 'parPayload'
> = {}
) => {
discovery(config, discoveryOptions);
jwksEndpoint(config, jwks);
codeExchange(config, await makeIdToken({ iss: 'https://acme.auth0.local/', ...idTokenClaims }));
userInfo(config, userInfoToken, userInfoPayload);
par(config);
par(config, parStatus, parPayload);
};

export const setup = async (
Expand Down
17 changes: 16 additions & 1 deletion tests/handlers/login.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ describe('login handler (app router)', () => {
expect(res.statusText).toMatch(/Login handler failed. CAUSE: Custom state value must be an object/);
});

test('should redirect to the identity provider', async () => {
test('should redirect to the identity provider when using pushedAuthorizationRequests', async () => {
const res = await getResponse({
url: '/api/auth/login',
config: {
Expand All @@ -275,4 +275,19 @@ describe('login handler (app router)', () => {
pathname: '/authorize'
});
});

test('should throw an error if the PAR endpoint returns an error', async () => {
const res = await getResponse({
url: '/api/auth/login',
config: {
clientSecret: '__test_client_secret__',
clientAuthMethod: 'client_secret_post',
pushedAuthorizationRequests: true
},
parStatus: 401,
parPayload: { error: 'invalid_client' }
});
expect(res.ok).toBe(false);
expect(res.statusText).toBe('Login handler failed. CAUSE: invalid_client');
});
});

0 comments on commit 3a5c2c4

Please sign in to comment.