From f4ed8359d2abf67c25faedb45f8ace1ad79bbcd1 Mon Sep 17 00:00:00 2001 From: Mariano Iglesias Date: Wed, 17 Feb 2021 23:25:39 -0300 Subject: [PATCH 1/2] Add support for specifying redirect_uri at runtime on the callback handler just as it's currently allowed on the login handler --- src/auth0-session/handlers/callback.ts | 5 +++-- tests/auth0-session/fixtures/server.ts | 13 ++++++++----- tests/auth0-session/handlers/callback.test.ts | 18 ++++++++++++++++++ 3 files changed, 29 insertions(+), 7 deletions(-) diff --git a/src/auth0-session/handlers/callback.ts b/src/auth0-session/handlers/callback.ts index 832e875d6..8328afbd0 100644 --- a/src/auth0-session/handlers/callback.ts +++ b/src/auth0-session/handlers/callback.ts @@ -15,6 +15,8 @@ export type AfterCallback = (req: any, res: any, session: any, state: Record Promise; @@ -27,8 +29,7 @@ export default function callbackHandlerFactory( ): HandleCallback { return async (req, res, options) => { const client = await getClient(); - - const redirectUri = getRedirectUri(config); + const redirectUri = options?.redirectUri || getRedirectUri(config); let expectedState; let tokenSet; diff --git a/tests/auth0-session/fixtures/server.ts b/tests/auth0-session/fixtures/server.ts index 63d593cc3..c38d904de 100644 --- a/tests/auth0-session/fixtures/server.ts +++ b/tests/auth0-session/fixtures/server.ts @@ -17,7 +17,8 @@ import { logoutHandler, callbackHandler, LoginOptions, - LogoutOptions + LogoutOptions, + CallbackOptions } from '../../../src/auth0-session'; import wellKnown from './well-known.json'; import { jwks } from './cert'; @@ -52,7 +53,7 @@ class TestSessionCache implements SessionCache { type Handlers = { handleLogin: (req: IncomingMessage, res: ServerResponse, opts?: LoginOptions) => Promise; handleLogout: (req: IncomingMessage, res: ServerResponse, opts?: LogoutOptions) => Promise; - handleCallback: (req: IncomingMessage, res: ServerResponse) => Promise; + handleCallback: (req: IncomingMessage, res: ServerResponse, opts?: CallbackOptions) => Promise; handleSession: (req: IncomingMessage, res: ServerResponse) => Promise; }; @@ -103,7 +104,7 @@ const parseJson = (req: IncomingMessage, res: ServerResponse): Promise async (req: IncomingMessage, res: ServerResponse): Promise => { const { pathname } = url.parse(req.url as string, true); const parsedReq = await parseJson(req, res); @@ -115,7 +116,7 @@ const requestListener = ( case '/logout': return await handlers.handleLogout(parsedReq, res, logoutOptions); case '/callback': - return await handlers.handleCallback(parsedReq, res); + return await handlers.handleCallback(parsedReq, res, callbackOptions); case '/session': return await handlers.handleSession(parsedReq, res); default: @@ -133,12 +134,14 @@ let server: HttpServer | HttpsServer; export const setup = async ( params: Omit, { + callbackOptions, loginOptions, logoutOptions, customListener, https }: { https?: boolean; + callbackOptions?: CallbackOptions; loginOptions?: LoginOptions; logoutOptions?: LogoutOptions; customListener?: (req: IncomingMessage, res: ServerResponse) => void; @@ -172,7 +175,7 @@ export const setup = async ( const port = await new Promise((resolve) => server.listen(0, () => resolve((server.address() as AddressInfo).port))); const baseURL = `http${https ? 's' : ''}://localhost:${port}`; - listener = customListener || requestListener(createHandlers({ ...params, baseURL }), { loginOptions, logoutOptions }); + listener = customListener || requestListener(createHandlers({ ...params, baseURL }), { callbackOptions, loginOptions, logoutOptions }); return baseURL; }; diff --git a/tests/auth0-session/handlers/callback.test.ts b/tests/auth0-session/handlers/callback.test.ts index e4ac69fae..c0b5a4879 100644 --- a/tests/auth0-session/handlers/callback.test.ts +++ b/tests/auth0-session/handlers/callback.test.ts @@ -372,4 +372,22 @@ describe('callback', () => { expect(res.statusCode).toEqual(302); expect(res.headers.location).toEqual(baseURL); }); + + it('should accept custom runtime redirect over base url', async () => { + const redirectUri = 'http://messi:3000/api/auth/callback/runtime'; + const baseURL = await setup(defaultConfig, { callbackOptions: { redirectUri } }); + const state = encodeState({ foo: 'bar' }); + const cookieJar = toSignedCookieJar( { state, nonce: '__test_nonce__' }, baseURL); + const { res } = await post(baseURL, '/callback', { + body: { + state: state, + id_token: makeIdToken() + }, + cookieJar, + fullResponse: true + }); + + expect(res.statusCode).toEqual(302); + expect(res.headers.location).toEqual(baseURL); + }); }); From 57a76114b2d4d24e96a9568184c982ac9ee71019 Mon Sep 17 00:00:00 2001 From: Mariano Iglesias Date: Thu, 18 Feb 2021 08:39:17 -0300 Subject: [PATCH 2/2] Adding redirectUri To CallbackOptions --- src/handlers/callback.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/handlers/callback.ts b/src/handlers/callback.ts index 5acf924ce..fa963f761 100644 --- a/src/handlers/callback.ts +++ b/src/handlers/callback.ts @@ -70,6 +70,8 @@ export type AfterCallback = ( */ export type CallbackOptions = { afterCallback?: AfterCallback; + + redirectUri?: string; }; /**