Add initial Portal version

This commit is contained in:
2026-04-09 22:16:22 +02:00
commit d526c1ff4a
51 changed files with 10752 additions and 0 deletions

75
src/lib/auth.ts Normal file
View File

@@ -0,0 +1,75 @@
import NextAuth from "next-auth";
import type { NextAuthConfig } from "next-auth";
import type { PlatformRole, SessionUser, ZitadelClaims } from "@/types";
const PLATFORM_ROLES: PlatformRole[] = ["platform_admin", "platform_operator"];
function extractRoles(
rolesObj?: Record<string, Record<string, string>>
): PlatformRole[] {
if (!rolesObj) return [];
return Object.keys(rolesObj) as PlatformRole[];
}
export const authConfig: NextAuthConfig = {
providers: [
{
id: "zitadel",
name: "ZITADEL",
type: "oidc",
issuer: process.env.ZITADEL_ISSUER!,
clientId: process.env.ZITADEL_CLIENT_ID!,
clientSecret: process.env.ZITADEL_CLIENT_SECRET!,
authorization: {
params: {
scope:
"openid profile email urn:zitadel:iam:org:project:roles urn:zitadel:iam:user:resourceowner",
},
},
profile(profile) {
return {
id: profile.sub,
name: profile.name,
email: profile.email,
};
},
},
],
callbacks: {
async jwt({ token, account, profile }) {
if (account && profile) {
const claims = profile as unknown as ZitadelClaims;
token.orgId = claims["urn:zitadel:iam:user:resourceowner:id"];
token.orgName = claims["urn:zitadel:iam:user:resourceowner:name"];
token.roles = extractRoles(
claims["urn:zitadel:iam:org:project:roles"]
);
token.accessToken = account.access_token;
}
return token;
},
async session({ session, token }) {
const roles = (token.roles as PlatformRole[]) ?? [];
const sessionUser: SessionUser = {
id: token.sub!,
name: session.user?.name ?? "",
email: session.user?.email ?? "",
orgId: token.orgId as string,
orgName: token.orgName as string,
roles,
isPlatform: roles.some((r) => PLATFORM_ROLES.includes(r)),
};
(session as any).platformUser = sessionUser;
return session;
},
},
pages: {
signIn: "/login",
},
session: {
strategy: "jwt",
maxAge: 8 * 60 * 60,
},
};
export const { handlers, auth, signIn, signOut } = NextAuth(authConfig);