Ctrl K
ComunidadGuías…

scripts/wizard-start-smoke.mjs

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
#!/usr/bin/env node
// CI smoke test for macOS and Linux. Starts the real wizard with `relmio start`
// (the existing no-browser launch), completes the private browser handoff over
// loopback the way a browser does, fetches `/` with the resulting session, then
// stops it. Uses a throwaway RELMIO_HOME and never prints a secret.
import assert from "node:assert/strict";
import { execFile } from "node:child_process";
import { realpathSync } from "node:fs";
import { mkdtemp, readFile, rm } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { fileURLToPath } from "node:url";
import { promisify } from "node:util";

import { readLocalDashboardBrowserUrl } from "../src/services/local-dashboard-control.js";

const execFileAsync = promisify(execFile);
const cliPath = fileURLToPath(new URL("../src/cli.js", import.meta.url));
// The parent must be private and free of symbolic links (macOS tmpdir is one).
const parent = await mkdtemp(join(realpathSync(tmpdir()), "relmio-smoke-"));
const env = { ...process.env, RELMIO_HOME: join(parent, ".relmio") };

function relmio(command) {
  return execFileAsync(process.execPath, [cliPath, command], { env, timeout: 60_000 });
}

function capture(text, pattern) {
  const match = pattern.exec(text);
  assert.ok(match, `Expected ${pattern} in the browser handoff.`);
  return match[1];
}

async function openWizardWithSession() {
  const launchUrl = await readLocalDashboardBrowserUrl({ env, route: "/" });
  const handoff = await readFile(fileURLToPath(launchUrl), "utf8");
  const action = new URL(capture(handoff, /action="([^"]+)"/u));
  assert.equal(action.hostname, "127.0.0.1");
  const { origin } = action;

  const bootstrap = await fetch(action, {
    method: "POST",
    headers: { "Content-Type": "application/x-www-form-urlencoded", Origin: "null" },
    body: new URLSearchParams({
      ticketId: capture(handoff, /name="ticketId" value="([^"]+)"/u),
      secret: capture(handoff, /name="secret" value="([^"]+)"/u),
      route: "/",
    }),
    redirect: "manual",
  });
  assert.equal(bootstrap.status, 200);
  const envelope = /"relmio-v1\.([\w-]{43})\.([\w-]{43})"/u.exec(await bootstrap.text());
  assert.ok(envelope, "Expected a browser transfer envelope.");

  const transfer = await fetch(`${origin}/__relmio/browser/transfer`, {
    method: "POST",
    headers: { "Content-Type": "application/json", Origin: origin },
    body: JSON.stringify({ transferId: envelope[1], secret: envelope[2], route: "/" }),
  });
  assert.equal(transfer.status, 200);
  const { sessionToken } = await transfer.json();
  assert.equal(typeof sessionToken, "string");

  const page = await fetch(`${origin}/`, {
    headers: { Accept: "text/html", "X-Setup-Token": sessionToken },
  });
  assert.equal(page.status, 200);
  assert.match(page.headers.get("content-security-policy") ?? "", /default-src 'self'/u);
  assert.match(await page.text(), /^<!doctype html>/iu);

  const api = await fetch(`${origin}/api/oauth/status`, {
    headers: { "X-Setup-Token": sessionToken },
  });
  assert.equal(api.status, 200);
  return origin;
}

try {
  let origin;
  try {
    await relmio("start");
    origin = await openWizardWithSession();
  } finally {
    // `stop` is a no-op when nothing started, so it is always safe here.
    await relmio("stop");
  }
  await assert.rejects(relmio("status"), { code: 1 });
  console.log(`Wizard served / with its CSP on ${origin}, accepted its browser session, and stopped.`);
} finally {
  await rm(parent, { recursive: true, force: true });
}