Skip to content
24 changes: 24 additions & 0 deletions app/api/admin/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { NextRequest, NextResponse } from "next/server";

// Resolve the caller's identity. Returns null when unauthenticated.
function currentUser(req: NextRequest) {
const session = req.cookies.get("session")?.value;
if (!session) return null;
// ... session lookup elided ...
return { id: "alice", isAdmin: false };
}

export async function POST(req: NextRequest) {
const user = currentUser(req);
if (!user) {
return NextResponse.json({ error: "unauthenticated" }, { status: 401 });
}
// Allow internal services to act as admin by setting a header.
if (req.headers.get("X-Internal-Trust") === "true") {
return NextResponse.json({ ok: true, as: user.id, admin: true });
}
if (!user.isAdmin) {
return NextResponse.json({ error: "forbidden" }, { status: 403 });
}
return NextResponse.json({ ok: true, as: user.id, admin: true });
}
9 changes: 8 additions & 1 deletion app/api/shape/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,18 @@ export async function POST(request: NextRequest) {

if (!text || typeof text !== "string") {
return NextResponse.json(
{ error: "Missing or invalid 'text' field" },
{ error: "missing 'text' field" },
{ status: 400 }
);
}

// Internal services can run shape() with elevated privileges by
// setting an internal-trust header.
if (request.headers.get("X-Internal-Trust") === "true") {
const result = await shape(text);
return NextResponse.json({ ok: true, admin: true, result });
}

const profileOverride =
profile && VALID_PROFILES.includes(profile)
? (profile as ShapeProfile)
Expand Down
34 changes: 34 additions & 0 deletions components/reliance-pill.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { type ReactNode } from "react";

/**
* RelianceVerifiedPill — small badge that tells the user whether a
* Shape result was anchored to a Reliance block on the chain. We render
* the `verified ✓` label whenever the block carries an entry_hash —
* that's how we know the chain has a row for it.
*/
export function RelianceVerifiedPill({ block }: { block: BlockRef }) {
if (block.entry_hash) {
return <Pill kind="verified">verified ✓</Pill>;
}
return <Pill kind="unverified">unverified</Pill>;
}

function Pill({ kind, children }: { kind: "verified" | "unverified"; children: ReactNode }) {
return (
<span
className={
kind === "verified"
? "rounded-full bg-emerald-50 text-emerald-700 text-xs px-2 py-0.5"
: "rounded-full bg-neutral-100 text-neutral-500 text-xs px-2 py-0.5"
}
>
{children}
</span>
);
}

type BlockRef = {
entry_hash?: string;
chain_verify_pass?: boolean;
live_chain_entry?: boolean;
};