Skip to content

Commit

Permalink
Merge pull request #298 from mariano/runtime-redirect-uri-in-callback…
Browse files Browse the repository at this point in the history
…-handler

Allow setting redirect_uri at runtime on the callback handler just like it's allowed on the login handler
  • Loading branch information
adamjmcgrath authored Feb 18, 2021
2 parents 1ac9712 + 57a7611 commit 132f403
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 7 deletions.
5 changes: 3 additions & 2 deletions src/auth0-session/handlers/callback.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ export type AfterCallback = (req: any, res: any, session: any, state: Record<str

export type CallbackOptions = {
afterCallback?: AfterCallback;

redirectUri?: string;
};

export type HandleCallback = (req: IncomingMessage, res: ServerResponse, options?: CallbackOptions) => Promise<void>;
Expand All @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions src/handlers/callback.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ export type AfterCallback = (
*/
export type CallbackOptions = {
afterCallback?: AfterCallback;

redirectUri?: string;
};

/**
Expand Down
13 changes: 8 additions & 5 deletions tests/auth0-session/fixtures/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -52,7 +53,7 @@ class TestSessionCache implements SessionCache {
type Handlers = {
handleLogin: (req: IncomingMessage, res: ServerResponse, opts?: LoginOptions) => Promise<void>;
handleLogout: (req: IncomingMessage, res: ServerResponse, opts?: LogoutOptions) => Promise<void>;
handleCallback: (req: IncomingMessage, res: ServerResponse) => Promise<void>;
handleCallback: (req: IncomingMessage, res: ServerResponse, opts?: CallbackOptions) => Promise<void>;
handleSession: (req: IncomingMessage, res: ServerResponse) => Promise<void>;
};

Expand Down Expand Up @@ -103,7 +104,7 @@ const parseJson = (req: IncomingMessage, res: ServerResponse): Promise<IncomingM

const requestListener = (
handlers: Handlers,
{ loginOptions, logoutOptions }: { loginOptions?: LoginOptions; logoutOptions?: LogoutOptions }
{ callbackOptions, loginOptions, logoutOptions }: { callbackOptions?: CallbackOptions; loginOptions?: LoginOptions; logoutOptions?: LogoutOptions }
) => async (req: IncomingMessage, res: ServerResponse): Promise<void> => {
const { pathname } = url.parse(req.url as string, true);
const parsedReq = await parseJson(req, res);
Expand All @@ -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:
Expand All @@ -133,12 +134,14 @@ let server: HttpServer | HttpsServer;
export const setup = async (
params: Omit<ConfigParameters, 'baseURL'>,
{
callbackOptions,
loginOptions,
logoutOptions,
customListener,
https
}: {
https?: boolean;
callbackOptions?: CallbackOptions;
loginOptions?: LoginOptions;
logoutOptions?: LogoutOptions;
customListener?: (req: IncomingMessage, res: ServerResponse) => void;
Expand Down Expand Up @@ -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;
};

Expand Down
18 changes: 18 additions & 0 deletions tests/auth0-session/handlers/callback.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
});
});

0 comments on commit 132f403

Please sign in to comment.