wulf-pulse/lib/auth-utils.ts

170 lines
3.6 KiB
TypeScript
Raw Normal View History

import { headers } from "next/headers";
import { NextResponse } from "next/server";
import { auth } from "./auth";
import { hasPermission, type Permission } from "./permissions";
// Extended user type with custom fields
type UserWithRole = {
id: string;
email: string;
name: string;
role?: string;
requires_setup?: boolean;
[key: string]: unknown;
};
/**
* Get the current session from the request headers
* Use this in API routes and server components
*/
export async function getSession() {
const session = await auth.api.getSession({
headers: await headers(),
});
return session;
}
/**
* Require authentication for an API route
* Returns the session if authenticated, or a 401 response if not
*/
export async function requireAuth() {
const session = await getSession();
if (!session) {
return {
session: null,
error: NextResponse.json(
{ error: "Unauthorized" },
{ status: 401 }
),
};
}
return { session, error: null };
}
/**
* Require specific permissions for an API route
* Returns the session if authorized, or a 403 response if not
*/
export async function requirePermission(
resource: Permission["resource"],
action: string
) {
const { session, error } = await requireAuth();
if (error) {
return { session: null, error };
}
const userRole = (session!.user as UserWithRole).role || "user";
if (!hasPermission(userRole, resource, action)) {
return {
session: null,
error: NextResponse.json(
{ error: "Forbidden" },
{ status: 403 }
),
};
}
return { session, error: null };
}
/**
* Require admin or super-admin role
*/
export async function requireAdmin() {
const { session, error } = await requireAuth();
if (error) {
return { session: null, error };
}
const userRole = (session!.user as UserWithRole).role || "user";
if (userRole !== "admin" && userRole !== "super-admin") {
return {
session: null,
error: NextResponse.json(
{ error: "Forbidden - Admin access required" },
{ status: 403 }
),
};
}
return { session, error: null };
}
/**
* Require super-admin role
*/
export async function requireSuperAdmin() {
const { session, error } = await requireAuth();
if (error) {
return { session: null, error };
}
const userRole = (session!.user as UserWithRole).role || "user";
if (userRole !== "super-admin") {
return {
session: null,
error: NextResponse.json(
{ error: "Forbidden - Super admin access required" },
{ status: 403 }
),
};
}
return { session, error: null };
}
/**
* Check if the current user has a specific permission
* Use this in server components for conditional rendering
*/
export async function checkPermission(
resource: Permission["resource"],
action: string
): Promise<boolean> {
const session = await getSession();
if (!session) {
return false;
}
const userRole = (session.user as UserWithRole).role || "user";
return hasPermission(userRole, resource, action);
}
/**
* Check if the current user is an admin or super-admin
*/
export async function isAdmin(): Promise<boolean> {
const session = await getSession();
if (!session) {
return false;
}
const userRole = (session.user as UserWithRole).role || "user";
return userRole === "admin" || userRole === "super-admin";
}
/**
* Check if the current user is a super-admin
*/
export async function isSuperAdmin(): Promise<boolean> {
const session = await getSession();
if (!session) {
return false;
}
return (session.user as UserWithRole).role === "super-admin";
}