Skip to content

Commit

Permalink
feat: added the option to not use post for the callback. Helps with L…
Browse files Browse the repository at this point in the history
…AX cookies
  • Loading branch information
meza committed Jul 8, 2023
1 parent 9a061f7 commit b30ef8a
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 23 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ export const authenticator = new Auth0RemixServer({
clientDetails: {
domain: process.env.AUTH0_DOMAIN,
clientID: process.env.AUTH0_CLIENT_ID,
clientSecret: process.env.AUTH0_CLIENT_SECRET
clientSecret: process.env.AUTH0_CLIENT_SECRET,
usePost: true // optional, defaults to true
},
callbackURL: `${process.env.APP_DOMAIN}/auth/callback`,
refreshTokenRotationEnabled: true,
Expand Down
1 change: 1 addition & 0 deletions src/Auth0RemixTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ export interface ClientCredentials {
clientSecret: string;
audience: string;
organization?: string | undefined;
usePost?: boolean | undefined;
}

export interface SessionStore {
Expand Down
16 changes: 4 additions & 12 deletions src/__snapshots__/index.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,10 @@ exports[`Auth0 Remix Server > logging out > calls the correct url 1`] = `"https:

exports[`Auth0 Remix Server > logging out > includes the headers supplied 1`] = `"https://test.domain.com/v2/logout?client_id=clientId&returnTo=http%3A%2F%2Flocalhost%3A3000%2Flogout-with-headers"`;

exports[`Auth0 Remix Server > the authorization process > adds custom callback url parameters 1`] = `"https://test.domain.com/authorize?response_type=code&response_mode=form_post&client_id=clientId&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fauth0%2Fcallback%3Ftest1%3DtestA%26test2%3DtestB%26test3%3DtestC&scope=offline_access+openid+profile+email&audience=https%3A%2F%2Ftest.domain.com%2Fapi%2Fv2%2F"`;
exports[`Auth0 Remix Server > the authorization process > adds custom callback url parameters 1`] = `"https://test.domain.com/authorize?redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fauth0%2Fcallback%3Ftest1%3DtestA%26test2%3DtestB%26test3%3DtestC&response_type=code&response_mode=form_post&client_id=clientId&scope=offline_access+openid+profile+email&audience=https%3A%2F%2Ftest.domain.com%2Fapi%2Fv2%2F"`;

exports[`Auth0 Remix Server > the authorization process > adds the connection when needed 1`] = `"https://test.domain.com/authorize?response_type=code&response_mode=form_post&client_id=clientId&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fauth0%2Fcallback&scope=offline_access+openid+profile+email&audience=https%3A%2F%2Ftest.domain.com%2Fapi%2Fv2%2F&connection=google"`;
exports[`Auth0 Remix Server > the authorization process > adds the organisation if needed 1`] = `"https://test.domain.com/authorize?redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fauth0%2Fcallback&response_type=code&response_mode=form_post&client_id=clientId&scope=offline_access+openid+profile+email&audience=https%3A%2F%2Ftest.domain.com%2Fapi%2Fv2%2F&organization=test-org"`;

exports[`Auth0 Remix Server > the authorization process > adds the organisation if needed 1`] = `"https://test.domain.com/authorize?response_type=code&response_mode=form_post&client_id=clientId&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fauth0%2Fcallback&scope=offline_access+openid+profile+email&audience=https%3A%2F%2Ftest.domain.com%2Fapi%2Fv2%2F&organization=test-org"`;
exports[`Auth0 Remix Server > the authorization process > forces the signup if asked 1`] = `"https://test.domain.com/authorize?redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fauth0%2Fcallback&response_type=code&response_mode=form_post&client_id=clientId&scope=offline_access+openid+profile+email&audience=https%3A%2F%2Ftest.domain.com%2Fapi%2Fv2%2F&screen_hint=signup"`;

exports[`Auth0 Remix Server > the authorization process > does silent auth if asked 1`] = `"https://test.domain.com/authorize?response_type=code&response_mode=form_post&client_id=clientId&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fauth0%2Fcallback&scope=offline_access+openid+profile+email&audience=https%3A%2F%2Ftest.domain.com%2Fapi%2Fv2%2F&prompt=none"`;

exports[`Auth0 Remix Server > the authorization process > forces the login if asked 1`] = `"https://test.domain.com/authorize?response_type=code&response_mode=form_post&client_id=clientId&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fauth0%2Fcallback&scope=offline_access+openid+profile+email&audience=https%3A%2F%2Ftest.domain.com%2Fapi%2Fv2%2F&prompt=login"`;

exports[`Auth0 Remix Server > the authorization process > forces the signup if asked 1`] = `"https://test.domain.com/authorize?response_type=code&response_mode=form_post&client_id=clientId&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fauth0%2Fcallback&scope=offline_access+openid+profile+email&audience=https%3A%2F%2Ftest.domain.com%2Fapi%2Fv2%2F&screen_hint=signup"`;

exports[`Auth0 Remix Server > the authorization process > redirects to the authorization endpoint 1`] = `"https://test.domain.com/authorize?response_type=code&response_mode=form_post&client_id=clientId&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fauth0%2Fcallback&scope=offline_access+openid+profile+email&audience=https%3A%2F%2Ftest.domain.com%2Fapi%2Fv2%2F"`;

exports[`Auth0 Remix Server > the authorization process > works correctly when both are asked 1`] = `"https://test.domain.com/authorize?response_type=code&response_mode=form_post&client_id=clientId&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fauth0%2Fcallback&scope=offline_access+openid+profile+email&audience=https%3A%2F%2Ftest.domain.com%2Fapi%2Fv2%2F&prompt=login&screen_hint=signup"`;
exports[`Auth0 Remix Server > the authorization process > redirects to the authorization endpoint 1`] = `"https://test.domain.com/authorize?redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fauth0%2Fcallback&response_type=code&response_mode=form_post&client_id=clientId&scope=offline_access+openid+profile+email&audience=https%3A%2F%2Ftest.domain.com%2Fapi%2Fv2%2F"`;
29 changes: 29 additions & 0 deletions src/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,35 @@ describe('Auth0 Remix Server', () => {
expect(redirectUrl).toMatchSnapshot();
});

it<LocalTestContext>('uses post when post is not set', ({ authOptions }) => {
const authorizer = new Auth0RemixServer(authOptions);

expect(() => authorizer.authorize()).toThrowError(redirectError); // a redirect happened

const redirectUrl = vi.mocked(redirect).mock.calls[0][0];
expect(redirectUrl).toContain('response_mode=form_post');
});

it<LocalTestContext>('uses post when post is set to true', ({ authOptions }) => {
authOptions.clientDetails.usePost = true;
const authorizer = new Auth0RemixServer(authOptions);

expect(() => authorizer.authorize()).toThrowError(redirectError); // a redirect happened

const redirectUrl = vi.mocked(redirect).mock.calls[0][0];
expect(redirectUrl).toContain('response_mode=form_post');
});

it<LocalTestContext>('uses get when post is set to false', ({ authOptions }) => {
authOptions.clientDetails.usePost = false;
const authorizer = new Auth0RemixServer(authOptions);

expect(() => authorizer.authorize()).toThrowError(redirectError); // a redirect happened

const redirectUrl = vi.mocked(redirect).mock.calls[0][0];
expect(redirectUrl).not.toContain('response_mode=form_post');
});

it<LocalTestContext>('forces the login if asked', ({ authOptions }) => {
const authorizer = new Auth0RemixServer(authOptions);

Expand Down
32 changes: 22 additions & 10 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ export class Auth0RemixServer {
clientID: auth0RemixOptions.clientDetails.clientID,
clientSecret: auth0RemixOptions.clientDetails.clientSecret,
audience: auth0RemixOptions.clientDetails.audience || `${this.domain}/api/v2/`,
organization: auth0RemixOptions.clientDetails.organization
organization: auth0RemixOptions.clientDetails.organization,
usePost: auth0RemixOptions.clientDetails.usePost
};
this.session = {
store: auth0RemixOptions.session.store,
Expand Down Expand Up @@ -105,12 +106,6 @@ export class Auth0RemixServer {
}

public authorize(opts: AuthorizeOptions = {}) {
const scope = [
'offline_access', // required for refresh token
'openid', // required for id_token and the /userinfo api endpoint
'profile',
'email'
];

const cbUrl = new URL(this.callbackURL);
if (opts.callbackParams) {
Expand All @@ -120,10 +115,28 @@ export class Auth0RemixServer {
}

const authorizationURL = new URL(this.auth0Urls.authorizationURL);
authorizationURL.searchParams.set('redirect_uri', cbUrl.toString());

this.setAuthorizationParameters(authorizationURL, opts);

throw redirect(authorizationURL.toString());
}

private setAuthorizationParameters(authorizationURL: URL, opts: AuthorizeOptions = {}) {
const scope = [
'offline_access', // required for refresh token
'openid', // required for id_token and the /userinfo api endpoint
'profile',
'email'
];

authorizationURL.searchParams.set('response_type', 'code');
authorizationURL.searchParams.set('response_mode', 'form_post');

if (this.clientCredentials.usePost !== false) {
authorizationURL.searchParams.set('response_mode', 'form_post');
}

authorizationURL.searchParams.set('client_id', this.clientCredentials.clientID);
authorizationURL.searchParams.set('redirect_uri', cbUrl.toString());
authorizationURL.searchParams.set('scope', scope.join(' '));
authorizationURL.searchParams.set('audience', this.clientCredentials.audience);
if (this.clientCredentials.organization) {
Expand All @@ -142,7 +155,6 @@ export class Auth0RemixServer {
authorizationURL.searchParams.set('connection', opts.connection);
}

throw redirect(authorizationURL.toString());
}

public async handleCallback(request: Request, options: HandleCallbackOptions): Promise<UserCredentials> {
Expand Down

0 comments on commit b30ef8a

Please sign in to comment.