From 8c503269d1d86c54126fa57853f138fc1efd10ca Mon Sep 17 00:00:00 2001 From: mrjvs Date: Thu, 4 Jan 2024 19:54:14 +0100 Subject: [PATCH] Fixed AWS and NodeJS support --- package.json | 2 +- pnpm-lock.yaml | 14 +++++++------- src/utils/turnstile.ts | 33 ++++++++++++++++++--------------- 3 files changed, 26 insertions(+), 23 deletions(-) diff --git a/package.json b/package.json index c9eac5f..e9c0af7 100644 --- a/package.json +++ b/package.json @@ -15,8 +15,8 @@ "preinstall": "npx only-allow pnpm" }, "dependencies": { - "@tsndr/cloudflare-worker-jwt": "^2.3.2", "h3": "^1.8.1", + "jose": "^5.2.0", "nitropack": "latest" }, "devDependencies": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2c6251a..f18e821 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5,12 +5,12 @@ settings: excludeLinksFromLockfile: false dependencies: - '@tsndr/cloudflare-worker-jwt': - specifier: ^2.3.2 - version: 2.3.2 h3: specifier: ^1.8.1 version: 1.8.1 + jose: + specifier: ^5.2.0 + version: 5.2.0 nitropack: specifier: latest version: 2.6.3 @@ -704,10 +704,6 @@ packages: rollup: 3.29.1 dev: false - /@tsndr/cloudflare-worker-jwt@2.3.2: - resolution: {integrity: sha512-g1jSm5olPqKh15kadnj0666YPudibHYGyFyM0URLXSeY5MzNIGkfhFedLgKHq8NCDBMzLUMX7Oz8d+jmQXqBuw==} - dev: false - /@types/estree@1.0.1: resolution: {integrity: sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==} dev: false @@ -2537,6 +2533,10 @@ packages: hasBin: true dev: false + /jose@5.2.0: + resolution: {integrity: sha512-oW3PCnvyrcm1HMvGTzqjxxfnEs9EoFOFWi2HsEGhlFVOXxTE3K9GKWVMFoFw06yPUqwpvEWic1BmtUZBI/tIjw==} + dev: false + /js-yaml@4.1.0: resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} hasBin: true diff --git a/src/utils/turnstile.ts b/src/utils/turnstile.ts index 2e4f22e..8209799 100644 --- a/src/utils/turnstile.ts +++ b/src/utils/turnstile.ts @@ -1,5 +1,5 @@ import { H3Event, EventHandlerRequest } from 'h3'; -import jsonwebtoken from '@tsndr/cloudflare-worker-jwt'; +import { SignJWT, jwtVerify } from 'jose'; import { getIp } from '@/utils/ip'; const turnstileSecret = process.env.TURNSTILE_SECRET ?? null; @@ -15,13 +15,10 @@ export function isTurnstileEnabled() { export async function makeToken(ip: string) { if (!jwtSecret) throw new Error('Cannot make token without a secret'); - return await jsonwebtoken.sign( - { - ip, - exp: Math.floor(Date.now() / 1000) + 60 * 10, // 10 Minutes - }, - jwtSecret, - ); + return await new SignJWT({ ip }) + .setProtectedHeader({ alg: 'HS256' }) + .setExpirationTime('10m') + .sign(new TextEncoder().encode(jwtSecret)); } export function setTokenHeader( @@ -54,13 +51,19 @@ export async function isAllowedToMakeRequest( if (token.startsWith(jwtPrefix)) { const jwtToken = token.slice(jwtPrefix.length); - const isValid = await jsonwebtoken.verify(jwtToken, jwtSecret, { - algorithm: 'HS256', - }); - if (!isValid) return false; - const jwtBody = jsonwebtoken.decode<{ ip: string }>(jwtToken); - if (!jwtBody.payload) return false; - if (getIp(event) !== jwtBody.payload.ip) return false; + let jwtPayload: { ip: string } | null = null; + try { + const jwtResult = await jwtVerify<{ ip: string }>( + jwtToken, + new TextEncoder().encode(jwtSecret), + { + algorithms: ['HS256'], + }, + ); + jwtPayload = jwtResult.payload; + } catch {} + if (!jwtPayload) return false; + if (getIp(event) !== jwtPayload.ip) return false; return true; }