Skip to content

Commit 656947b

Browse files
authored
feat(clerk): Switch to @clerk/backend SDK (#102)
The @clerk/clerk-sdk-node package has reached its [end of support](https://clerk.com/changelog/2025-01-10-node-sdk-eol) back in January. This PR updates the Clerk auth provider to use the recommended JS Backend SDK (@clerk/backend). This also removes the deprecated authDecoder function which used the rate-limited API and relied on the now unsupported Node SDK. Huge shoutout to @wobsoriano for getting started on this over in redwoodjs/graphql#11953
1 parent 36f464a commit 656947b

File tree

6 files changed

+53
-144
lines changed

6 files changed

+53
-144
lines changed

.changesets/102.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
- feat(clerk): Switch to `@clerk/backend` SDK (#102) by @Tobbe
2+
3+
The @clerk/clerk-sdk-node package has reached its
4+
[end of support](https://clerk.com/changelog/2025-01-10-node-sdk-eol) back in
5+
January. This PR updates the Clerk auth provider to use the recommended JS
6+
Backend SDK (@clerk/backend).
7+
8+
# Breaking changes
9+
10+
- Removes the deprecated `authDecoder` function which used the rate-limited API
11+
and relied on the now unsupported Node SDK.
12+
- You now have to specify `process.env.CLERK_API_URL`, it no longer has a
13+
default fallback

packages/auth-providers/clerk/api/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
"test:watch": "vitest watch"
4040
},
4141
"dependencies": {
42-
"@clerk/clerk-sdk-node": "5.0.52"
42+
"@clerk/backend": "1.33.1"
4343
},
4444
"devDependencies": {
4545
"@arethetypeswrong/cli": "0.18.1",

packages/auth-providers/clerk/api/src/__tests__/clerk.test.ts

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
import type { APIGatewayProxyEvent, Context as LambdaContext } from 'aws-lambda'
22
import { beforeAll, afterAll, describe, test, expect } from 'vitest'
33

4-
import { authDecoder, clerkAuthDecoder } from '../decoder'
4+
import { clerkAuthDecoder } from '../decoder'
55

66
const req = {
77
event: {} as APIGatewayProxyEvent,
88
context: {} as LambdaContext,
99
}
1010

11-
let consoleError
11+
let consoleError: typeof console.error
1212

1313
beforeAll(() => {
1414
consoleError = console.error
@@ -19,20 +19,6 @@ afterAll(() => {
1919
console.error = consoleError
2020
})
2121

22-
describe('deprecated authDecoder', () => {
23-
test('returns null for unsupported type', async () => {
24-
const decoded = await authDecoder('token', 'netlify', req)
25-
26-
expect(decoded).toBe(null)
27-
})
28-
29-
test('rejects when the token is invalid', async () => {
30-
process.env.CLERK_JWT_KEY = 'jwt-key'
31-
32-
await expect(authDecoder('invalid-token', 'clerk', req)).rejects.toThrow()
33-
})
34-
})
35-
3622
describe('clerkAuthDecoder', () => {
3723
test('returns null for unsupported type', async () => {
3824
const decoded = await clerkAuthDecoder('token', 'netlify', req)

packages/auth-providers/clerk/api/src/decoder.ts

Lines changed: 2 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,5 @@
11
import type { Decoder } from '@cedarjs/api'
22

3-
/**
4-
* @deprecated This function will be removed; it uses a rate-limited API. Use `clerkAuthDecoder` instead.
5-
*/
6-
export const authDecoder: Decoder = async (token: string, type: string) => {
7-
if (type !== 'clerk') {
8-
return null
9-
}
10-
11-
const { createClerkClient, verifyToken } = await import(
12-
'@clerk/clerk-sdk-node'
13-
)
14-
15-
try {
16-
const options = {
17-
apiUrl: process.env.CLERK_API_URL || 'https://api.clerk.dev',
18-
jwtKey: process.env.CLERK_JWT_KEY,
19-
secretKey: process.env.CLERK_SECRET_KEY,
20-
}
21-
22-
const jwtPayload = await verifyToken(token, options)
23-
24-
if (!jwtPayload.sub) {
25-
return Promise.reject(new Error('Session invalid'))
26-
}
27-
28-
const clerkClient = createClerkClient(options)
29-
30-
const user = await clerkClient.users.getUser(jwtPayload.sub)
31-
32-
return {
33-
...user,
34-
roles: user.publicMetadata['roles'] ?? [],
35-
}
36-
} catch (error) {
37-
console.error(error)
38-
return Promise.reject(error)
39-
}
40-
}
41-
423
export const clerkAuthDecoder: Decoder = async (
434
token: string,
445
type: string,
@@ -47,11 +8,11 @@ export const clerkAuthDecoder: Decoder = async (
478
return null
489
}
4910

50-
const { verifyToken } = await import('@clerk/clerk-sdk-node')
11+
const { verifyToken } = await import('@clerk/backend')
5112

5213
try {
5314
const jwtPayload = await verifyToken(token, {
54-
apiUrl: process.env.CLERK_API_URL || 'https://api.clerk.dev',
15+
apiUrl: process.env.CLERK_API_URL,
5516
jwtKey: process.env.CLERK_JWT_KEY,
5617
secretKey: process.env.CLERK_SECRET_KEY,
5718
})
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
export { authDecoder, clerkAuthDecoder } from './decoder'
1+
export { clerkAuthDecoder } from './decoder'

yarn.lock

Lines changed: 34 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -2173,7 +2173,7 @@ __metadata:
21732173
"@arethetypeswrong/cli": "npm:0.18.1"
21742174
"@cedarjs/api": "workspace:*"
21752175
"@cedarjs/framework-tools": "workspace:*"
2176-
"@clerk/clerk-sdk-node": "npm:5.0.52"
2176+
"@clerk/backend": "npm:1.33.1"
21772177
"@types/aws-lambda": "npm:8.10.145"
21782178
concurrently: "npm:8.2.2"
21792179
publint: "npm:0.3.12"
@@ -3662,16 +3662,21 @@ __metadata:
36623662
languageName: node
36633663
linkType: hard
36643664

3665-
"@clerk/backend@npm:1.14.1":
3666-
version: 1.14.1
3667-
resolution: "@clerk/backend@npm:1.14.1"
3665+
"@clerk/backend@npm:1.33.1":
3666+
version: 1.33.1
3667+
resolution: "@clerk/backend@npm:1.33.1"
36683668
dependencies:
3669-
"@clerk/shared": "npm:2.9.2"
3670-
"@clerk/types": "npm:4.26.0"
3671-
cookie: "npm:0.7.0"
3672-
snakecase-keys: "npm:5.4.4"
3673-
tslib: "npm:2.4.1"
3674-
checksum: 10c0/056d89dadb4789601574c064f1c937e8440eab25bc7996a2942b9dd543814957f902de5be1b6103ae1d2277efa53c70d47d19903cead6e84a3c37dc9b31413e8
3669+
"@clerk/shared": "npm:^3.9.4"
3670+
"@clerk/types": "npm:^4.59.2"
3671+
cookie: "npm:1.0.2"
3672+
snakecase-keys: "npm:8.0.1"
3673+
tslib: "npm:2.8.1"
3674+
peerDependencies:
3675+
svix: ^1.62.0
3676+
peerDependenciesMeta:
3677+
svix:
3678+
optional: true
3679+
checksum: 10c0/9158047d3ee156ce7aa26c9771302d7c0b406b73fc25bebbb6cc5cd2d0355c67854a21be11a5661354b7f2b52c0ed6354f1db44b8dc6af81a362e250aeee3718
36753680
languageName: node
36763681
linkType: hard
36773682

@@ -3689,39 +3694,6 @@ __metadata:
36893694
languageName: node
36903695
linkType: hard
36913696

3692-
"@clerk/clerk-sdk-node@npm:5.0.52":
3693-
version: 5.0.52
3694-
resolution: "@clerk/clerk-sdk-node@npm:5.0.52"
3695-
dependencies:
3696-
"@clerk/backend": "npm:1.14.1"
3697-
"@clerk/shared": "npm:2.9.2"
3698-
"@clerk/types": "npm:4.26.0"
3699-
tslib: "npm:2.4.1"
3700-
checksum: 10c0/5044c1a2600a9183a8b5db22437cf21c5f11e25cfeebe0449939eaadfc753b34e18bb868bde03fb69b5f2fcc277168812e75c3d4e15928ce4d9e428fefc1c121
3701-
languageName: node
3702-
linkType: hard
3703-
3704-
"@clerk/shared@npm:2.9.2":
3705-
version: 2.9.2
3706-
resolution: "@clerk/shared@npm:2.9.2"
3707-
dependencies:
3708-
"@clerk/types": "npm:4.26.0"
3709-
glob-to-regexp: "npm:0.4.1"
3710-
js-cookie: "npm:3.0.5"
3711-
std-env: "npm:^3.7.0"
3712-
swr: "npm:^2.2.0"
3713-
peerDependencies:
3714-
react: ">=18 || >=19.0.0-beta"
3715-
react-dom: ">=18 || >=19.0.0-beta"
3716-
peerDependenciesMeta:
3717-
react:
3718-
optional: true
3719-
react-dom:
3720-
optional: true
3721-
checksum: 10c0/5d8022dbce5d34d6087d1f74673fa3804c8eb4708d64e02fb004bc8e0d466ec1b1708aa4de273bd1a62e1522e6e3fbae2abb6055319f8ccb4926cca8d9c04a2d
3722-
languageName: node
3723-
linkType: hard
3724-
37253697
"@clerk/shared@npm:^3.9.4":
37263698
version: 3.9.4
37273699
resolution: "@clerk/shared@npm:3.9.4"
@@ -3744,15 +3716,6 @@ __metadata:
37443716
languageName: node
37453717
linkType: hard
37463718

3747-
"@clerk/types@npm:4.26.0":
3748-
version: 4.26.0
3749-
resolution: "@clerk/types@npm:4.26.0"
3750-
dependencies:
3751-
csstype: "npm:3.1.1"
3752-
checksum: 10c0/ad71935ea18604150605f8ab1f7287edce23bc3fd5085f662c1c69f670d8ce914dd019bf9f046d1c113c5919cbf700de39b88e8fe7ed6bad372d9fe4d1ded28c
3753-
languageName: node
3754-
linkType: hard
3755-
37563719
"@clerk/types@npm:4.59.2, @clerk/types@npm:^4.59.2":
37573720
version: 4.59.2
37583721
resolution: "@clerk/types@npm:4.59.2"
@@ -14531,13 +14494,6 @@ __metadata:
1453114494
languageName: node
1453214495
linkType: hard
1453314496

14534-
"cookie@npm:0.7.0":
14535-
version: 0.7.0
14536-
resolution: "cookie@npm:0.7.0"
14537-
checksum: 10c0/15c20c9b85431c8565b1750f9bccff0bd289b943d956e25fffce3b146e57934075965c8305a4e3a65a70622c9ed483e013daf9159d9c50f5c3f97f2e7c8117ac
14538-
languageName: node
14539-
linkType: hard
14540-
1454114497
"cookie@npm:0.7.1":
1454214498
version: 0.7.1
1454314499
resolution: "cookie@npm:0.7.1"
@@ -14940,13 +14896,6 @@ __metadata:
1494014896
languageName: node
1494114897
linkType: hard
1494214898

14943-
"csstype@npm:3.1.1":
14944-
version: 3.1.1
14945-
resolution: "csstype@npm:3.1.1"
14946-
checksum: 10c0/7c8b8c5923049d84132581c13bae6e1faf999746fe3998ba5f3819a8e1cdc7512ace87b7d0a4a69f0f4b8ba11daf835d4f1390af23e09fc4f0baad52c084753a
14947-
languageName: node
14948-
linkType: hard
14949-
1495014899
"csstype@npm:3.1.3, csstype@npm:^3.0.2":
1495114900
version: 3.1.3
1495214901
resolution: "csstype@npm:3.1.3"
@@ -27159,14 +27108,14 @@ __metadata:
2715927108
languageName: node
2716027109
linkType: hard
2716127110

27162-
"snakecase-keys@npm:5.4.4":
27163-
version: 5.4.4
27164-
resolution: "snakecase-keys@npm:5.4.4"
27111+
"snakecase-keys@npm:8.0.1":
27112+
version: 8.0.1
27113+
resolution: "snakecase-keys@npm:8.0.1"
2716527114
dependencies:
2716627115
map-obj: "npm:^4.1.0"
2716727116
snake-case: "npm:^3.0.4"
27168-
type-fest: "npm:^2.5.2"
27169-
checksum: 10c0/72afc51818d9f8cee00b4ccdc3b83bb26e48de21c4ef77d28d0d70b431bec17e48aa3e64c2c418fd9f2b70ac0a8afce24b4e615238877c4ee451b5212b983fb0
27117+
type-fest: "npm:^4.15.0"
27118+
checksum: 10c0/3615126462e413fe5e1637c945362e99c3ac497bc49d867397547ab1a87ff2827ae890d1aa022ef06c27cb3924bcb3714db2f4e76770e6ebd3625f3e16d79d27
2717027119
languageName: node
2717127120
linkType: hard
2717227121

@@ -27462,7 +27411,7 @@ __metadata:
2746227411
languageName: node
2746327412
linkType: hard
2746427413

27465-
"std-env@npm:^3.7.0, std-env@npm:^3.8.0, std-env@npm:^3.9.0":
27414+
"std-env@npm:^3.8.0, std-env@npm:^3.9.0":
2746627415
version: 3.9.0
2746727416
resolution: "std-env@npm:3.9.0"
2746827417
checksum: 10c0/4a6f9218aef3f41046c3c7ecf1f98df00b30a07f4f35c6d47b28329bc2531eef820828951c7d7b39a1c5eb19ad8a46e3ddfc7deb28f0a2f3ceebee11bab7ba50
@@ -27981,7 +27930,7 @@ __metadata:
2798127930
languageName: node
2798227931
linkType: hard
2798327932

27984-
"swr@npm:^2.2.0, swr@npm:^2.3.3":
27933+
"swr@npm:^2.3.3":
2798527934
version: 2.3.3
2798627935
resolution: "swr@npm:2.3.3"
2798727936
dependencies:
@@ -28604,13 +28553,6 @@ __metadata:
2860428553
languageName: node
2860528554
linkType: hard
2860628555

28607-
"tslib@npm:2.4.1, tslib@npm:~2.4.0":
28608-
version: 2.4.1
28609-
resolution: "tslib@npm:2.4.1"
28610-
checksum: 10c0/9ac0e4fd1033861f0b4f0d848dc3009ebcc3aa4757a06e8602a2d8a7aed252810e3540e54e70709f06c0f95311faa8584f769bcbede48aff785eb7e4d399b9ec
28611-
languageName: node
28612-
linkType: hard
28613-
2861428556
"tslib@npm:2.8.1, tslib@npm:^2.0.0, tslib@npm:^2.0.1, tslib@npm:^2.0.3, tslib@npm:^2.1.0, tslib@npm:^2.2.0, tslib@npm:^2.3.0, tslib@npm:^2.3.1, tslib@npm:^2.4.0, tslib@npm:^2.5.0, tslib@npm:^2.5.2, tslib@npm:^2.6.2, tslib@npm:^2.6.3, tslib@npm:^2.8.1":
2861528557
version: 2.8.1
2861628558
resolution: "tslib@npm:2.8.1"
@@ -28625,6 +28567,13 @@ __metadata:
2862528567
languageName: node
2862628568
linkType: hard
2862728569

28570+
"tslib@npm:~2.4.0":
28571+
version: 2.4.1
28572+
resolution: "tslib@npm:2.4.1"
28573+
checksum: 10c0/9ac0e4fd1033861f0b4f0d848dc3009ebcc3aa4757a06e8602a2d8a7aed252810e3540e54e70709f06c0f95311faa8584f769bcbede48aff785eb7e4d399b9ec
28574+
languageName: node
28575+
linkType: hard
28576+
2862828577
"tslib@npm:~2.5.0":
2862928578
version: 2.5.3
2863028579
resolution: "tslib@npm:2.5.3"
@@ -28789,7 +28738,7 @@ __metadata:
2878928738
languageName: node
2879028739
linkType: hard
2879128740

28792-
"type-fest@npm:^2.19.0, type-fest@npm:^2.5.2, type-fest@npm:~2.19":
28741+
"type-fest@npm:^2.19.0, type-fest@npm:~2.19":
2879328742
version: 2.19.0
2879428743
resolution: "type-fest@npm:2.19.0"
2879528744
checksum: 10c0/a5a7ecf2e654251613218c215c7493574594951c08e52ab9881c9df6a6da0aeca7528c213c622bc374b4e0cb5c443aa3ab758da4e3c959783ce884c3194e12cb
@@ -28803,10 +28752,10 @@ __metadata:
2880328752
languageName: node
2880428753
linkType: hard
2880528754

28806-
"type-fest@npm:^4.18.2":
28807-
version: 4.40.1
28808-
resolution: "type-fest@npm:4.40.1"
28809-
checksum: 10c0/590cb7d4dcd3da83efe49b5b52cd041661f6fa29f18cb76650fe1fdeb4090688e92955656e9d981e606abb13d25c0418be8c6c6504d80e87fe18dc9ca0888392
28755+
"type-fest@npm:^4.15.0, type-fest@npm:^4.18.2":
28756+
version: 4.41.0
28757+
resolution: "type-fest@npm:4.41.0"
28758+
checksum: 10c0/f5ca697797ed5e88d33ac8f1fec21921839871f808dc59345c9cf67345bfb958ce41bd821165dbf3ae591cedec2bf6fe8882098dfdd8dc54320b859711a2c1e4
2881028759
languageName: node
2881128760
linkType: hard
2881228761

0 commit comments

Comments
 (0)