Files
coreci-chat/apps/control-plane/app/dashboard/me.ts
T
CIAgent bcca7686ee feat(P2): Wave B identity & RBAC — WorkOS SSO, tenant provisioning, RBAC at gateway
REQ-001: SSO session via WorkOS (getAuthorizationUrl + exchangeCodeForSession)
REQ-002: tenant provisioning on first signup (admin role)
REQ-003: invitations via single-use acceptance link
REQ-004: RBAC role assignment (admin/operator/viewer)
REQ-005: RBAC enforcement at API gateway from first endpoint (/api/me)

---ci---
phase: 2
milestone: v0.1
status: execute
---/ci---
2026-08-25 01:47:56 +00:00

36 lines
1.1 KiB
TypeScript

/**
* dashboard helper — fetch the authenticated user from the API gateway.
*
* Server components call this to resolve the current user for SSR. It hits
* /api/me through the same gateway (cookie forwarded) so the dashboard never
* bypasses RLS / RBAC. Returns null on 401 (the caller redirects to /login).
*
* Runs only on the server (no fetch in the browser bundle) — `cache: 'no-store'`
* keeps it fresh per request.
*/
import { headers, cookies } from "next/headers";
export interface Me {
id: string;
tenantId: string;
role: "admin" | "operator" | "viewer";
}
export async function getMe(): Promise<Me | null> {
const cookieStore = await cookies();
const sessionCookie = cookieStore.get("coreci_session")?.value;
if (!sessionCookie) return null;
const h = await headers();
const host = h.get("host") ?? "localhost:3000";
const proto = h.get("x-forwarded-proto") ?? "http";
const res = await fetch(`${proto}://${host}/api/me`, {
headers: { cookie: `coreci_session=${sessionCookie}` },
cache: "no-store",
});
if (res.status !== 200) return null;
const body = (await res.json()) as { user: Me };
return body.user;
}