import bcryptjs from "bcryptjs"; import { prisma } from "./prisma"; import { ReadonlyRequestCookies } from "next/dist/server/web/spec-extension/adapters/request-cookies"; import { cookies } from "next/headers"; import { User } from "@prisma/client"; /** * Hash a password using bcryptjs */ export async function hashPassword(password: string): Promise { const salt = await bcryptjs.genSalt(10); return bcryptjs.hash(password, salt); } /** * Verify a password against its hash */ export async function verifyPassword( password: string, hash: string ): Promise { return bcryptjs.compare(password, hash); } /** * Create a session token for a user (30-day expiration) */ export async function createSession( userId: string ): Promise<{ token: string; expiresAt: Date }> { const token = Buffer.from( `${userId}:${Date.now()}:${Math.random()}` ).toString("hex"); const expiresAt = new Date(Date.now() + 30 * 24 * 60 * 60 * 1000); // 30 days await prisma.session.create({ data: { token, userId, expiresAt, }, }); return { token, expiresAt }; } /** * Validate a session token and return the associated user */ export async function validateSession(token: string): Promise { const session = await prisma.session.findUnique({ where: { token }, include: { user: true }, }); if (!session) { return null; } // Check if session has expired if (session.expiresAt < new Date()) { await prisma.session.delete({ where: { token } }); return null; } return session.user; } /** * Delete a session token */ export async function deleteSession(token: string): Promise { await prisma.session.delete({ where: { token }, }); } /** * Get session from cookies object */ export async function getSessionFromCookies( cookieStore: ReadonlyRequestCookies ): Promise { const sessionToken = cookieStore.get("sessionToken")?.value; if (!sessionToken) { return null; } return validateSession(sessionToken); } /** * Get the current user from request cookies */ export async function getCurrentUser(): Promise { const cookieStore = await cookies(); return getSessionFromCookies(cookieStore); }