@glwhappen/web-code 1.32.0 → 1.32.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/dist/assets/{index-u6XmIqLb.js → index-CfT-2Nkf.js} +2 -2
  2. package/dist/index.html +1 -1
  3. package/dist-server/server/cursor-cli.js +33 -15
  4. package/dist-server/server/cursor-cli.js.map +1 -1
  5. package/dist-server/server/gemini-cli.js +48 -29
  6. package/dist-server/server/gemini-cli.js.map +1 -1
  7. package/dist-server/server/index.js +20 -17
  8. package/dist-server/server/index.js.map +1 -1
  9. package/dist-server/server/modules/database/repositories/push-subscriptions.js +11 -5
  10. package/dist-server/server/modules/database/repositories/push-subscriptions.js.map +1 -1
  11. package/dist-server/server/modules/projects/projects.routes.js +14 -0
  12. package/dist-server/server/modules/projects/projects.routes.js.map +1 -1
  13. package/dist-server/server/modules/projects/services/project-authorization.service.js +54 -0
  14. package/dist-server/server/modules/projects/services/project-authorization.service.js.map +1 -0
  15. package/dist-server/server/modules/projects/services/project-clone.service.js +13 -4
  16. package/dist-server/server/modules/projects/services/project-clone.service.js.map +1 -1
  17. package/dist-server/server/modules/projects/services/project-management.service.js +4 -2
  18. package/dist-server/server/modules/projects/services/project-management.service.js.map +1 -1
  19. package/dist-server/server/modules/projects/tests/project-authorization.service.test.js +51 -0
  20. package/dist-server/server/modules/projects/tests/project-authorization.service.test.js.map +1 -0
  21. package/dist-server/server/modules/projects/tests/project-clone.service.test.js +10 -1
  22. package/dist-server/server/modules/projects/tests/project-clone.service.test.js.map +1 -1
  23. package/dist-server/server/modules/projects/tests/project-management.service.test.js +31 -10
  24. package/dist-server/server/modules/projects/tests/project-management.service.test.js.map +1 -1
  25. package/dist-server/server/modules/websocket/services/chat-websocket.service.js +77 -13
  26. package/dist-server/server/modules/websocket/services/chat-websocket.service.js.map +1 -1
  27. package/dist-server/server/routes/agent.js +35 -7
  28. package/dist-server/server/routes/agent.js.map +1 -1
  29. package/dist-server/server/routes/settings.js +1 -1
  30. package/dist-server/server/routes/settings.js.map +1 -1
  31. package/dist-server/server/services/notification-orchestrator.js +1 -1
  32. package/dist-server/server/services/notification-orchestrator.js.map +1 -1
  33. package/dist-server/server/shared/utils.js +60 -9
  34. package/dist-server/server/shared/utils.js.map +1 -1
  35. package/package.json +1 -1
  36. package/server/cursor-cli.js +33 -15
  37. package/server/gemini-cli.js +48 -28
  38. package/server/index.js +21 -17
  39. package/server/modules/database/repositories/push-subscriptions.ts +14 -5
  40. package/server/modules/projects/projects.routes.ts +16 -0
  41. package/server/modules/projects/services/project-authorization.service.ts +70 -0
  42. package/server/modules/projects/services/project-clone.service.ts +18 -4
  43. package/server/modules/projects/services/project-management.service.ts +12 -3
  44. package/server/modules/projects/tests/project-authorization.service.test.ts +68 -0
  45. package/server/modules/projects/tests/project-clone.service.test.ts +11 -1
  46. package/server/modules/projects/tests/project-management.service.test.ts +38 -10
  47. package/server/modules/websocket/services/chat-websocket.service.ts +87 -19
  48. package/server/routes/agent.js +34 -7
  49. package/server/routes/settings.js +1 -1
  50. package/server/services/notification-orchestrator.js +1 -1
  51. package/server/shared/utils.ts +70 -9
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-authorization.service.test.js","sourceRoot":"","sources":["../../../../../server/modules/projects/tests/project-authorization.service.test.ts"],"names":[],"mappings":"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"}
@@ -9,6 +9,7 @@ function buildDependencies(overrides = {}) {
9
9
  return {
10
10
  validatePath: async () => ({ valid: true, resolvedPath: '/workspace/root' }),
11
11
  ensureDirectory: async () => undefined,
12
+ resolveUserWorkspaceRoot: async () => '/workspace/root',
12
13
  pathExists: async () => false,
13
14
  removePath: async () => undefined,
14
15
  getGithubTokenById: async () => ({ github_token: 'token-value' }),
@@ -34,6 +35,7 @@ test('startCloneProject rejects when workspace path is missing', async () => {
34
35
  workspacePath: '',
35
36
  githubUrl: 'https://github.com/example/repo',
36
37
  userId: 1,
38
+ username: 'tester',
37
39
  }, {
38
40
  onProgress: () => undefined,
39
41
  onComplete: () => undefined,
@@ -48,6 +50,7 @@ test('startCloneProject rejects when github URL is missing', async () => {
48
50
  workspacePath: '/workspace/root',
49
51
  githubUrl: '',
50
52
  userId: 1,
53
+ username: 'tester',
51
54
  }, {
52
55
  onProgress: () => undefined,
53
56
  onComplete: () => undefined,
@@ -62,6 +65,7 @@ test('startCloneProject rejects github URL values that begin with option prefixe
62
65
  workspacePath: '/workspace/root',
63
66
  githubUrl: '--upload-pack=malicious',
64
67
  userId: 1,
68
+ username: 'tester',
65
69
  }, {
66
70
  onProgress: () => undefined,
67
71
  onComplete: () => undefined,
@@ -77,6 +81,7 @@ test('startCloneProject rejects when selected github token does not exist', asyn
77
81
  githubUrl: 'https://github.com/example/repo',
78
82
  githubTokenId: 12,
79
83
  userId: 1,
84
+ username: 'tester',
80
85
  }, {
81
86
  onProgress: () => undefined,
82
87
  onComplete: () => undefined,
@@ -95,10 +100,12 @@ test('startCloneProject completes and emits complete payload when git exits succ
95
100
  let capturedUserId = 0;
96
101
  let capturedProjectPath = '';
97
102
  let capturedCustomName = '';
103
+ let capturedUsername = '';
98
104
  const operation = await startCloneProject({
99
105
  workspacePath: '/workspace/root',
100
106
  githubUrl: 'https://github.com/example/repo.git',
101
107
  userId: 1,
108
+ username: 'tester',
102
109
  }, {
103
110
  onProgress: (message) => {
104
111
  progressMessages.push(message);
@@ -108,8 +115,9 @@ test('startCloneProject completes and emits complete payload when git exits succ
108
115
  },
109
116
  }, buildDependencies({
110
117
  spawnGitClone: () => gitProcess,
111
- registerProject: async (userId, projectPath, customName) => {
118
+ registerProject: async (userId, username, projectPath, customName) => {
112
119
  capturedUserId = userId;
120
+ capturedUsername = username;
113
121
  capturedProjectPath = projectPath;
114
122
  capturedCustomName = customName;
115
123
  return { project: { projectId: 'project-1', path: projectPath } };
@@ -119,6 +127,7 @@ test('startCloneProject completes and emits complete payload when git exits succ
119
127
  await operation.waitForCompletion;
120
128
  assert.ok(progressMessages.some((message) => message.includes("Cloning into 'repo'")));
121
129
  assert.equal(capturedUserId, 1);
130
+ assert.equal(capturedUsername, 'tester');
122
131
  assert.equal(capturedCustomName, 'repo');
123
132
  assert.equal(path.basename(capturedProjectPath), 'repo');
124
133
  assert.notEqual(completePayload, null);
@@ -1 +1 @@
1
- {"version":3,"file":"project-clone.service.test.js","sourceRoot":"","sources":["../../../../../server/modules/projects/tests/project-clone.service.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"project-clone.service.test.js","sourceRoot":"","sources":["../../../../../server/modules/projects/tests/project-clone.service.test.ts"],"names":[],"mappings":"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"}
@@ -3,15 +3,18 @@ import test from 'node:test';
3
3
  import { createProject } from '../../../modules/projects/services/project-management.service.js';
4
4
  import { AppError } from '../../../shared/utils.js';
5
5
  const TEST_USER_ID = 1;
6
+ const TEST_USERNAME = 'tester';
7
+ const TEST_USER_WORKSPACE_ROOT = '/workspace/tester';
6
8
  const projectRow = {
7
9
  project_id: 'project-1',
8
- project_path: '/workspace/my-project',
10
+ project_path: '/workspace/tester/my-project',
9
11
  custom_project_name: 'my-project',
10
12
  isStarred: 0,
11
13
  isArchived: 0,
12
14
  };
15
+ const resolveUserWorkspaceRoot = async () => TEST_USER_WORKSPACE_ROOT;
13
16
  test('createProject throws when project path is missing', async () => {
14
- await assert.rejects(async () => createProject({ userId: TEST_USER_ID, projectPath: '' }), (error) => {
17
+ await assert.rejects(async () => createProject({ userId: TEST_USER_ID, username: TEST_USERNAME, projectPath: '' }), (error) => {
15
18
  assert.ok(error instanceof AppError);
16
19
  assert.equal(error.code, 'PROJECT_PATH_REQUIRED');
17
20
  assert.equal(error.statusCode, 400);
@@ -19,9 +22,10 @@ test('createProject throws when project path is missing', async () => {
19
22
  });
20
23
  });
21
24
  test('createProject throws when path validation fails', async () => {
22
- await assert.rejects(async () => createProject({ userId: TEST_USER_ID, projectPath: '/invalid/path' }, {
25
+ await assert.rejects(async () => createProject({ userId: TEST_USER_ID, username: TEST_USERNAME, projectPath: '/invalid/path' }, {
23
26
  validatePath: async () => ({ valid: false, error: 'blocked path' }),
24
27
  ensureWorkspaceDirectory: async () => undefined,
28
+ resolveUserWorkspaceRoot,
25
29
  persistProjectPath: () => ({ outcome: 'created', project: projectRow }),
26
30
  getProjectByPath: () => projectRow,
27
31
  }), (error) => {
@@ -33,25 +37,41 @@ test('createProject throws when path validation fails', async () => {
33
37
  });
34
38
  });
35
39
  test('createProject throws conflict when active project path already exists', async () => {
36
- await assert.rejects(async () => createProject({ userId: TEST_USER_ID, projectPath: '/workspace/my-project' }, {
37
- validatePath: async () => ({ valid: true, resolvedPath: '/workspace/my-project' }),
40
+ await assert.rejects(async () => createProject({ userId: TEST_USER_ID, username: TEST_USERNAME, projectPath: '/workspace/tester/my-project' }, {
41
+ validatePath: async () => ({ valid: true, resolvedPath: '/workspace/tester/my-project' }),
38
42
  ensureWorkspaceDirectory: async () => undefined,
43
+ resolveUserWorkspaceRoot,
39
44
  persistProjectPath: () => ({ outcome: 'active_conflict', project: projectRow }),
40
45
  getProjectByPath: () => projectRow,
41
46
  }), (error) => {
42
47
  assert.ok(error instanceof AppError);
43
48
  assert.equal(error.code, 'PROJECT_ALREADY_EXISTS');
44
49
  assert.equal(error.statusCode, 409);
45
- assert.equal(error.details, 'Project path already exists: /workspace/my-project');
50
+ assert.equal(error.details, 'Project path already exists: /workspace/tester/my-project');
46
51
  return true;
47
52
  });
48
53
  });
54
+ test('createProject passes the per-user workspace root to validatePath', async () => {
55
+ let capturedWorkspaceRoot = '';
56
+ await createProject({ userId: TEST_USER_ID, username: TEST_USERNAME, projectPath: '/workspace/tester/my-project' }, {
57
+ validatePath: async (_projectPath, workspaceRoot) => {
58
+ capturedWorkspaceRoot = workspaceRoot;
59
+ return { valid: true, resolvedPath: '/workspace/tester/my-project' };
60
+ },
61
+ ensureWorkspaceDirectory: async () => undefined,
62
+ resolveUserWorkspaceRoot,
63
+ persistProjectPath: () => ({ outcome: 'created', project: projectRow }),
64
+ getProjectByPath: () => projectRow,
65
+ });
66
+ assert.equal(capturedWorkspaceRoot, TEST_USER_WORKSPACE_ROOT);
67
+ });
49
68
  test('createProject falls back to directory name when custom name is not provided', async () => {
50
69
  let capturedUserId = 0;
51
70
  let capturedCustomName = null;
52
- const result = await createProject({ userId: TEST_USER_ID, projectPath: '/workspace/my-project', customName: '' }, {
53
- validatePath: async () => ({ valid: true, resolvedPath: '/workspace/my-project' }),
71
+ const result = await createProject({ userId: TEST_USER_ID, username: TEST_USERNAME, projectPath: '/workspace/tester/my-project', customName: '' }, {
72
+ validatePath: async () => ({ valid: true, resolvedPath: '/workspace/tester/my-project' }),
54
73
  ensureWorkspaceDirectory: async () => undefined,
74
+ resolveUserWorkspaceRoot,
55
75
  persistProjectPath: (userId, _projectPath, customName) => {
56
76
  capturedUserId = userId;
57
77
  capturedCustomName = customName;
@@ -71,9 +91,10 @@ test('createProject falls back to directory name when custom name is not provide
71
91
  assert.equal(result.project.displayName, 'my-project');
72
92
  });
73
93
  test('createProject returns archived reuse outcome when archived row is reused', async () => {
74
- const result = await createProject({ userId: TEST_USER_ID, projectPath: '/workspace/my-project' }, {
75
- validatePath: async () => ({ valid: true, resolvedPath: '/workspace/my-project' }),
94
+ const result = await createProject({ userId: TEST_USER_ID, username: TEST_USERNAME, projectPath: '/workspace/tester/my-project' }, {
95
+ validatePath: async () => ({ valid: true, resolvedPath: '/workspace/tester/my-project' }),
76
96
  ensureWorkspaceDirectory: async () => undefined,
97
+ resolveUserWorkspaceRoot,
77
98
  persistProjectPath: () => ({
78
99
  outcome: 'reactivated_archived',
79
100
  project: {
@@ -1 +1 @@
1
- {"version":3,"file":"project-management.service.test.js","sourceRoot":"","sources":["../../../../../server/modules/projects/tests/project-management.service.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"project-management.service.test.js","sourceRoot":"","sources":["../../../../../server/modules/projects/tests/project-management.service.test.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,7 @@
1
+ import { assertUserOwnsProjectPath } from '../../../modules/projects/services/project-authorization.service.js';
1
2
  import { connectedClients } from '../../../modules/websocket/services/websocket-state.service.js';
2
3
  import { WebSocketWriter } from '../../../modules/websocket/services/websocket-writer.service.js';
3
- import { createNormalizedMessage, parseIncomingJsonObject } from '../../../shared/utils.js';
4
+ import { AppError, createNormalizedMessage, parseIncomingJsonObject } from '../../../shared/utils.js';
4
5
  const DEFAULT_PROVIDER = 'claude';
5
6
  /**
6
7
  * Normalizes potentially invalid provider names coming from websocket payloads.
@@ -28,6 +29,32 @@ function readRequestUserId(request) {
28
29
  }
29
30
  return null;
30
31
  }
32
+ /**
33
+ * Pulls `cwd` out of the websocket message options and confirms the caller
34
+ * owns it. Returning the normalized path lets the downstream spawn use the
35
+ * canonical form instead of whatever the client happened to send.
36
+ *
37
+ * Without this gate, any authenticated user could spawn a CLI in another
38
+ * user's project (or any path on disk) by setting `options.cwd` directly.
39
+ */
40
+ function authorizeOptionsCwd(userId, options) {
41
+ try {
42
+ const cwd = assertUserOwnsProjectPath(userId, options?.cwd);
43
+ return { authorized: true, cwd };
44
+ }
45
+ catch (error) {
46
+ if (error instanceof AppError) {
47
+ return { authorized: false, error };
48
+ }
49
+ return {
50
+ authorized: false,
51
+ error: new AppError('Failed to authorize working directory', {
52
+ code: 'PROJECT_AUTHORIZATION_FAILED',
53
+ statusCode: 500,
54
+ }),
55
+ };
56
+ }
57
+ }
31
58
  /**
32
59
  * Handles authenticated chat websocket messages used by the main chat panel.
33
60
  */
@@ -35,6 +62,14 @@ export function handleChatConnection(ws, request, dependencies) {
35
62
  console.log('[INFO] Chat WebSocket connected');
36
63
  connectedClients.add(ws);
37
64
  const writer = new WebSocketWriter(ws, readRequestUserId(request));
65
+ const sendAuthorizationError = (error, provider) => {
66
+ writer.send({
67
+ type: 'error',
68
+ error: error.message,
69
+ code: error.code,
70
+ provider,
71
+ });
72
+ };
38
73
  ws.on('message', async (rawMessage) => {
39
74
  try {
40
75
  const parsed = parseIncomingJsonObject(rawMessage);
@@ -47,26 +82,55 @@ export function handleChatConnection(ws, request, dependencies) {
47
82
  throw new Error('Message type is required');
48
83
  }
49
84
  if (messageType === 'claude-command') {
50
- await dependencies.queryClaudeSDK(data.command ?? '', data.options, writer);
85
+ const authorization = authorizeOptionsCwd(writer.userId, data.options);
86
+ if (!authorization.authorized) {
87
+ sendAuthorizationError(authorization.error, 'claude');
88
+ return;
89
+ }
90
+ const sanitizedOptions = { ...(data.options ?? {}), cwd: authorization.cwd };
91
+ await dependencies.queryClaudeSDK(data.command ?? '', sanitizedOptions, writer);
51
92
  return;
52
93
  }
53
94
  if (messageType === 'cursor-command') {
54
- await dependencies.spawnCursor(data.command ?? '', data.options, writer);
95
+ const authorization = authorizeOptionsCwd(writer.userId, data.options);
96
+ if (!authorization.authorized) {
97
+ sendAuthorizationError(authorization.error, 'cursor');
98
+ return;
99
+ }
100
+ const sanitizedOptions = { ...(data.options ?? {}), cwd: authorization.cwd };
101
+ await dependencies.spawnCursor(data.command ?? '', sanitizedOptions, writer);
55
102
  return;
56
103
  }
57
104
  if (messageType === 'codex-command') {
58
- await dependencies.queryCodex(data.command ?? '', data.options, writer);
105
+ const authorization = authorizeOptionsCwd(writer.userId, data.options);
106
+ if (!authorization.authorized) {
107
+ sendAuthorizationError(authorization.error, 'codex');
108
+ return;
109
+ }
110
+ const sanitizedOptions = { ...(data.options ?? {}), cwd: authorization.cwd };
111
+ await dependencies.queryCodex(data.command ?? '', sanitizedOptions, writer);
59
112
  return;
60
113
  }
61
114
  if (messageType === 'gemini-command') {
62
- await dependencies.spawnGemini(data.command ?? '', data.options, writer);
115
+ const authorization = authorizeOptionsCwd(writer.userId, data.options);
116
+ if (!authorization.authorized) {
117
+ sendAuthorizationError(authorization.error, 'gemini');
118
+ return;
119
+ }
120
+ const sanitizedOptions = { ...(data.options ?? {}), cwd: authorization.cwd };
121
+ await dependencies.spawnGemini(data.command ?? '', sanitizedOptions, writer);
63
122
  return;
64
123
  }
65
124
  if (messageType === 'cursor-resume') {
125
+ const authorization = authorizeOptionsCwd(writer.userId, data.options);
126
+ if (!authorization.authorized) {
127
+ sendAuthorizationError(authorization.error, 'cursor');
128
+ return;
129
+ }
66
130
  await dependencies.spawnCursor('', {
67
131
  sessionId: data.sessionId,
68
132
  resume: true,
69
- cwd: data.options?.cwd,
133
+ cwd: authorization.cwd,
70
134
  }, writer);
71
135
  return;
72
136
  }
@@ -76,13 +140,13 @@ export function handleChatConnection(ws, request, dependencies) {
76
140
  const userId = writer.userId;
77
141
  let success = false;
78
142
  if (provider === 'cursor') {
79
- success = dependencies.abortCursorSession(sessionId);
143
+ success = dependencies.abortCursorSession(sessionId, userId);
80
144
  }
81
145
  else if (provider === 'codex') {
82
146
  success = dependencies.abortCodexSession(sessionId, userId);
83
147
  }
84
148
  else if (provider === 'gemini') {
85
- success = dependencies.abortGeminiSession(sessionId);
149
+ success = dependencies.abortGeminiSession(sessionId, userId);
86
150
  }
87
151
  else {
88
152
  success = await dependencies.abortClaudeSDKSession(sessionId, userId);
@@ -110,7 +174,7 @@ export function handleChatConnection(ws, request, dependencies) {
110
174
  }
111
175
  if (messageType === 'cursor-abort') {
112
176
  const sessionId = typeof data.sessionId === 'string' ? data.sessionId : '';
113
- const success = dependencies.abortCursorSession(sessionId);
177
+ const success = dependencies.abortCursorSession(sessionId, writer.userId);
114
178
  writer.send(createNormalizedMessage({
115
179
  kind: 'complete',
116
180
  exitCode: success ? 0 : 1,
@@ -127,13 +191,13 @@ export function handleChatConnection(ws, request, dependencies) {
127
191
  const userId = writer.userId;
128
192
  let isActive = false;
129
193
  if (provider === 'cursor') {
130
- isActive = dependencies.isCursorSessionActive(sessionId);
194
+ isActive = dependencies.isCursorSessionActive(sessionId, userId);
131
195
  }
132
196
  else if (provider === 'codex') {
133
197
  isActive = dependencies.isCodexSessionActive(sessionId, userId);
134
198
  }
135
199
  else if (provider === 'gemini') {
136
- isActive = dependencies.isGeminiSessionActive(sessionId);
200
+ isActive = dependencies.isGeminiSessionActive(sessionId, userId);
137
201
  }
138
202
  else {
139
203
  isActive = dependencies.isClaudeSDKSessionActive(sessionId, userId);
@@ -168,9 +232,9 @@ export function handleChatConnection(ws, request, dependencies) {
168
232
  type: 'active-sessions',
169
233
  sessions: {
170
234
  claude: dependencies.getActiveClaudeSDKSessions(userId),
171
- cursor: dependencies.getActiveCursorSessions(),
235
+ cursor: dependencies.getActiveCursorSessions(userId),
172
236
  codex: dependencies.getActiveCodexSessions(userId),
173
- gemini: dependencies.getActiveGeminiSessions(),
237
+ gemini: dependencies.getActiveGeminiSessions(userId),
174
238
  },
175
239
  });
176
240
  }
@@ -1 +1 @@
1
- {"version":3,"file":"chat-websocket.service.js","sourceRoot":"","sources":["../../../../../server/modules/websocket/services/chat-websocket.service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"chat-websocket.service.js","sourceRoot":"","sources":["../../../../../server/modules/websocket/services/chat-websocket.service.ts"],"names":[],"mappings":"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"}
@@ -12,7 +12,8 @@ import { spawnGemini } from '../gemini-cli.js';
12
12
  import { Octokit } from '@octokit/rest';
13
13
  import { CLAUDE_MODELS, CURSOR_MODELS, CODEX_MODELS } from '../../shared/modelConstants.js';
14
14
  import { IS_PLATFORM } from '../constants/config.js';
15
- import { normalizeProjectPath } from '../shared/utils.js';
15
+ import { assertUserOwnsProjectPath } from '../modules/projects/services/project-authorization.service.js';
16
+ import { AppError, ensureUserWorkspaceRoot, normalizeProjectPath, validateWorkspacePath } from '../shared/utils.js';
16
17
  const router = express.Router();
17
18
  /**
18
19
  * Middleware to authenticate agent API requests.
@@ -805,7 +806,17 @@ router.post('/', validateExternalApiKey, async (req, res) => {
805
806
  const tokenToUse = githubToken || githubTokensDb.getActiveGithubToken(req.user.id);
806
807
  let targetPath;
807
808
  if (projectPath) {
808
- targetPath = projectPath;
809
+ // Confine clone destinations to the caller's per-user workspace root so
810
+ // an API key cannot drop a fresh checkout into another user's directory.
811
+ const userWorkspaceRoot = await ensureUserWorkspaceRoot(req.user.username);
812
+ const validation = await validateWorkspacePath(projectPath, userWorkspaceRoot);
813
+ if (!validation.valid) {
814
+ return res.status(403).json({
815
+ success: false,
816
+ error: validation.error || 'Invalid project path for clone destination',
817
+ });
818
+ }
819
+ targetPath = validation.resolvedPath || projectPath;
809
820
  }
810
821
  else {
811
822
  // Generate a unique path for cloning
@@ -815,9 +826,21 @@ router.post('/', validateExternalApiKey, async (req, res) => {
815
826
  finalProjectPath = await cloneGitHubRepo(githubUrl.trim(), tokenToUse, targetPath);
816
827
  }
817
828
  else {
818
- // Use existing project path
819
- finalProjectPath = normalizeProjectPath(path.resolve(projectPath));
820
- // Verify the path exists
829
+ // Existing project path: only the owning user may operate on it.
830
+ try {
831
+ finalProjectPath = assertUserOwnsProjectPath(req.user.id, projectPath);
832
+ }
833
+ catch (authorizationError) {
834
+ if (authorizationError instanceof AppError) {
835
+ return res.status(authorizationError.statusCode).json({
836
+ success: false,
837
+ error: authorizationError.message,
838
+ code: authorizationError.code,
839
+ });
840
+ }
841
+ throw authorizationError;
842
+ }
843
+ // Verify the path exists on disk; ownership check above already confirmed registration.
821
844
  try {
822
845
  await fs.access(finalProjectPath);
823
846
  }
@@ -826,10 +849,15 @@ router.post('/', validateExternalApiKey, async (req, res) => {
826
849
  }
827
850
  }
828
851
  finalProjectPath = normalizeProjectPath(finalProjectPath);
829
- // Warn if the same project path is actively used by another user
852
+ // Reject cross-user shared paths outright; previous warn-only behavior let
853
+ // user A operate inside a path also registered to user B.
830
854
  const sharedPathCheck = projectsDb.isProjectPathUsedByOthers(req.user.id, finalProjectPath);
831
855
  if (sharedPathCheck.used) {
832
- console.warn(`[WARN] Project path "${finalProjectPath}" is shared with user(s): ${sharedPathCheck.usernames.join(', ')}`);
856
+ return res.status(403).json({
857
+ success: false,
858
+ error: 'Project path is already registered to another user',
859
+ code: 'PROJECT_PATH_CROSS_USER',
860
+ });
833
861
  }
834
862
  // Register project path in DB (or reuse existing active registration)
835
863
  const registrationResult = projectsDb.createProjectPath(req.user.id, finalProjectPath, null);