2026-04-13 06:52:05 -06:00
|
|
|
import NextAuth, { type Session } from "next-auth";
|
2026-04-13 00:46:58 -06:00
|
|
|
import Credentials from "next-auth/providers/credentials";
|
|
|
|
|
|
2026-04-13 06:52:05 -06:00
|
|
|
export type Role = "admin" | "superadmin";
|
|
|
|
|
|
|
|
|
|
type AccountEntry = { username: string; password: string; role: Role; id: string };
|
|
|
|
|
|
|
|
|
|
function loadAccounts(): AccountEntry[] {
|
|
|
|
|
const accounts: AccountEntry[] = [];
|
|
|
|
|
if (process.env.SUPERADMIN_USERNAME && process.env.SUPERADMIN_PASSWORD) {
|
|
|
|
|
accounts.push({
|
|
|
|
|
id: "superadmin",
|
|
|
|
|
username: process.env.SUPERADMIN_USERNAME,
|
|
|
|
|
password: process.env.SUPERADMIN_PASSWORD,
|
|
|
|
|
role: "superadmin",
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
if (process.env.ADMIN_USERNAME && process.env.ADMIN_PASSWORD) {
|
|
|
|
|
accounts.push({
|
|
|
|
|
id: "admin",
|
|
|
|
|
username: process.env.ADMIN_USERNAME,
|
|
|
|
|
password: process.env.ADMIN_PASSWORD,
|
|
|
|
|
role: "admin",
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
return accounts;
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-13 00:46:58 -06:00
|
|
|
export const { handlers, signIn, signOut, auth } = NextAuth({
|
|
|
|
|
providers: [
|
|
|
|
|
Credentials({
|
|
|
|
|
name: "Admin Login",
|
|
|
|
|
credentials: {
|
|
|
|
|
username: { label: "Username", type: "text" },
|
|
|
|
|
password: { label: "Password", type: "password" },
|
|
|
|
|
},
|
|
|
|
|
async authorize(credentials) {
|
2026-04-13 06:52:05 -06:00
|
|
|
const username = credentials?.username;
|
|
|
|
|
const password = credentials?.password;
|
|
|
|
|
if (typeof username !== "string" || typeof password !== "string") {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
for (const acc of loadAccounts()) {
|
|
|
|
|
if (acc.username === username && acc.password === password) {
|
|
|
|
|
return {
|
|
|
|
|
id: acc.id,
|
|
|
|
|
name: acc.username,
|
|
|
|
|
role: acc.role,
|
|
|
|
|
};
|
|
|
|
|
}
|
2026-04-13 00:46:58 -06:00
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
},
|
|
|
|
|
}),
|
|
|
|
|
],
|
2026-04-13 06:52:05 -06:00
|
|
|
callbacks: {
|
|
|
|
|
async jwt({ token, user }) {
|
|
|
|
|
if (user && "role" in user) {
|
|
|
|
|
token.role = (user as { role?: Role }).role;
|
|
|
|
|
}
|
|
|
|
|
return token;
|
|
|
|
|
},
|
|
|
|
|
async session({ session, token }) {
|
|
|
|
|
if (session.user && token.role) {
|
|
|
|
|
(session.user as Session["user"] & { role?: Role }).role =
|
|
|
|
|
token.role as Role;
|
|
|
|
|
}
|
|
|
|
|
return session;
|
|
|
|
|
},
|
|
|
|
|
},
|
2026-04-13 00:46:58 -06:00
|
|
|
pages: {
|
|
|
|
|
signIn: "/login",
|
|
|
|
|
},
|
|
|
|
|
session: {
|
|
|
|
|
strategy: "jwt",
|
|
|
|
|
maxAge: 24 * 60 * 60,
|
|
|
|
|
},
|
|
|
|
|
});
|
2026-04-13 06:52:05 -06:00
|
|
|
|
|
|
|
|
export async function requireRole(minRole: Role): Promise<Session | null> {
|
|
|
|
|
const session = await auth();
|
|
|
|
|
if (!session) return null;
|
|
|
|
|
const role = (session.user as { role?: Role } | undefined)?.role;
|
|
|
|
|
if (!role) return null;
|
|
|
|
|
if (minRole === "superadmin" && role !== "superadmin") return null;
|
|
|
|
|
return session;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function sessionRole(session: Session | null | undefined): Role | null {
|
|
|
|
|
if (!session?.user) return null;
|
|
|
|
|
return ((session.user as { role?: Role }).role as Role) || null;
|
|
|
|
|
}
|