Skip to content

Commit 932c8c4

Browse files
authored
Revert "feat(nextjs): Hint correct middleware location when missing clerkMiddleware (#4979) (#5026)
1 parent b416e9e commit 932c8c4

File tree

9 files changed

+29
-121
lines changed

9 files changed

+29
-121
lines changed

.changeset/orange-clouds-relax.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+
Revert: Improve error messages when clerkMiddleware is missing by suggesting the correct path to place the middleware.ts file (#4979).

packages/nextjs/src/app-router/server/ClerkProvider.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import { getDynamicAuthData } from '../../server/buildClerkProps';
77
import type { NextClerkProviderProps } from '../../types';
88
import { canUseKeyless } from '../../utils/feature-flags';
99
import { mergeNextClerkPropsWithEnv } from '../../utils/mergeNextClerkPropsWithEnv';
10-
import { onlyTry } from '../../utils/only-try';
1110
import { isNext13 } from '../../utils/sdk-versions';
1211
import { ClientClerkProvider } from '../client/ClerkProvider';
1312
import { deleteKeylessAction } from '../keyless-actions';
@@ -24,6 +23,15 @@ const getNonceFromCSPHeader = React.cache(async function getNonceFromCSPHeader()
2423
return getScriptNonceFromHeader((await headers()).get('Content-Security-Policy') || '') || '';
2524
});
2625

26+
/** Discards errors thrown by attempted code */
27+
const onlyTry = (cb: () => unknown) => {
28+
try {
29+
cb();
30+
} catch {
31+
// ignore
32+
}
33+
};
34+
2735
export async function ClerkProvider(
2836
props: Without<NextClerkProviderProps, '__unstable_invokeMiddlewareOnAuthStateChange'>,
2937
) {

packages/nextjs/src/app-router/server/auth.ts

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,12 @@ import { constants, createClerkRequest, createRedirect, type RedirectFun } from
33
import { notFound, redirect } from 'next/navigation';
44

55
import { PUBLISHABLE_KEY, SIGN_IN_URL, SIGN_UP_URL } from '../../server/constants';
6-
import { createAsyncGetAuth } from '../../server/createGetAuth';
6+
import { createGetAuth } from '../../server/createGetAuth';
77
import { authAuthHeaderMissing } from '../../server/errors';
88
import { getAuthKeyFromRequest, getHeader } from '../../server/headers-utils';
99
import type { AuthProtect } from '../../server/protect';
1010
import { createProtect } from '../../server/protect';
1111
import { decryptClerkRequestData } from '../../server/utils';
12-
import { isNextWithUnstableServerActions } from '../../utils/sdk-versions';
1312
import { buildRequestLike } from './utils';
1413

1514
/**
@@ -26,10 +25,8 @@ type Auth = AuthObject & {
2625
*/
2726
redirectToSignIn: RedirectFun<ReturnType<typeof redirect>>;
2827
};
29-
3028
export interface AuthFn {
3129
(): Promise<Auth>;
32-
3330
/**
3431
* `auth` includes a single property, the `protect()` method, which you can use in two ways:
3532
* - to check if a user is authenticated (signed in)
@@ -63,22 +60,9 @@ export const auth: AuthFn = async () => {
6360
require('server-only');
6461

6562
const request = await buildRequestLike();
66-
67-
const stepsBasedOnSrcDirectory = async () => {
68-
if (isNextWithUnstableServerActions) {
69-
return [];
70-
}
71-
72-
try {
73-
const isSrcAppDir = await import('../../server/keyless-node.js').then(m => m.hasSrcAppDir());
74-
return [`Your Middleware exists at ./${isSrcAppDir ? 'src/' : ''}middleware.ts`];
75-
} catch {
76-
return [];
77-
}
78-
};
79-
const authObject = await createAsyncGetAuth({
63+
const authObject = createGetAuth({
8064
debugLoggerName: 'auth()',
81-
noAuthStatusMessage: authAuthHeaderMissing('auth', await stepsBasedOnSrcDirectory()),
65+
noAuthStatusMessage: authAuthHeaderMissing(),
8266
})(request);
8367

8468
const clerkUrl = getAuthKeyFromRequest(request, 'ClerkUrl');

packages/nextjs/src/app-router/server/utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ export async function buildRequestLike(): Promise<NextRequest> {
3434
}
3535

3636
throw new Error(
37-
`Clerk: auth(), currentUser() and clerkClient(), are only supported in App Router (/app directory).\nIf you're using /pages, try getAuth() instead.\nOriginal error: ${e}`,
37+
`Clerk: auth() and currentUser() are only supported in App Router (/app directory).\nIf you're using /pages, try getAuth() instead.\nOriginal error: ${e}`,
3838
);
3939
}
4040
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import hmacSHA1 from 'crypto-js/hmac-sha1';
33
import { NextRequest } from 'next/server';
44
import { describe, expect, it } from 'vitest';
55

6-
import { createSyncGetAuth, getAuth } from '../createGetAuth';
6+
import { createGetAuth, getAuth } from '../createGetAuth';
77

88
const mockSecretKey = 'sk_test_mock';
99

@@ -16,7 +16,7 @@ const mockTokenSignature = hmacSHA1(mockToken, 'sk_test_mock').toString();
1616

1717
describe('createGetAuth(opts)', () => {
1818
it('returns a getAuth function', () => {
19-
expect(createSyncGetAuth({ debugLoggerName: 'test', noAuthStatusMessage: 'test' })).toBeInstanceOf(Function);
19+
expect(createGetAuth({ debugLoggerName: 'test', noAuthStatusMessage: 'test' })).toBeInstanceOf(Function);
2020
});
2121
});
2222

packages/nextjs/src/server/createGetAuth.ts

Lines changed: 6 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,29 @@
1+
import type { AuthObject } from '@clerk/backend';
12
import { constants } from '@clerk/backend/internal';
23
import { isTruthy } from '@clerk/shared/underscore';
34

45
import { withLogger } from '../utils/debugLogger';
5-
import { isNextWithUnstableServerActions } from '../utils/sdk-versions';
66
import { getAuthDataFromRequest } from './data/getAuthDataFromRequest';
77
import { getAuthAuthHeaderMissing } from './errors';
8-
import { detectClerkMiddleware, getHeader } from './headers-utils';
8+
import { getHeader } from './headers-utils';
99
import type { RequestLike } from './types';
1010
import { assertAuthStatus } from './utils';
1111

12-
export const createAsyncGetAuth = ({
13-
debugLoggerName,
12+
export const createGetAuth = ({
1413
noAuthStatusMessage,
15-
}: {
16-
debugLoggerName: string;
17-
noAuthStatusMessage: string;
18-
}) =>
19-
withLogger(debugLoggerName, logger => {
20-
return async (req: RequestLike, opts?: { secretKey?: string }) => {
21-
if (isTruthy(getHeader(req, constants.Headers.EnableDebug))) {
22-
logger.enable();
23-
}
24-
25-
if (!detectClerkMiddleware(req)) {
26-
// Keep the same behaviour for versions that may have issues with bundling `node:fs`
27-
if (isNextWithUnstableServerActions) {
28-
assertAuthStatus(req, noAuthStatusMessage);
29-
}
30-
31-
const missConfiguredMiddlewareLocation = await import('./keyless-node.js')
32-
.then(m => m.suggestMiddlewareLocation())
33-
.catch(() => undefined);
34-
35-
if (missConfiguredMiddlewareLocation) {
36-
throw new Error(missConfiguredMiddlewareLocation);
37-
}
38-
39-
// still throw there is no suggested move location
40-
assertAuthStatus(req, noAuthStatusMessage);
41-
}
42-
43-
return getAuthDataFromRequest(req, { ...opts, logger });
44-
};
45-
});
46-
47-
export const createSyncGetAuth = ({
4814
debugLoggerName,
49-
noAuthStatusMessage,
5015
}: {
5116
debugLoggerName: string;
5217
noAuthStatusMessage: string;
5318
}) =>
5419
withLogger(debugLoggerName, logger => {
55-
return (req: RequestLike, opts?: { secretKey?: string }) => {
20+
return (req: RequestLike, opts?: { secretKey?: string }): AuthObject => {
5621
if (isTruthy(getHeader(req, constants.Headers.EnableDebug))) {
5722
logger.enable();
5823
}
5924

6025
assertAuthStatus(req, noAuthStatusMessage);
26+
6127
return getAuthDataFromRequest(req, { ...opts, logger });
6228
};
6329
});
@@ -141,7 +107,7 @@ export const createSyncGetAuth = ({
141107
* }
142108
* ```
143109
*/
144-
export const getAuth = createSyncGetAuth({
110+
export const getAuth = createGetAuth({
145111
debugLoggerName: 'getAuth()',
146112
noAuthStatusMessage: getAuthAuthHeaderMissing(),
147113
});

packages/nextjs/src/server/errors.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@ Check if signInUrl is missing from your configuration or if it is not an absolut
2020

2121
export const getAuthAuthHeaderMissing = () => authAuthHeaderMissing('getAuth');
2222

23-
export const authAuthHeaderMissing = (helperName = 'auth', prefixSteps?: string[]) =>
23+
export const authAuthHeaderMissing = (helperName = 'auth') =>
2424
`Clerk: ${helperName}() was called but Clerk can't detect usage of clerkMiddleware(). Please ensure the following:
25-
- ${prefixSteps ? [...prefixSteps, ''].join('\n- ') : ' '}clerkMiddleware() is used in your Next.js Middleware.
25+
- clerkMiddleware() is used in your Next.js Middleware.
2626
- Your Middleware matcher is configured to match this route or page.
2727
- If you are using the src directory, make sure the Middleware file is inside of it.
2828

packages/nextjs/src/server/keyless-node.ts

Lines changed: 1 addition & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -212,47 +212,4 @@ function removeKeyless() {
212212
unlockFileWriting();
213213
}
214214

215-
function hasSrcAppDir() {
216-
const { existsSync } = safeNodeRuntimeFs();
217-
const path = safeNodeRuntimePath();
218-
219-
const projectWithAppSrc = path.join(process.cwd(), 'src', 'app');
220-
221-
return !!existsSync(projectWithAppSrc);
222-
}
223-
224-
function suggestMiddlewareLocation() {
225-
const suggestionMessage = (to?: 'src/', from?: 'src/app/' | 'app/') =>
226-
`Clerk: Move your middleware file to ./${to || ''}middleware.ts. Currently located at ./${from || ''}middleware.ts`;
227-
228-
const { existsSync } = safeNodeRuntimeFs();
229-
const path = safeNodeRuntimePath();
230-
231-
const projectWithAppSrcPath = path.join(process.cwd(), 'src', 'app');
232-
const projectWithAppPath = path.join(process.cwd(), 'app');
233-
234-
if (existsSync(projectWithAppSrcPath)) {
235-
if (existsSync(path.join(projectWithAppSrcPath, 'middleware.ts'))) {
236-
return suggestionMessage('src/', 'src/app/');
237-
}
238-
239-
if (existsSync(path.join(process.cwd(), 'middleware.ts'))) {
240-
return suggestionMessage('src/');
241-
}
242-
243-
// default error
244-
return undefined;
245-
}
246-
247-
if (existsSync(projectWithAppPath)) {
248-
if (existsSync(path.join(projectWithAppPath, 'middleware.ts'))) {
249-
return suggestionMessage(undefined, 'app/');
250-
}
251-
// default error
252-
return undefined;
253-
}
254-
255-
return undefined;
256-
}
257-
258-
export { createOrReadKeyless, removeKeyless, suggestMiddlewareLocation, hasSrcAppDir };
215+
export { createOrReadKeyless, removeKeyless };

packages/nextjs/src/utils/only-try.ts

Lines changed: 0 additions & 12 deletions
This file was deleted.

0 commit comments

Comments
 (0)