import assert from "node:assert/strict"; import { createHmac } from "node:crypto"; import test from "node:test"; import { createRequire } from "node:module"; const require = createRequire(import.meta.url); const { issueAgentAccessToken, resolveAgentUserId, } = require("../app/utils/agentJwt"); const decodeJwtPart = (part) => JSON.parse(Buffer.from(part, "base64url").toString("utf8")); test("resolveAgentUserId matches previous X-User-Id order", () => { assert.equal( resolveAgentUserId({ localUserId: "local-1", id: "id-2", pepUserId: "pep-88", }), "local-1", ); assert.equal( resolveAgentUserId({ id: "id-2", pepUserId: "pep-88", }), "id-2", ); }); test("resolveAgentUserId reads nested AIUserInfo", () => { assert.equal( resolveAgentUserId({ token: "ai-center-token", AIUserInfo: { id: "center-user-9" }, }), "center-user-9", ); }); test("issueAgentAccessToken signs HS256 JWT with userid as sub", () => { const secret = "local-development-only-long-random-secret"; const issued = issueAgentAccessToken({ userInfo: { id: "user-42" }, config: { algorithm: "HS256", secret, expiresInSeconds: 3600, }, now: 1_700_000_000_000, }); assert.equal(issued.token_type, "Bearer"); assert.equal(issued.sub, "user-42"); assert.equal(issued.expires_in, 3600); assert.equal(issued.expires_at, 1_700_000_000 + 3600); const [headerPart, payloadPart, signaturePart] = issued.token.split("."); const header = decodeJwtPart(headerPart); const payload = decodeJwtPart(payloadPart); const expectedSignature = createHmac("sha256", secret) .update(`${headerPart}.${payloadPart}`) .digest("base64url"); assert.equal(header.alg, "HS256"); assert.equal(payload.sub, "user-42"); assert.equal(payload.iat, 1_700_000_000); assert.equal(payload.exp, 1_700_000_000 + 3600); assert.equal(signaturePart, expectedSignature); assert.equal(payload.iss, undefined); assert.equal(payload.aud, undefined); }); test("issueAgentAccessToken writes issuer and audience when configured", () => { const issued = issueAgentAccessToken({ userInfo: { userId: "user-7" }, config: { algorithm: "HS256", secret: "secret", issuer: "query-api", audience: "freesun-agent2", }, }); const payload = decodeJwtPart(issued.token.split(".")[1]); assert.equal(payload.iss, "query-api"); assert.equal(payload.aud, "freesun-agent2"); }); test("issueAgentAccessToken rejects missing userid", () => { assert.throws( () => issueAgentAccessToken({ userInfo: {}, config: { algorithm: "HS256", secret: "secret" }, }), (error) => error.status === 401 && /认证用户信息无效/.test(error.message), ); }); test("issueAgentAccessToken rejects missing HS256 secret", () => { assert.throws( () => issueAgentAccessToken({ userInfo: { id: "user-1" }, config: { algorithm: "HS256", secret: "" }, }), (error) => error.status === 503 && /未配置 Agent JWT 签名密钥/.test(error.message), ); });