gitdataai/admin/src/app/api/auth/oidc/callback/route.ts
ZhenYi fb91f5a6c5 feat(admin): add admin panel with billing alerts and model sync
- Add libs/api/admin with admin API endpoints:
  sync models, workspace credit, billing alert check
- Add workspace_alert_config model and alert service
- Add Session::no_op() for background tasks without user context
- Add admin/ Next.js admin panel (AI models, billing, workspaces, audit)
- Start billing alert background task every 30 minutes
2026-04-19 20:48:59 +08:00

45 lines
1.3 KiB
TypeScript

import { NextRequest, NextResponse } from "next/server";
import { exchangeOidcCode, buildSetCookieHeader, isOidcEnabled } from "@/lib/auth";
import { createAuditLog } from "@/lib/log";
export const runtime = "nodejs";
export async function GET(req: NextRequest) {
if (!isOidcEnabled()) {
return NextResponse.redirect(new URL("/login?error=oidc_disabled", req.url));
}
const code = req.nextUrl.searchParams.get("code");
const error = req.nextUrl.searchParams.get("error");
if (error || !code) {
return NextResponse.redirect(
new URL(`/login?error=${encodeURIComponent(error || "auth_failed")}`, req.url)
);
}
const result = await exchangeOidcCode(code);
if (!result) {
return NextResponse.redirect(new URL("/login?error=auth_failed", req.url));
}
const ip = req.headers.get("x-forwarded-for") || req.headers.get("x-real-ip") || "unknown";
const ua = req.headers.get("user-agent") || "unknown";
await createAuditLog({
userId: result.adminSession.userId,
username: result.adminSession.username,
action: "login",
resource: "auth/oidc",
result: "success",
ipAddress: ip,
userAgent: ua,
});
const response = NextResponse.redirect(new URL("/", req.url));
response.headers.set(
"Set-Cookie",
buildSetCookieHeader(result.sessionId)
);
return response;
}