File size: 3,171 Bytes
5cb63c1 | 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 | /**
* Plugin route runtime-scope regression tests for trusted-proxy headers.
*/
import type { IncomingMessage } from "node:http";
import { describe, expect, it } from "vitest";
import { createExpectedBroadOperatorScopes } from "../scope-expectations.test-support.js";
import { resolvePluginRouteRuntimeOperatorScopes } from "./plugin-route-runtime-scopes.js";
function createReq(headers: Record<string, string> = {}): IncomingMessage {
return { headers } as IncomingMessage;
}
describe("resolvePluginRouteRuntimeOperatorScopes", () => {
it("preserves declared trusted-proxy scopes when the header is present", () => {
expect(
resolvePluginRouteRuntimeOperatorScopes(createReq({ "x-openclaw-scopes": "operator.read" }), {
authMethod: "trusted-proxy",
trustDeclaredOperatorScopes: true,
}),
).toEqual(["operator.read"]);
});
it("keeps trusted-proxy plugin routes on write scope when the header is absent", () => {
expect(
resolvePluginRouteRuntimeOperatorScopes(createReq(), {
authMethod: "trusted-proxy",
trustDeclaredOperatorScopes: true,
}),
).toEqual(["operator.write"]);
});
it("keeps shared-secret bearer plugin routes on write scope even when scopes are declared", () => {
expect(
resolvePluginRouteRuntimeOperatorScopes(
createReq({
authorization: "Bearer secret",
"x-openclaw-scopes": "operator.admin,operator.write",
}),
{ authMethod: "token", trustDeclaredOperatorScopes: false },
),
).toEqual(["operator.write"]);
});
it("does not trust caller-declared admin scopes on plugin routes for mode=none requests", () => {
expect(
resolvePluginRouteRuntimeOperatorScopes(
createReq({ "x-openclaw-scopes": "operator.admin,operator.write" }),
{ authMethod: "none", trustDeclaredOperatorScopes: true },
),
).toEqual(["operator.write"]);
});
it("restores trusted default operator scopes for shared-secret bearer routes opting into trusted-operator surface", () => {
expect(
resolvePluginRouteRuntimeOperatorScopes(
createReq({
authorization: "Bearer secret",
}),
{ authMethod: "token", trustDeclaredOperatorScopes: false },
"trusted-operator",
),
).toEqual(createExpectedBroadOperatorScopes());
});
it("restores trusted default operator scopes for trusted-proxy routes opting into trusted-operator when scopes header is absent", () => {
expect(
resolvePluginRouteRuntimeOperatorScopes(
createReq(),
{ authMethod: "trusted-proxy", trustDeclaredOperatorScopes: true },
"trusted-operator",
),
).toEqual(createExpectedBroadOperatorScopes());
});
it("preserves trusted-proxy declared scopes for routes opting into trusted-operator surface", () => {
expect(
resolvePluginRouteRuntimeOperatorScopes(
createReq({ "x-openclaw-scopes": "operator.admin,operator.write" }),
{ authMethod: "trusted-proxy", trustDeclaredOperatorScopes: true },
"trusted-operator",
),
).toEqual(["operator.admin", "operator.write"]);
});
});
|