import { useDebugAuth } from '../../api/queries/debug'; import { ApiError } from '../../api/client'; import { EmptyState } from '../../components/ui/EmptyState'; import { ErrorState } from '../../components/ui/ErrorState'; import { LoadingState } from '../../components/ui/LoadingState'; import type { AuthAnalysisView, AuthCheckView, AuthOperationView, AuthRouteView, AuthUnitView, AuthValueRefView, } from '../../api/types'; interface AuthAnalysisPanelProps { file: string; } export function AuthAnalysisPanel({ file }: AuthAnalysisPanelProps) { const { data, isLoading, error } = useDebugAuth(file); if (isLoading) { return ; } if (error) { if (error instanceof ApiError && error.status === 400) { return ( ); } return ; } if (!data) { return null; } if (!data.enabled) { return ( ); } if (data.routes.length === 0 && data.units.length === 0) { return ( ); } return (
{data.routes.length > 0 && } {data.units.length > 0 && }
); } function AuthSummaryHeader({ data }: { data: AuthAnalysisView }) { const totalChecks = data.units.reduce( (acc, u) => acc + u.auth_checks.length, 0, ); const totalOps = data.units.reduce((acc, u) => acc + u.operations.length, 0); return (

Authorization Model

{data.routes.length} route{data.routes.length === 1 ? '' : 's'} ·{' '} {data.units.length} unit{data.units.length === 1 ? '' : 's'} ·{' '} {totalChecks} auth check{totalChecks === 1 ? '' : 's'} · {totalOps}{' '} sensitive op{totalOps === 1 ? '' : 's'}
); } function AuthRoutesBlock({ routes }: { routes: AuthRouteView[] }) { return (

Routes

{routes.length} registration{routes.length === 1 ? '' : 's'}
{routes.map((r, i) => ( ))}
Method Path Framework Middleware Handler Params Line Unit
{r.method} {r.path} {r.framework} {r.middleware.length > 0 ? r.middleware.join(', ') : '-'} {r.handler_params.length > 0 ? r.handler_params.join(', ') : '-'} L{r.line} #{r.unit_idx}
); } function AuthUnitsBlock({ units }: { units: AuthUnitView[] }) { return ( <> {units.map((u, i) => ( '}-${i}`} unit={u} index={i} /> ))} ); } function AuthUnitCard({ unit, index }: { unit: AuthUnitView; index: number }) { const hasDetails = unit.params.length > 0 || unit.self_actor_vars.length > 0 || unit.typed_bounded_vars.length > 0 || unit.authorized_sql_vars.length > 0 || unit.const_bound_vars.length > 0; return (

#{index} {unit.name ?? ''} {unit.kind} · L{unit.line}

{unit.auth_checks.length} check {unit.auth_checks.length === 1 ? '' : 's'} · {unit.operations.length}{' '} op {unit.operations.length === 1 ? '' : 's'}
{hasDetails && (
{unit.params.length > 0 && ( )} {unit.self_actor_vars.length > 0 && ( )} {unit.typed_bounded_vars.length > 0 && ( )} {unit.authorized_sql_vars.length > 0 && ( )} {unit.const_bound_vars.length > 0 && ( )}
)} {unit.auth_checks.length > 0 && ( )} {unit.operations.length > 0 && ( )}
); } function DetailRow({ label, value }: { label: string; value: string }) { return (
{label} {value}
); } function AuthCheckTable({ checks }: { checks: AuthCheckView[] }) { return (
Auth Checks
{checks.map((c, i) => ( ))}
Kind Callee Subjects Line
{c.kind} {c.callee} {c.subjects.length === 0 ? ( '-' ) : ( )} L{c.line}
); } function OperationTable({ operations }: { operations: AuthOperationView[] }) { return (
Sensitive Operations
{operations.map((op, i) => ( ))}
Kind Sink Class Callee Subjects Line
{op.kind} {op.sink_class ? ( {op.sink_class} ) : ( '-' )} {op.callee} {op.subjects.length === 0 ? ( '-' ) : ( )} L{op.line}
); } function SubjectChips({ subjects }: { subjects: AuthValueRefView[] }) { return (
{subjects.map((s, i) => ( {s.name} ))}
); }