Skip to content

Commit

Permalink
chore(adapter-nextjs): resolve comments
Browse files Browse the repository at this point in the history
  • Loading branch information
HuiSF committed Dec 21, 2024
1 parent ff48e7a commit 56dd741
Show file tree
Hide file tree
Showing 17 changed files with 77 additions and 85 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { handleSignInCallbackRequest } from '../../../src/auth/handlers/handleSi
import {
appendSetCookieHeaders,
createAuthFlowProofCookiesRemoveOptions,
createOnSignInCompletedRedirectIntermediate,
createOnSignInCompleteRedirectIntermediate,
createSignInFlowProofCookies,
createTokenCookies,
createTokenCookiesSetOptions,
Expand All @@ -30,8 +30,8 @@ const mockAppendSetCookieHeaders = jest.mocked(appendSetCookieHeaders);
const mockCreateAuthFlowProofCookiesRemoveOptions = jest.mocked(
createAuthFlowProofCookiesRemoveOptions,
);
const mockCreateOnSignInCompletedRedirectIntermediate = jest.mocked(
createOnSignInCompletedRedirectIntermediate,
const mockCreateOnSignInCompleteRedirectIntermediate = jest.mocked(
createOnSignInCompleteRedirectIntermediate,
);
const mockCreateSignInFlowProofCookies = jest.mocked(
createSignInFlowProofCookies,
Expand All @@ -58,7 +58,7 @@ describe('handleSignInCallbackRequest', () => {
afterEach(() => {
mockAppendSetCookieHeaders.mockClear();
mockCreateAuthFlowProofCookiesRemoveOptions.mockClear();
mockCreateOnSignInCompletedRedirectIntermediate.mockClear();
mockCreateOnSignInCompleteRedirectIntermediate.mockClear();
mockCreateSignInFlowProofCookies.mockClear();
mockCreateTokenCookies.mockClear();
mockCreateTokenCookiesSetOptions.mockClear();
Expand Down Expand Up @@ -188,6 +188,11 @@ describe('handleSignInCallbackRequest', () => {
'/',
`<html>redirect to /</html>`,
],
[
{ ...mockHandlerInput, redirectOnSignInComplete: '' },
'/',
`<html>redirect to /</html>`,
],
] as [CreateAuthRoutesHandlersInput, string, string][])(
'returns a 200 response with expected redirect target: with handlerInput=%p, expectedFinalRedirect=%s, generates expected html=%s',
async (handlerInput, expectedFinalRedirect, expectedHtml) => {
Expand Down Expand Up @@ -245,7 +250,7 @@ describe('handleSignInCallbackRequest', () => {
headers.append('Set-cookie', 'mock-cookie-1');
headers.append('Set-cookie', 'mock-cookie-2');
});
mockCreateOnSignInCompletedRedirectIntermediate.mockImplementationOnce(
mockCreateOnSignInCompleteRedirectIntermediate.mockImplementationOnce(
({ redirectOnSignInComplete }) =>
`<html>redirect to ${redirectOnSignInComplete}</html>`,
);
Expand Down Expand Up @@ -297,7 +302,7 @@ describe('handleSignInCallbackRequest', () => {
mockCreateAuthFlowProofCookiesRemoveOptionsResult,
);
expect(
mockCreateOnSignInCompletedRedirectIntermediate,
mockCreateOnSignInCompleteRedirectIntermediate,
).toHaveBeenCalledWith({
redirectOnSignInComplete: expectedFinalRedirect,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { handleSignInCallbackRequestForPagesRouter } from '../../../src/auth/han
import {
appendSetCookieHeadersToNextApiResponse,
createAuthFlowProofCookiesRemoveOptions,
createOnSignInCompletedRedirectIntermediate,
createOnSignInCompleteRedirectIntermediate,
createSignInFlowProofCookies,
createTokenCookies,
createTokenCookiesSetOptions,
Expand All @@ -33,8 +33,8 @@ const mockAppendSetCookieHeadersToNextApiResponse = jest.mocked(
const mockCreateAuthFlowProofCookiesRemoveOptions = jest.mocked(
createAuthFlowProofCookiesRemoveOptions,
);
const mockCreateOnSignInCompletedRedirectIntermediate = jest.mocked(
createOnSignInCompletedRedirectIntermediate,
const mockCreateOnSignInCompleteRedirectIntermediate = jest.mocked(
createOnSignInCompleteRedirectIntermediate,
);
const mockCreateSignInFlowProofCookies = jest.mocked(
createSignInFlowProofCookies,
Expand Down Expand Up @@ -70,7 +70,7 @@ describe('handleSignInCallbackRequest', () => {
afterEach(() => {
mockAppendSetCookieHeadersToNextApiResponse.mockClear();
mockCreateAuthFlowProofCookiesRemoveOptions.mockClear();
mockCreateOnSignInCompletedRedirectIntermediate.mockClear();
mockCreateOnSignInCompleteRedirectIntermediate.mockClear();
mockCreateSignInFlowProofCookies.mockClear();
mockCreateTokenCookies.mockClear();
mockCreateTokenCookiesSetOptions.mockClear();
Expand Down Expand Up @@ -283,7 +283,7 @@ describe('handleSignInCallbackRequest', () => {
response.appendHeader('Set-cookie', 'mock-cookie-2');
},
);
mockCreateOnSignInCompletedRedirectIntermediate.mockImplementationOnce(
mockCreateOnSignInCompleteRedirectIntermediate.mockImplementationOnce(
({ redirectOnSignInComplete }) =>
`<html>redirect to ${redirectOnSignInComplete}</html>`,
);
Expand Down Expand Up @@ -334,7 +334,7 @@ describe('handleSignInCallbackRequest', () => {
);

expect(
mockCreateOnSignInCompletedRedirectIntermediate,
mockCreateOnSignInCompleteRedirectIntermediate,
).toHaveBeenCalledWith({
redirectOnSignInComplete: expectedFinalRedirect,
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { createOnSignInCompletedRedirectIntermediate } from '../../../src/auth/utils/createOnSignInCompletedRedirectIntermediate';
import { createOnSignInCompleteRedirectIntermediate } from '../../../src/auth/utils/createOnSignInCompleteRedirectIntermediate';

describe('createOnSignInCompletedRedirectIntermediate', () => {
it('returns html with script that redirects to the redirectUrl', () => {
const redirectUrl = 'https://example.com';
const result = createOnSignInCompletedRedirectIntermediate({
const result = createOnSignInCompleteRedirectIntermediate({
redirectOnSignInComplete: redirectUrl,
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { resolveIdentityProviderFromUrl } from '../../../src/auth/utils/resolveI
describe('resolveIdentityProviderFromUrl', () => {
test.each([
['https://example.com?provider=Google', 'Google'],
['https://example.com?provider=GOogLe', 'Google'],
['https://example.com?provider=Facebook', 'Facebook'],
['https://example.com?provider=Amazon', 'LoginWithAmazon'],
['https://example.com?provider=Apple', 'SignInWithApple'],
Expand Down
46 changes: 22 additions & 24 deletions packages/adapter-nextjs/__tests__/auth/utils/tokenCookies.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,30 +44,28 @@ describe('createTokenCookies', () => {
userPoolClientId: mockUserPoolClientId,
});

expect(result.sort()).toEqual(
[
{
name: `${expectedCookieNamePrefix}.accessToken`,
value: 'access_token',
},
{
name: `${expectedCookieNamePrefix}.idToken`,
value: 'id_token',
},
{
name: `${expectedCookieNamePrefix}.refreshToken`,
value: 'refresh_token',
},
{
name: `${expectedCookieNamePrefix}.clockDrift`,
value: '-42',
},
{
name: `${AUTH_KEY_PREFIX}.${mockUserPoolClientId}.LastAuthUser`,
value: mockUserName,
},
].sort(),
);
expect(result).toEqual([
{
name: `${expectedCookieNamePrefix}.accessToken`,
value: 'access_token',
},
{
name: `${expectedCookieNamePrefix}.idToken`,
value: 'id_token',
},
{
name: `${expectedCookieNamePrefix}.refreshToken`,
value: 'refresh_token',
},
{
name: `${expectedCookieNamePrefix}.clockDrift`,
value: '-42',
},
{
name: `${AUTH_KEY_PREFIX}.${mockUserPoolClientId}.LastAuthUser`,
value: mockUserName,
},
]);
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { PKCE_COOKIE_NAME, STATE_COOKIE_NAME } from '../constant';
import {
appendSetCookieHeaders,
createAuthFlowProofCookiesRemoveOptions,
createOnSignInCompletedRedirectIntermediate,
createOnSignInCompleteRedirectIntermediate,
createSignInFlowProofCookies,
createTokenCookies,
createTokenCookiesSetOptions,
Expand Down Expand Up @@ -73,8 +73,8 @@ export const handleSignInCallbackRequest: HandleSignInCallbackRequest = async ({
headers.set('Content-Type', 'text/html');

return new Response(
createOnSignInCompletedRedirectIntermediate({
redirectOnSignInComplete: handlerInput.redirectOnSignInComplete ?? '/',
createOnSignInCompleteRedirectIntermediate({
redirectOnSignInComplete: handlerInput.redirectOnSignInComplete || '/',
}),
{
status: 200,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { PKCE_COOKIE_NAME, STATE_COOKIE_NAME } from '../constant';
import {
appendSetCookieHeadersToNextApiResponse,
createAuthFlowProofCookiesRemoveOptions,
createOnSignInCompletedRedirectIntermediate,
createOnSignInCompleteRedirectIntermediate,
createSignInFlowProofCookies,
createTokenCookies,
createTokenCookiesSetOptions,
Expand Down Expand Up @@ -85,9 +85,9 @@ export const handleSignInCallbackRequestForPagesRouter: HandleSignInCallbackRequ
.appendHeader('Content-Type', 'text/html')
.status(200)
.send(
createOnSignInCompletedRedirectIntermediate({
createOnSignInCompleteRedirectIntermediate({
redirectOnSignInComplete:
handlerInput.redirectOnSignInComplete ?? '/',
handlerInput.redirectOnSignInComplete || '/',
}),
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,10 @@ export const handleSignInSignUpRequestForPagesRouter: HandleSignInSignUpRequestF
createAuthFlowProofCookiesSetOptions(setCookieOptions),
);

response.redirect(
302,
const redirectUrl =
type === 'signIn'
? createAuthorizeEndpoint(oAuthConfig.domain, redirectUrlSearchParams)
: createSignUpEndpoint(oAuthConfig.domain, redirectUrlSearchParams),
);
: createSignUpEndpoint(oAuthConfig.domain, redirectUrlSearchParams);

response.redirect(302, redirectUrl);
};
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,6 @@ export const handleSignOutRequestForPagesRouter: HandleSignOutRequestForPagesRou

response.redirect(
302,
createLogoutEndpoint(oAuthConfig.domain, urlSearchParams).toString(),
createLogoutEndpoint(oAuthConfig.domain, urlSearchParams),
);
};
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

export const createOnSignInCompletedRedirectIntermediate = ({
export const createOnSignInCompleteRedirectIntermediate = ({
redirectOnSignInComplete,
}: {
redirectOnSignInComplete: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,9 @@ export const createUrlSearchParamsForTokenExchange = (input: {
redirect_uri: string;
code_verifier: string;
grant_type: string;
}): URLSearchParams => createUrlSearchParamsFromObject(input);
}): URLSearchParams => new URLSearchParams(input);

export const createUrlSearchParamsForTokenRevocation = (input: {
token: string;
client_id: string;
}): URLSearchParams => createUrlSearchParamsFromObject(input);

const createUrlSearchParamsFromObject = (
input: Record<string, string>,
): URLSearchParams => new URLSearchParams(input);
}): URLSearchParams => new URLSearchParams(input);
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,20 @@

import { NextApiRequest } from 'next';

export const getCookieValuesFromNextApiRequest = <CookieNames extends string[]>(
export const getCookieValuesFromNextApiRequest = <
CookieNames extends string[],
R = {
[key in CookieNames[number]]?: string | undefined;
},
>(
request: NextApiRequest,
cookieNames: CookieNames,
): {
[key in CookieNames[number]]?: string | undefined;
} => {
): R => {
const result: Record<string, string | undefined> = {};

for (const cookieName of cookieNames) {
result[cookieName] = request.cookies[cookieName];
}

return result as {
[key in CookieNames[number]]?: string | undefined;
};
return result as R;
};
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,11 @@ export const getCookieValuesFromRequest = <CookieNames extends string[]>(
const cookieValues: Record<string, string> = cookieHeader
.split(';')
.map(cookie => cookie.trim().split('='))
.reduce(
(result, [key, value]) => {
result[key] = value;
.reduce<Record<string, string>>((result, [key, value]) => {
result[key] = value;

return result;
},
{} as Record<string, string>,
);
return result;
}, {});

const result: Record<string, string | undefined> = {};
for (const cookieName of cookieNames) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,12 @@ export const getSearchParamValueFromUrl = (
urlStr: string,
paramName: string,
): string | null => {
try {
return new URL(urlStr).searchParams.get(paramName);
} catch (error) {
// In Next.js Pages Router the request object is an instance of IncomingMessage
// whose url property may contain only the path part of the URL + query params.
// In this case, we need to parse the URL manually
if (urlStr.includes('?')) {
const queryParams = urlStr.split('?')[1];
if (queryParams) {
return new URLSearchParams(queryParams).get(paramName);
}
if (urlStr.includes('?')) {
const queryParams = urlStr.split('?')[1];
if (queryParams) {
return new URLSearchParams(queryParams).get(paramName);
}

return null;
}

return null;
};
2 changes: 1 addition & 1 deletion packages/adapter-nextjs/src/auth/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export {
createAuthFlowProofCookiesRemoveOptions,
} from './authFlowProofCookies';
export { createAuthFlowProofs } from './createAuthFlowProofs';
export { createOnSignInCompletedRedirectIntermediate } from './createOnSignInCompletedRedirectIntermediate';
export { createOnSignInCompleteRedirectIntermediate } from './createOnSignInCompleteRedirectIntermediate';
export { createUrlSearchParamsForSignInSignUp } from './createUrlSearchParams';
export {
createAuthorizeEndpoint,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@ const resolveProvider = (provider: string | null): string | null => {
};

const capitalize = (value: string) =>
`${value[0].toUpperCase()}${value.substring(1)}`;
`${value[0].toUpperCase()}${value.substring(1).toLowerCase()}`;

0 comments on commit 56dd741

Please sign in to comment.