From 9e6822fc7af72bc68f59a33a58aa8c6ee7157979 Mon Sep 17 00:00:00 2001 From: Lncvrt Date: Thu, 22 Jan 2026 17:38:09 -0700 Subject: [PATCH] Validate verify code at register endpoint --- src/index.ts | 3 +- src/routes/berrydash/account/register/post.ts | 46 +++++++++++++++++-- 2 files changed, 44 insertions(+), 5 deletions(-) diff --git a/src/index.ts b/src/index.ts index d3853e3..2003a0c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -386,7 +386,8 @@ app.post( body: t.Object({ username: t.String(), password: t.String(), - email: t.String() + email: t.String(), + verifyCode: t.String() }) } ) diff --git a/src/routes/berrydash/account/register/post.ts b/src/routes/berrydash/account/register/post.ts index 790fdb6..29d28a1 100644 --- a/src/routes/berrydash/account/register/post.ts +++ b/src/routes/berrydash/account/register/post.ts @@ -5,8 +5,8 @@ import { jsonResponse } from '../../../../lib/util' import isEmail from 'validator/lib/isEmail' -import { berryDashUserData, users } from '../../../../lib/tables' -import { eq, or } from 'drizzle-orm' +import { berryDashUserData, users, verifyCodes } from '../../../../lib/tables' +import { and, desc, eq, or, sql } from 'drizzle-orm' import bcrypt from 'bcryptjs' import { randomBytes } from 'crypto' @@ -14,6 +14,7 @@ type Body = { username: string password: string email: string + verifyCode: string } export async function handler (context: Context) { @@ -29,13 +30,26 @@ export async function handler (context: Context) { const { connection: connection1, db: db1 } = dbInfo1 const body = context.body as Body - if (!body.username || !body.password || !body.email) { + if (!body.username || !body.password || !body.email || !body.verifyCode) { connection0.end() connection1.end() return jsonResponse( { success: false, - message: 'Username, password and email must be in POST data', + message: + 'Username, password, email and verifyCode must be in POST data', + data: null + }, + 400 + ) + } + if (body.verifyCode.length != 16) { + connection0.end() + connection1.end() + return jsonResponse( + { + success: false, + message: 'Invalid verify code (codes can only be used once)', data: null }, 400 @@ -120,6 +134,30 @@ export async function handler (context: Context) { ) } + const codeExists = await db0 + .select({ code: verifyCodes.code }) + .from(verifyCodes) + .where( + and( + eq(verifyCodes.ip, ip), + eq(verifyCodes.used, false), + eq(verifyCodes.code, body.verifyCode), + sql`${verifyCodes.timestamp} >= UNIX_TIMESTAMP() - 600` + ) + ) + .orderBy(desc(verifyCodes.id)) + .limit(1) + .execute() + if (!codeExists[0]) + return jsonResponse( + { + success: false, + message: 'Invalid verify code (codes can only be used once)', + data: null + }, + 400 + ) + const result = await db0 .insert(users) .values({