Skip to content

Commit 621d0cb

Browse files
committed
feat(adapter-nextjs): server-side auth api route integrating cognito hosted ui
1 parent c99dfa3 commit 621d0cb

File tree

67 files changed

+4598
-100
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

67 files changed

+4598
-100
lines changed

packages/adapter-nextjs/__tests__/auth/createAuthRouteHandlersFactory.test.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ describe('createAuthRoutesHandlersFactory', () => {
150150
oAuthConfig: mockAmplifyConfig.Auth!.Cognito!.loginWith!.oauth,
151151
setCookieOptions: mockRuntimeOptions.cookies,
152152
origin: 'https://example.com',
153+
userPoolClientId: 'def',
153154
});
154155
});
155156

@@ -170,6 +171,7 @@ describe('createAuthRoutesHandlersFactory', () => {
170171
oAuthConfig: mockAmplifyConfig.Auth!.Cognito!.loginWith!.oauth,
171172
setCookieOptions: mockRuntimeOptions.cookies,
172173
origin: 'https://example.com',
174+
userPoolClientId: 'def',
173175
});
174176
});
175177

@@ -211,6 +213,7 @@ describe('createAuthRoutesHandlersFactory', () => {
211213
oAuthConfig: mockAmplifyConfig.Auth!.Cognito!.loginWith!.oauth,
212214
setCookieOptions: {},
213215
origin: 'https://example.com',
216+
userPoolClientId: 'def',
214217
});
215218
});
216219
});

packages/adapter-nextjs/__tests__/auth/handleAuthApiRouteRequestForAppRouter.test.ts

Lines changed: 146 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,23 @@ import { OAuthConfig } from '@aws-amplify/core';
66

77
import { handleAuthApiRouteRequestForAppRouter } from '../../src/auth/handleAuthApiRouteRequestForAppRouter';
88
import { CreateAuthRoutesHandlersInput } from '../../src/auth/types';
9+
import {
10+
handleSignInCallbackRequest,
11+
handleSignInSignUpRequest,
12+
handleSignOutCallbackRequest,
13+
handleSignOutRequest,
14+
} from '../../src/auth/handlers';
15+
16+
jest.mock('../../src/auth/handlers');
17+
18+
const mockHandleSignInSignUpRequest = jest.mocked(handleSignInSignUpRequest);
19+
const mockHandleSignOutRequest = jest.mocked(handleSignOutRequest);
20+
const mockHandleSignInCallbackRequest = jest.mocked(
21+
handleSignInCallbackRequest,
22+
);
23+
const mockHandleSignOutCallbackRequest = jest.mocked(
24+
handleSignOutCallbackRequest,
25+
);
926

1027
describe('handleAuthApiRouteRequestForAppRouter', () => {
1128
const testOrigin = 'https://example.com';
@@ -23,17 +40,18 @@ describe('handleAuthApiRouteRequestForAppRouter', () => {
2340
};
2441
const _ = handleAuthApiRouteRequestForAppRouter;
2542

26-
it('returns a 405 response when input.request has an unsupported method', () => {
43+
it('returns a 405 response when input.request has an unsupported method', async () => {
2744
const request = new NextRequest(
2845
new URL('https://example.com/api/auth/sign-in'),
2946
{
3047
method: 'POST',
3148
},
3249
);
33-
const response = handleAuthApiRouteRequestForAppRouter({
50+
const response = await handleAuthApiRouteRequestForAppRouter({
3451
request,
3552
handlerContext: testHandlerContext,
3653
handlerInput: testHandlerInput,
54+
userPoolClientId: 'userPoolClientId',
3755
oAuthConfig: testOAuthConfig,
3856
setCookieOptions: {},
3957
origin: testOrigin,
@@ -42,17 +60,18 @@ describe('handleAuthApiRouteRequestForAppRouter', () => {
4260
expect(response.status).toBe(405);
4361
});
4462

45-
it('returns a 400 response when handlerContext.params.slug is undefined', () => {
63+
it('returns a 400 response when handlerContext.params.slug is undefined', async () => {
4664
const request = new NextRequest(
4765
new URL('https://example.com/api/auth/sign-in'),
4866
{
4967
method: 'GET',
5068
},
5169
);
52-
const response = handleAuthApiRouteRequestForAppRouter({
70+
const response = await handleAuthApiRouteRequestForAppRouter({
5371
request,
5472
handlerContext: { params: { slug: undefined } },
5573
handlerInput: testHandlerInput,
74+
userPoolClientId: 'userPoolClientId',
5675
oAuthConfig: testOAuthConfig,
5776
setCookieOptions: {},
5877
origin: testOrigin,
@@ -61,17 +80,18 @@ describe('handleAuthApiRouteRequestForAppRouter', () => {
6180
expect(response.status).toBe(400);
6281
});
6382

64-
it('returns a 404 response when handlerContext.params.slug is not a supported path', () => {
83+
it('returns a 404 response when handlerContext.params.slug is not a supported path', async () => {
6584
const request = new NextRequest(
6685
new URL('https://example.com/api/auth/exchange-token'),
6786
{
6887
method: 'GET',
6988
},
7089
);
71-
const response = handleAuthApiRouteRequestForAppRouter({
90+
const response = await handleAuthApiRouteRequestForAppRouter({
7291
request,
7392
handlerContext: { params: { slug: 'exchange-token' } },
7493
handlerInput: testHandlerInput,
94+
userPoolClientId: 'userPoolClientId',
7595
oAuthConfig: testOAuthConfig,
7696
setCookieOptions: {},
7797
origin: testOrigin,
@@ -80,23 +100,135 @@ describe('handleAuthApiRouteRequestForAppRouter', () => {
80100
expect(response.status).toBe(404);
81101
});
82102

83-
// TODO(HuiSF): add use cases tests for each supported path when implemented
84-
it('returns a 501 response when handlerContext.params.slug is a supported path', () => {
85-
const request = new NextRequest(
86-
new URL('https://example.com/api/auth/sign-in'),
103+
test.each([
104+
['sign-in', 'signIn'],
105+
['sign-up', 'signUp'],
106+
])(
107+
`calls handleSignInSignUpRequest with correct params when handlerContext.params.slug is %s`,
108+
async (slug, expectedType) => {
109+
const mockRequest = new NextRequest(
110+
new URL('https://example.com/api/auth/sign-in'),
111+
{
112+
method: 'GET',
113+
},
114+
);
115+
const mockResponse = new Response(null, { status: 302 });
116+
117+
mockHandleSignInSignUpRequest.mockReturnValueOnce(mockResponse);
118+
119+
const response = await handleAuthApiRouteRequestForAppRouter({
120+
request: mockRequest,
121+
handlerContext: { params: { slug } },
122+
handlerInput: testHandlerInput,
123+
userPoolClientId: 'userPoolClientId',
124+
oAuthConfig: testOAuthConfig,
125+
setCookieOptions: {},
126+
origin: testOrigin,
127+
});
128+
129+
expect(response).toBe(mockResponse);
130+
expect(mockHandleSignInSignUpRequest).toHaveBeenCalledWith({
131+
request: mockRequest,
132+
userPoolClientId: 'userPoolClientId',
133+
oAuthConfig: testOAuthConfig,
134+
customState: testHandlerInput.customState,
135+
origin: testOrigin,
136+
setCookieOptions: {},
137+
type: expectedType,
138+
});
139+
},
140+
);
141+
142+
it('calls handleSignOutRequest with correct params when handlerContext.params.slug is sign-out', async () => {
143+
const mockRequest = new NextRequest(
144+
new URL('https://example.com/api/auth/sign-out'),
87145
{
88146
method: 'GET',
89147
},
90148
);
91-
const response = handleAuthApiRouteRequestForAppRouter({
92-
request,
93-
handlerContext: { params: { slug: 'sign-in' } },
149+
const mockResponse = new Response(null, { status: 302 });
150+
151+
mockHandleSignOutRequest.mockReturnValueOnce(mockResponse);
152+
153+
const response = await handleAuthApiRouteRequestForAppRouter({
154+
request: mockRequest,
155+
handlerContext: { params: { slug: 'sign-out' } },
156+
handlerInput: testHandlerInput,
157+
userPoolClientId: 'userPoolClientId',
158+
oAuthConfig: testOAuthConfig,
159+
setCookieOptions: {},
160+
origin: testOrigin,
161+
});
162+
163+
expect(response).toBe(mockResponse);
164+
expect(mockHandleSignOutRequest).toHaveBeenCalledWith({
165+
userPoolClientId: 'userPoolClientId',
166+
oAuthConfig: testOAuthConfig,
167+
origin: testOrigin,
168+
setCookieOptions: {},
169+
});
170+
});
171+
172+
it('calls handleSignInCallbackRequest with correct params when handlerContext.params.slug is sign-in-callback', async () => {
173+
const mockRequest = new NextRequest(
174+
new URL('https://example.com/api/auth/sign-in-callback'),
175+
{
176+
method: 'GET',
177+
},
178+
);
179+
const mockResponse = new Response(null, { status: 302 });
180+
181+
mockHandleSignInCallbackRequest.mockResolvedValueOnce(mockResponse);
182+
183+
const response = await handleAuthApiRouteRequestForAppRouter({
184+
request: mockRequest,
185+
handlerContext: { params: { slug: 'sign-in-callback' } },
186+
handlerInput: testHandlerInput,
187+
userPoolClientId: 'userPoolClientId',
188+
oAuthConfig: testOAuthConfig,
189+
setCookieOptions: {},
190+
origin: testOrigin,
191+
});
192+
193+
expect(response).toBe(mockResponse);
194+
expect(mockHandleSignInCallbackRequest).toHaveBeenCalledWith({
195+
request: mockRequest,
196+
handlerInput: testHandlerInput,
197+
oAuthConfig: testOAuthConfig,
198+
origin: testOrigin,
199+
setCookieOptions: {},
200+
userPoolClientId: 'userPoolClientId',
201+
});
202+
});
203+
204+
it('calls handleSignOutCallbackRequest with correct params when handlerContext.params.slug is sign-out-callback', async () => {
205+
const mockRequest = new NextRequest(
206+
new URL('https://example.com/api/auth/sign-out-callback'),
207+
{
208+
method: 'GET',
209+
},
210+
);
211+
const mockResponse = new Response(null, { status: 302 });
212+
213+
mockHandleSignOutCallbackRequest.mockResolvedValueOnce(mockResponse);
214+
215+
const response = await handleAuthApiRouteRequestForAppRouter({
216+
request: mockRequest,
217+
handlerContext: { params: { slug: 'sign-out-callback' } },
94218
handlerInput: testHandlerInput,
219+
userPoolClientId: 'userPoolClientId',
95220
oAuthConfig: testOAuthConfig,
96221
setCookieOptions: {},
97222
origin: testOrigin,
98223
});
99224

100-
expect(response.status).toBe(501);
225+
expect(response).toBe(mockResponse);
226+
expect(mockHandleSignOutCallbackRequest).toHaveBeenCalledWith({
227+
request: mockRequest,
228+
handlerInput: testHandlerInput,
229+
oAuthConfig: testOAuthConfig,
230+
setCookieOptions: {},
231+
userPoolClientId: 'userPoolClientId',
232+
});
101233
});
102234
});

0 commit comments

Comments
 (0)