Skip to content

Commit

Permalink
Clerk: Switch to getToken (redwoodjs#4846)
Browse files Browse the repository at this point in the history
* Clerk: Switch to getToken

* Use Clerk's own errors

Co-authored-by: David Thyresson <[email protected]>
  • Loading branch information
2 people authored and thedavidprice committed Mar 31, 2022
1 parent 6f5e598 commit 6e097e1
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 33 deletions.
51 changes: 20 additions & 31 deletions packages/api/src/auth/decoders/clerk.ts
Original file line number Diff line number Diff line change
@@ -1,41 +1,30 @@
import type { APIGatewayProxyEvent, Context as LambdaContext } from 'aws-lambda'
import type IClerk from '@clerk/clerk-sdk-node/instance'

interface Req {
event: APIGatewayProxyEvent
context: LambdaContext
}

export const clerk = async (token: string, req: Req) => {
export const clerk = async (token: string) => {
// Use require here, to prevent needing clerk sdk in api deps
const { sessions, users } = require('@clerk/clerk-sdk-node')

if (!process.env.CLERK_API_KEY) {
console.error('CLERK_API_KEY env var is not set.')
throw new Error('CLERK_API_KEY env var is not set.')
}
const Clerk = require('@clerk/clerk-sdk-node/instance').default

// Clerk sessions are a combination of a clerk "current session id", which we store
// in the Redwood auth token, and the __session cookie, which contains a second session
// bearer token. The two tokens together define which device is browsing and as who.
const clerkCookieName = '__session'
const cookies = req.event.headers['cookie']?.split(';').map((c) => c.trim())
const sessionCookie = cookies
?.find((c) => c.startsWith(clerkCookieName + '='))
?.substring(clerkCookieName.length + 1)
const { users, base }: IClerk = new Clerk()

if (!sessionCookie || sessionCookie.length < 1) {
return Promise.reject(new Error('Clerk __session token is not set'))
if (!process.env.CLERK_JWT_KEY) {
console.error('CLERK_JWT_KEY env var is not set.')
throw new Error('CLERK_JWT_KEY env var is not set.')
}

const session = await sessions.verifySession(token, sessionCookie)
if (!session.userId) {
return Promise.reject(new Error('Session invalid'))
}
try {
const jwtPayload = await base.verifySessionToken(token)

if (!jwtPayload.sub) {
return Promise.reject(new Error('Session invalid'))
}

const user = await users.getUser(session.userId)
const user = await users.getUser(jwtPayload.sub)

return {
...user,
roles: user.publicMetadata['roles'] ?? [],
return {
...user,
roles: user.publicMetadata['roles'] ?? [],
}
} catch (error) {
return Promise.reject(error)
}
}
13 changes: 11 additions & 2 deletions packages/auth/src/authClients/clerk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,17 @@ export const clerk = (client: Clerk): AuthClientClerk => {
clerkClient(client)?.signOut(options),
signup: async (options?: SignUpProps) =>
clerkClient(client)?.openSignUp(options || {}),
// Clerk uses the session ID PLUS the __session cookie.
getToken: async () => clerkClient(client)?.session?.id || null,
getToken: async () => {
let token

try {
token = await clerkClient(client)?.session?.getToken()
} catch {
token = null
}

return token || null
},
getUserMetadata: async () => {
return clerkClient(client)?.user
? {
Expand Down

0 comments on commit 6e097e1

Please sign in to comment.