ai-query对接新版freesun-agent接口的分支
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

108 lines
3.2 KiB

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),
);
});