mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 04:49:34 +00:00
fix(gateway): land access/auth/config migration cluster
Land #28960 by @Glucksberg (Tailscale origin auto-allowlist). Land #29394 by @synchronic1 (allowedOrigins upgrade migration). Land #29198 by @Mariana-Codebase (plugin HTTP auth guard + route precedence). Land #30910 by @liuxiaopai-ai (tailscale bind/config.patch guard). Co-authored-by: Glucksberg <markuscontasul@gmail.com> Co-authored-by: synchronic1 <synchronic1@users.noreply.github.com> Co-authored-by: Mariana Sinisterra <mariana.data@outlook.com> Co-authored-by: liuxiaopai-ai <73659136+liuxiaopai-ai@users.noreply.github.com>
This commit is contained in:
@@ -104,3 +104,113 @@ describe("legacy migrate mention routing", () => {
|
||||
).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe("legacy migrate controlUi.allowedOrigins seed (issue #29385)", () => {
|
||||
it("seeds allowedOrigins for bind=lan with no existing controlUi config", () => {
|
||||
const res = migrateLegacyConfig({
|
||||
gateway: {
|
||||
bind: "lan",
|
||||
auth: { mode: "token", token: "tok" },
|
||||
},
|
||||
});
|
||||
expect(res.config?.gateway?.controlUi?.allowedOrigins).toEqual([
|
||||
"http://localhost:18789",
|
||||
"http://127.0.0.1:18789",
|
||||
]);
|
||||
expect(res.changes.some((c) => c.includes("gateway.controlUi.allowedOrigins"))).toBe(true);
|
||||
expect(res.changes.some((c) => c.includes("bind=lan"))).toBe(true);
|
||||
});
|
||||
|
||||
it("seeds allowedOrigins using configured port", () => {
|
||||
const res = migrateLegacyConfig({
|
||||
gateway: {
|
||||
bind: "lan",
|
||||
port: 9000,
|
||||
auth: { mode: "token", token: "tok" },
|
||||
},
|
||||
});
|
||||
expect(res.config?.gateway?.controlUi?.allowedOrigins).toEqual([
|
||||
"http://localhost:9000",
|
||||
"http://127.0.0.1:9000",
|
||||
]);
|
||||
});
|
||||
|
||||
it("seeds allowedOrigins including custom bind host for bind=custom", () => {
|
||||
const res = migrateLegacyConfig({
|
||||
gateway: {
|
||||
bind: "custom",
|
||||
customBindHost: "192.168.1.100",
|
||||
auth: { mode: "token", token: "tok" },
|
||||
},
|
||||
});
|
||||
expect(res.config?.gateway?.controlUi?.allowedOrigins).toContain("http://192.168.1.100:18789");
|
||||
expect(res.config?.gateway?.controlUi?.allowedOrigins).toContain("http://localhost:18789");
|
||||
});
|
||||
|
||||
it("does not overwrite existing allowedOrigins — returns null (no migration needed)", () => {
|
||||
// When allowedOrigins already exists, the migration is a no-op.
|
||||
// applyLegacyMigrations returns next=null when changes.length===0, so config is null.
|
||||
const res = migrateLegacyConfig({
|
||||
gateway: {
|
||||
bind: "lan",
|
||||
auth: { mode: "token", token: "tok" },
|
||||
controlUi: { allowedOrigins: ["https://control.example.com"] },
|
||||
},
|
||||
});
|
||||
expect(res.config).toBeNull();
|
||||
expect(res.changes).toHaveLength(0);
|
||||
});
|
||||
|
||||
it("does not migrate when dangerouslyAllowHostHeaderOriginFallback is set — returns null", () => {
|
||||
const res = migrateLegacyConfig({
|
||||
gateway: {
|
||||
bind: "lan",
|
||||
auth: { mode: "token", token: "tok" },
|
||||
controlUi: { dangerouslyAllowHostHeaderOriginFallback: true },
|
||||
},
|
||||
});
|
||||
expect(res.config).toBeNull();
|
||||
expect(res.changes).toHaveLength(0);
|
||||
});
|
||||
|
||||
it("seeds allowedOrigins when existing entries are blank strings", () => {
|
||||
const res = migrateLegacyConfig({
|
||||
gateway: {
|
||||
bind: "lan",
|
||||
auth: { mode: "token", token: "tok" },
|
||||
controlUi: { allowedOrigins: ["", " "] },
|
||||
},
|
||||
});
|
||||
expect(res.config?.gateway?.controlUi?.allowedOrigins).toEqual([
|
||||
"http://localhost:18789",
|
||||
"http://127.0.0.1:18789",
|
||||
]);
|
||||
expect(res.changes.some((c) => c.includes("gateway.controlUi.allowedOrigins"))).toBe(true);
|
||||
});
|
||||
|
||||
it("does not migrate loopback bind — returns null", () => {
|
||||
const res = migrateLegacyConfig({
|
||||
gateway: {
|
||||
bind: "loopback",
|
||||
auth: { mode: "token", token: "tok" },
|
||||
},
|
||||
});
|
||||
expect(res.config).toBeNull();
|
||||
expect(res.changes).toHaveLength(0);
|
||||
});
|
||||
|
||||
it("preserves existing controlUi fields when seeding allowedOrigins", () => {
|
||||
const res = migrateLegacyConfig({
|
||||
gateway: {
|
||||
bind: "lan",
|
||||
auth: { mode: "token", token: "tok" },
|
||||
controlUi: { basePath: "/app" },
|
||||
},
|
||||
});
|
||||
expect(res.config?.gateway?.controlUi?.basePath).toBe("/app");
|
||||
expect(res.config?.gateway?.controlUi?.allowedOrigins).toEqual([
|
||||
"http://localhost:18789",
|
||||
"http://127.0.0.1:18789",
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user