Ctrl K
ComunidadGuías…

test/grok-auth.test.js

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

Archivo original ↗Preguntar a KiBot
"use strict";

const assert = require("assert");
const fs = require("fs");
const os = require("os");
const path = require("path");
const GrokAuth = require("../lib/grok-auth");

const dir = fs.mkdtempSync(path.join(os.tmpdir(), "vrcloud-grok-"));
const file = path.join(dir, "grok-session.json");

function jwt(payload) {
  const h = Buffer.from(JSON.stringify({ alg: "none", typ: "JWT" })).toString("base64url");
  const p = Buffer.from(JSON.stringify(payload)).toString("base64url");
  return h + "." + p + ".sig";
}

let now = 1_700_000_000_000;
const calls = [];
let nextResponses = [];

async function fakeFetch(url, init) {
  calls.push({ url: String(url), method: (init && init.method) || "GET", body: (init && init.body) || "" });
  const r = nextResponses.shift();
  if (!r) throw new Error("unexpected fetch: " + url);
  return {
    ok: r.status >= 200 && r.status < 300,
    status: r.status,
    statusText: r.statusText || "",
    async text() { return typeof r.body === "string" ? r.body : JSON.stringify(r.body || {}); },
    async json() { return typeof r.body === "string" ? JSON.parse(r.body) : (r.body || {}); },
  };
}

const auth = new GrokAuth({
  file,
  secret: "test-auth-secret-at-least-32-chars!!",
  fetch: fakeFetch,
  now: () => now,
  autoPoll: false,
  cliAuthFile: path.join(dir, "missing-cli.json"),
});

assert.strictEqual(auth.connected(), false);
let st = auth.status();
assert.strictEqual(st.connected, false);
assert.strictEqual(st.pending, null);
assert.ok(!JSON.stringify(st).includes("device_code"));
assert.ok(!JSON.stringify(st).includes("access"));

nextResponses.push({
  status: 200,
  body: {
    issuer: "https://auth.x.ai",
    device_authorization_endpoint: "https://auth.x.ai/oauth2/device/code",
    token_endpoint: "https://auth.x.ai/oauth2/token",
    revocation_endpoint: "https://auth.x.ai/oauth2/revoke",
    userinfo_endpoint: "https://auth.x.ai/oauth2/userinfo",
  },
});
nextResponses.push({
  status: 200,
  body: {
    device_code: "dev-secret-xyz",
    user_code: "ABCD-EFGH",
    verification_uri: "https://auth.x.ai/activate",
    verification_uri_complete: "https://auth.x.ai/activate?user_code=ABCD-EFGH",
    expires_in: 600,
    interval: 1,
  },
});

auth.startLogin().then(async (started) => {
  assert.ok(started.pending);
  assert.strictEqual(started.pending.userCode, "ABCD-EFGH");
  assert.ok(started.pending.verificationUriComplete.indexOf("ABCD-EFGH") !== -1);
  assert.ok(!JSON.stringify(started).includes("dev-secret-xyz"));
  assert.ok(fs.existsSync(file));
  if (process.platform !== "win32") {
    assert.strictEqual(fs.statSync(file).mode & 0o777, 0o600);
  }
  const disk = fs.readFileSync(file, "utf8");
  assert.ok(!disk.includes("dev-secret-xyz"));
  assert.ok(!disk.includes("access_token"));

  nextResponses.push({ status: 200, body: { error: "authorization_pending" } });
  const pending = await auth.pollOnce();
  assert.strictEqual(pending, "pending");
  assert.ok(auth.pending);

  const access = jwt({ email: "op@example.com", sub: "u1", exp: Math.floor((now + 6 * 3600 * 1000) / 1000) });
  nextResponses.push({
    status: 200,
    body: { access_token: access, refresh_token: "ref-1", expires_in: 21600, token_type: "Bearer" },
  });
  const ok = await auth.pollOnce();
  assert.strictEqual(ok, "ok");
  assert.strictEqual(auth.connected(), true);
  assert.strictEqual(auth.pending, null);
  const live = auth.status();
  assert.strictEqual(live.connected, true);
  assert.strictEqual(live.email, "op@example.com");
  assert.ok(live.emailMasked.indexOf("@example.com") !== -1);
  assert.ok(!JSON.stringify(live).includes(access));
  assert.ok(!JSON.stringify(live).includes("ref-1"));

  const token = await auth.getAccessToken();
  assert.strictEqual(token, access);

  now += 7 * 3600 * 1000;
  const access2 = jwt({ email: "op@example.com", sub: "u1", exp: Math.floor((now + 6 * 3600 * 1000) / 1000) });
  nextResponses.push({
    status: 200,
    body: { access_token: access2, refresh_token: "ref-2", expires_in: 21600 },
  });
  const refreshed = await auth.getAccessToken();
  assert.strictEqual(refreshed, access2);
  assert.strictEqual(auth.session.refreshToken, "ref-2");

  nextResponses.push({ status: 200, body: {} });
  await auth.logout();
  assert.strictEqual(auth.connected(), false);
  assert.strictEqual(auth.status().connected, false);
  const after = JSON.parse(fs.readFileSync(file, "utf8"));
  assert.strictEqual(after.public.connected, false);

  const reloaded = new GrokAuth({
    file,
    secret: "test-auth-secret-at-least-32-chars!!",
    fetch: fakeFetch,
    now: () => now,
    cliAuthFile: path.join(dir, "missing-cli.json"),
  });
  assert.strictEqual(reloaded.connected(), false);

  assert.strictEqual(GrokAuth.maskEmail("ab@x.ai"), "a\u2026@x.ai");
  assert.ok(GrokAuth.jwtExp(access2) > now);

  fs.rmSync(dir, { recursive: true, force: true });
  console.log("grok-auth: ok");
}).catch((e) => {
  console.error(e);
  process.exit(1);
});