fix: hide login key and sub-keys from sub-key sessions

This commit is contained in:
M1
2026-03-18 11:48:51 +04:00
parent c56af82053
commit eeb0318c4d
2 changed files with 32 additions and 14 deletions
+27 -13
View File
@@ -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`