Spaces:
Paused
Paused
File size: 4,936 Bytes
91ee702 | 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 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 | import { describe, it, expect, vi, beforeEach } from "vitest";
import { Hono } from "hono";
const mockConfig = {
server: { proxy_api_key: "test-key" as string | null },
session: { ttl_minutes: 60, cleanup_interval_minutes: 5 },
};
vi.mock("../../config.js", () => ({
getConfig: vi.fn(() => mockConfig),
}));
const mockGetConnInfo = vi.fn(() => ({ remote: { address: "192.168.1.100" } }));
vi.mock("@hono/node-server/conninfo", () => ({
getConnInfo: (...args: unknown[]) => mockGetConnInfo(...args),
}));
vi.mock("../../auth/dashboard-session.js", async () => {
const validSessions = new Set<string>();
return {
validateSession: vi.fn((id: string) => validSessions.has(id)),
_addTestSession: (id: string) => validSessions.add(id),
_clearTestSessions: () => validSessions.clear(),
};
});
import { dashboardAuth } from "../dashboard-auth.js";
// eslint-disable-next-line @typescript-eslint/consistent-type-imports
const sessionMod = await import("../../auth/dashboard-session.js") as {
validateSession: ReturnType<typeof vi.fn>;
_addTestSession: (id: string) => void;
_clearTestSessions: () => void;
};
function createApp(): Hono {
const app = new Hono();
app.use("*", dashboardAuth);
// Catch-all handler to confirm middleware passed through
app.all("*", (c) => c.json({ ok: true }));
return app;
}
describe("dashboard-auth middleware", () => {
beforeEach(() => {
vi.clearAllMocks();
mockConfig.server.proxy_api_key = "test-key";
mockGetConnInfo.mockReturnValue({ remote: { address: "192.168.1.100" } });
sessionMod._clearTestSessions();
});
it("passes through when proxy_api_key is not set", async () => {
mockConfig.server.proxy_api_key = null;
const app = createApp();
const res = await app.request("/auth/accounts");
expect(res.status).toBe(200);
});
it("passes through for localhost requests", async () => {
mockGetConnInfo.mockReturnValue({ remote: { address: "127.0.0.1" } });
const app = createApp();
const res = await app.request("/auth/accounts");
expect(res.status).toBe(200);
});
it("passes through for ::1 localhost", async () => {
mockGetConnInfo.mockReturnValue({ remote: { address: "::1" } });
const app = createApp();
const res = await app.request("/admin/rotation-settings");
expect(res.status).toBe(200);
});
it("passes through for GET / (HTML shell)", async () => {
const app = createApp();
const res = await app.request("/");
expect(res.status).toBe(200);
});
it("passes through for GET /desktop", async () => {
const app = createApp();
const res = await app.request("/desktop");
expect(res.status).toBe(200);
});
it("passes through for /assets/* (static files)", async () => {
const app = createApp();
const res = await app.request("/assets/index-abc123.js");
expect(res.status).toBe(200);
});
it("passes through for /health", async () => {
const app = createApp();
const res = await app.request("/health");
expect(res.status).toBe(200);
});
it("passes through for /v1/* API routes", async () => {
const app = createApp();
const res = await app.request("/v1/chat/completions");
expect(res.status).toBe(200);
});
it("passes through for /v1beta/* API routes", async () => {
const app = createApp();
const res = await app.request("/v1beta/models");
expect(res.status).toBe(200);
});
it("passes through for dashboard auth endpoints", async () => {
const app = createApp();
for (const path of ["/auth/dashboard-login", "/auth/dashboard-logout", "/auth/dashboard-status"]) {
const res = await app.request(path);
expect(res.status).toBe(200);
}
});
it("returns 401 for /auth/accounts without session", async () => {
const app = createApp();
const res = await app.request("/auth/accounts");
expect(res.status).toBe(401);
const body = await res.json();
expect(body.error).toBeTruthy();
});
it("returns 401 for /admin/* without session", async () => {
const app = createApp();
const res = await app.request("/admin/rotation-settings");
expect(res.status).toBe(401);
});
it("returns 401 for /auth/status without session", async () => {
const app = createApp();
const res = await app.request("/auth/status");
expect(res.status).toBe(401);
});
it("passes through with valid session cookie", async () => {
sessionMod._addTestSession("valid-session-id");
const app = createApp();
const res = await app.request("/auth/accounts", {
headers: { Cookie: "_codex_session=valid-session-id" },
});
expect(res.status).toBe(200);
});
it("returns 401 with invalid session cookie", async () => {
const app = createApp();
const res = await app.request("/auth/accounts", {
headers: { Cookie: "_codex_session=invalid-id" },
});
expect(res.status).toBe(401);
});
});
|