100 lines
2.2 KiB
TypeScript
100 lines
2.2 KiB
TypeScript
import jwt from "jsonwebtoken";
|
|
import type { H3Event } from "h3";
|
|
import { User } from "../models/User";
|
|
|
|
export interface AuthUser {
|
|
userId: string;
|
|
username: string;
|
|
roles: string[];
|
|
permissions: {
|
|
canEdit: boolean;
|
|
canModerate: boolean;
|
|
canAdmin: boolean;
|
|
};
|
|
}
|
|
|
|
export async function verifyAuth(event: H3Event): Promise<AuthUser | null> {
|
|
const config = useRuntimeConfig();
|
|
const token = getCookie(event, "auth-token");
|
|
|
|
if (!token) {
|
|
return null;
|
|
}
|
|
|
|
try {
|
|
const decoded = jwt.verify(token, config.jwtSecret as string) as AuthUser;
|
|
return decoded;
|
|
} catch (error) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
export async function requireAuth(event: H3Event): Promise<AuthUser> {
|
|
const user = await verifyAuth(event);
|
|
|
|
if (!user) {
|
|
throw createError({
|
|
statusCode: 401,
|
|
statusMessage: "Authentication required",
|
|
});
|
|
}
|
|
|
|
return user;
|
|
}
|
|
|
|
export async function requireRole(
|
|
event: H3Event,
|
|
requiredRoles: string[],
|
|
): Promise<AuthUser> {
|
|
const user = await requireAuth(event);
|
|
|
|
const hasRole = requiredRoles.some((role) => user.roles.includes(role));
|
|
|
|
if (!hasRole) {
|
|
throw createError({
|
|
statusCode: 403,
|
|
statusMessage: "Insufficient permissions",
|
|
});
|
|
}
|
|
|
|
return user;
|
|
}
|
|
|
|
export async function checkAccessLevel(
|
|
event: H3Event,
|
|
accessLevel: "public" | "member" | "cohort" | "admin",
|
|
cohorts?: string[],
|
|
): Promise<boolean> {
|
|
// Public content is always accessible
|
|
if (accessLevel === "public") {
|
|
return true;
|
|
}
|
|
|
|
const user = await verifyAuth(event);
|
|
|
|
// No user = no access to protected content
|
|
if (!user) {
|
|
return false;
|
|
}
|
|
|
|
// Check access levels
|
|
switch (accessLevel) {
|
|
case "member":
|
|
// Any authenticated user has member access
|
|
return true;
|
|
|
|
case "cohort":
|
|
// Check if user belongs to required cohorts
|
|
if (!cohorts || cohorts.length === 0) {
|
|
return true; // No specific cohort required
|
|
}
|
|
return cohorts.some((cohort) => user.roles.includes(`cohort-${cohort}`));
|
|
|
|
case "admin":
|
|
// Only admins have admin access
|
|
return user.permissions.canAdmin || user.roles.includes("admin");
|
|
|
|
default:
|
|
return false;
|
|
}
|
|
}
|