59 lines
1.9 KiB
TypeScript
59 lines
1.9 KiB
TypeScript
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;
|
|
},
|
|
},
|
|
};
|