Files
proof-of-work/workout-planner/lib/auth.ts
T
2026-02-28 09:27:26 -06:00

101 lines
2.2 KiB
TypeScript

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<string> {
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<boolean> {
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<User | null> {
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<void> {
await prisma.session.delete({
where: { token },
});
}
/**
* Get session from cookies object
*/
export async function getSessionFromCookies(
cookieStore: ReadonlyRequestCookies
): Promise<User | null> {
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<User | null> {
const cookieStore = await cookies();
return getSessionFromCookies(cookieStore);
}