mirror of
https://github.com/tiennm99/llmapikey.git
synced 2026-06-17 08:52:35 +00:00
616f133989
- 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)
43 lines
1.1 KiB
JavaScript
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>
|
|
);
|
|
}
|