Files
BaraBingo/lib/auth.ts
SlavaVlad 05677924b5
Some checks failed
Deploy / build-and-deploy (push) Failing after 2m53s
V1 bingo
2026-06-14 21:29:43 +03:00

79 lines
2.7 KiB
TypeScript

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<string> {
return bcrypt.hash(password, 10);
}
export async function verifyPassword(password: string, hash: string): Promise<boolean> {
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 };