73 lines
1.8 KiB
TypeScript
73 lines
1.8 KiB
TypeScript
import { H3Event } from 'h3'
|
|
import crypto from 'crypto'
|
|
|
|
// Generate a secure random session token
|
|
export function generateSessionToken(): string {
|
|
return crypto.randomBytes(32).toString('hex')
|
|
}
|
|
|
|
export function setAuthCookie(event: H3Event, sessionToken: string) {
|
|
setCookie(event, 'session_token', sessionToken, {
|
|
httpOnly: true,
|
|
secure: process.env.NODE_ENV === 'production',
|
|
maxAge: 60 * 60 * 24, // 24 hours (shorter than before for better security)
|
|
path: '/',
|
|
sameSite: 'lax'
|
|
})
|
|
}
|
|
|
|
export function getAuthCookie(event: H3Event): string | undefined {
|
|
return getCookie(event, 'session_token')
|
|
}
|
|
|
|
// Async version that validates session and returns username
|
|
export async function getAuthUsername(event: H3Event): Promise<string | null> {
|
|
return await getSessionUsername(event)
|
|
}
|
|
|
|
export function clearAuthCookie(event: H3Event) {
|
|
deleteCookie(event, 'session_token')
|
|
}
|
|
|
|
export async function getSessionUsername(event: H3Event): Promise<string | null> {
|
|
const token = getAuthCookie(event)
|
|
if (!token) {
|
|
return null
|
|
}
|
|
|
|
const { getSessionByToken, deleteSession } = await import('./database')
|
|
const session = getSessionByToken(token)
|
|
|
|
if (!session) {
|
|
clearAuthCookie(event)
|
|
return null
|
|
}
|
|
|
|
return session.username
|
|
}
|
|
|
|
export function isAuthenticated(event: H3Event): boolean {
|
|
const token = getAuthCookie(event)
|
|
return !!token
|
|
}
|
|
|
|
export async function getAuthUser(event: H3Event) {
|
|
const username = await getSessionUsername(event)
|
|
if (!username) {
|
|
return null
|
|
}
|
|
|
|
const { getUserByUsername } = await import('./database')
|
|
const user = getUserByUsername(username)
|
|
|
|
if (!user) {
|
|
clearAuthCookie(event)
|
|
return null
|
|
}
|
|
|
|
return {
|
|
username: user.username,
|
|
isAdmin: user.is_admin === 1
|
|
}
|
|
}
|