diff --git a/tests/unit/session-discovery.test.ts b/tests/unit/session-discovery.test.ts index 4fdcbd2..cc2f828 100644 --- a/tests/unit/session-discovery.test.ts +++ b/tests/unit/session-discovery.test.ts @@ -15,12 +15,13 @@ describe("session-discovery", () => { const projectDir = path.join(tmpDir, "test-project"); await fs.mkdir(projectDir, { recursive: true }); + const sessionPath = path.join(projectDir, "sess-001.jsonl"); await fs.writeFile( path.join(projectDir, "sessions-index.json"), makeIndex([ { sessionId: "sess-001", - fullPath: "/tmp/sess-001.jsonl", + fullPath: sessionPath, summary: "Test session", firstPrompt: "Hello", created: "2025-10-15T10:00:00Z", @@ -36,7 +37,7 @@ describe("session-discovery", () => { expect(sessions[0].summary).toBe("Test session"); expect(sessions[0].project).toBe("test-project"); expect(sessions[0].messageCount).toBe(5); - expect(sessions[0].path).toBe("/tmp/sess-001.jsonl"); + expect(sessions[0].path).toBe(sessionPath); await fs.rm(tmpDir, { recursive: true }); }); @@ -116,6 +117,7 @@ describe("session-discovery", () => { const projectDir = path.join(tmpDir, "traversal-project"); await fs.mkdir(projectDir, { recursive: true }); + const goodPath = path.join(projectDir, "good-001.jsonl"); await fs.writeFile( path.join(projectDir, "sessions-index.json"), makeIndex([ @@ -133,7 +135,7 @@ describe("session-discovery", () => { }, { sessionId: "good-001", - fullPath: "/home/ubuntu/.claude/projects/xyz/good-001.jsonl", + fullPath: goodPath, created: "2025-10-15T10:00:00Z", modified: "2025-10-15T11:00:00Z", }, @@ -147,17 +149,23 @@ describe("session-discovery", () => { await fs.rm(tmpDir, { recursive: true }); }); - it("uses fullPath from index entry", async () => { - const tmpDir = path.join(os.tmpdir(), `sv-test-fp-${Date.now()}`); - const projectDir = path.join(tmpDir, "fp-project"); + it("rejects absolute paths outside the projects directory", async () => { + const tmpDir = path.join(os.tmpdir(), `sv-test-containment-${Date.now()}`); + const projectDir = path.join(tmpDir, "contained-project"); await fs.mkdir(projectDir, { recursive: true }); await fs.writeFile( path.join(projectDir, "sessions-index.json"), makeIndex([ { - sessionId: "fp-001", - fullPath: "/home/ubuntu/.claude/projects/xyz/fp-001.jsonl", + sessionId: "escaped-001", + fullPath: "/etc/shadow.jsonl", + created: "2025-10-15T10:00:00Z", + modified: "2025-10-15T11:00:00Z", + }, + { + sessionId: "escaped-002", + fullPath: "/tmp/other-dir/secret.jsonl", created: "2025-10-15T10:00:00Z", modified: "2025-10-15T11:00:00Z", }, @@ -165,10 +173,32 @@ describe("session-discovery", () => { ); const sessions = await discoverSessions(tmpDir); - expect(sessions[0].path).toBe( - "/home/ubuntu/.claude/projects/xyz/fp-001.jsonl" + expect(sessions).toHaveLength(0); + + await fs.rm(tmpDir, { recursive: true }); + }); + + it("uses fullPath from index entry", async () => { + const tmpDir = path.join(os.tmpdir(), `sv-test-fp-${Date.now()}`); + const projectDir = path.join(tmpDir, "fp-project"); + await fs.mkdir(projectDir, { recursive: true }); + + const sessionPath = path.join(projectDir, "fp-001.jsonl"); + await fs.writeFile( + path.join(projectDir, "sessions-index.json"), + makeIndex([ + { + sessionId: "fp-001", + fullPath: sessionPath, + created: "2025-10-15T10:00:00Z", + modified: "2025-10-15T11:00:00Z", + }, + ]) ); + const sessions = await discoverSessions(tmpDir); + expect(sessions[0].path).toBe(sessionPath); + await fs.rm(tmpDir, { recursive: true }); }); });