bin-lemon-internal-token.test.js
2.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
/**
* bin/lemon.js — commit b7b5096(全站鉴权)之后,agent-chat.js 挂了 requireAuthOrInternal,
* 这个 CLI 跑在 agent 自己的 claude CLI 子进程里,没有登录 cookie,只能靠父进程通过
* process.env 传下来的 LEMON_INTERNAL_TOKEN 过 internal 校验(server/middleware/jwt-auth.js)。
*
* 用一个假的 HTTP 服务器代替真实后端,只验证 bin/lemon.js 发请求时带没带这个 header。
*/
import { describe, it, expect, beforeAll, afterAll } from 'vitest';
import http from 'http';
import { execFile } from 'child_process';
import path from 'path';
const LEMON_BIN = path.resolve(__dirname, '../../../bin/lemon.js');
let server, port, lastHeaders;
function runLemon(args, env) {
return new Promise((resolve) => {
execFile('node', [LEMON_BIN, ...args], { env }, () => resolve());
});
}
describe('bin/lemon.js — LEMON_INTERNAL_TOKEN 透传', () => {
beforeAll(async () => {
server = http.createServer((req, res) => {
lastHeaders = req.headers;
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ ok: true }));
});
// 用随机端口,避免跟本机真实跑着的 3010 dev server 撞车(LEMON_API_BASE 让 bin/lemon.js 指过来)
await new Promise((resolve) => server.listen(0, resolve));
port = server.address().port;
});
afterAll(() => new Promise((resolve) => server.close(resolve)));
it('设了 LEMON_INTERNAL_TOKEN 时,请求头带上 x-internal-token', async () => {
await runLemon(
['task', 'report', '--taskId', 't1', '--from', 'a', '--to', 'b'],
{ ...process.env, LEMON_API_BASE: `http://localhost:${port}/api`, LEMON_INTERNAL_TOKEN: 'test-token-abc' }
);
expect(lastHeaders['x-internal-token']).toBe('test-token-abc');
});
it('没设 LEMON_INTERNAL_TOKEN 时,不带这个 header(不伪造身份)', async () => {
const env = { ...process.env, LEMON_API_BASE: `http://localhost:${port}/api` };
delete env.LEMON_INTERNAL_TOKEN;
await runLemon(['task', 'report', '--taskId', 't1', '--from', 'a', '--to', 'b'], env);
expect(lastHeaders['x-internal-token']).toBeUndefined();
});
});