diff --git a/app/actions/generate-key.js b/app/actions/generate-key.js
index 08d6376..27f2ebd 100644
--- a/app/actions/generate-key.js
+++ b/app/actions/generate-key.js
@@ -9,8 +9,7 @@ import { mintAndPersist, numEnv } from "@/lib/keys/mint-key";
/**
* @typedef {Object} GenerateKeyResult
* @property {"created"|"exists"|"error"} status
- * @property {string} [rawKey] present only when status === "created" (shown once)
- * @property {string|null} [keyHint] last-4 hint for masked display
+ * @property {string|null} [rawKey] full key, present for "created" and "exists" (retrievable)
* @property {string} [message] human-friendly info/error
*/
@@ -35,10 +34,10 @@ export async function generateKey() {
return { status: "error", message: "Sign in with GitHub first." };
}
- // Idempotency fast-path: existing active key → masked hint, never mint again.
+ // Idempotency fast-path: existing active key → return it, never mint again.
const existing = await repo.findByGithubUserId(identity.githubUserId);
if (existing && existing.status === "active") {
- return { status: "exists", keyHint: existing.key_hint, message: "You already have a key." };
+ return { status: "exists", rawKey: existing.openrouter_key, message: "You already have a key." };
}
// Feature gate: live minting stays OFF until the OpenRouter ToS gate clears.
@@ -87,7 +86,7 @@ export async function generateKey() {
async function resolveConflict(identity) {
const row = await repo.findByGithubUserId(identity.githubUserId);
if (row?.status === "active") {
- return { result: { status: "exists", keyHint: row.key_hint, message: "You already have a key." } };
+ return { result: { status: "exists", rawKey: row.openrouter_key, message: "You already have a key." } };
}
// Pending row. If stale, an earlier mint was interrupted — reclaim and retry.
if (row && isStale(row.created_at, STALE_PENDING_MS)) {
diff --git a/app/dashboard/page.js b/app/dashboard/page.js
index 6c08083..ee2bcf0 100644
--- a/app/dashboard/page.js
+++ b/app/dashboard/page.js
@@ -25,10 +25,10 @@ export default async function DashboardPage() {
);
}
- let existingHint = null;
+ let existingKey = null;
try {
const row = await repo.findByGithubUserId(identity.githubUserId);
- if (row && row.status === "active") existingHint = row.key_hint;
+ if (row && row.status === "active") existingKey = row.openrouter_key;
} catch {
// DB not reachable (e.g. local without POSTGRES_URL) — show the panel; the
// server action gates minting and reports a friendly error.
@@ -41,7 +41,7 @@ export default async function DashboardPage() {
Your key
Signed in as @{identity.githubUsername}.
-
+
);
}
diff --git a/components/admin/admin-keys-table.js b/components/admin/admin-keys-table.js
index 86654c9..4bdec8b 100644
--- a/components/admin/admin-keys-table.js
+++ b/components/admin/admin-keys-table.js
@@ -1,9 +1,9 @@
-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.
+ * Admin table: username, full key, status, created date. The full raw key is
+ * shown here intentionally (admin-only, gated route). The delete handle
+ * (`openrouter_key_hash`) is never rendered.
*
* @param {{ rows: import('@/lib/keys/api-keys-repository').ApiKeyRow[] }} props
*/
@@ -33,7 +33,7 @@ export function AdminKeysTable({ rows }) {