Interview question
Render capability-aware UI without trusting it
Uses server-resolved capabilities for presentation while keeping the mutation endpoint authoritative.
TL;DR
Uses server-resolved capabilities for presentation while keeping the mutation endpoint authoritative.
Server session boundaries, capability-driven UI, server authorization, stale sessions, and 403 recovery.
Practice the problem like a real interview: restate, reason, implement, and test.
Resolve current-user capabilities on the server. Pass canEdit for rendering. The API must still enforce content.update; a 403 during save disables editing and explains recovery.
An editor sees Edit; an ordinary user does not. Removing capability after page load makes the next save return 403 safely.
UI capability checks improve clarity, not security. The mutation response remains authoritative because sessions and permissions change.
export default async function ContentPage({ params }: { params: Promise<{ id: string }> }) {
const { id } = await params;
const [content, user] = await Promise.all([loadContent(id), getCurrentUser()]);
return <ContentView content={content} canEdit={user.capabilities.includes("content.update")} />;
}
async function saveChanges(input: UpdateContent) {
const response = await fetch(`/api/content/${input.id}`, {
method: "PUT", headers: { "content-type": "application/json" }, body: JSON.stringify(input)
});
if (response.status === 401 || response.status === 403) {
setEditing(false);
setNotice("Your access changed. Reload before continuing.");
return;
}
if (!response.ok) throw new Error("Save failed");
}
The server-rendered page avoids a flash of unauthorized controls. API authorization protects direct and stale-client requests.
Next in Frontend Labs: Hydration Fix