refactor(db): migrate staff and app actions from Prisma facade to Drizzle

Co-authored-by: Cursor <[email protected]>
This commit is contained in:
SimoandCursor committed 2026-07-31 21:35:05 +02:00
1 parent 9854719cfd
commit ed9c23c702
85 files changed
+2612 -1832

No files matched your search

+30 -21
View File
@@ -1,10 +1,11 @@
"use server";
import { createHash, randomBytes, timingSafeEqual } from "node:crypto";
import { eq } from "drizzle-orm";
import { redirect } from "next/navigation";
import { env } from "@/env";
import { hashPassword } from "@/lib/auth/password";
import { prisma } from "@/lib/prisma";
import { db, PasswordReset, User } from "@/lib/db";
import { clientIp, rateLimit } from "@/lib/rate-limit";
import { captchaConfig, verifyCaptcha } from "@/lib/services/captcha";
import { sendMail } from "@/lib/services/email";
@@ -38,17 +39,19 @@ export async function requestReset(formData: FormData): Promise<void> {
// Always respond the same way so we don't reveal which emails exist.
if (allowed && /^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(email)) {
try {
const user = await prisma.user.findFirst({
where: { mail: email },
select: { id: true },
});
const [user] = await db
.select({ id: User.id })
.from(User)
.where(eq(User.mail, email))
.limit(1);
if (user) {
const token = randomBytes(32).toString("hex");
await prisma.passwordReset.upsert({
where: { email },
update: { token: sha256(token), createdAt: new Date() },
create: { email, token: sha256(token), createdAt: new Date() },
});
const hashed = sha256(token);
const createdAt = new Date();
await db
.insert(PasswordReset)
.values({ email, token: hashed, createdAt })
.onDuplicateKeyUpdate({ set: { token: hashed, createdAt } });
const link = `${env.APP_URL}/reset?email=${encodeURIComponent(email)}&token=${token}`;
await sendMail(
email,
@@ -86,7 +89,11 @@ export async function resetPassword(formData: FormData): Promise<void> {
if (!error) {
try {
const row = await prisma.passwordReset.findUnique({ where: { email } });
const [row] = await db
.select()
.from(PasswordReset)
.where(eq(PasswordReset.email, email))
.limit(1);
const fresh = row?.createdAt
? Date.now() - row.createdAt.getTime() < TOKEN_TTL_MS
: false;
@@ -98,19 +105,21 @@ export async function resetPassword(formData: FormData): Promise<void> {
if (!row || !fresh || !match) {
error = "This reset link is invalid or has expired";
} else {
const user = await prisma.user.findFirst({
where: { mail: email },
select: { id: true },
});
const [user] = await db
.select({ id: User.id })
.from(User)
.where(eq(User.mail, email))
.limit(1);
if (!user) {
error = "Account not found";
} else {
await prisma.user.update({
where: { id: user.id },
data: { password: await hashPassword(password) },
});
await prisma.passwordReset
.delete({ where: { email } })
await db
.update(User)
.set({ password: await hashPassword(password) })
.where(eq(User.id, user.id));
await db
.delete(PasswordReset)
.where(eq(PasswordReset.email, email))
.catch(() => {});
}
}