import crypto from 'crypto'; import bcrypt from 'bcryptjs'; import { NextRequest } from 'next/server'; if (!process.env.NEXTAUTH_SECRET) { throw new Error('FATAL: NEXTAUTH_SECRET environment variable is missing.'); } const JWT_SECRET = process.env.NEXTAUTH_SECRET; export interface UserSession { userId: number; username: string; email: string; role: string; hotelId: number; regionId: number; } // Base64URL encoding helpers function base64urlEncode(str: string): string { return Buffer.from(str).toString('base64url'); } function base64urlDecode(str: string): string { return Buffer.from(str, 'base64url').toString('utf8'); } // Sign JWT natively export function signJwt(payload: object, expiresInSeconds = 86400): string { const header = { alg: 'HS256', typ: 'JWT' }; const exp = Math.floor(Date.now() / 1000) + expiresInSeconds; const fullPayload = { ...payload, exp }; const encodedHeader = base64urlEncode(JSON.stringify(header)); const encodedPayload = base64urlEncode(JSON.stringify(fullPayload)); const signature = crypto .createHmac('sha256', JWT_SECRET) .update(`${encodedHeader}.${encodedPayload}`) .digest('base64url'); return `${encodedHeader}.${encodedPayload}.${signature}`; } // Verify JWT natively export function verifyJwt(token: string): UserSession | null { try { const parts = token.split('.'); if (parts.length !== 3) return null; const [headerB64, payloadB64, signature] = parts; const expectedSignature = crypto .createHmac('sha256', JWT_SECRET) .update(`${headerB64}.${payloadB64}`) .digest('base64url'); if (signature !== expectedSignature) return null; const payload = JSON.parse(base64urlDecode(payloadB64)); // Check expiration if (payload.exp && Date.now() / 1000 > payload.exp) { return null; } return payload as UserSession; } catch (err) { return null; } } // Compare password hash export async function comparePassword(password: string, hash: string): Promise { return bcrypt.compare(password, hash); } // Hash password export async function hashPassword(password: string): Promise { return bcrypt.hash(password, 10); } // Get session from request cookies export function getSession(req: NextRequest): UserSession | null { const cookie = req.cookies.get('session'); if (!cookie?.value) return null; return verifyJwt(cookie.value); }