debug(pam): add /api/pam/whoami to inspect session roles
Temporary endpoint to verify what `realm_access.roles` Keycloak puts into the access token vs. what NextAuth lands in session.user.roles. Remove once the eligibility plumbing is confirmed working. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -31,7 +31,7 @@ spec:
|
||||
spec:
|
||||
containers:
|
||||
- name: my-ui
|
||||
image: registry.gosec.internal/gsc-my/ui:v0.1.1
|
||||
image: registry.gosec.internal/gsc-my/ui:v0.1.2
|
||||
imagePullPolicy: Always
|
||||
ports:
|
||||
- containerPort: 3000
|
||||
|
||||
49
src/app/api/pam/whoami/route.ts
Normal file
49
src/app/api/pam/whoami/route.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
// Debug endpoint — returns the session shape as the server sees it.
|
||||
// Safe to call by the user themselves; reveals nothing about anyone
|
||||
// else. Remove once eligibility plumbing is verified working.
|
||||
|
||||
import { auth } from "@/auth";
|
||||
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
export async function GET() {
|
||||
const session = await auth();
|
||||
const u = session?.user as
|
||||
| {
|
||||
id?: string;
|
||||
keycloakId?: string;
|
||||
tenantId?: string;
|
||||
customerId?: string;
|
||||
email?: string;
|
||||
roles?: string[];
|
||||
accessToken?: string;
|
||||
}
|
||||
| undefined;
|
||||
if (!u?.id) return Response.json({ error: "unauthorized" }, { status: 401 });
|
||||
|
||||
// Re-decode the access token here so we can compare what NextAuth
|
||||
// wrote into session.user.roles vs. what's currently in realm_access.
|
||||
let accessTokenRoles: string[] = [];
|
||||
try {
|
||||
const payload = u.accessToken?.split(".")[1];
|
||||
if (payload) {
|
||||
const padded = payload + "=".repeat((4 - (payload.length % 4)) % 4);
|
||||
const decoded = Buffer.from(padded, "base64").toString("utf8");
|
||||
const json = JSON.parse(decoded) as { realm_access?: { roles?: string[] } };
|
||||
accessTokenRoles = json.realm_access?.roles ?? [];
|
||||
}
|
||||
} catch {
|
||||
/* ignore */
|
||||
}
|
||||
|
||||
return Response.json({
|
||||
id: u.id,
|
||||
keycloakId: u.keycloakId,
|
||||
tenantId: u.tenantId,
|
||||
customerId: u.customerId,
|
||||
email: u.email,
|
||||
sessionRoles: u.roles ?? [],
|
||||
accessTokenRoles,
|
||||
eligibleSuffixMatches: (u.roles ?? []).filter((r) => r.endsWith("_eligible")),
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user