Ctrl K
ComunidadGuías…

test/claude-expired-auth.test.js

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

Archivo original ↗Preguntar a KiBot
var test = require("node:test");
var assert = require("node:assert/strict");
var users = require("../lib/users");
var normalize = require("../lib/yoke/adapters/claude").contractTestKit.normalizeEvent;
var attachMessageProcessor = require("../lib/sdk-message-processor").attachMessageProcessor;
var expired = "Failed to authenticate: OAuth session expired and could not be refreshed";

function fixture(t, linuxUser) {
  t.mock.method(users, "isMultiUser", function () { return true; });
  t.mock.method(users, "findUserById", function (id) {
    return id === "member" ? { id: id, role: "member", linuxUser: linuxUser } : null;
  });
  var session = {
    localId: 22, vendor: "claude", ownerId: "member", cliSessionId: "expired-session",
    history: [], messageUUIDs: [], responsePreview: "", pendingPermissions: {},
    pendingElicitations: {}, pendingAskUser: {}, sentToolResults: {},
  };
  var sent = [];
  var notifications = [];
  var processor = attachMessageProcessor({
    sm: {
      sendAndRecord: function (target, msg) { target.history.push(msg); },
      sendToSession: function (target, msg) { sent.push({ target: target.localId, message: msg }); },
      broadcastSessionList: function () {},
    },
    opts: {}, onProcessingChanged: function () {}, onTurnDone: function () {},
    getNotificationsModule: function () {
      return { notify: function (type, data) { notifications.push({ type: type, data: data }); } };
    },
  });
  return {
    session: session, sent: sent, notifications: notifications,
    finish: function (text, cost) {
      session.isProcessing = true;
      session._awaitingTurnResult = true;
      processor.processSDKMessage(session, normalize({ type: "assistant", message: {
        role: "assistant", content: [{ type: "text", text: text }],
      } }));
      processor.processSDKMessage(session, normalize({ type: "result", subtype: "success", total_cost_usd: cost, duration_ms: 100 }));
    },
  };
}

test("expired OAuth response sends transient recovery for the session's Linux user", function (t) {
  var f = fixture(t, "clay_member");
  f.finish(expired, 0);
  var auth = f.sent.filter(function (entry) { return entry.message.type === "auth_required"; });
  assert.equal(auth.length, 1);
  assert.equal(auth[0].target, 22);
  assert.equal(auth[0].message.vendor, "claude");
  assert.equal(auth[0].message.linuxUser, "clay_member");
  assert.equal(auth[0].message.canAutoLogin, true);
  assert.equal(f.session.cliSessionId, null);
  assert.equal(f.session.isProcessing, false);
  assert.equal(f.session.history.some(function (msg) { return msg.type === "auth_required"; }), false);
  var notice = f.notifications.find(function (entry) { return entry.type === "auth_required"; });
  assert.equal(notice.data.ownerId, "member");
  f.finish(expired, 0);
  assert.equal(f.sent.filter(function (entry) { return entry.message.type === "auth_required"; }).length, 1);
});

test("expired OAuth does not grant host login access to an unmapped member", function (t) {
  var f = fixture(t, null);
  f.finish(expired, 0);
  var auth = f.sent.find(function (entry) { return entry.message.type === "auth_required"; });
  assert.equal(auth.message.canAutoLogin, false);
  assert.equal(auth.message.linuxUser, null);
});

test("older not-logged-in responses still request recovery", function (t) {
  var f = fixture(t, "clay_member");
  f.finish("Not logged in · Please run /login", 0);
  assert.equal(f.sent.some(function (entry) { return entry.message.type === "auth_required"; }), true);
});

test("paid responses, explanations and other vendors do not trigger expired-Claude recovery", function (t) {
  var f = fixture(t, "clay_member");
  f.finish(expired, 0.01);
  f.finish("The error says: " + expired, 0);
  f.finish(expired + " — here is how to fix it.", 0);
  f.session.vendor = "codex";
  f.finish(expired, 0);
  assert.equal(f.sent.some(function (entry) { return entry.message.type === "auth_required"; }), false);
});