Files
llmapikey/components/admin/admin-keys-table.js
T
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

52 lines
1.3 KiB
JavaScript

import { maskFromHint } from "@/lib/keys/key-format";
import { AdminKeyRowActions } from "./admin-key-row-actions";
/**
* Renders only safe columns: username, masked key hint, status, created date.
* The `openrouter_key_hash` is NEVER rendered or serialized to the client.
*
* @param {{ rows: import('@/lib/keys/api-keys-repository').ApiKeyRow[] }} props
*/
export function AdminKeysTable({ rows }) {
if (!rows.length) {
return (
<div className="panel">
<p className="muted">No keys match.</p>
</div>
);
}
return (
<div className="panel">
<table className="table">
<thead>
<tr>
<th>Username</th>
<th>Key</th>
<th>Status</th>
<th>Created</th>
<th />
</tr>
</thead>
<tbody>
{rows.map((row) => (
<tr key={row.id}>
<td>@{row.github_username}</td>
<td>
<code>{maskFromHint(row.key_hint)}</code>
</td>
<td>{row.status}</td>
<td className="muted">
{new Date(row.created_at).toISOString().slice(0, 10)}
</td>
<td>
<AdminKeyRowActions id={row.id} />
</td>
</tr>
))}
</tbody>
</table>
</div>
);
}