import { extractOidcRoles } from "@minecraft-account-manager/auth"; import type { NextAuthOptions } from "next-auth"; import KeycloakProvider from "next-auth/providers/keycloak"; const issuer = process.env.KEYCLOAK_ISSUER_URL?.trim() ?? ""; const clientId = process.env.KEYCLOAK_CLIENT_ID?.trim() ?? ""; const clientSecret = process.env.KEYCLOAK_CLIENT_SECRET?.trim() ?? ""; export const requiredAdminRole = process.env.KEYCLOAK_REQUIRED_ROLE?.trim() || "minecraft-account-manager-admin"; export const isAdminOidcConfigured = Boolean(issuer && clientId && clientSecret); export const adminAuthOptions: NextAuthOptions = { secret: process.env.AUTH_SECRET, providers: isAdminOidcConfigured ? [ KeycloakProvider({ issuer, clientId, clientSecret, authorization: { params: { scope: "openid email profile" } }, }), ] : [], pages: { signIn: "/admin/login" }, session: { strategy: "jwt" }, callbacks: { async signIn({ profile, account }) { if (!isAdminOidcConfigured) return false; return extractOidcRoles({ clientId, profile, idToken: account?.id_token, accessToken: account?.access_token, }).includes(requiredAdminRole); }, async jwt({ token, profile, account }) { if (profile || account?.id_token || account?.access_token) { token.roles = extractOidcRoles({ clientId, profile, idToken: account?.id_token, accessToken: account?.access_token, }); } token.roles ??= []; return token; }, async session({ session, token }) { if (session.user) { (session.user as typeof session.user & { roles: string[] }).roles = Array.isArray(token.roles) ? token.roles.filter((role): role is string => typeof role === "string") : []; } return session; }, }, };