fix: require admin scope for chat resets

This commit is contained in:
Shakker
2026-08-02 15:05:09 +01:00
parent 400fe799d8
commit e3f75fd241
3 changed files with 8 additions and 7 deletions
+6 -5
View File
@@ -257,6 +257,7 @@ describe("refreshSlashCommands", () => {
describe("conversation reset confirmation", () => {
it.each([
["stop", "chat.abort"],
["reset", "chat.send"],
["clear", "sessions.reset"],
["compact", "sessions.compact"],
] as const)("rejects /%s without its exact operator scope", async (command, method) => {
@@ -351,7 +352,7 @@ describe("conversation reset confirmation", () => {
connected: true,
connectionEpoch: 1,
hello: {
auth: { role: "operator", scopes: ["operator.write"] },
auth: { role: "operator", scopes: ["operator.admin"] },
features: { methods: ["chat.send"] },
} as ApplicationGatewaySnapshot["hello"],
sessionKey: "agent:main:current",
@@ -372,7 +373,7 @@ describe("conversation reset confirmation", () => {
expect(sendResetMessage).not.toHaveBeenCalled();
});
it("rechecks /reset write scope after confirmation", async () => {
it("rechecks /reset admin scope after confirmation", async () => {
let settleConfirmation: ((confirmed: boolean) => void) | undefined;
const confirmation = new Promise<boolean>((resolve) => {
settleConfirmation = resolve;
@@ -382,7 +383,7 @@ describe("conversation reset confirmation", () => {
...legacyConnectedSessionAccess(),
connectionEpoch: 1,
hello: {
auth: { role: "operator", scopes: ["operator.write"] },
auth: { role: "operator", scopes: ["operator.admin"] },
features: { methods: ["chat.send"] },
} as ApplicationGatewaySnapshot["hello"],
sessionKey: "agent:main:current",
@@ -396,14 +397,14 @@ describe("conversation reset confirmation", () => {
sendResetMessage,
});
host.hello = {
auth: { role: "operator", scopes: ["operator.read"] },
auth: { role: "operator", scopes: ["operator.write"] },
features: { methods: ["chat.send"] },
} as ApplicationGatewaySnapshot["hello"];
settleConfirmation?.(true);
await expect(pending).resolves.toBe("failed");
expect(sendResetMessage).not.toHaveBeenCalled();
expect(host.lastError).toContain("operator.write");
expect(host.lastError).toContain("operator.admin");
});
it("continues /reset when the session key changes to an equivalent alias", async () => {
+1 -1
View File
@@ -140,7 +140,7 @@ export function readChatResetTargetAccess(
}
const access = readSessionMethodAccess(currentSessionAccessSnapshot(host), {
method: "chat.send",
requiredScope: "operator.write",
requiredScope: "operator.admin",
});
return access.allowed ? { allowed: true } : access;
}
+1 -1
View File
@@ -4378,7 +4378,7 @@ describe("handleSendChat", () => {
connectionEpoch: 1,
confirmConversationReset: vi.fn(async () => await confirmation.promise),
hello: {
auth: { role: "operator", scopes: ["operator.write"] },
auth: { role: "operator", scopes: ["operator.admin"] },
features: { methods: ["chat.send"] },
},
});