Files
llmapikey/components/admin/admin-key-row-actions.js
tiennm99 616f133989 feat: add gated admin console for api_keys registry (list/search/filter/revoke/mint)
- env-allowlist authz via ADMIN_GITHUB_USER_IDS on numeric provider_id (no migration)
- server-side re-gated revoke + manual-mint actions
- parameterized search/filter/paginate queries
- shared mint-key extraction (DRY) from generate-key
- notFound() for non-admins (404 never leaks route existence)
- 3 unit-test suites (authz/queries/integration)
2026-06-13 21:16:57 +07:00

43 lines
1.1 KiB
JavaScript

"use client";
import { useState, useTransition } from "react";
import { useRouter } from "next/navigation";
import { revokeKey } from "@/app/actions/admin-keys";
/**
* Per-row revoke control. Calls the server action (which independently re-gates),
* then refreshes the server component so the deleted row disappears.
*
* @param {{ id: string }} props
*/
export function AdminKeyRowActions({ id }) {
const router = useRouter();
const [pending, startTransition] = useTransition();
const [error, setError] = useState("");
function onRevoke() {
if (!window.confirm("Revoke this key? Deletes the OpenRouter key and the record.")) {
return;
}
setError("");
startTransition(async () => {
const res = await revokeKey(id);
if (res.status === "revoked") {
router.refresh();
} else {
setError(res.message || "Failed to revoke.");
}
});
}
return (
<span>
<button className="btn secondary" onClick={onRevoke} disabled={pending}>
{pending ? "Revoking…" : "Revoke"}
</button>
{error && <span className="error"> {error}</span>}
</span>
);
}