Files
claude-code/packages/remote-control-server/src/__tests__/middleware.test.ts
claude-code-best 2da6514095 feat: 支持自托管的 remote-control-server (#214)
* feat: 支持自托管的 remote-control-server (#214)

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2026-04-09 17:40:50 +08:00

209 lines
6.2 KiB
TypeScript

import { describe, test, expect, beforeEach, afterAll, mock } from "bun:test";
// Mock config before imports
const mockConfig = {
port: 3000,
host: "0.0.0.0",
apiKeys: ["test-api-key"],
baseUrl: "http://localhost:3000",
pollTimeout: 8,
heartbeatInterval: 20,
jwtExpiresIn: 3600,
disconnectTimeout: 300,
};
mock.module("../config", () => ({
config: mockConfig,
getBaseUrl: () => "http://localhost:3000",
}));
import { Hono } from "hono";
import { storeReset, storeCreateUser } from "../store";
import { apiKeyAuth, sessionIngressAuth, uuidAuth, getUuidFromRequest } from "../auth/middleware";
import { issueToken } from "../auth/token";
import { generateWorkerJwt } from "../auth/jwt";
// Helper: create a test app with middleware and a simple handler
function createTestApp() {
const app = new Hono();
// Test route for apiKeyAuth
app.get("/api-key-test", apiKeyAuth, (c) => {
return c.json({ username: c.get("username") || null });
});
// Test route for sessionIngressAuth
app.get("/ingress/:id", sessionIngressAuth, (c) => {
return c.json({ ok: true, jwtPayload: c.get("jwtPayload") || null });
});
// Test route for uuidAuth
app.get("/uuid-test", uuidAuth, (c) => {
return c.json({ uuid: c.get("uuid") });
});
// Test route for getUuidFromRequest
app.get("/uuid-extract", (c) => {
return c.json({ uuid: getUuidFromRequest(c) });
});
return app;
}
describe("Auth Middleware", () => {
let app: Hono;
beforeEach(() => {
storeReset();
app = createTestApp();
});
describe("apiKeyAuth", () => {
test("accepts valid API key with username header", async () => {
const res = await app.request("/api-key-test", {
headers: {
Authorization: "Bearer test-api-key",
"X-Username": "alice",
},
});
expect(res.status).toBe(200);
const body = await res.json();
expect(body.username).toBe("alice");
});
test("accepts valid API key with username query param", async () => {
const res = await app.request("/api-key-test?username=bob", {
headers: { Authorization: "Bearer test-api-key" },
});
expect(res.status).toBe(200);
const body = await res.json();
expect(body.username).toBe("bob");
});
test("accepts valid session token", async () => {
storeCreateUser("charlie");
const { token } = issueToken("charlie");
const res = await app.request("/api-key-test", {
headers: { Authorization: `Bearer ${token}` },
});
expect(res.status).toBe(200);
const body = await res.json();
expect(body.username).toBe("charlie");
});
test("rejects invalid token", async () => {
const res = await app.request("/api-key-test", {
headers: { Authorization: "Bearer wrong-key" },
});
expect(res.status).toBe(401);
});
test("rejects missing token", async () => {
const res = await app.request("/api-key-test");
expect(res.status).toBe(401);
});
test("accepts token from query param", async () => {
storeCreateUser("dave");
const { token } = issueToken("dave");
const res = await app.request(`/api-key-test?token=${token}`);
expect(res.status).toBe(200);
const body = await res.json();
expect(body.username).toBe("dave");
});
});
describe("sessionIngressAuth", () => {
const originalKeys = process.env.RCS_API_KEYS;
beforeEach(() => {
process.env.RCS_API_KEYS = "test-api-key";
});
afterAll(() => {
process.env.RCS_API_KEYS = originalKeys;
});
test("accepts valid API key", async () => {
const res = await app.request("/ingress/ses_123", {
headers: { Authorization: "Bearer test-api-key" },
});
expect(res.status).toBe(200);
});
test("accepts valid JWT with matching session_id", async () => {
const jwt = generateWorkerJwt("ses_123", 3600);
const res = await app.request("/ingress/ses_123", {
headers: { Authorization: `Bearer ${jwt}` },
});
expect(res.status).toBe(200);
const body = await res.json();
expect(body.jwtPayload).not.toBeNull();
expect(body.jwtPayload.session_id).toBe("ses_123");
});
test("rejects JWT with mismatched session_id", async () => {
const jwt = generateWorkerJwt("ses_456", 3600);
const res = await app.request("/ingress/ses_123", {
headers: { Authorization: `Bearer ${jwt}` },
});
expect(res.status).toBe(403);
});
test("rejects missing token", async () => {
const res = await app.request("/ingress/ses_123");
expect(res.status).toBe(401);
});
test("rejects invalid token", async () => {
const res = await app.request("/ingress/ses_123", {
headers: { Authorization: "Bearer invalid" },
});
expect(res.status).toBe(401);
});
});
describe("uuidAuth", () => {
test("accepts UUID from query param", async () => {
const res = await app.request("/uuid-test?uuid=test-uuid-1");
expect(res.status).toBe(200);
const body = await res.json();
expect(body.uuid).toBe("test-uuid-1");
});
test("accepts UUID from header", async () => {
const res = await app.request("/uuid-test", {
headers: { "X-UUID": "test-uuid-2" },
});
expect(res.status).toBe(200);
const body = await res.json();
expect(body.uuid).toBe("test-uuid-2");
});
test("rejects missing UUID", async () => {
const res = await app.request("/uuid-test");
expect(res.status).toBe(401);
});
});
describe("getUuidFromRequest", () => {
test("extracts from query param", async () => {
const res = await app.request("/uuid-extract?uuid=from-query");
const body = await res.json();
expect(body.uuid).toBe("from-query");
});
test("extracts from header", async () => {
const res = await app.request("/uuid-extract", {
headers: { "X-UUID": "from-header" },
});
const body = await res.json();
expect(body.uuid).toBe("from-header");
});
test("returns undefined when no UUID", async () => {
const res = await app.request("/uuid-extract");
const body = await res.json();
expect(body.uuid).toBeUndefined();
});
});
});