Skip to content

Commit 71d3ff7

Browse files
committed
fix(fastify): use runtime keys for auth client
1 parent 54ddc2f commit 71d3ff7

3 files changed

Lines changed: 62 additions & 10 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@clerk/fastify': patch
3+
---
4+
5+
Use runtime plugin keys when creating the request client used by Fastify auth middleware, so nonce handshake payload exchange works when keys are passed directly to `clerkPlugin`.

packages/fastify/src/__tests__/withClerkMiddleware.test.ts

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,22 @@ import { beforeEach, describe, expect, test, vi } from 'vitest';
44

55
import { clerkPlugin, getAuth } from '../index';
66

7-
const authenticateRequestMock = vi.fn();
7+
const { authenticateRequestMock, createClerkClientMock } = vi.hoisted(() => {
8+
const authenticateRequestMock = vi.fn();
9+
const createClerkClientMock = vi.fn(() => {
10+
return {
11+
authenticateRequest: (...args: any) => authenticateRequestMock(...args),
12+
};
13+
});
14+
15+
return { authenticateRequestMock, createClerkClientMock };
16+
});
817

918
vi.mock('@clerk/backend', async () => {
1019
const actual = await vi.importActual('@clerk/backend');
1120
return {
1221
...actual,
13-
createClerkClient: () => {
14-
return {
15-
authenticateRequest: (...args: any) => authenticateRequestMock(...args),
16-
};
17-
},
22+
createClerkClient: (...args: any[]) => createClerkClientMock(...args),
1823
};
1924
});
2025

@@ -24,6 +29,38 @@ describe('withClerkMiddleware(options)', () => {
2429
vi.restoreAllMocks();
2530
});
2631

32+
test('creates the request client with plugin runtime keys', async () => {
33+
authenticateRequestMock.mockResolvedValueOnce({
34+
headers: new Headers(),
35+
toAuth: () => ({
36+
tokenType: 'session_token',
37+
}),
38+
});
39+
const fastify = Fastify();
40+
await fastify.register(clerkPlugin, {
41+
secretKey: 'runtime_secret_key',
42+
publishableKey: 'runtime_publishable_key',
43+
});
44+
45+
fastify.get('/', (request: FastifyRequest, reply: FastifyReply) => {
46+
const auth = getAuth(request);
47+
reply.send({ auth });
48+
});
49+
50+
const response = await fastify.inject({
51+
method: 'GET',
52+
path: '/',
53+
});
54+
55+
expect(response.statusCode).toEqual(200);
56+
expect(createClerkClientMock).toHaveBeenLastCalledWith(
57+
expect.objectContaining({
58+
secretKey: 'runtime_secret_key',
59+
publishableKey: 'runtime_publishable_key',
60+
}),
61+
);
62+
});
63+
2764
test('handles signin with Authorization Bearer', async () => {
2865
authenticateRequestMock.mockResolvedValueOnce({
2966
headers: new Headers(),

packages/fastify/src/withClerkMiddleware.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,31 @@
1+
import { createClerkClient } from '@clerk/backend';
12
import { AuthStatus } from '@clerk/backend/internal';
23
import { clerkFrontendApiProxy, DEFAULT_PROXY_PATH, stripTrailingSlashes } from '@clerk/backend/proxy';
34
import type { FastifyReply, FastifyRequest } from 'fastify';
45
import { Readable } from 'stream';
56

6-
import { clerkClient } from './clerkClient';
77
import * as constants from './constants';
88
import type { ClerkFastifyOptions } from './types';
99
import { fastifyRequestToRequest, requestToProxyRequest } from './utils';
1010

1111
export const withClerkMiddleware = (options: ClerkFastifyOptions) => {
1212
const frontendApiProxy = options.frontendApiProxy;
1313
const proxyPath = stripTrailingSlashes(frontendApiProxy?.path ?? DEFAULT_PROXY_PATH) || DEFAULT_PROXY_PATH;
14+
const publishableKey = options.publishableKey || constants.PUBLISHABLE_KEY;
15+
const secretKey = options.secretKey || constants.SECRET_KEY;
16+
const clerkClient = createClerkClient({
17+
...options,
18+
publishableKey,
19+
secretKey,
20+
machineSecretKey: options.machineSecretKey || constants.MACHINE_SECRET_KEY,
21+
apiUrl: options.apiUrl || constants.API_URL,
22+
apiVersion: options.apiVersion || constants.API_VERSION,
23+
jwtKey: options.jwtKey || constants.JWT_KEY,
24+
userAgent: options.userAgent || `${constants.SDK_METADATA.name}@${constants.SDK_METADATA.version}`,
25+
sdkMetadata: options.sdkMetadata || constants.SDK_METADATA,
26+
});
1427

1528
return async (fastifyRequest: FastifyRequest, reply: FastifyReply) => {
16-
const publishableKey = options.publishableKey || constants.PUBLISHABLE_KEY;
17-
const secretKey = options.secretKey || constants.SECRET_KEY;
18-
1929
// Handle Frontend API proxy requests and auto-derive proxyUrl
2030
let resolvedProxyUrl = options.proxyUrl;
2131
if (frontendApiProxy) {

0 commit comments

Comments
 (0)