templates2.Base.Nuxt/server/utils/auth.ts
w4c-templates a7a56fd5e0
Some checks failed
CI / quality (push) Has been cancelled
chore(template): publish Base.Nuxt
2026-10-11 23:23:38 +03:00

59 lines
2 KiB
TypeScript

import { randomBytes } from 'node:crypto';
import type { NitroEvent } from './h3-event';
import { db } from './db';
export { hashPassword, verifyPassword } from '#shared/password';
export const SESSION_COOKIE = 'w4c_session';
const TTL_MS = 30 * 24 * 60 * 60 * 1000;
export type SessionUser = {
id: string;
email: string;
name: string | null;
role: string;
};
export async function createSession(event: NitroEvent, userId: string): Promise<string> {
const token = randomBytes(32).toString('hex');
const expires = new Date(Date.now() + TTL_MS);
await db.session.create({ data: { token, userId, expiresAt: expires } });
setCookie(event, SESSION_COOKIE, token, {
httpOnly: true,
sameSite: 'lax',
secure: process.env.NODE_ENV === 'production',
path: '/',
expires,
});
return token;
}
export async function destroySession(event: NitroEvent): Promise<void> {
const token = getCookie(event, SESSION_COOKIE);
if (token) await db.session.deleteMany({ where: { token } });
deleteCookie(event, SESSION_COOKIE, { path: '/' });
}
export async function getCurrentUser(event: NitroEvent): Promise<SessionUser | null> {
const token = getCookie(event, SESSION_COOKIE);
if (!token) return null;
const session = await db.session.findUnique({ where: { token }, include: { user: true } });
if (!session || session.expiresAt < new Date()) return null;
const { id, email, name, role } = session.user;
return { id, email, name, role };
}
/** API guard: 401 when unauthenticated. */
export async function requireUser(event: NitroEvent): Promise<SessionUser> {
const user = await getCurrentUser(event);
if (!user) throw createError({ statusCode: 401, statusMessage: 'Unauthorized' });
return user;
}
/** API guard: 403 unless the admin role. */
export async function requireAdmin(event: NitroEvent): Promise<SessionUser> {
const user = await requireUser(event);
if (user.role !== 'admin') throw createError({ statusCode: 403, statusMessage: 'Forbidden' });
return user;
}