Files
WatchLink/src/lib/user-actions.ts

60 lines
1.5 KiB
TypeScript
Raw Normal View History

2026-05-15 03:11:41 +02:00
"use server";
import { compare, hash } from "bcryptjs";
import { redirect } from "next/navigation";
import { prisma } from "./prisma";
import { setSession } from "./session";
function normalizeUsername(value: FormDataEntryValue | null) {
return String(value || "")
.trim()
.toLowerCase()
.replace(/[^a-z0-9_-]/g, "");
}
export async function registerUser(formData: FormData) {
const username = normalizeUsername(formData.get("username"));
const password = String(formData.get("password") || "");
if (!username || password.length < 10) {
throw new Error("Username is required and password must be at least 10 characters.");
}
const passwordHash = await hash(password, 12);
const user = await prisma.user.create({
data: {
username,
displayName: username,
passwordHash,
ownedRooms: {
create: {
slug: `@${username}`,
name: `${username}'s room`,
visibility: "FRIENDS"
}
}
}
});
await setSession(user.id);
redirect("/dashboard");
}
export async function loginUser(formData: FormData) {
const username = normalizeUsername(formData.get("username"));
const password = String(formData.get("password") || "");
const user = await prisma.user.findUnique({ where: { username } });
if (!user) {
throw new Error("Invalid username or password.");
}
const ok = await compare(password, user.passwordHash);
if (!ok) {
throw new Error("Invalid username or password.");
}
await setSession(user.id);
redirect("/dashboard");
}