feat: support optional per-installation Basic Auth on the MCP proxy
All checks were successful
CI / test (push) Successful in 31s
All checks were successful
CI / test (push) Successful in 31s
Lets a client still using Basic Auth credentials (e.g. against the previous nginx + htpasswd setup) keep working without switching to a bearer token immediately. Bearer auth remains the default and the only option when no Basic Auth credentials are configured. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
60
apps/server/src/proxy/mcpProxy.test.ts
Normal file
60
apps/server/src/proxy/mcpProxy.test.ts
Normal file
@@ -0,0 +1,60 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { isAuthorized } from "./mcpProxy.js";
|
||||
import type { Installation } from "../db/installations.js";
|
||||
|
||||
function makeInstallation(overrides: Partial<Installation> = {}): Installation {
|
||||
return {
|
||||
id: "1",
|
||||
slug: "test",
|
||||
name: "Test",
|
||||
repoUrl: "https://example.com/repo.git",
|
||||
gitRef: null,
|
||||
status: "running",
|
||||
statusDetail: null,
|
||||
imageTag: "mcpmgr/test:latest",
|
||||
containerId: null,
|
||||
containerName: "mcp-test",
|
||||
internalPort: 8080,
|
||||
httpPath: "/mcp",
|
||||
portEnvVar: "PORT",
|
||||
hostEnvVar: "HOST",
|
||||
env: {},
|
||||
bearerToken: "secret-token",
|
||||
basicAuthUsername: null,
|
||||
basicAuthPassword: null,
|
||||
createdAt: "2026-01-01T00:00:00.000Z",
|
||||
updatedAt: "2026-01-01T00:00:00.000Z",
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
describe("isAuthorized", () => {
|
||||
it("accepts a matching bearer token", () => {
|
||||
expect(isAuthorized(makeInstallation(), "Bearer secret-token")).toBe(true);
|
||||
});
|
||||
|
||||
it("rejects a wrong bearer token", () => {
|
||||
expect(isAuthorized(makeInstallation(), "Bearer wrong")).toBe(false);
|
||||
});
|
||||
|
||||
it("rejects basic auth when no credentials are configured", () => {
|
||||
const creds = Buffer.from("user:pass").toString("base64");
|
||||
expect(isAuthorized(makeInstallation(), `Basic ${creds}`)).toBe(false);
|
||||
});
|
||||
|
||||
it("accepts matching basic auth when credentials are configured", () => {
|
||||
const installation = makeInstallation({ basicAuthUsername: "user", basicAuthPassword: "pass" });
|
||||
const creds = Buffer.from("user:pass").toString("base64");
|
||||
expect(isAuthorized(installation, `Basic ${creds}`)).toBe(true);
|
||||
});
|
||||
|
||||
it("rejects wrong basic auth credentials", () => {
|
||||
const installation = makeInstallation({ basicAuthUsername: "user", basicAuthPassword: "pass" });
|
||||
const creds = Buffer.from("user:wrong").toString("base64");
|
||||
expect(isAuthorized(installation, `Basic ${creds}`)).toBe(false);
|
||||
});
|
||||
|
||||
it("rejects when no Authorization header is present", () => {
|
||||
expect(isAuthorized(makeInstallation(), "")).toBe(false);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user