Skip to content

Commit 052e2b0

Browse files
dimklnikosdouvlis
authored andcommitted
fix(nextjs): Execute logger.commit() on every middleware invocation (#3871)
Co-authored-by: Nikos Douvlis <[email protected]>
1 parent 3d88c43 commit 052e2b0

File tree

3 files changed

+46
-28
lines changed

3 files changed

+46
-28
lines changed

.changeset/poor-cheetahs-rhyme.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@clerk/nextjs": patch
3+
---
4+
5+
Fix debug logs on `debug: true` parameter of `clerkMiddleware()`

packages/nextjs/src/server/__tests__/clerkMiddleware.test.ts

Lines changed: 34 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ import { NextRequest, NextResponse } from 'next/server';
77

88
const publishableKey = 'pk_test_Y2xlcmsuaW5jbHVkZWQua2F0eWRpZC05Mi5sY2wuZGV2JA';
99
const authenticateRequestMock = jest.fn().mockResolvedValue({
10-
toAuth: () => ({}),
10+
toAuth: () => ({
11+
debug: (d: any) => d,
12+
}),
1113
headers: new Headers(),
1214
publishableKey,
1315
});
@@ -33,12 +35,15 @@ import { decryptClerkRequestData } from '../utils';
3335
* Disable console warnings about config matchers
3436
*/
3537
const consoleWarn = console.warn;
36-
global.console.warn = jest.fn();
38+
const consoleLog = console.log;
39+
3740
beforeAll(() => {
3841
global.console.warn = jest.fn();
42+
global.console.log = jest.fn();
3943
});
4044
afterAll(() => {
4145
global.console.warn = consoleWarn;
46+
global.console.log = consoleLog;
4247
});
4348

4449
// Removing this mock will cause the clerkMiddleware tests to fail due to missing publishable key
@@ -168,24 +173,6 @@ describe('createRouteMatcher', () => {
168173
});
169174
});
170175

171-
describe('authenticateRequest & handshake', () => {
172-
beforeEach(() => {
173-
authenticateRequestMock.mockClear();
174-
});
175-
176-
it('returns 307 and starts the handshake flow for handshake requestState status', async () => {
177-
const mockLocationUrl = 'https://example.com';
178-
authenticateRequestMock.mockResolvedValueOnce({
179-
publishableKey,
180-
status: AuthStatus.Handshake,
181-
headers: new Headers({ Location: mockLocationUrl }),
182-
});
183-
const resp = await clerkMiddleware()(mockRequest({ url: '/protected' }), {} as NextFetchEvent);
184-
expect(resp?.status).toEqual(307);
185-
expect(resp?.headers.get('Location')).toEqual(mockLocationUrl);
186-
});
187-
});
188-
189176
describe('clerkMiddleware(params)', () => {
190177
it('renders route as normally when used without params', async () => {
191178
const signInResp = await clerkMiddleware()(mockRequest({ url: '/sign-in' }), {} as NextFetchEvent);
@@ -203,7 +190,7 @@ describe('clerkMiddleware(params)', () => {
203190
expect(signInResp?.headers.get('a-custom-header')).toEqual('1');
204191
});
205192

206-
it('renders route when when exported directly without being called', async () => {
193+
it('renders route when exported directly without being called', async () => {
207194
// This is equivalent to export default clerkMiddleware;
208195
const signInResp = await clerkMiddleware(mockRequest({ url: '/sign-in' }), {} as NextFetchEvent);
209196
expect(signInResp?.status).toEqual(200);
@@ -567,6 +554,32 @@ describe('clerkMiddleware(params)', () => {
567554
expect(clerkClient().authenticateRequest).toBeCalled();
568555
});
569556
});
557+
558+
describe('debug', () => {
559+
beforeEach(() => {
560+
(global.console.log as jest.Mock).mockClear();
561+
});
562+
563+
it('outputs debug logs when used with only params', async () => {
564+
const signInResp = await clerkMiddleware({ debug: true })(mockRequest({ url: '/sign-in' }), {} as NextFetchEvent);
565+
expect(signInResp?.status).toEqual(200);
566+
// 6 times results from header, footer, options, url, requestState, auth logs
567+
expect(global.console.log).toBeCalledTimes(6);
568+
});
569+
570+
it('outputs debug logs when used with a custom handler', async () => {
571+
const signInResp = await clerkMiddleware(
572+
(_, request) => {
573+
expect(request.url).toContain('/sign-in');
574+
return NextResponse.next({ headers: { 'a-custom-header': '1' } });
575+
},
576+
{ debug: true },
577+
)(mockRequest({ url: '/sign-in' }), {} as NextFetchEvent);
578+
expect(signInResp?.status).toEqual(200);
579+
// 6 times results from header, footer, options, url, requestState, auth logs
580+
expect(global.console.log).toBeCalledTimes(6);
581+
});
582+
});
570583
});
571584

572585
describe('Dev Browser JWT when redirecting to cross origin for page requests', function () {

packages/nextjs/src/server/clerkMiddleware.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -73,12 +73,9 @@ interface ClerkMiddleware {
7373

7474
export const clerkMiddlewareRequestDataStore = new AsyncLocalStorage<Partial<AuthenticateRequestOptions>>();
7575

76-
export const clerkMiddleware: ClerkMiddleware = withLogger('clerkMiddleware', logger => (...args: unknown[]): any => {
76+
export const clerkMiddleware: ClerkMiddleware = (...args: unknown[]): any => {
7777
const [request, event] = parseRequestAndEvent(args);
7878
const [handler, params] = parseHandlerAndOptions(args);
79-
if (params.debug) {
80-
logger.enable();
81-
}
8279

8380
const publishableKey = assertKey(params.publishableKey || PUBLISHABLE_KEY, () =>
8481
errorThrower.throwMissingPublishableKeyError(),
@@ -104,7 +101,10 @@ export const clerkMiddleware: ClerkMiddleware = withLogger('clerkMiddleware', lo
104101
}),
105102
);
106103

107-
const nextMiddleware: NextMiddleware = async (request, event) => {
104+
const nextMiddleware: NextMiddleware = withLogger('clerkMiddleware', logger => async (request, event) => {
105+
if (params.debug) {
106+
logger.enable();
107+
}
108108
const clerkRequest = createClerkRequest(request);
109109
logger.debug('options', options);
110110
logger.debug('url', () => clerkRequest.toJSON());
@@ -164,7 +164,7 @@ export const clerkMiddleware: ClerkMiddleware = withLogger('clerkMiddleware', lo
164164
decorateRequest(clerkRequest, handlerResult, requestState, params);
165165

166166
return handlerResult;
167-
};
167+
});
168168

169169
// If we have a request and event, we're being called as a middleware directly
170170
// eg, export default clerkMiddleware;
@@ -176,7 +176,7 @@ export const clerkMiddleware: ClerkMiddleware = withLogger('clerkMiddleware', lo
176176
// eg, export default clerkMiddleware(auth => { ... });
177177
return nextMiddleware;
178178
});
179-
});
179+
};
180180

181181
const parseRequestAndEvent = (args: unknown[]) => {
182182
return [args[0] instanceof Request ? args[0] : undefined, args[0] instanceof Request ? args[1] : undefined] as [

0 commit comments

Comments
 (0)