fix(server-mode): a session-only share resumes in a free slot only
A start that names no slot means pane 0; for a user with only a session of the workspace that was let through and answered ERUNLIVE whenever another user's agent held pane 0 (found by the browser run). The client already sends slot: "auto"; the scope now requires it.
This commit is contained in:
@@ -479,6 +479,7 @@ describe("sharing one session", () => {
|
||||
});
|
||||
await refused("POST", "/api/run", { laneId: laneS, initialPrompt: "hi" });
|
||||
await refused("POST", `/api/lanes/${laneS}/start`, { resumeSessionId: "s1-shared", slot: 0 });
|
||||
await refused("POST", `/api/lanes/${laneS}/start`, { resumeSessionId: "s1-shared" });
|
||||
await refused("GET", `/api/lanes/${laneS}/git/tree?source=1`);
|
||||
await refused("GET", `/api/artifacts/candidates?laneId=${laneS}`);
|
||||
await refused("PATCH", "/api/sessions/s1-shared", { name: "mine now" });
|
||||
@@ -494,7 +495,10 @@ describe("sharing one session", () => {
|
||||
db.prepare("INSERT INTO session_shares (session_id, user_id) VALUES ('sT-other', ?)").run(
|
||||
users.carol.id
|
||||
);
|
||||
await refused("POST", `/api/lanes/${laneT}/start`, { resumeSessionId: "s1-shared" });
|
||||
await refused("POST", `/api/lanes/${laneT}/start`, {
|
||||
resumeSessionId: "s1-shared",
|
||||
slot: "auto",
|
||||
});
|
||||
db.prepare("DELETE FROM session_shares WHERE session_id = 'sT-other'").run();
|
||||
// Another session of it is not even there.
|
||||
const other = await call("POST", `/api/lanes/${laneS}/start`, {
|
||||
@@ -505,7 +509,7 @@ describe("sharing one session", () => {
|
||||
// A resume of the shared one gets past the scope (and then needs their own account).
|
||||
const resume = await call("POST", `/api/lanes/${laneS}/start`, {
|
||||
as: "carol",
|
||||
body: { resumeSessionId: "s1-shared", prompt: "hi" },
|
||||
body: { resumeSessionId: "s1-shared", prompt: "hi", slot: "auto" },
|
||||
});
|
||||
assert.ok(![403, 404].includes(resume.status), JSON.stringify(resume.body));
|
||||
// Reads of the workspace's git and its own row pass.
|
||||
|
||||
+3
-2
@@ -399,8 +399,9 @@ function sessionShareAllows(req, rest, laneId) {
|
||||
b.forkSession !== true &&
|
||||
b.shell !== true &&
|
||||
b.resume !== true &&
|
||||
// A free slot the server picks: pane 0 is the workspace's own run.
|
||||
(b.slot === undefined || b.slot === "auto") &&
|
||||
// A free slot the server picks (no slot means pane 0, the workspace's
|
||||
// own run — another user's live agent there would answer ERUNLIVE).
|
||||
b.slot === "auto" &&
|
||||
sessionSharedWith(b.resumeSessionId, memberId(req)) &&
|
||||
Boolean(
|
||||
sql("SELECT 1 FROM sessions WHERE id = ? AND lane_id = ?").get(b.resumeSessionId, laneId)
|
||||
|
||||
Reference in New Issue
Block a user