import { v4 as uuidv4 } from "uuid"; import bcrypt from "bcryptjs"; import { db } from "./db"; import { users, sessions } from "./db/schema"; import { eq, and } from "drizzle-orm"; import { cookies } from "next/headers"; const SESSION_COOKIE = "barabingo_session"; const SESSION_DAYS = 7; export async function hashPassword(password: string): Promise { return bcrypt.hash(password, 10); } export async function verifyPassword(password: string, hash: string): Promise { return bcrypt.compare(password, hash); } const ADMIN_NICKNAMES = ["admin"]; export async function registerUser(nickname: string, password: string) { const existing = db.select().from(users).where(eq(users.nickname, nickname)).get(); if (existing) return { error: "Nickname taken" }; const userCount = db.select().from(users).all().length; const nicknameLower = nickname.toLowerCase(); const firstUser = userCount === 0; const isAdmin = firstUser || ADMIN_NICKNAMES.includes(nicknameLower); const id = uuidv4(); const passwordHash = await hashPassword(password); const createdAt = new Date().toISOString(); db.insert(users).values({ id, nickname, passwordHash, isAdmin, createdAt }).run(); return { id, nickname, isAdmin }; } export async function loginUser(nickname: string, password: string) { const user = db.select().from(users).where(eq(users.nickname, nickname)).get(); if (!user) return { error: "User not found" }; const valid = await verifyPassword(password, user.passwordHash); if (!valid) return { error: "Wrong password" }; const sessionId = uuidv4(); const expiresAt = new Date(Date.now() + SESSION_DAYS * 86400000).toISOString(); const createdAt = new Date().toISOString(); db.insert(sessions).values({ id: sessionId, userId: user.id, expiresAt, createdAt }).run(); return { sessionId, user: { id: user.id, nickname: user.nickname, isAdmin: user.isAdmin } }; } export async function getSession(token?: string) { if (!token) return null; const session = db.select().from(sessions).where(eq(sessions.id, token)).get(); if (!session) return null; if (new Date(session.expiresAt) < new Date()) { db.delete(sessions).where(eq(sessions.id, token)).run(); return null; } const user = db.select().from(users).where(eq(users.id, session.userId)).get(); if (!user) return null; return { id: user.id, nickname: user.nickname, isAdmin: user.isAdmin }; } export async function deleteSession(token: string) { db.delete(sessions).where(eq(sessions.id, token)).run(); } export async function getServerSession() { const cookieStore = await cookies(); const token = cookieStore.get(SESSION_COOKIE)?.value; if (!token) return null; return getSession(token); } export { SESSION_COOKIE };