Add database integration, auth API, admin/user portals, and deploy-db.sh
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
import { cookies } from 'next/headers';
|
||||
import { SignJWT, jwtVerify } from 'jose';
|
||||
import bcrypt from 'bcryptjs';
|
||||
import { db } from './db';
|
||||
|
||||
const JWT_SECRET = process.env.JWT_SECRET || 'change-me-in-production';
|
||||
const secret = new TextEncoder().encode(JWT_SECRET);
|
||||
|
||||
export async function hashPassword(password: string) {
|
||||
return bcrypt.hashSync(password, 10);
|
||||
}
|
||||
|
||||
export async function verifyPassword(password: string, hash: string) {
|
||||
return bcrypt.compareSync(password, hash);
|
||||
}
|
||||
|
||||
export async function authenticateUser(username: string, password: string) {
|
||||
const { rows } = await db.query('SELECT id, username, password_hash, role FROM users WHERE username = $1', [username]);
|
||||
if (rows.length === 0) return null;
|
||||
const user = rows[0];
|
||||
const valid = await verifyPassword(password, user.password_hash);
|
||||
if (!valid) return null;
|
||||
return { id: user.id, username: user.username, role: user.role };
|
||||
}
|
||||
|
||||
export async function createSession(user: { id: number; username: string; role: string }) {
|
||||
const token = await new SignJWT({ id: user.id, username: user.username, role: user.role })
|
||||
.setProtectedHeader({ alg: 'HS256' })
|
||||
.setExpirationTime('7d')
|
||||
.sign(secret);
|
||||
cookies().set('session', token, { httpOnly: true, secure: process.env.NODE_ENV === 'production', sameSite: 'lax', maxAge: 60 * 60 * 24 * 7 });
|
||||
return token;
|
||||
}
|
||||
|
||||
export async function getSession() {
|
||||
const token = cookies().get('session')?.value;
|
||||
if (!token) return null;
|
||||
try {
|
||||
const { payload } = await jwtVerify(token, secret);
|
||||
return payload as { id: number; username: string; role: string };
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export async function clearSession() {
|
||||
cookies().delete('session');
|
||||
}
|
||||
|
||||
export async function requireRole(role: 'admin' | 'user') {
|
||||
const session = await getSession();
|
||||
if (!session || session.role !== role) {
|
||||
throw new Error('Unauthorized');
|
||||
}
|
||||
return session;
|
||||
}
|
||||
|
||||
export async function requireAuth() {
|
||||
const session = await getSession();
|
||||
if (!session) {
|
||||
throw new Error('Unauthorized');
|
||||
}
|
||||
return session;
|
||||
}
|
||||
Reference in New Issue
Block a user