Fix same-directory workspace ownership
This commit is contained in:
@@ -110,6 +110,20 @@ it("lists subdirectory terminals when querying the workspace root", async () =>
|
||||
expect(rootTerminals.map((terminal) => terminal.id)).toEqual([created.id]);
|
||||
});
|
||||
|
||||
it("includes only stamped terminals in workspace-scoped queries", async () => {
|
||||
manager = createTerminalManager();
|
||||
const cwd = realpathSync(tmpdir());
|
||||
const legacy = await manager.createTerminal({ cwd });
|
||||
const owned = await manager.createTerminal({ cwd, workspaceId: "ws-owned" });
|
||||
const sibling = await manager.createTerminal({ cwd, workspaceId: "ws-sibling" });
|
||||
|
||||
const scoped = await manager.getTerminals(cwd, { workspaceId: "ws-owned" });
|
||||
const unscoped = await manager.getTerminals(cwd);
|
||||
|
||||
expect(scoped.map((terminal) => terminal.id)).toEqual([owned.id]);
|
||||
expect(unscoped.map((terminal) => terminal.id)).toEqual([legacy.id, owned.id, sibling.id]);
|
||||
});
|
||||
|
||||
it("creates additional terminal with auto-incrementing name", async () => {
|
||||
manager = createTerminalManager();
|
||||
const cwd = realpathSync(tmpdir());
|
||||
|
||||
@@ -296,14 +296,10 @@ export function createTerminalManager(
|
||||
}
|
||||
|
||||
// When the query carries a workspaceId, two workspaces sharing a cwd must
|
||||
// not see each other's terminals. Exclude sessions owned by a different
|
||||
// workspace; keep sessions without an owner (COMPAT: created by clients
|
||||
// that predate terminal workspace ownership).
|
||||
// not see each other's terminals. A missing owner is not workspace
|
||||
// membership; unscoped callers can still list those legacy terminals.
|
||||
if (options?.workspaceId !== undefined) {
|
||||
return sessions.filter(
|
||||
(session) =>
|
||||
session.workspaceId === undefined || session.workspaceId === options.workspaceId,
|
||||
);
|
||||
return sessions.filter((session) => session.workspaceId === options.workspaceId);
|
||||
}
|
||||
return sessions;
|
||||
},
|
||||
|
||||
@@ -566,6 +566,57 @@ it("lists terminals locally without waiting on the worker", async () => {
|
||||
expect(worker.sentMessages.some((message) => message.type === "getTerminals")).toBe(false);
|
||||
});
|
||||
|
||||
it("includes only stamped terminals in workspace-scoped local reads", async () => {
|
||||
const worker = new FakeTerminalWorker();
|
||||
manager = createWorkerTerminalManager({
|
||||
requestTimeoutMs: 5,
|
||||
forkWorker: () => worker,
|
||||
});
|
||||
|
||||
worker.emitWorkerMessage({
|
||||
type: "terminalCreated",
|
||||
terminal: {
|
||||
id: "terminal-legacy",
|
||||
name: "Legacy",
|
||||
cwd: "/workspace",
|
||||
activity: null,
|
||||
},
|
||||
state: createTerminalState(),
|
||||
});
|
||||
worker.emitWorkerMessage({
|
||||
type: "terminalCreated",
|
||||
terminal: {
|
||||
id: "terminal-owned",
|
||||
name: "Owned",
|
||||
cwd: "/workspace",
|
||||
workspaceId: "ws-owned",
|
||||
activity: null,
|
||||
},
|
||||
state: createTerminalState(),
|
||||
});
|
||||
worker.emitWorkerMessage({
|
||||
type: "terminalCreated",
|
||||
terminal: {
|
||||
id: "terminal-sibling",
|
||||
name: "Sibling",
|
||||
cwd: "/workspace",
|
||||
workspaceId: "ws-sibling",
|
||||
activity: null,
|
||||
},
|
||||
state: createTerminalState(),
|
||||
});
|
||||
|
||||
const scoped = await manager.getTerminals("/workspace", { workspaceId: "ws-owned" });
|
||||
const unscoped = await manager.getTerminals("/workspace");
|
||||
|
||||
expect(scoped.map((terminal) => terminal.id)).toEqual(["terminal-owned"]);
|
||||
expect(unscoped.map((terminal) => terminal.id)).toEqual([
|
||||
"terminal-legacy",
|
||||
"terminal-owned",
|
||||
"terminal-sibling",
|
||||
]);
|
||||
});
|
||||
|
||||
it("rejects non-absolute cwd in getTerminals", async () => {
|
||||
const worker = new FakeTerminalWorker();
|
||||
manager = createWorkerTerminalManager({
|
||||
|
||||
@@ -653,14 +653,10 @@ export function createWorkerTerminalManager(
|
||||
}
|
||||
|
||||
// When the query carries a workspaceId, two workspaces sharing a cwd must
|
||||
// not see each other's terminals. Exclude sessions owned by a different
|
||||
// workspace; keep sessions without an owner (COMPAT: created by clients
|
||||
// that predate terminal workspace ownership).
|
||||
// not see each other's terminals. A missing owner is not workspace
|
||||
// membership; unscoped callers can still list those legacy terminals.
|
||||
if (options?.workspaceId !== undefined) {
|
||||
return sessions.filter(
|
||||
(session) =>
|
||||
session.workspaceId === undefined || session.workspaceId === options.workspaceId,
|
||||
);
|
||||
return sessions.filter((session) => session.workspaceId === options.workspaceId);
|
||||
}
|
||||
return sessions;
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user