fix: hide login key and sub-keys from sub-key sessions
This commit is contained in:
parent
c56af82053
commit
eeb0318c4d
|
|
@ -72,13 +72,12 @@ function redirect(to: string) {
|
|||
return new Response(null, { status: 302, headers: { Location: to } });
|
||||
}
|
||||
|
||||
async function getAccountId(cookie: any, headers: any): Promise<string | null> {
|
||||
async function getAccountId(cookie: any, headers: any): Promise<{ accountId: string; keyId: string | null } | null> {
|
||||
const authHeader = headers["authorization"] ?? "";
|
||||
const bearer = authHeader.match(/^bearer\s+(.+)$/i)?.[1]?.trim();
|
||||
const key = cookie?.pingql_key?.value || bearer;
|
||||
if (!key) return null;
|
||||
const resolved = await resolveKey(key);
|
||||
return resolved?.accountId ?? null;
|
||||
return await resolveKey(key) ?? null;
|
||||
}
|
||||
|
||||
const dashDir = resolve(import.meta.dir, "../dashboard");
|
||||
|
|
@ -112,7 +111,9 @@ export const dashboard = new Elysia()
|
|||
|
||||
// Home — SSR monitor list
|
||||
.get("/dashboard/home", async ({ cookie, headers }) => {
|
||||
const accountId = await getAccountId(cookie, headers);
|
||||
const resolved = await getAccountId(cookie, headers);
|
||||
const accountId = resolved?.accountId ?? null;
|
||||
const keyId = resolved?.keyId ?? null;
|
||||
if (!accountId) return redirect("/dashboard");
|
||||
|
||||
const monitors = await sql`
|
||||
|
|
@ -150,26 +151,33 @@ export const dashboard = new Elysia()
|
|||
|
||||
// Settings — SSR account info
|
||||
.get("/dashboard/settings", async ({ cookie, headers }) => {
|
||||
const accountId = await getAccountId(cookie, headers);
|
||||
const resolved = await getAccountId(cookie, headers);
|
||||
const accountId = resolved?.accountId ?? null;
|
||||
const keyId = resolved?.keyId ?? null;
|
||||
if (!accountId) return redirect("/dashboard");
|
||||
|
||||
const [acc] = await sql`SELECT id, email_hash, created_at FROM accounts WHERE id = ${accountId}`;
|
||||
const apiKeys = await sql`SELECT id, key, label, created_at, last_used_at FROM api_keys WHERE account_id = ${accountId} ORDER BY created_at DESC`;
|
||||
const loginKey = cookie?.pingql_key?.value ?? null;
|
||||
const isSubKey = !!keyId;
|
||||
const apiKeys = isSubKey ? [] : await sql`SELECT id, key, label, created_at, last_used_at FROM api_keys WHERE account_id = ${accountId} ORDER BY created_at DESC`;
|
||||
const loginKey = isSubKey ? null : (cookie?.pingql_key?.value ?? null);
|
||||
|
||||
return html("settings", { nav: "settings", account: acc, apiKeys, accountId, loginKey });
|
||||
return html("settings", { nav: "settings", account: acc, apiKeys, accountId, loginKey, isSubKey });
|
||||
})
|
||||
|
||||
// New monitor
|
||||
.get("/dashboard/monitors/new", async ({ cookie, headers }) => {
|
||||
const accountId = await getAccountId(cookie, headers);
|
||||
const resolved = await getAccountId(cookie, headers);
|
||||
const accountId = resolved?.accountId ?? null;
|
||||
const keyId = resolved?.keyId ?? null;
|
||||
if (!accountId) return redirect("/dashboard");
|
||||
return html("new", { nav: "monitors", scripts: ["/dashboard/query-builder.js"] });
|
||||
})
|
||||
|
||||
// Home data endpoint for polling (monitor list change detection)
|
||||
.get("/dashboard/home/data", async ({ cookie, headers }) => {
|
||||
const accountId = await getAccountId(cookie, headers);
|
||||
const resolved = await getAccountId(cookie, headers);
|
||||
const accountId = resolved?.accountId ?? null;
|
||||
const keyId = resolved?.keyId ?? null;
|
||||
if (!accountId) return new Response(JSON.stringify({ error: "Unauthorized" }), { status: 401 });
|
||||
|
||||
const monitors = await sql`
|
||||
|
|
@ -182,7 +190,9 @@ export const dashboard = new Elysia()
|
|||
|
||||
// Monitor detail — SSR with initial data
|
||||
.get("/dashboard/monitors/:id", async ({ cookie, headers, params }) => {
|
||||
const accountId = await getAccountId(cookie, headers);
|
||||
const resolved = await getAccountId(cookie, headers);
|
||||
const accountId = resolved?.accountId ?? null;
|
||||
const keyId = resolved?.keyId ?? null;
|
||||
if (!accountId) return redirect("/dashboard");
|
||||
|
||||
const [monitor] = await sql`
|
||||
|
|
@ -200,7 +210,9 @@ export const dashboard = new Elysia()
|
|||
|
||||
// Chart partial endpoint — returns just the latency chart SVG
|
||||
.get("/dashboard/monitors/:id/chart", async ({ cookie, headers, params }) => {
|
||||
const accountId = await getAccountId(cookie, headers);
|
||||
const resolved = await getAccountId(cookie, headers);
|
||||
const accountId = resolved?.accountId ?? null;
|
||||
const keyId = resolved?.keyId ?? null;
|
||||
if (!accountId) return new Response("Unauthorized", { status: 401 });
|
||||
|
||||
const [monitor] = await sql`
|
||||
|
|
@ -220,7 +232,9 @@ export const dashboard = new Elysia()
|
|||
|
||||
// Sparkline partial — returns just the SVG for one monitor
|
||||
.get("/dashboard/monitors/:id/sparkline", async ({ cookie, headers, params }) => {
|
||||
const accountId = await getAccountId(cookie, headers);
|
||||
const resolved = await getAccountId(cookie, headers);
|
||||
const accountId = resolved?.accountId ?? null;
|
||||
const keyId = resolved?.keyId ?? null;
|
||||
if (!accountId) return new Response("Unauthorized", { status: 401 });
|
||||
|
||||
const [monitor] = await sql`
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
<section class="bg-gray-900 rounded-xl border border-gray-800 p-6">
|
||||
<h2 class="text-sm font-semibold text-gray-300 mb-4">Account</h2>
|
||||
<div class="space-y-3">
|
||||
<% if (!it.isSubKey) { %>
|
||||
<div>
|
||||
<label class="block text-xs text-gray-500 mb-1">Login Key</label>
|
||||
<div class="flex gap-2">
|
||||
|
|
@ -22,6 +23,7 @@
|
|||
<button onclick="confirmReset()" class="px-3 bg-gray-800 hover:bg-gray-700 border border-red-900/50 hover:border-red-700/50 text-red-400 rounded-lg text-xs transition-colors">Rotate</button>
|
||||
</div>
|
||||
</div>
|
||||
<% } %>
|
||||
<div>
|
||||
<label class="block text-xs text-gray-500 mb-1">Member since</label>
|
||||
<p id="created-at" class="text-sm text-gray-400"><%= createdDate %></p>
|
||||
|
|
@ -45,7 +47,8 @@
|
|||
|
||||
|
||||
|
||||
<!-- Sub-keys -->
|
||||
<!-- Sub-keys (hidden for sub-key sessions) -->
|
||||
<% if (!it.isSubKey) { %>
|
||||
<section class="bg-gray-900 rounded-xl border border-gray-800 p-6">
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
<div>
|
||||
|
|
@ -87,6 +90,7 @@
|
|||
<% } %>
|
||||
</div>
|
||||
</section>
|
||||
<% } %>
|
||||
|
||||
</main>
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue