Gateway: preserve operator scopes without device identity
This commit is contained in:
parent
996de610e8
commit
896f111a95
@ -63,7 +63,7 @@ describe("gateway auth compatibility baseline", () => {
|
||||
}
|
||||
});
|
||||
|
||||
test("clears client-declared scopes for shared-token operator connects", async () => {
|
||||
test("keeps requested scopes for shared-token operator connects without device identity", async () => {
|
||||
const ws = await openWs(port);
|
||||
try {
|
||||
const res = await connectReq(ws, {
|
||||
@ -74,8 +74,8 @@ describe("gateway auth compatibility baseline", () => {
|
||||
expect(res.ok).toBe(true);
|
||||
|
||||
const adminRes = await rpcReq(ws, "set-heartbeats", { enabled: false });
|
||||
expect(adminRes.ok).toBe(false);
|
||||
expect(adminRes.error?.message).toBe("missing scope: operator.admin");
|
||||
expect(adminRes.ok).toBe(true);
|
||||
expect((adminRes.payload as { enabled?: boolean } | undefined)?.enabled).toBe(false);
|
||||
} finally {
|
||||
ws.close();
|
||||
}
|
||||
@ -183,7 +183,7 @@ describe("gateway auth compatibility baseline", () => {
|
||||
}
|
||||
});
|
||||
|
||||
test("clears client-declared scopes for shared-password operator connects", async () => {
|
||||
test("keeps requested scopes for shared-password operator connects without device identity", async () => {
|
||||
const ws = await openWs(port);
|
||||
try {
|
||||
const res = await connectReq(ws, {
|
||||
@ -194,8 +194,8 @@ describe("gateway auth compatibility baseline", () => {
|
||||
expect(res.ok).toBe(true);
|
||||
|
||||
const adminRes = await rpcReq(ws, "set-heartbeats", { enabled: false });
|
||||
expect(adminRes.ok).toBe(false);
|
||||
expect(adminRes.error?.message).toBe("missing scope: operator.admin");
|
||||
expect(adminRes.ok).toBe(true);
|
||||
expect((adminRes.payload as { enabled?: boolean } | undefined)?.enabled).toBe(false);
|
||||
} finally {
|
||||
ws.close();
|
||||
}
|
||||
|
||||
@ -526,7 +526,7 @@ export function attachGatewayWsMessageHandler(params: {
|
||||
hasSharedAuth,
|
||||
isLocalClient,
|
||||
});
|
||||
if (!device && (!isControlUi || decision.kind !== "allow")) {
|
||||
if (!device && decision.kind !== "allow" && !isControlUi) {
|
||||
clearUnboundScopes();
|
||||
}
|
||||
if (decision.kind === "allow") {
|
||||
|
||||
@ -580,11 +580,11 @@ vi.mock("../channels/web/index.js", async () => {
|
||||
};
|
||||
});
|
||||
vi.mock("../commands/agent.js", () => ({
|
||||
agentCommand,
|
||||
agentCommandFromIngress: agentCommand,
|
||||
agentCommand: hoisted.agentCommand,
|
||||
agentCommandFromIngress: hoisted.agentCommand,
|
||||
}));
|
||||
vi.mock("../auto-reply/reply.js", () => ({
|
||||
getReplyFromConfig,
|
||||
getReplyFromConfig: hoisted.getReplyFromConfig,
|
||||
}));
|
||||
vi.mock("../cli/deps.js", async () => {
|
||||
const actual = await vi.importActual<typeof import("../cli/deps.js")>("../cli/deps.js");
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user