@agent-relay/cloud 0.1.0
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.
- package/dist/api/admin.d.ts +8 -0
- package/dist/api/admin.d.ts.map +1 -0
- package/dist/api/admin.js +225 -0
- package/dist/api/admin.js.map +1 -0
- package/dist/api/auth.d.ts +20 -0
- package/dist/api/auth.d.ts.map +1 -0
- package/dist/api/auth.js +136 -0
- package/dist/api/auth.js.map +1 -0
- package/dist/api/billing.d.ts +7 -0
- package/dist/api/billing.d.ts.map +1 -0
- package/dist/api/billing.js +564 -0
- package/dist/api/billing.js.map +1 -0
- package/dist/api/cli-pty-runner.d.ts +53 -0
- package/dist/api/cli-pty-runner.d.ts.map +1 -0
- package/dist/api/cli-pty-runner.js +193 -0
- package/dist/api/cli-pty-runner.js.map +1 -0
- package/dist/api/codex-auth-helper.d.ts +21 -0
- package/dist/api/codex-auth-helper.d.ts.map +1 -0
- package/dist/api/codex-auth-helper.js +327 -0
- package/dist/api/codex-auth-helper.js.map +1 -0
- package/dist/api/consensus.d.ts +13 -0
- package/dist/api/consensus.d.ts.map +1 -0
- package/dist/api/consensus.js +261 -0
- package/dist/api/consensus.js.map +1 -0
- package/dist/api/coordinators.d.ts +8 -0
- package/dist/api/coordinators.d.ts.map +1 -0
- package/dist/api/coordinators.js +750 -0
- package/dist/api/coordinators.js.map +1 -0
- package/dist/api/daemons.d.ts +12 -0
- package/dist/api/daemons.d.ts.map +1 -0
- package/dist/api/daemons.js +535 -0
- package/dist/api/daemons.js.map +1 -0
- package/dist/api/generic-webhooks.d.ts +8 -0
- package/dist/api/generic-webhooks.d.ts.map +1 -0
- package/dist/api/generic-webhooks.js +129 -0
- package/dist/api/generic-webhooks.js.map +1 -0
- package/dist/api/git.d.ts +8 -0
- package/dist/api/git.d.ts.map +1 -0
- package/dist/api/git.js +269 -0
- package/dist/api/git.js.map +1 -0
- package/dist/api/github-app.d.ts +11 -0
- package/dist/api/github-app.d.ts.map +1 -0
- package/dist/api/github-app.js +223 -0
- package/dist/api/github-app.js.map +1 -0
- package/dist/api/middleware/planLimits.d.ts +43 -0
- package/dist/api/middleware/planLimits.d.ts.map +1 -0
- package/dist/api/middleware/planLimits.js +202 -0
- package/dist/api/middleware/planLimits.js.map +1 -0
- package/dist/api/monitoring.d.ts +11 -0
- package/dist/api/monitoring.d.ts.map +1 -0
- package/dist/api/monitoring.js +578 -0
- package/dist/api/monitoring.js.map +1 -0
- package/dist/api/nango-auth.d.ts +9 -0
- package/dist/api/nango-auth.d.ts.map +1 -0
- package/dist/api/nango-auth.js +674 -0
- package/dist/api/nango-auth.js.map +1 -0
- package/dist/api/onboarding.d.ts +15 -0
- package/dist/api/onboarding.d.ts.map +1 -0
- package/dist/api/onboarding.js +679 -0
- package/dist/api/onboarding.js.map +1 -0
- package/dist/api/policy.d.ts +8 -0
- package/dist/api/policy.d.ts.map +1 -0
- package/dist/api/policy.js +229 -0
- package/dist/api/policy.js.map +1 -0
- package/dist/api/provider-env.d.ts +14 -0
- package/dist/api/provider-env.d.ts.map +1 -0
- package/dist/api/provider-env.js +75 -0
- package/dist/api/provider-env.js.map +1 -0
- package/dist/api/providers.d.ts +7 -0
- package/dist/api/providers.d.ts.map +1 -0
- package/dist/api/providers.js +564 -0
- package/dist/api/providers.js.map +1 -0
- package/dist/api/repos.d.ts +8 -0
- package/dist/api/repos.d.ts.map +1 -0
- package/dist/api/repos.js +577 -0
- package/dist/api/repos.js.map +1 -0
- package/dist/api/sessions.d.ts +11 -0
- package/dist/api/sessions.d.ts.map +1 -0
- package/dist/api/sessions.js +302 -0
- package/dist/api/sessions.js.map +1 -0
- package/dist/api/teams.d.ts +7 -0
- package/dist/api/teams.d.ts.map +1 -0
- package/dist/api/teams.js +281 -0
- package/dist/api/teams.js.map +1 -0
- package/dist/api/test-helpers.d.ts +10 -0
- package/dist/api/test-helpers.d.ts.map +1 -0
- package/dist/api/test-helpers.js +745 -0
- package/dist/api/test-helpers.js.map +1 -0
- package/dist/api/usage.d.ts +7 -0
- package/dist/api/usage.d.ts.map +1 -0
- package/dist/api/usage.js +111 -0
- package/dist/api/usage.js.map +1 -0
- package/dist/api/webhooks.d.ts +8 -0
- package/dist/api/webhooks.d.ts.map +1 -0
- package/dist/api/webhooks.js +645 -0
- package/dist/api/webhooks.js.map +1 -0
- package/dist/api/workspaces.d.ts +25 -0
- package/dist/api/workspaces.d.ts.map +1 -0
- package/dist/api/workspaces.js +1799 -0
- package/dist/api/workspaces.js.map +1 -0
- package/dist/billing/index.d.ts +9 -0
- package/dist/billing/index.d.ts.map +1 -0
- package/dist/billing/index.js +9 -0
- package/dist/billing/index.js.map +1 -0
- package/dist/billing/plans.d.ts +39 -0
- package/dist/billing/plans.d.ts.map +1 -0
- package/dist/billing/plans.js +245 -0
- package/dist/billing/plans.js.map +1 -0
- package/dist/billing/service.d.ts +80 -0
- package/dist/billing/service.d.ts.map +1 -0
- package/dist/billing/service.js +388 -0
- package/dist/billing/service.js.map +1 -0
- package/dist/billing/types.d.ts +141 -0
- package/dist/billing/types.d.ts.map +1 -0
- package/dist/billing/types.js +7 -0
- package/dist/billing/types.js.map +1 -0
- package/dist/config.d.ts +5 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +5 -0
- package/dist/config.js.map +1 -0
- package/dist/db/bulk-ingest.d.ts +89 -0
- package/dist/db/bulk-ingest.d.ts.map +1 -0
- package/dist/db/bulk-ingest.js +268 -0
- package/dist/db/bulk-ingest.js.map +1 -0
- package/dist/db/drizzle.d.ts +256 -0
- package/dist/db/drizzle.d.ts.map +1 -0
- package/dist/db/drizzle.js +1286 -0
- package/dist/db/drizzle.js.map +1 -0
- package/dist/db/index.d.ts +55 -0
- package/dist/db/index.d.ts.map +1 -0
- package/dist/db/index.js +68 -0
- package/dist/db/index.js.map +1 -0
- package/dist/db/schema.d.ts +4873 -0
- package/dist/db/schema.d.ts.map +1 -0
- package/dist/db/schema.js +620 -0
- package/dist/db/schema.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +38 -0
- package/dist/index.js.map +1 -0
- package/dist/provisioner/index.d.ts +207 -0
- package/dist/provisioner/index.d.ts.map +1 -0
- package/dist/provisioner/index.js +2114 -0
- package/dist/provisioner/index.js.map +1 -0
- package/dist/server.d.ts +17 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +1924 -0
- package/dist/server.js.map +1 -0
- package/dist/services/auto-scaler.d.ts +152 -0
- package/dist/services/auto-scaler.d.ts.map +1 -0
- package/dist/services/auto-scaler.js +439 -0
- package/dist/services/auto-scaler.js.map +1 -0
- package/dist/services/capacity-manager.d.ts +148 -0
- package/dist/services/capacity-manager.d.ts.map +1 -0
- package/dist/services/capacity-manager.js +449 -0
- package/dist/services/capacity-manager.js.map +1 -0
- package/dist/services/ci-agent-spawner.d.ts +49 -0
- package/dist/services/ci-agent-spawner.d.ts.map +1 -0
- package/dist/services/ci-agent-spawner.js +373 -0
- package/dist/services/ci-agent-spawner.js.map +1 -0
- package/dist/services/cloud-message-bus.d.ts +28 -0
- package/dist/services/cloud-message-bus.d.ts.map +1 -0
- package/dist/services/cloud-message-bus.js +19 -0
- package/dist/services/cloud-message-bus.js.map +1 -0
- package/dist/services/compute-enforcement.d.ts +57 -0
- package/dist/services/compute-enforcement.d.ts.map +1 -0
- package/dist/services/compute-enforcement.js +175 -0
- package/dist/services/compute-enforcement.js.map +1 -0
- package/dist/services/coordinator.d.ts +62 -0
- package/dist/services/coordinator.d.ts.map +1 -0
- package/dist/services/coordinator.js +389 -0
- package/dist/services/coordinator.js.map +1 -0
- package/dist/services/index.d.ts +17 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +25 -0
- package/dist/services/index.js.map +1 -0
- package/dist/services/intro-expiration.d.ts +60 -0
- package/dist/services/intro-expiration.d.ts.map +1 -0
- package/dist/services/intro-expiration.js +252 -0
- package/dist/services/intro-expiration.js.map +1 -0
- package/dist/services/mention-handler.d.ts +65 -0
- package/dist/services/mention-handler.d.ts.map +1 -0
- package/dist/services/mention-handler.js +405 -0
- package/dist/services/mention-handler.js.map +1 -0
- package/dist/services/nango.d.ts +201 -0
- package/dist/services/nango.d.ts.map +1 -0
- package/dist/services/nango.js +392 -0
- package/dist/services/nango.js.map +1 -0
- package/dist/services/persistence.d.ts +131 -0
- package/dist/services/persistence.d.ts.map +1 -0
- package/dist/services/persistence.js +200 -0
- package/dist/services/persistence.js.map +1 -0
- package/dist/services/planLimits.d.ts +147 -0
- package/dist/services/planLimits.d.ts.map +1 -0
- package/dist/services/planLimits.js +335 -0
- package/dist/services/planLimits.js.map +1 -0
- package/dist/services/presence-registry.d.ts +56 -0
- package/dist/services/presence-registry.d.ts.map +1 -0
- package/dist/services/presence-registry.js +91 -0
- package/dist/services/presence-registry.js.map +1 -0
- package/dist/services/scaling-orchestrator.d.ts +159 -0
- package/dist/services/scaling-orchestrator.d.ts.map +1 -0
- package/dist/services/scaling-orchestrator.js +502 -0
- package/dist/services/scaling-orchestrator.js.map +1 -0
- package/dist/services/scaling-policy.d.ts +121 -0
- package/dist/services/scaling-policy.d.ts.map +1 -0
- package/dist/services/scaling-policy.js +415 -0
- package/dist/services/scaling-policy.js.map +1 -0
- package/dist/services/ssh-security.d.ts +31 -0
- package/dist/services/ssh-security.d.ts.map +1 -0
- package/dist/services/ssh-security.js +63 -0
- package/dist/services/ssh-security.js.map +1 -0
- package/dist/services/workspace-keepalive.d.ts +76 -0
- package/dist/services/workspace-keepalive.d.ts.map +1 -0
- package/dist/services/workspace-keepalive.js +234 -0
- package/dist/services/workspace-keepalive.js.map +1 -0
- package/dist/shims/consensus.d.ts +23 -0
- package/dist/shims/consensus.d.ts.map +1 -0
- package/dist/shims/consensus.js +5 -0
- package/dist/shims/consensus.js.map +1 -0
- package/dist/webhooks/index.d.ts +24 -0
- package/dist/webhooks/index.d.ts.map +1 -0
- package/dist/webhooks/index.js +29 -0
- package/dist/webhooks/index.js.map +1 -0
- package/dist/webhooks/parsers/github.d.ts +8 -0
- package/dist/webhooks/parsers/github.d.ts.map +1 -0
- package/dist/webhooks/parsers/github.js +234 -0
- package/dist/webhooks/parsers/github.js.map +1 -0
- package/dist/webhooks/parsers/index.d.ts +23 -0
- package/dist/webhooks/parsers/index.d.ts.map +1 -0
- package/dist/webhooks/parsers/index.js +30 -0
- package/dist/webhooks/parsers/index.js.map +1 -0
- package/dist/webhooks/parsers/linear.d.ts +9 -0
- package/dist/webhooks/parsers/linear.d.ts.map +1 -0
- package/dist/webhooks/parsers/linear.js +258 -0
- package/dist/webhooks/parsers/linear.js.map +1 -0
- package/dist/webhooks/parsers/slack.d.ts +9 -0
- package/dist/webhooks/parsers/slack.d.ts.map +1 -0
- package/dist/webhooks/parsers/slack.js +214 -0
- package/dist/webhooks/parsers/slack.js.map +1 -0
- package/dist/webhooks/responders/github.d.ts +8 -0
- package/dist/webhooks/responders/github.d.ts.map +1 -0
- package/dist/webhooks/responders/github.js +73 -0
- package/dist/webhooks/responders/github.js.map +1 -0
- package/dist/webhooks/responders/index.d.ts +23 -0
- package/dist/webhooks/responders/index.d.ts.map +1 -0
- package/dist/webhooks/responders/index.js +30 -0
- package/dist/webhooks/responders/index.js.map +1 -0
- package/dist/webhooks/responders/linear.d.ts +9 -0
- package/dist/webhooks/responders/linear.d.ts.map +1 -0
- package/dist/webhooks/responders/linear.js +149 -0
- package/dist/webhooks/responders/linear.js.map +1 -0
- package/dist/webhooks/responders/slack.d.ts +20 -0
- package/dist/webhooks/responders/slack.d.ts.map +1 -0
- package/dist/webhooks/responders/slack.js +178 -0
- package/dist/webhooks/responders/slack.js.map +1 -0
- package/dist/webhooks/router.d.ts +25 -0
- package/dist/webhooks/router.d.ts.map +1 -0
- package/dist/webhooks/router.js +504 -0
- package/dist/webhooks/router.js.map +1 -0
- package/dist/webhooks/rules-engine.d.ts +24 -0
- package/dist/webhooks/rules-engine.d.ts.map +1 -0
- package/dist/webhooks/rules-engine.js +287 -0
- package/dist/webhooks/rules-engine.js.map +1 -0
- package/dist/webhooks/types.d.ts +186 -0
- package/dist/webhooks/types.d.ts.map +1 -0
- package/dist/webhooks/types.js +8 -0
- package/dist/webhooks/types.js.map +1 -0
- package/package.json +55 -0
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent Session Persistence API Routes
|
|
3
|
+
*
|
|
4
|
+
* Provides endpoints for workspace containers to persist agent session data.
|
|
5
|
+
* Workspaces call these endpoints instead of accessing the database directly,
|
|
6
|
+
* which provides better security isolation (workspaces can only write their own data).
|
|
7
|
+
*
|
|
8
|
+
* Authentication: Workspace token (same as git gateway)
|
|
9
|
+
*/
|
|
10
|
+
import crypto from 'crypto';
|
|
11
|
+
import { Router } from 'express';
|
|
12
|
+
import { eq } from 'drizzle-orm';
|
|
13
|
+
import { getDb } from '../db/drizzle.js';
|
|
14
|
+
import { agentSessions, agentSummaries } from '../db/schema.js';
|
|
15
|
+
import { getConfig } from '../config.js';
|
|
16
|
+
export const sessionsRouter = Router();
|
|
17
|
+
// Validation patterns
|
|
18
|
+
const UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
19
|
+
const AGENT_NAME_REGEX = /^[a-zA-Z0-9_-]+$/;
|
|
20
|
+
const MAX_AGENT_NAME_LENGTH = 255;
|
|
21
|
+
/**
|
|
22
|
+
* Generate expected workspace token using HMAC
|
|
23
|
+
*/
|
|
24
|
+
function generateExpectedToken(workspaceId) {
|
|
25
|
+
const config = getConfig();
|
|
26
|
+
return crypto
|
|
27
|
+
.createHmac('sha256', config.sessionSecret)
|
|
28
|
+
.update(`workspace:${workspaceId}`)
|
|
29
|
+
.digest('hex');
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Verify workspace access token
|
|
33
|
+
*/
|
|
34
|
+
function verifyWorkspaceToken(req, workspaceId) {
|
|
35
|
+
const authHeader = req.get('authorization');
|
|
36
|
+
if (!authHeader) {
|
|
37
|
+
return { valid: false, reason: 'No Authorization header. WORKSPACE_TOKEN may not be set in the container.' };
|
|
38
|
+
}
|
|
39
|
+
if (!authHeader.startsWith('Bearer ')) {
|
|
40
|
+
return { valid: false, reason: 'Invalid Authorization header format. Expected: Bearer <token>' };
|
|
41
|
+
}
|
|
42
|
+
const providedToken = authHeader.slice(7);
|
|
43
|
+
if (!providedToken) {
|
|
44
|
+
return { valid: false, reason: 'Empty bearer token provided.' };
|
|
45
|
+
}
|
|
46
|
+
const expectedToken = generateExpectedToken(workspaceId);
|
|
47
|
+
try {
|
|
48
|
+
const isValid = crypto.timingSafeEqual(Buffer.from(providedToken), Buffer.from(expectedToken));
|
|
49
|
+
if (!isValid) {
|
|
50
|
+
return { valid: false, reason: 'Token mismatch. Workspace may need reprovisioning or SESSION_SECRET changed.' };
|
|
51
|
+
}
|
|
52
|
+
return { valid: true };
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
return { valid: false, reason: 'Token comparison failed (length mismatch). Workspace may need reprovisioning.' };
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Validate UUID format
|
|
60
|
+
*/
|
|
61
|
+
function isValidUUID(value) {
|
|
62
|
+
return UUID_REGEX.test(value);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Validate agent name format
|
|
66
|
+
*/
|
|
67
|
+
function isValidAgentName(name) {
|
|
68
|
+
if (name.length > MAX_AGENT_NAME_LENGTH) {
|
|
69
|
+
return { valid: false, reason: `agentName exceeds maximum length of ${MAX_AGENT_NAME_LENGTH} characters` };
|
|
70
|
+
}
|
|
71
|
+
if (!AGENT_NAME_REGEX.test(name)) {
|
|
72
|
+
return { valid: false, reason: 'agentName contains invalid characters (only alphanumeric, underscore, and hyphen allowed)' };
|
|
73
|
+
}
|
|
74
|
+
return { valid: true };
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Validate summary object structure
|
|
78
|
+
*/
|
|
79
|
+
function validateSummary(summary) {
|
|
80
|
+
if (typeof summary !== 'object' || summary === null || Array.isArray(summary)) {
|
|
81
|
+
return { valid: false, reason: 'summary must be an object' };
|
|
82
|
+
}
|
|
83
|
+
const s = summary;
|
|
84
|
+
const allowedKeys = ['currentTask', 'completedTasks', 'decisions', 'context', 'files'];
|
|
85
|
+
for (const key of Object.keys(s)) {
|
|
86
|
+
if (!allowedKeys.includes(key)) {
|
|
87
|
+
// Allow extra keys but log warning (don't reject - for forward compatibility)
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
// Validate types of known fields
|
|
92
|
+
if (s.currentTask !== undefined && typeof s.currentTask !== 'string') {
|
|
93
|
+
return { valid: false, reason: 'summary.currentTask must be a string' };
|
|
94
|
+
}
|
|
95
|
+
if (s.completedTasks !== undefined && !Array.isArray(s.completedTasks)) {
|
|
96
|
+
return { valid: false, reason: 'summary.completedTasks must be an array' };
|
|
97
|
+
}
|
|
98
|
+
if (s.decisions !== undefined && !Array.isArray(s.decisions)) {
|
|
99
|
+
return { valid: false, reason: 'summary.decisions must be an array' };
|
|
100
|
+
}
|
|
101
|
+
if (s.context !== undefined && typeof s.context !== 'string') {
|
|
102
|
+
return { valid: false, reason: 'summary.context must be a string' };
|
|
103
|
+
}
|
|
104
|
+
if (s.files !== undefined && !Array.isArray(s.files)) {
|
|
105
|
+
return { valid: false, reason: 'summary.files must be an array' };
|
|
106
|
+
}
|
|
107
|
+
return { valid: true };
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* POST /api/sessions/create
|
|
111
|
+
* Create a new agent session
|
|
112
|
+
*
|
|
113
|
+
* Body: { workspaceId: string, agentName: string }
|
|
114
|
+
* Returns: { sessionId: string }
|
|
115
|
+
*/
|
|
116
|
+
sessionsRouter.post('/create', async (req, res) => {
|
|
117
|
+
const { workspaceId, agentName } = req.body;
|
|
118
|
+
if (!workspaceId || typeof workspaceId !== 'string') {
|
|
119
|
+
return res.status(400).json({ error: 'workspaceId is required', code: 'MISSING_WORKSPACE_ID' });
|
|
120
|
+
}
|
|
121
|
+
if (!isValidUUID(workspaceId)) {
|
|
122
|
+
return res.status(400).json({ error: 'workspaceId must be a valid UUID', code: 'INVALID_WORKSPACE_ID' });
|
|
123
|
+
}
|
|
124
|
+
if (!agentName || typeof agentName !== 'string') {
|
|
125
|
+
return res.status(400).json({ error: 'agentName is required', code: 'MISSING_AGENT_NAME' });
|
|
126
|
+
}
|
|
127
|
+
const agentNameValidation = isValidAgentName(agentName);
|
|
128
|
+
if (!agentNameValidation.valid) {
|
|
129
|
+
return res.status(400).json({ error: agentNameValidation.reason, code: 'INVALID_AGENT_NAME' });
|
|
130
|
+
}
|
|
131
|
+
const tokenVerification = verifyWorkspaceToken(req, workspaceId);
|
|
132
|
+
if (!tokenVerification.valid) {
|
|
133
|
+
console.warn(`[sessions] Token verification failed for workspace ${workspaceId.substring(0, 8)}: ${tokenVerification.reason}`);
|
|
134
|
+
return res.status(401).json({
|
|
135
|
+
error: 'Invalid workspace token',
|
|
136
|
+
code: 'INVALID_WORKSPACE_TOKEN',
|
|
137
|
+
hint: tokenVerification.reason,
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
try {
|
|
141
|
+
const db = getDb();
|
|
142
|
+
const result = await db.insert(agentSessions).values({
|
|
143
|
+
workspaceId,
|
|
144
|
+
agentName,
|
|
145
|
+
status: 'active',
|
|
146
|
+
startedAt: new Date(),
|
|
147
|
+
}).returning();
|
|
148
|
+
const session = result[0];
|
|
149
|
+
if (!session) {
|
|
150
|
+
return res.status(500).json({ error: 'Failed to create session', code: 'CREATE_FAILED' });
|
|
151
|
+
}
|
|
152
|
+
console.log(`[sessions] Created session ${session.id.substring(0, 8)} for ${agentName} in workspace ${workspaceId.substring(0, 8)}`);
|
|
153
|
+
return res.json({ sessionId: session.id });
|
|
154
|
+
}
|
|
155
|
+
catch (err) {
|
|
156
|
+
console.error(`[sessions] Failed to create session:`, err);
|
|
157
|
+
return res.status(500).json({ error: 'Internal server error', code: 'INTERNAL_ERROR' });
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
/**
|
|
161
|
+
* POST /api/sessions/summary
|
|
162
|
+
* Add a summary to an existing session
|
|
163
|
+
*
|
|
164
|
+
* Body: {
|
|
165
|
+
* workspaceId: string,
|
|
166
|
+
* sessionId: string,
|
|
167
|
+
* agentName: string,
|
|
168
|
+
* summary: { currentTask?: string, completedTasks?: string[], ... }
|
|
169
|
+
* }
|
|
170
|
+
* Returns: { summaryId: string }
|
|
171
|
+
*/
|
|
172
|
+
sessionsRouter.post('/summary', async (req, res) => {
|
|
173
|
+
const { workspaceId, sessionId, agentName, summary } = req.body;
|
|
174
|
+
if (!workspaceId || typeof workspaceId !== 'string') {
|
|
175
|
+
return res.status(400).json({ error: 'workspaceId is required', code: 'MISSING_WORKSPACE_ID' });
|
|
176
|
+
}
|
|
177
|
+
if (!isValidUUID(workspaceId)) {
|
|
178
|
+
return res.status(400).json({ error: 'workspaceId must be a valid UUID', code: 'INVALID_WORKSPACE_ID' });
|
|
179
|
+
}
|
|
180
|
+
if (!sessionId || typeof sessionId !== 'string') {
|
|
181
|
+
return res.status(400).json({ error: 'sessionId is required', code: 'MISSING_SESSION_ID' });
|
|
182
|
+
}
|
|
183
|
+
if (!isValidUUID(sessionId)) {
|
|
184
|
+
return res.status(400).json({ error: 'sessionId must be a valid UUID', code: 'INVALID_SESSION_ID' });
|
|
185
|
+
}
|
|
186
|
+
if (!agentName || typeof agentName !== 'string') {
|
|
187
|
+
return res.status(400).json({ error: 'agentName is required', code: 'MISSING_AGENT_NAME' });
|
|
188
|
+
}
|
|
189
|
+
const agentNameValidation = isValidAgentName(agentName);
|
|
190
|
+
if (!agentNameValidation.valid) {
|
|
191
|
+
return res.status(400).json({ error: agentNameValidation.reason, code: 'INVALID_AGENT_NAME' });
|
|
192
|
+
}
|
|
193
|
+
if (!summary) {
|
|
194
|
+
return res.status(400).json({ error: 'summary is required', code: 'MISSING_SUMMARY' });
|
|
195
|
+
}
|
|
196
|
+
const summaryValidation = validateSummary(summary);
|
|
197
|
+
if (!summaryValidation.valid) {
|
|
198
|
+
return res.status(400).json({ error: summaryValidation.reason, code: 'INVALID_SUMMARY' });
|
|
199
|
+
}
|
|
200
|
+
const tokenVerification = verifyWorkspaceToken(req, workspaceId);
|
|
201
|
+
if (!tokenVerification.valid) {
|
|
202
|
+
console.warn(`[sessions] Summary: Token verification failed for workspace ${workspaceId.substring(0, 8)}`);
|
|
203
|
+
return res.status(401).json({
|
|
204
|
+
error: 'Invalid workspace token',
|
|
205
|
+
code: 'INVALID_WORKSPACE_TOKEN',
|
|
206
|
+
hint: tokenVerification.reason,
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
try {
|
|
210
|
+
const db = getDb();
|
|
211
|
+
// Verify the session exists and belongs to this workspace
|
|
212
|
+
const existingSession = await db.select()
|
|
213
|
+
.from(agentSessions)
|
|
214
|
+
.where(eq(agentSessions.id, sessionId))
|
|
215
|
+
.limit(1);
|
|
216
|
+
if (!existingSession[0]) {
|
|
217
|
+
return res.status(404).json({ error: 'Session not found', code: 'SESSION_NOT_FOUND' });
|
|
218
|
+
}
|
|
219
|
+
if (existingSession[0].workspaceId !== workspaceId) {
|
|
220
|
+
return res.status(403).json({ error: 'Session does not belong to this workspace', code: 'SESSION_FORBIDDEN' });
|
|
221
|
+
}
|
|
222
|
+
const result = await db.insert(agentSummaries).values({
|
|
223
|
+
sessionId,
|
|
224
|
+
agentName,
|
|
225
|
+
summary,
|
|
226
|
+
createdAt: new Date(),
|
|
227
|
+
}).returning();
|
|
228
|
+
const summaryRecord = result[0];
|
|
229
|
+
if (!summaryRecord) {
|
|
230
|
+
return res.status(500).json({ error: 'Failed to create summary', code: 'CREATE_FAILED' });
|
|
231
|
+
}
|
|
232
|
+
console.log(`[sessions] Saved summary for ${agentName}: ${summary.currentTask || 'no task'}`);
|
|
233
|
+
return res.json({ summaryId: summaryRecord.id });
|
|
234
|
+
}
|
|
235
|
+
catch (err) {
|
|
236
|
+
console.error(`[sessions] Failed to save summary:`, err);
|
|
237
|
+
return res.status(500).json({ error: 'Internal server error', code: 'INTERNAL_ERROR' });
|
|
238
|
+
}
|
|
239
|
+
});
|
|
240
|
+
/**
|
|
241
|
+
* POST /api/sessions/end
|
|
242
|
+
* Mark a session as ended
|
|
243
|
+
*
|
|
244
|
+
* Body: {
|
|
245
|
+
* workspaceId: string,
|
|
246
|
+
* sessionId: string,
|
|
247
|
+
* endMarker: { summary?: string, completedTasks?: string[] }
|
|
248
|
+
* }
|
|
249
|
+
* Returns: { success: true }
|
|
250
|
+
*/
|
|
251
|
+
sessionsRouter.post('/end', async (req, res) => {
|
|
252
|
+
const { workspaceId, sessionId, endMarker } = req.body;
|
|
253
|
+
if (!workspaceId || typeof workspaceId !== 'string') {
|
|
254
|
+
return res.status(400).json({ error: 'workspaceId is required', code: 'MISSING_WORKSPACE_ID' });
|
|
255
|
+
}
|
|
256
|
+
if (!isValidUUID(workspaceId)) {
|
|
257
|
+
return res.status(400).json({ error: 'workspaceId must be a valid UUID', code: 'INVALID_WORKSPACE_ID' });
|
|
258
|
+
}
|
|
259
|
+
if (!sessionId || typeof sessionId !== 'string') {
|
|
260
|
+
return res.status(400).json({ error: 'sessionId is required', code: 'MISSING_SESSION_ID' });
|
|
261
|
+
}
|
|
262
|
+
if (!isValidUUID(sessionId)) {
|
|
263
|
+
return res.status(400).json({ error: 'sessionId must be a valid UUID', code: 'INVALID_SESSION_ID' });
|
|
264
|
+
}
|
|
265
|
+
const tokenVerification = verifyWorkspaceToken(req, workspaceId);
|
|
266
|
+
if (!tokenVerification.valid) {
|
|
267
|
+
console.warn(`[sessions] End: Token verification failed for workspace ${workspaceId.substring(0, 8)}`);
|
|
268
|
+
return res.status(401).json({
|
|
269
|
+
error: 'Invalid workspace token',
|
|
270
|
+
code: 'INVALID_WORKSPACE_TOKEN',
|
|
271
|
+
hint: tokenVerification.reason,
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
try {
|
|
275
|
+
const db = getDb();
|
|
276
|
+
// Verify the session exists and belongs to this workspace
|
|
277
|
+
const existingSession = await db.select()
|
|
278
|
+
.from(agentSessions)
|
|
279
|
+
.where(eq(agentSessions.id, sessionId))
|
|
280
|
+
.limit(1);
|
|
281
|
+
if (!existingSession[0]) {
|
|
282
|
+
return res.status(404).json({ error: 'Session not found', code: 'SESSION_NOT_FOUND' });
|
|
283
|
+
}
|
|
284
|
+
if (existingSession[0].workspaceId !== workspaceId) {
|
|
285
|
+
return res.status(403).json({ error: 'Session does not belong to this workspace', code: 'SESSION_FORBIDDEN' });
|
|
286
|
+
}
|
|
287
|
+
await db.update(agentSessions)
|
|
288
|
+
.set({
|
|
289
|
+
status: 'ended',
|
|
290
|
+
endedAt: new Date(),
|
|
291
|
+
endMarker: endMarker || {},
|
|
292
|
+
})
|
|
293
|
+
.where(eq(agentSessions.id, sessionId));
|
|
294
|
+
console.log(`[sessions] Session ended for workspace ${workspaceId.substring(0, 8)}: ${endMarker?.summary || 'no summary'}`);
|
|
295
|
+
return res.json({ success: true });
|
|
296
|
+
}
|
|
297
|
+
catch (err) {
|
|
298
|
+
console.error(`[sessions] Failed to end session:`, err);
|
|
299
|
+
return res.status(500).json({ error: 'Internal server error', code: 'INTERNAL_ERROR' });
|
|
300
|
+
}
|
|
301
|
+
});
|
|
302
|
+
//# sourceMappingURL=sessions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessions.js","sourceRoot":"","sources":["../../src/api/sessions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"teams.d.ts","sourceRoot":"","sources":["../../src/api/teams.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,eAAO,MAAM,WAAW,4CAAW,CAAC"}
|
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Teams API Routes
|
|
3
|
+
*
|
|
4
|
+
* Manage workspace members, invitations, and roles.
|
|
5
|
+
*/
|
|
6
|
+
import { Router } from 'express';
|
|
7
|
+
import { requireAuth } from './auth.js';
|
|
8
|
+
import { db } from '../db/index.js';
|
|
9
|
+
export const teamsRouter = Router();
|
|
10
|
+
// All routes require authentication
|
|
11
|
+
teamsRouter.use(requireAuth);
|
|
12
|
+
/**
|
|
13
|
+
* GET /api/workspaces/:workspaceId/members
|
|
14
|
+
* List workspace members
|
|
15
|
+
*/
|
|
16
|
+
teamsRouter.get('/workspaces/:workspaceId/members', async (req, res) => {
|
|
17
|
+
const userId = req.session.userId;
|
|
18
|
+
const workspaceId = req.params.workspaceId;
|
|
19
|
+
try {
|
|
20
|
+
// Check user has access to workspace
|
|
21
|
+
const canView = await db.workspaceMembers.canView(workspaceId, userId);
|
|
22
|
+
if (!canView) {
|
|
23
|
+
// Also check if user is the workspace owner (legacy single-user workspaces)
|
|
24
|
+
const workspace = await db.workspaces.findById(workspaceId);
|
|
25
|
+
if (!workspace || workspace.userId !== userId) {
|
|
26
|
+
return res.status(403).json({ error: 'Access denied' });
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
const members = await db.workspaceMembers.findByWorkspaceId(workspaceId);
|
|
30
|
+
// Fetch user info for each member
|
|
31
|
+
const membersWithUsers = await Promise.all(members.map(async (m) => {
|
|
32
|
+
const user = await db.users.findById(m.userId);
|
|
33
|
+
return {
|
|
34
|
+
id: m.id,
|
|
35
|
+
userId: m.userId,
|
|
36
|
+
role: m.role,
|
|
37
|
+
invitedAt: m.invitedAt,
|
|
38
|
+
acceptedAt: m.acceptedAt,
|
|
39
|
+
isPending: !m.acceptedAt,
|
|
40
|
+
user: user
|
|
41
|
+
? {
|
|
42
|
+
githubUsername: user.githubUsername,
|
|
43
|
+
email: user.email ?? undefined,
|
|
44
|
+
avatarUrl: user.avatarUrl ?? undefined,
|
|
45
|
+
}
|
|
46
|
+
: undefined,
|
|
47
|
+
};
|
|
48
|
+
}));
|
|
49
|
+
res.json({ members: membersWithUsers });
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
console.error('Error listing members:', error);
|
|
53
|
+
res.status(500).json({ error: 'Failed to list members' });
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
/**
|
|
57
|
+
* POST /api/workspaces/:workspaceId/members
|
|
58
|
+
* Invite a user to workspace
|
|
59
|
+
*/
|
|
60
|
+
teamsRouter.post('/workspaces/:workspaceId/members', async (req, res) => {
|
|
61
|
+
const userId = req.session.userId;
|
|
62
|
+
const workspaceId = req.params.workspaceId;
|
|
63
|
+
const { githubUsername, role = 'member' } = req.body;
|
|
64
|
+
if (!githubUsername) {
|
|
65
|
+
return res.status(400).json({ error: 'GitHub username is required' });
|
|
66
|
+
}
|
|
67
|
+
const validRoles = ['admin', 'member', 'viewer'];
|
|
68
|
+
if (!validRoles.includes(role)) {
|
|
69
|
+
return res.status(400).json({ error: 'Invalid role. Must be admin, member, or viewer' });
|
|
70
|
+
}
|
|
71
|
+
try {
|
|
72
|
+
// Check user is owner or admin
|
|
73
|
+
const isOwner = await db.workspaceMembers.isOwner(workspaceId, userId);
|
|
74
|
+
const workspace = await db.workspaces.findById(workspaceId);
|
|
75
|
+
if (!isOwner && workspace?.userId !== userId) {
|
|
76
|
+
const membership = await db.workspaceMembers.findMembership(workspaceId, userId);
|
|
77
|
+
if (!membership || membership.role !== 'admin') {
|
|
78
|
+
return res.status(403).json({ error: 'Only owners and admins can invite members' });
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
// Check plan allows team members
|
|
82
|
+
const owner = await db.users.findById(workspace.userId);
|
|
83
|
+
if (owner?.plan !== 'team' && owner?.plan !== 'enterprise') {
|
|
84
|
+
return res.status(402).json({
|
|
85
|
+
error: 'Team members require Team or Enterprise plan',
|
|
86
|
+
upgrade: '/settings/billing',
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
// Find user by GitHub username
|
|
90
|
+
const invitee = await db.users.findByGithubUsername(githubUsername);
|
|
91
|
+
if (!invitee) {
|
|
92
|
+
return res.status(404).json({
|
|
93
|
+
error: 'User not found. They must sign up first.',
|
|
94
|
+
inviteLink: `https://agent-relay.com/invite?workspace=${workspaceId}`,
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
// Check if already a member
|
|
98
|
+
const existing = await db.workspaceMembers.findMembership(workspaceId, invitee.id);
|
|
99
|
+
if (existing) {
|
|
100
|
+
return res.status(409).json({ error: 'User is already a member' });
|
|
101
|
+
}
|
|
102
|
+
// Add member (pending acceptance)
|
|
103
|
+
const member = await db.workspaceMembers.addMember({
|
|
104
|
+
workspaceId,
|
|
105
|
+
userId: invitee.id,
|
|
106
|
+
role,
|
|
107
|
+
invitedBy: userId,
|
|
108
|
+
});
|
|
109
|
+
// TODO: Send email notification to invitee
|
|
110
|
+
res.status(201).json({
|
|
111
|
+
success: true,
|
|
112
|
+
member: {
|
|
113
|
+
id: member.id,
|
|
114
|
+
userId: member.userId,
|
|
115
|
+
role: member.role,
|
|
116
|
+
isPending: true,
|
|
117
|
+
user: {
|
|
118
|
+
githubUsername: invitee.githubUsername,
|
|
119
|
+
email: invitee.email,
|
|
120
|
+
avatarUrl: invitee.avatarUrl,
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
catch (error) {
|
|
126
|
+
console.error('Error inviting member:', error);
|
|
127
|
+
res.status(500).json({ error: 'Failed to invite member' });
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
/**
|
|
131
|
+
* PATCH /api/workspaces/:workspaceId/members/:memberId
|
|
132
|
+
* Update member role
|
|
133
|
+
*/
|
|
134
|
+
teamsRouter.patch('/workspaces/:workspaceId/members/:memberId', async (req, res) => {
|
|
135
|
+
const userId = req.session.userId;
|
|
136
|
+
const workspaceId = req.params.workspaceId;
|
|
137
|
+
const memberId = req.params.memberId;
|
|
138
|
+
const { role } = req.body;
|
|
139
|
+
const validRoles = ['admin', 'member', 'viewer'];
|
|
140
|
+
if (!validRoles.includes(role)) {
|
|
141
|
+
return res.status(400).json({ error: 'Invalid role' });
|
|
142
|
+
}
|
|
143
|
+
try {
|
|
144
|
+
// Check user is owner or admin
|
|
145
|
+
const isOwner = await db.workspaceMembers.isOwner(workspaceId, userId);
|
|
146
|
+
const workspace = await db.workspaces.findById(workspaceId);
|
|
147
|
+
if (!isOwner && workspace?.userId !== userId) {
|
|
148
|
+
return res.status(403).json({ error: 'Only owners can change roles' });
|
|
149
|
+
}
|
|
150
|
+
// Get the member to update
|
|
151
|
+
const members = await db.workspaceMembers.findByWorkspaceId(workspaceId);
|
|
152
|
+
const member = members.find((m) => m.id === memberId);
|
|
153
|
+
if (!member) {
|
|
154
|
+
return res.status(404).json({ error: 'Member not found' });
|
|
155
|
+
}
|
|
156
|
+
// Can't change owner role
|
|
157
|
+
if (member.role === 'owner') {
|
|
158
|
+
return res.status(400).json({ error: 'Cannot change owner role' });
|
|
159
|
+
}
|
|
160
|
+
await db.workspaceMembers.updateRole(workspaceId, member.userId, role);
|
|
161
|
+
res.json({ success: true, role });
|
|
162
|
+
}
|
|
163
|
+
catch (error) {
|
|
164
|
+
console.error('Error updating role:', error);
|
|
165
|
+
res.status(500).json({ error: 'Failed to update role' });
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
/**
|
|
169
|
+
* DELETE /api/workspaces/:workspaceId/members/:memberId
|
|
170
|
+
* Remove member from workspace
|
|
171
|
+
*/
|
|
172
|
+
teamsRouter.delete('/workspaces/:workspaceId/members/:memberId', async (req, res) => {
|
|
173
|
+
const userId = req.session.userId;
|
|
174
|
+
const workspaceId = req.params.workspaceId;
|
|
175
|
+
const memberId = req.params.memberId;
|
|
176
|
+
try {
|
|
177
|
+
const members = await db.workspaceMembers.findByWorkspaceId(workspaceId);
|
|
178
|
+
const member = members.find((m) => m.id === memberId);
|
|
179
|
+
if (!member) {
|
|
180
|
+
return res.status(404).json({ error: 'Member not found' });
|
|
181
|
+
}
|
|
182
|
+
// Users can remove themselves
|
|
183
|
+
if (member.userId === userId) {
|
|
184
|
+
if (member.role === 'owner') {
|
|
185
|
+
return res.status(400).json({ error: 'Owner cannot leave. Transfer ownership first.' });
|
|
186
|
+
}
|
|
187
|
+
await db.workspaceMembers.removeMember(workspaceId, userId);
|
|
188
|
+
return res.json({ success: true });
|
|
189
|
+
}
|
|
190
|
+
// Otherwise, must be owner or admin
|
|
191
|
+
const isOwner = await db.workspaceMembers.isOwner(workspaceId, userId);
|
|
192
|
+
const workspace = await db.workspaces.findById(workspaceId);
|
|
193
|
+
if (!isOwner && workspace?.userId !== userId) {
|
|
194
|
+
const myMembership = await db.workspaceMembers.findMembership(workspaceId, userId);
|
|
195
|
+
if (!myMembership || myMembership.role !== 'admin') {
|
|
196
|
+
return res.status(403).json({ error: 'Permission denied' });
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
// Can't remove owner
|
|
200
|
+
if (member.role === 'owner') {
|
|
201
|
+
return res.status(400).json({ error: 'Cannot remove owner' });
|
|
202
|
+
}
|
|
203
|
+
await db.workspaceMembers.removeMember(workspaceId, member.userId);
|
|
204
|
+
res.json({ success: true });
|
|
205
|
+
}
|
|
206
|
+
catch (error) {
|
|
207
|
+
console.error('Error removing member:', error);
|
|
208
|
+
res.status(500).json({ error: 'Failed to remove member' });
|
|
209
|
+
}
|
|
210
|
+
});
|
|
211
|
+
/**
|
|
212
|
+
* GET /api/invites
|
|
213
|
+
* Get pending invites for current user
|
|
214
|
+
*/
|
|
215
|
+
teamsRouter.get('/invites', async (req, res) => {
|
|
216
|
+
const userId = req.session.userId;
|
|
217
|
+
try {
|
|
218
|
+
const invites = await db.workspaceMembers.getPendingInvites(userId);
|
|
219
|
+
res.json({
|
|
220
|
+
invites: invites.map((inv) => ({
|
|
221
|
+
id: inv.id,
|
|
222
|
+
workspaceId: inv.workspaceId,
|
|
223
|
+
workspaceName: inv.workspace_name,
|
|
224
|
+
role: inv.role,
|
|
225
|
+
invitedAt: inv.invitedAt,
|
|
226
|
+
invitedBy: inv.inviter_username,
|
|
227
|
+
})),
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
catch (error) {
|
|
231
|
+
console.error('Error getting invites:', error);
|
|
232
|
+
res.status(500).json({ error: 'Failed to get invites' });
|
|
233
|
+
}
|
|
234
|
+
});
|
|
235
|
+
/**
|
|
236
|
+
* POST /api/invites/:inviteId/accept
|
|
237
|
+
* Accept workspace invitation
|
|
238
|
+
*/
|
|
239
|
+
teamsRouter.post('/invites/:inviteId/accept', async (req, res) => {
|
|
240
|
+
const userId = req.session.userId;
|
|
241
|
+
const inviteId = req.params.inviteId;
|
|
242
|
+
try {
|
|
243
|
+
const invites = await db.workspaceMembers.getPendingInvites(userId);
|
|
244
|
+
const invite = invites.find((i) => i.id === inviteId);
|
|
245
|
+
if (!invite) {
|
|
246
|
+
return res.status(404).json({ error: 'Invite not found' });
|
|
247
|
+
}
|
|
248
|
+
await db.workspaceMembers.acceptInvite(invite.workspaceId, userId);
|
|
249
|
+
res.json({
|
|
250
|
+
success: true,
|
|
251
|
+
workspaceId: invite.workspaceId,
|
|
252
|
+
message: 'Invitation accepted',
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
catch (error) {
|
|
256
|
+
console.error('Error accepting invite:', error);
|
|
257
|
+
res.status(500).json({ error: 'Failed to accept invite' });
|
|
258
|
+
}
|
|
259
|
+
});
|
|
260
|
+
/**
|
|
261
|
+
* POST /api/invites/:inviteId/decline
|
|
262
|
+
* Decline workspace invitation
|
|
263
|
+
*/
|
|
264
|
+
teamsRouter.post('/invites/:inviteId/decline', async (req, res) => {
|
|
265
|
+
const userId = req.session.userId;
|
|
266
|
+
const inviteId = req.params.inviteId;
|
|
267
|
+
try {
|
|
268
|
+
const invites = await db.workspaceMembers.getPendingInvites(userId);
|
|
269
|
+
const invite = invites.find((i) => i.id === inviteId);
|
|
270
|
+
if (!invite) {
|
|
271
|
+
return res.status(404).json({ error: 'Invite not found' });
|
|
272
|
+
}
|
|
273
|
+
await db.workspaceMembers.removeMember(invite.workspaceId, userId);
|
|
274
|
+
res.json({ success: true, message: 'Invitation declined' });
|
|
275
|
+
}
|
|
276
|
+
catch (error) {
|
|
277
|
+
console.error('Error declining invite:', error);
|
|
278
|
+
res.status(500).json({ error: 'Failed to decline invite' });
|
|
279
|
+
}
|
|
280
|
+
});
|
|
281
|
+
//# sourceMappingURL=teams.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"teams.js","sourceRoot":"","sources":["../../src/api/teams.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test Helper API Routes
|
|
3
|
+
*
|
|
4
|
+
* These endpoints are ONLY available in test/development mode.
|
|
5
|
+
* They allow integration tests to create users and daemons without OAuth.
|
|
6
|
+
*
|
|
7
|
+
* IMPORTANT: These routes are disabled in production (NODE_ENV=production).
|
|
8
|
+
*/
|
|
9
|
+
export declare const testHelpersRouter: import("express-serve-static-core").Router;
|
|
10
|
+
//# sourceMappingURL=test-helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-helpers.d.ts","sourceRoot":"","sources":["../../src/api/test-helpers.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAUH,eAAO,MAAM,iBAAiB,4CAAW,CAAC"}
|