diff --git a/scripts/homolog/lib/adminClient.mjs b/scripts/homolog/lib/adminClient.mjs new file mode 100644 index 0000000000..343c483e11 --- /dev/null +++ b/scripts/homolog/lib/adminClient.mjs @@ -0,0 +1,49 @@ +// Cookie confirmado em src/app/api/auth/login/route.ts (cookieStore.set("auth_token", ...)) +// e em src/shared/utils/apiAuth.ts (isDashboardSessionAuthenticated lê "auth_token"). +const TOKEN_COOKIE = "auth_token"; + +export function extractJwtCookie(setCookies) { + for (const c of setCookies || []) { + const m = c.match(new RegExp(`^(${TOKEN_COOKIE}=[^;]+)`)); + if (m) return m[1]; + } + return null; +} + +export function extractApiKey(body) { + if (!body?.key || !body?.id) throw new Error("POST /api/keys sem key/id no corpo"); + return { key: body.key, id: body.id }; +} + +/** Login admin → cria API key efêmera. Retorna {key, id, cookie, revoke()}. */ +export async function createEphemeralKey(baseUrl, password) { + const login = await fetch(`${baseUrl}/api/auth/login`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ password }), + }); + if (!login.ok) throw new Error(`login falhou: HTTP ${login.status}`); + const cookie = extractJwtCookie(login.headers.getSetCookie()); + if (!cookie) throw new Error("login sem cookie de sessão"); + + const create = await fetch(`${baseUrl}/api/keys`, { + method: "POST", + headers: { "Content-Type": "application/json", cookie }, + body: JSON.stringify({ name: `homolog-${new Date().toISOString().slice(0, 10)}` }), + }); + if (!create.ok) throw new Error(`criação de key falhou: HTTP ${create.status}`); + const { key, id } = extractApiKey(await create.json()); + + return { + key, + id, + cookie, + async revoke() { + const del = await fetch(`${baseUrl}/api/keys/${id}`, { + method: "DELETE", + headers: { cookie }, + }); + if (!del.ok) throw new Error(`revogação da key ${id} falhou: HTTP ${del.status}`); + }, + }; +} diff --git a/tests/unit/homolog-admin-client.test.ts b/tests/unit/homolog-admin-client.test.ts new file mode 100644 index 0000000000..225f66073c --- /dev/null +++ b/tests/unit/homolog-admin-client.test.ts @@ -0,0 +1,17 @@ +import { test } from "node:test"; +import assert from "node:assert/strict"; +import { extractJwtCookie, extractApiKey } from "../../scripts/homolog/lib/adminClient.mjs"; + +test("extrai o cookie JWT do set-cookie do login", () => { + const jwt = extractJwtCookie(["auth_token=abc.def.ghi; Path=/; HttpOnly; SameSite=Lax"]); + assert.equal(jwt, "auth_token=abc.def.ghi"); +}); + +test("retorna null sem set-cookie de token", () => { + assert.equal(extractJwtCookie(["other=1; Path=/"]), null); +}); + +test("extrai key e id do POST /api/keys", () => { + const r = extractApiKey({ key: "or-abc123", id: "k1", name: "homolog-run" }); + assert.deepEqual(r, { key: "or-abc123", id: "k1" }); +});