Replies: 1 comment
|
Thanks for the thoughtful question! You can already guarantee that the import { makeWorker, makeDurableObject } from '@livestore/sync-cf/cf-worker'
import { verifyJwt } from './jwt.ts' // wrap your preferred JWT library (jose, etc.)
type SyncPayload = { authToken?: string; userId?: string }
type Claims = { sub?: string }
const ensureAuthorized = (payload: unknown): Claims & { authToken: string } => {
if (payload === undefined || payload === null || typeof payload !== 'object') {
throw new Error('Missing auth payload')
}
const { authToken, userId } = payload as SyncPayload
if (!authToken) {
throw new Error('Missing auth token')
}
const claims: Claims = verifyJwt(authToken)
if (!claims.sub) {
throw new Error('Token missing subject claim')
}
if (userId !== undefined && userId !== claims.sub) {
throw new Error('Payload userId mismatch')
}
return { ...claims, authToken }
}
export default makeWorker({
syncBackendBinding: 'SYNC_BACKEND_DO',
validatePayload: (payload) => {
ensureAuthorized(payload)
},
})
export class SyncBackendDO extends makeDurableObject({
onPush: async (message, { payload }) => {
const { sub: userId } = ensureAuthorized(payload)
await ensureTenantAccess(userId!, message.batch)
},
}) {}Because the Durable Object always gets the original payload, it must repeat the JWT verification (or retrieve cached claims keyed by Feel free to adapt the helper to cache verified claims, project additional attributes, or integrate stricter authorization checks as needed. |
Uh oh!
There was an error while loading. Please reload this page.
I'm walking through the docs for LiveStore 0.4.0 before I do our migration and have some questions.
Taking the example
Alongside the sync/auth
How can I verify that
userIdin theonPushmatches that from the (presumed) JWT in theauthToken? Ideally I would know which user was pushing in this case so that I could validate that the message was allowed.All reactions