diff --git a/app/root.tsx b/app/root.tsx index 312bfc7c5..4f9c14a3e 100644 --- a/app/root.tsx +++ b/app/root.tsx @@ -105,7 +105,7 @@ export async function loader({ request }: Route.LoaderArgs) { await logout({ request, redirectTo: '/' }) } const { toast, headers: toastHeaders } = await getToast(request) - const honeyProps = honeypot.getInputProps() + const honeyProps = await honeypot.getInputProps() return data( { diff --git a/app/routes/_auth+/forgot-password.tsx b/app/routes/_auth+/forgot-password.tsx index 37fd2fd9f..0b1c1880d 100644 --- a/app/routes/_auth+/forgot-password.tsx +++ b/app/routes/_auth+/forgot-password.tsx @@ -25,7 +25,7 @@ const ForgotPasswordSchema = z.object({ export async function action({ request }: Route.ActionArgs) { const formData = await request.formData() - checkHoneypot(formData) + await checkHoneypot(formData) const submission = await parseWithZod(formData, { schema: ForgotPasswordSchema.superRefine(async (data, ctx) => { const user = await prisma.user.findFirst({ diff --git a/app/routes/_auth+/login.tsx b/app/routes/_auth+/login.tsx index 1b0238eeb..6d58a9ef8 100644 --- a/app/routes/_auth+/login.tsx +++ b/app/routes/_auth+/login.tsx @@ -38,7 +38,7 @@ export async function loader({ request }: Route.LoaderArgs) { export async function action({ request }: Route.ActionArgs) { await requireAnonymous(request) const formData = await request.formData() - checkHoneypot(formData) + await checkHoneypot(formData) const submission = await parseWithZod(formData, { schema: (intent) => LoginFormSchema.transform(async (data, ctx) => { diff --git a/app/routes/_auth+/onboarding.tsx b/app/routes/_auth+/onboarding.tsx index 4d955a3dd..4c90e76f2 100644 --- a/app/routes/_auth+/onboarding.tsx +++ b/app/routes/_auth+/onboarding.tsx @@ -56,7 +56,7 @@ export async function loader({ request }: Route.LoaderArgs) { export async function action({ request }: Route.ActionArgs) { const email = await requireOnboardingEmail(request) const formData = await request.formData() - checkHoneypot(formData) + await checkHoneypot(formData) const submission = await parseWithZod(formData, { schema: (intent) => SignupFormSchema.superRefine(async (data, ctx) => { diff --git a/app/routes/_auth+/signup.tsx b/app/routes/_auth+/signup.tsx index fdb030f91..fa11a9b9b 100644 --- a/app/routes/_auth+/signup.tsx +++ b/app/routes/_auth+/signup.tsx @@ -31,7 +31,7 @@ const SignupSchema = z.object({ export async function action({ request }: Route.ActionArgs) { const formData = await request.formData() - checkHoneypot(formData) + await checkHoneypot(formData) const submission = await parseWithZod(formData, { schema: SignupSchema.superRefine(async (data, ctx) => { diff --git a/app/routes/_auth+/verify.tsx b/app/routes/_auth+/verify.tsx index 7c33868f2..c726a3b36 100644 --- a/app/routes/_auth+/verify.tsx +++ b/app/routes/_auth+/verify.tsx @@ -34,7 +34,7 @@ export const VerifySchema = z.object({ export async function action({ request }: Route.ActionArgs) { const formData = await request.formData() - checkHoneypot(formData) + await checkHoneypot(formData) return validateRequest(request, formData) } diff --git a/app/utils/honeypot.server.ts b/app/utils/honeypot.server.ts index 91e6bcb83..55b18a524 100644 --- a/app/utils/honeypot.server.ts +++ b/app/utils/honeypot.server.ts @@ -5,9 +5,9 @@ export const honeypot = new Honeypot({ encryptionSeed: process.env.HONEYPOT_SECRET, }) -export function checkHoneypot(formData: FormData) { +export async function checkHoneypot(formData: FormData) { try { - honeypot.check(formData) + await honeypot.check(formData) } catch (error) { if (error instanceof SpamError) { throw new Response('Form not submitted properly', { status: 400 }) diff --git a/package-lock.json b/package-lock.json index b761508fc..e7c1227bd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,6 +16,8 @@ "@epic-web/totp": "^2.0.0", "@mjackson/form-data-parser": "^0.6.0", "@nasa-gcn/remix-seo": "^2.0.1", + "@oslojs/crypto": "^1.0.1", + "@oslojs/encoding": "^1.1.0", "@paralleldrive/cuid2": "^2.2.2", "@prisma/client": "^6.2.1", "@radix-ui/react-checkbox": "^1.1.3", @@ -43,7 +45,6 @@ "compression": "^1.7.5", "cookie": "^1.0.2", "cross-env": "^7.0.3", - "crypto-js": "^4.2.0", "date-fns": "^4.1.0", "dotenv": "^16.4.7", "execa": "^9.5.2", @@ -65,7 +66,7 @@ "react-router": "^7.1.3", "remix-auth": "^3.7.0", "remix-auth-github": "^1.7.0", - "remix-utils": "^7.7.0", + "remix-utils": "^8.0.0", "set-cookie-parser": "^2.7.1", "sonner": "^1.7.2", "source-map-support": "^0.5.21", @@ -2588,6 +2589,37 @@ "@opentelemetry/api": "^1.1.0" } }, + "node_modules/@oslojs/asn1": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@oslojs/asn1/-/asn1-1.0.0.tgz", + "integrity": "sha512-zw/wn0sj0j0QKbIXfIlnEcTviaCzYOY3V5rAyjR6YtOByFtJiT574+8p9Wlach0lZH9fddD4yb9laEAIl4vXQA==", + "license": "MIT", + "dependencies": { + "@oslojs/binary": "1.0.0" + } + }, + "node_modules/@oslojs/binary": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@oslojs/binary/-/binary-1.0.0.tgz", + "integrity": "sha512-9RCU6OwXU6p67H4NODbuxv2S3eenuQ4/WFLrsq+K/k682xrznH5EVWA7N4VFk9VYVcbFtKqur5YQQZc0ySGhsQ==", + "license": "MIT" + }, + "node_modules/@oslojs/crypto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@oslojs/crypto/-/crypto-1.0.1.tgz", + "integrity": "sha512-7n08G8nWjAr/Yu3vu9zzrd0L9XnrJfpMioQcvCMxBIiF5orECHe5/3J0jmXRVvgfqMm/+4oxlQ+Sq39COYLcNQ==", + "license": "MIT", + "dependencies": { + "@oslojs/asn1": "1.0.0", + "@oslojs/binary": "1.0.0" + } + }, + "node_modules/@oslojs/encoding": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@oslojs/encoding/-/encoding-1.1.0.tgz", + "integrity": "sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==", + "license": "MIT" + }, "node_modules/@paralleldrive/cuid2": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/@paralleldrive/cuid2/-/cuid2-2.2.2.tgz", @@ -7616,12 +7648,6 @@ "node": ">= 8" } }, - "node_modules/crypto-js": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz", - "integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==", - "license": "MIT" - }, "node_modules/css-select": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", @@ -13768,44 +13794,33 @@ } }, "node_modules/remix-utils": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/remix-utils/-/remix-utils-7.7.0.tgz", - "integrity": "sha512-J8NhP044nrNIam/xOT1L9a4RQ9FSaA2wyrUwmN8ZT+c/+CdAAf70yfaLnvMyKcV5U+8BcURQ/aVbth77sT6jGA==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/remix-utils/-/remix-utils-8.0.0.tgz", + "integrity": "sha512-vrs8Iytnuwi+KF+VYOPT3vzDX7cLbys897pwzLpMzLjOXJQ/S60dApHCmQ9cPWH3XHRgvaoJjZ6+sMGaax4fbg==", "funding": [ "https://github.com/sponsors/sergiodxa" ], "license": "MIT", "dependencies": { - "type-fest": "^4.18.1" + "type-fest": "^4.30.0" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" }, "peerDependencies": { - "@remix-run/cloudflare": "^2.0.0", - "@remix-run/node": "^2.0.0", - "@remix-run/react": "^2.0.0", - "@remix-run/router": "^1.7.2", - "crypto-js": "^4.1.1", + "@oslojs/crypto": "^1.0.1", + "@oslojs/encoding": "^1.1.0", "intl-parse-accept-language": "^1.0.0", "is-ip": "^5.0.1", - "react": "^18.0.0", + "react": "^18.0.0 || ^19.0.0", + "react-router": "^7.0.0", "zod": "^3.22.4" }, "peerDependenciesMeta": { - "@remix-run/cloudflare": { + "@oslojs/crypto": { "optional": true }, - "@remix-run/node": { - "optional": true - }, - "@remix-run/react": { - "optional": true - }, - "@remix-run/router": { - "optional": true - }, - "crypto-js": { + "@oslojs/encoding": { "optional": true }, "intl-parse-accept-language": { @@ -13817,6 +13832,9 @@ "react": { "optional": true }, + "react-router": { + "optional": true + }, "zod": { "optional": true } diff --git a/package.json b/package.json index 25a563e1e..17fe59ac9 100644 --- a/package.json +++ b/package.json @@ -53,6 +53,8 @@ "@epic-web/totp": "^2.0.0", "@mjackson/form-data-parser": "^0.6.0", "@nasa-gcn/remix-seo": "^2.0.1", + "@oslojs/crypto": "^1.0.1", + "@oslojs/encoding": "^1.1.0", "@paralleldrive/cuid2": "^2.2.2", "@prisma/client": "^6.2.1", "@radix-ui/react-checkbox": "^1.1.3", @@ -80,7 +82,6 @@ "compression": "^1.7.5", "cookie": "^1.0.2", "cross-env": "^7.0.3", - "crypto-js": "^4.2.0", "date-fns": "^4.1.0", "dotenv": "^16.4.7", "execa": "^9.5.2", @@ -102,7 +103,7 @@ "react-router": "^7.1.3", "remix-auth": "^3.7.0", "remix-auth-github": "^1.7.0", - "remix-utils": "^7.7.0", + "remix-utils": "^8.0.0", "set-cookie-parser": "^2.7.1", "sonner": "^1.7.2", "source-map-support": "^0.5.21",