Skip to content

Commit

Permalink
fix(nextjs,backend): Add debug logger to clerkMiddleware (#3189)
Browse files Browse the repository at this point in the history
  • Loading branch information
nikosdouvlis committed Apr 15, 2024
1 parent fb794ce commit e6fc58a
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 7 deletions.
7 changes: 7 additions & 0 deletions .changeset/unlucky-cheetahs-suffer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@clerk/backend': patch
'@clerk/nextjs': patch
---

Introduce `debug: true` option for the `clerkMiddleware` helper

12 changes: 12 additions & 0 deletions packages/backend/src/tokens/__tests__/clerkRequest.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -152,5 +152,17 @@ export default (QUnit: QUnit) => {
assert.equal(createClerkRequest(req).clerkUrl.toString(), 'https://example.com/path?foo=bar');
});
});

module('toJSON', () => {
it('returns data as a JSON object', assert => {
const req = createClerkRequest(new Request('http://localhost:3000'));
const json = req.toJSON();
assert.equal(json.url, 'http://localhost:3000/');
assert.equal(json.method, 'GET');
assert.equal(json.headers, '{}');
assert.equal(json.clerkUrl, 'http://localhost:3000/');
assert.equal(json.cookies, '{}');
});
});
});
};
14 changes: 10 additions & 4 deletions packages/backend/src/tokens/clerkRequest.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { parse as parseCookies } from 'cookie';

import { constants } from '../constants';
import type { ClerkUrl, WithClerkUrl } from './clerkUrl';
import type { ClerkUrl } from './clerkUrl';
import { createClerkUrl } from './clerkUrl';

class ClerkRequest extends Request {
Expand All @@ -26,9 +26,15 @@ class ClerkRequest extends Request {
this.cookies = this.parseCookies(this);
}

public decorateWithClerkUrl = <R extends object>(req: R): WithClerkUrl<R> => {
return Object.assign(req, { clerkUrl: this.clerkUrl });
};
public toJSON() {
return {
url: this.clerkUrl.href,
method: this.method,
headers: JSON.stringify(Object.fromEntries(this.headers)),
clerkUrl: this.clerkUrl.toString(),
cookies: JSON.stringify(Object.fromEntries(this.cookies)),
};
}

/**
* Used to fix request.url using the x-forwarded-* headers
Expand Down
21 changes: 18 additions & 3 deletions packages/nextjs/src/server/clerkMiddleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import type { NextMiddleware } from 'next/server';
import { NextResponse } from 'next/server';

import { isRedirect, serverRedirectWithAuth, setHeader } from '../utils';
import { withLogger } from '../utils/debugLogger';
import { clerkClient } from './clerkClient';
import { PUBLISHABLE_KEY, SECRET_KEY, SIGN_IN_URL, SIGN_UP_URL } from './constants';
import { errorThrower } from './errorThrower';
Expand Down Expand Up @@ -48,7 +49,7 @@ export type ClerkMiddlewareOptions = AuthenticateRequestOptions & { debug?: bool

/**
* Middleware for Next.js that handles authentication and authorization with Clerk.
* For more details, please refer to the docs: https://clerk.com/docs/references/nextjs/clerkMiddleware
* For more details, please refer to the docs: https://beta.clerk.com/docs/references/nextjs/clerk-middleware
*/
interface ClerkMiddleware {
/**
Expand All @@ -68,9 +69,13 @@ interface ClerkMiddleware {
(request: NextMiddlewareRequestParam, event: NextMiddlewareEvtParam): NextMiddlewareReturn;
}

export const clerkMiddleware: ClerkMiddleware = (...args: unknown[]): any => {
export const clerkMiddleware: ClerkMiddleware = withLogger('clerkMiddleware', logger => (...args: unknown[]): any => {
const [request, event] = parseRequestAndEvent(args);
const [handler, params] = parseHandlerAndOptions(args);
if (params.debug) {
logger.enable();
}

const publishableKey = assertKey(params.publishableKey || PUBLISHABLE_KEY, () =>
errorThrower.throwMissingPublishableKeyError(),
);
Expand All @@ -96,12 +101,20 @@ export const clerkMiddleware: ClerkMiddleware = (...args: unknown[]): any => {

const nextMiddleware: NextMiddleware = async (request, event) => {
const clerkRequest = createClerkRequest(request);
logger.debug('options', options);
logger.debug('url', () => clerkRequest.toJSON());

const requestState = await clerkClient.authenticateRequest(
clerkRequest,
createAuthenticateRequestOptions(clerkRequest, options),
);

logger.debug('requestState', () => ({
status: requestState.status,
headers: JSON.stringify(Object.fromEntries(requestState.headers)),
reason: requestState.reason,
}));

const locationHeader = requestState.headers.get(constants.Headers.Location);
if (locationHeader) {
return new Response(null, { status: 307, headers: requestState.headers });
Expand All @@ -110,6 +123,7 @@ export const clerkMiddleware: ClerkMiddleware = (...args: unknown[]): any => {
}

const authObject = requestState.toAuth();
logger.debug('auth', () => ({ auth: authObject, debug: authObject.debug() }));

const redirectToSignIn = createMiddlewareRedirectToSignIn(clerkRequest);
const protect = createMiddlewareProtect(clerkRequest, authObject, redirectToSignIn);
Expand All @@ -123,6 +137,7 @@ export const clerkMiddleware: ClerkMiddleware = (...args: unknown[]): any => {
}

if (isRedirect(handlerResult)) {
logger.debug('handlerResult is redirect');
return serverRedirectWithAuth(clerkRequest, handlerResult, options);
}

Expand Down Expand Up @@ -152,7 +167,7 @@ export const clerkMiddleware: ClerkMiddleware = (...args: unknown[]): any => {
// Otherwise, return a middleware that can be called with a request and event
// eg, export default clerkMiddleware(auth => { ... });
return nextMiddleware;
};
});

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

0 comments on commit e6fc58a

Please sign in to comment.