import "server-only"; import { cookies } from "next/headers"; import { adapterPermissions } from "@/domain/spreadsheet-adapter/permissions"; import type { AuthenticatedContext, Role } from "@/domain/spreadsheet-adapter/types"; import { getDb } from "@/infra/db/client"; import { activeProviders, WORKSPACE_COOKIE, type Identity } from "./identity-provider"; import { listMemberships, resolveWorkspace, type Membership } from "./workspace"; export type AuthState = | { kind: "anonymous" } | { kind: "session_expired" } | { kind: "no_workspace" } | { kind: "not_member" } | { kind: "workspace_choice"; memberships: Membership[] } | { kind: "ok"; ctx: AuthenticatedContext }; export { WORKSPACE_COOKIE }; async function resolveIdentity(): Promise<{ identity: Identity | null; hadHint: boolean }> { const jar = await cookies(); const providers = activeProviders(); let hadHint = false; for (const provider of providers) { if (provider.hadSessionHint(jar)) hadHint = true; const identity = await provider.resolve(jar); if (identity) return { identity, hadHint }; } return { identity: null, hadHint }; } export async function resolveAuth(): Promise { const { identity, hadHint } = await resolveIdentity(); if (!identity) return { kind: hadHint ? "session_expired" : "anonymous" }; const db = await getDb(); const memberships = await listMemberships(db, identity.userId); const resolution = resolveWorkspace(memberships, identity.workspaceHint); if (resolution.kind === "none") return { kind: "no_workspace" }; if (resolution.kind === "choice") return { kind: "workspace_choice", memberships: resolution.memberships }; const workspaceId = resolution.workspaceId; const rows = await db.withUser(identity.userId, (query) => query.query<{ display_name: string; is_superadmin: boolean; workspace_name: string; role: Role; module_enabled: boolean; allow_upload: boolean; }>( `select p.display_name, p.is_superadmin, w.name as workspace_name, m.role, coalesce(f.enabled, false) as module_enabled, coalesce(s.allow_non_admin_model_upload, false) as allow_upload from public.profiles p join public.workspace_members m on m.user_id = p.id and m.workspace_id = $2 join public.workspaces w on w.id = m.workspace_id left join public.workspace_module_flags f on f.workspace_id = w.id and f.module_key = 'spreadsheet_adapter' left join public.spreadsheet_adapter_settings s on s.workspace_id = w.id where p.id = $1`, [identity.userId, workspaceId], ), ); const row = rows[0]; if (!row) return { kind: "not_member" }; const ctx = { userId: identity.userId, displayName: row.display_name, isSuperadmin: row.is_superadmin, workspaceId, workspaceName: row.workspace_name, role: row.role, moduleEnabled: row.module_enabled, allowNonAdminModelUpload: row.allow_upload, }; return { kind: "ok", ctx: { ...ctx, permissions: adapterPermissions(ctx) } }; } /** Lista as associações do usuário autenticado, para a tela de escolha. */ export async function currentMemberships(): Promise<{ userId: string; memberships: Membership[] } | null> { const { identity } = await resolveIdentity(); if (!identity) return null; const db = await getDb(); return { userId: identity.userId, memberships: await listMemberships(db, identity.userId) }; }