@de-otio/chaoskb-server 0.2.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.
Files changed (157) hide show
  1. package/dist/lib/admin-handler/index.d.ts +22 -0
  2. package/dist/lib/admin-handler/index.d.ts.map +1 -0
  3. package/dist/lib/admin-handler/index.js +92 -0
  4. package/dist/lib/admin-handler/index.js.map +1 -0
  5. package/dist/lib/admin-handler/index.ts +123 -0
  6. package/dist/lib/admin-handler/routes/metrics.d.ts +11 -0
  7. package/dist/lib/admin-handler/routes/metrics.d.ts.map +1 -0
  8. package/dist/lib/admin-handler/routes/metrics.js +200 -0
  9. package/dist/lib/admin-handler/routes/metrics.js.map +1 -0
  10. package/dist/lib/admin-handler/routes/metrics.ts +234 -0
  11. package/dist/lib/admin-handler/routes/overview.d.ts +9 -0
  12. package/dist/lib/admin-handler/routes/overview.d.ts.map +1 -0
  13. package/dist/lib/admin-handler/routes/overview.js +110 -0
  14. package/dist/lib/admin-handler/routes/overview.js.map +1 -0
  15. package/dist/lib/admin-handler/routes/overview.ts +133 -0
  16. package/dist/lib/admin-handler/routes/tenants.d.ts +10 -0
  17. package/dist/lib/admin-handler/routes/tenants.d.ts.map +1 -0
  18. package/dist/lib/admin-handler/routes/tenants.js +108 -0
  19. package/dist/lib/admin-handler/routes/tenants.js.map +1 -0
  20. package/dist/lib/admin-handler/routes/tenants.ts +134 -0
  21. package/dist/lib/chaoskb-stack.d.ts +22 -0
  22. package/dist/lib/chaoskb-stack.d.ts.map +1 -0
  23. package/dist/lib/chaoskb-stack.js +60 -0
  24. package/dist/lib/chaoskb-stack.js.map +1 -0
  25. package/dist/lib/constructs/admin-api.d.ts +16 -0
  26. package/dist/lib/constructs/admin-api.d.ts.map +1 -0
  27. package/dist/lib/constructs/admin-api.js +93 -0
  28. package/dist/lib/constructs/admin-api.js.map +1 -0
  29. package/dist/lib/constructs/admin-dashboard.d.ts +18 -0
  30. package/dist/lib/constructs/admin-dashboard.d.ts.map +1 -0
  31. package/dist/lib/constructs/admin-dashboard.js +172 -0
  32. package/dist/lib/constructs/admin-dashboard.js.map +1 -0
  33. package/dist/lib/constructs/api.d.ts +17 -0
  34. package/dist/lib/constructs/api.d.ts.map +1 -0
  35. package/dist/lib/constructs/api.js +81 -0
  36. package/dist/lib/constructs/api.js.map +1 -0
  37. package/dist/lib/constructs/auth.d.ts +11 -0
  38. package/dist/lib/constructs/auth.d.ts.map +1 -0
  39. package/dist/lib/constructs/auth.js +18 -0
  40. package/dist/lib/constructs/auth.js.map +1 -0
  41. package/dist/lib/constructs/blob-store.d.ts +10 -0
  42. package/dist/lib/constructs/blob-store.d.ts.map +1 -0
  43. package/dist/lib/constructs/blob-store.js +31 -0
  44. package/dist/lib/constructs/blob-store.js.map +1 -0
  45. package/dist/lib/deploy-cli.d.ts +3 -0
  46. package/dist/lib/deploy-cli.d.ts.map +1 -0
  47. package/dist/lib/deploy-cli.js +49 -0
  48. package/dist/lib/deploy-cli.js.map +1 -0
  49. package/dist/lib/handler/index.d.ts +23 -0
  50. package/dist/lib/handler/index.d.ts.map +1 -0
  51. package/dist/lib/handler/index.js +276 -0
  52. package/dist/lib/handler/index.js.map +1 -0
  53. package/dist/lib/handler/index.ts +372 -0
  54. package/dist/lib/handler/logger.d.ts +16 -0
  55. package/dist/lib/handler/logger.d.ts.map +1 -0
  56. package/dist/lib/handler/logger.js +26 -0
  57. package/dist/lib/handler/logger.js.map +1 -0
  58. package/dist/lib/handler/logger.ts +36 -0
  59. package/dist/lib/handler/middleware/input-validation.d.ts +6 -0
  60. package/dist/lib/handler/middleware/input-validation.d.ts.map +1 -0
  61. package/dist/lib/handler/middleware/input-validation.js +36 -0
  62. package/dist/lib/handler/middleware/input-validation.js.map +1 -0
  63. package/dist/lib/handler/middleware/input-validation.ts +44 -0
  64. package/dist/lib/handler/middleware/rate-limit.d.ts +14 -0
  65. package/dist/lib/handler/middleware/rate-limit.d.ts.map +1 -0
  66. package/dist/lib/handler/middleware/rate-limit.js +94 -0
  67. package/dist/lib/handler/middleware/rate-limit.js.map +1 -0
  68. package/dist/lib/handler/middleware/rate-limit.ts +121 -0
  69. package/dist/lib/handler/middleware/ssh-auth.d.ts +48 -0
  70. package/dist/lib/handler/middleware/ssh-auth.d.ts.map +1 -0
  71. package/dist/lib/handler/middleware/ssh-auth.js +256 -0
  72. package/dist/lib/handler/middleware/ssh-auth.js.map +1 -0
  73. package/dist/lib/handler/middleware/ssh-auth.ts +300 -0
  74. package/dist/lib/handler/routes/audit.d.ts +24 -0
  75. package/dist/lib/handler/routes/audit.d.ts.map +1 -0
  76. package/dist/lib/handler/routes/audit.js +94 -0
  77. package/dist/lib/handler/routes/audit.js.map +1 -0
  78. package/dist/lib/handler/routes/audit.ts +101 -0
  79. package/dist/lib/handler/routes/blobs.d.ts +13 -0
  80. package/dist/lib/handler/routes/blobs.d.ts.map +1 -0
  81. package/dist/lib/handler/routes/blobs.js +298 -0
  82. package/dist/lib/handler/routes/blobs.js.map +1 -0
  83. package/dist/lib/handler/routes/blobs.ts +348 -0
  84. package/dist/lib/handler/routes/devices.d.ts +48 -0
  85. package/dist/lib/handler/routes/devices.d.ts.map +1 -0
  86. package/dist/lib/handler/routes/devices.js +394 -0
  87. package/dist/lib/handler/routes/devices.js.map +1 -0
  88. package/dist/lib/handler/routes/devices.ts +458 -0
  89. package/dist/lib/handler/routes/export.d.ts +9 -0
  90. package/dist/lib/handler/routes/export.d.ts.map +1 -0
  91. package/dist/lib/handler/routes/export.js +40 -0
  92. package/dist/lib/handler/routes/export.js.map +1 -0
  93. package/dist/lib/handler/routes/export.ts +55 -0
  94. package/dist/lib/handler/routes/github.d.ts +31 -0
  95. package/dist/lib/handler/routes/github.d.ts.map +1 -0
  96. package/dist/lib/handler/routes/github.js +118 -0
  97. package/dist/lib/handler/routes/github.js.map +1 -0
  98. package/dist/lib/handler/routes/github.ts +162 -0
  99. package/dist/lib/handler/routes/health.d.ts +6 -0
  100. package/dist/lib/handler/routes/health.d.ts.map +1 -0
  101. package/dist/lib/handler/routes/health.js +14 -0
  102. package/dist/lib/handler/routes/health.js.map +1 -0
  103. package/dist/lib/handler/routes/health.ts +10 -0
  104. package/dist/lib/handler/routes/invites.d.ts +24 -0
  105. package/dist/lib/handler/routes/invites.d.ts.map +1 -0
  106. package/dist/lib/handler/routes/invites.js +445 -0
  107. package/dist/lib/handler/routes/invites.js.map +1 -0
  108. package/dist/lib/handler/routes/invites.ts +527 -0
  109. package/dist/lib/handler/routes/notifications.d.ts +39 -0
  110. package/dist/lib/handler/routes/notifications.d.ts.map +1 -0
  111. package/dist/lib/handler/routes/notifications.js +150 -0
  112. package/dist/lib/handler/routes/notifications.js.map +1 -0
  113. package/dist/lib/handler/routes/notifications.ts +163 -0
  114. package/dist/lib/handler/routes/projects.d.ts +24 -0
  115. package/dist/lib/handler/routes/projects.d.ts.map +1 -0
  116. package/dist/lib/handler/routes/projects.js +47 -0
  117. package/dist/lib/handler/routes/projects.js.map +1 -0
  118. package/dist/lib/handler/routes/projects.ts +69 -0
  119. package/dist/lib/handler/routes/register.d.ts +19 -0
  120. package/dist/lib/handler/routes/register.d.ts.map +1 -0
  121. package/dist/lib/handler/routes/register.js +327 -0
  122. package/dist/lib/handler/routes/register.js.map +1 -0
  123. package/dist/lib/handler/routes/register.ts +363 -0
  124. package/dist/lib/handler/routes/restore.d.ts +9 -0
  125. package/dist/lib/handler/routes/restore.d.ts.map +1 -0
  126. package/dist/lib/handler/routes/restore.js +52 -0
  127. package/dist/lib/handler/routes/restore.js.map +1 -0
  128. package/dist/lib/handler/routes/restore.ts +73 -0
  129. package/dist/lib/handler/routes/revocation.d.ts +13 -0
  130. package/dist/lib/handler/routes/revocation.d.ts.map +1 -0
  131. package/dist/lib/handler/routes/revocation.js +63 -0
  132. package/dist/lib/handler/routes/revocation.js.map +1 -0
  133. package/dist/lib/handler/routes/revocation.ts +87 -0
  134. package/dist/lib/handler/routes/rotation.d.ts +24 -0
  135. package/dist/lib/handler/routes/rotation.d.ts.map +1 -0
  136. package/dist/lib/handler/routes/rotation.js +291 -0
  137. package/dist/lib/handler/routes/rotation.js.map +1 -0
  138. package/dist/lib/handler/routes/rotation.ts +336 -0
  139. package/dist/lib/handler/routes/tenants.d.ts +11 -0
  140. package/dist/lib/handler/routes/tenants.d.ts.map +1 -0
  141. package/dist/lib/handler/routes/tenants.js +181 -0
  142. package/dist/lib/handler/routes/tenants.js.map +1 -0
  143. package/dist/lib/handler/routes/tenants.ts +198 -0
  144. package/dist/lib/handler/routes/wrapped-key.d.ts +21 -0
  145. package/dist/lib/handler/routes/wrapped-key.d.ts.map +1 -0
  146. package/dist/lib/handler/routes/wrapped-key.js +76 -0
  147. package/dist/lib/handler/routes/wrapped-key.js.map +1 -0
  148. package/dist/lib/handler/routes/wrapped-key.ts +108 -0
  149. package/dist/lib/index.d.ts +7 -0
  150. package/dist/lib/index.d.ts.map +1 -0
  151. package/dist/lib/index.js +16 -0
  152. package/dist/lib/index.js.map +1 -0
  153. package/dist/vitest.config.d.ts +3 -0
  154. package/dist/vitest.config.d.ts.map +1 -0
  155. package/dist/vitest.config.js +18 -0
  156. package/dist/vitest.config.js.map +1 -0
  157. package/package.json +61 -0
@@ -0,0 +1,445 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.handleCreateInvite = handleCreateInvite;
37
+ exports.handleListInvites = handleListInvites;
38
+ exports.handleAcceptInvite = handleAcceptInvite;
39
+ exports.handleDeclineInvite = handleDeclineInvite;
40
+ const crypto = __importStar(require("crypto"));
41
+ const lib_dynamodb_1 = require("@aws-sdk/lib-dynamodb");
42
+ const logger_js_1 = require("../logger.js");
43
+ const audit_js_1 = require("./audit.js");
44
+ const JSON_HEADERS = { 'Content-Type': 'application/json' };
45
+ const FOURTEEN_DAYS_MS = 14 * 24 * 60 * 60 * 1000;
46
+ const FOURTEEN_DAYS_SECONDS = 14 * 24 * 60 * 60;
47
+ const TWENTY_FOUR_HOURS_SECONDS = 24 * 60 * 60;
48
+ const HOUR_SECONDS = 3600;
49
+ const DAY_SECONDS = 86400;
50
+ const HOURLY_INVITE_LIMIT = 10;
51
+ const DAILY_INVITE_LIMIT = 50;
52
+ const MAX_PENDING_INVITES = 20;
53
+ /**
54
+ * Check sender rate limits for invite creation.
55
+ * Uses DynamoDB counters with hourly and daily windows.
56
+ */
57
+ async function checkInviteRateLimit(senderFingerprint, ddb, tableName) {
58
+ const now = Math.floor(Date.now() / 1000);
59
+ const hourWindow = Math.floor(now / HOUR_SECONDS);
60
+ const dayWindow = Math.floor(now / DAY_SECONDS);
61
+ // Check hourly limit
62
+ const hourResult = await ddb.send(new lib_dynamodb_1.UpdateCommand({
63
+ TableName: tableName,
64
+ Key: {
65
+ PK: `RATE#INVITE#${senderFingerprint}`,
66
+ SK: `HOUR#${hourWindow}`,
67
+ },
68
+ UpdateExpression: 'SET #count = if_not_exists(#count, :zero) + :one, #ttl = :ttl',
69
+ ExpressionAttributeNames: {
70
+ '#count': 'count',
71
+ '#ttl': 'ttl',
72
+ },
73
+ ExpressionAttributeValues: {
74
+ ':zero': 0,
75
+ ':one': 1,
76
+ ':ttl': hourWindow * HOUR_SECONDS + HOUR_SECONDS + 120,
77
+ },
78
+ ReturnValues: 'UPDATED_NEW',
79
+ }));
80
+ const hourlyCount = hourResult.Attributes?.['count'] ?? 1;
81
+ if (hourlyCount > HOURLY_INVITE_LIMIT) {
82
+ return { allowed: false, message: 'Hourly invite limit exceeded (max 10/hour)' };
83
+ }
84
+ // Check daily limit
85
+ const dayResult = await ddb.send(new lib_dynamodb_1.UpdateCommand({
86
+ TableName: tableName,
87
+ Key: {
88
+ PK: `RATE#INVITE#${senderFingerprint}`,
89
+ SK: `DAY#${dayWindow}`,
90
+ },
91
+ UpdateExpression: 'SET #count = if_not_exists(#count, :zero) + :one, #ttl = :ttl',
92
+ ExpressionAttributeNames: {
93
+ '#count': 'count',
94
+ '#ttl': 'ttl',
95
+ },
96
+ ExpressionAttributeValues: {
97
+ ':zero': 0,
98
+ ':one': 1,
99
+ ':ttl': dayWindow * DAY_SECONDS + DAY_SECONDS + 120,
100
+ },
101
+ ReturnValues: 'UPDATED_NEW',
102
+ }));
103
+ const dailyCount = dayResult.Attributes?.['count'] ?? 1;
104
+ if (dailyCount > DAILY_INVITE_LIMIT) {
105
+ return { allowed: false, message: 'Daily invite limit exceeded (max 50/day)' };
106
+ }
107
+ return { allowed: true };
108
+ }
109
+ /**
110
+ * Check that the recipient doesn't have too many pending invites.
111
+ */
112
+ async function checkRecipientPendingCount(recipientFingerprint, ddb, tableName) {
113
+ const result = await ddb.send(new lib_dynamodb_1.QueryCommand({
114
+ TableName: tableName,
115
+ IndexName: 'GSI-RecipientFingerprint',
116
+ KeyConditionExpression: 'recipientFingerprint = :fp',
117
+ FilterExpression: '#status = :pending',
118
+ ExpressionAttributeNames: {
119
+ '#status': 'status',
120
+ },
121
+ ExpressionAttributeValues: {
122
+ ':fp': recipientFingerprint,
123
+ ':pending': 'pending',
124
+ },
125
+ Select: 'COUNT',
126
+ }));
127
+ return (result.Count ?? 0) < MAX_PENDING_INVITES;
128
+ }
129
+ /**
130
+ * POST /v1/invites - Create an invite
131
+ */
132
+ async function handleCreateInvite(tenantId, fingerprint, body, ddb, tableName) {
133
+ if (!body) {
134
+ return {
135
+ statusCode: 400,
136
+ headers: JSON_HEADERS,
137
+ body: JSON.stringify({ error: 'invalid_request', message: 'Request body is required' }),
138
+ };
139
+ }
140
+ let parsed;
141
+ try {
142
+ parsed = JSON.parse(body);
143
+ }
144
+ catch {
145
+ return {
146
+ statusCode: 400,
147
+ headers: JSON_HEADERS,
148
+ body: JSON.stringify({ error: 'invalid_request', message: 'Invalid JSON body' }),
149
+ };
150
+ }
151
+ if (!parsed.recipientFingerprint ||
152
+ !parsed.projectTenantId ||
153
+ !parsed.encryptedPayload ||
154
+ !parsed.role) {
155
+ return {
156
+ statusCode: 400,
157
+ headers: JSON_HEADERS,
158
+ body: JSON.stringify({
159
+ error: 'invalid_request',
160
+ message: 'recipientFingerprint, projectTenantId, encryptedPayload, and role are required',
161
+ }),
162
+ };
163
+ }
164
+ // Validate encryptedPayload is valid base64
165
+ if (!/^[A-Za-z0-9+/]+=*$/.test(parsed.encryptedPayload)) {
166
+ return {
167
+ statusCode: 400,
168
+ headers: JSON_HEADERS,
169
+ body: JSON.stringify({ error: 'invalid_request', message: 'encryptedPayload must be valid base64' }),
170
+ };
171
+ }
172
+ // Check sender rate limits
173
+ const rateCheck = await checkInviteRateLimit(fingerprint, ddb, tableName);
174
+ if (!rateCheck.allowed) {
175
+ return {
176
+ statusCode: 429,
177
+ headers: JSON_HEADERS,
178
+ body: JSON.stringify({ error: 'rate_limited', message: rateCheck.message }),
179
+ };
180
+ }
181
+ // Check recipient pending count
182
+ const recipientOk = await checkRecipientPendingCount(parsed.recipientFingerprint, ddb, tableName);
183
+ if (!recipientOk) {
184
+ return {
185
+ statusCode: 409,
186
+ headers: JSON_HEADERS,
187
+ body: JSON.stringify({
188
+ error: 'recipient_limit',
189
+ message: 'Recipient has too many pending invites',
190
+ }),
191
+ };
192
+ }
193
+ const inviteId = crypto.randomUUID();
194
+ const now = new Date();
195
+ const createdAt = now.toISOString();
196
+ const expiresAt = new Date(now.getTime() + FOURTEEN_DAYS_MS).toISOString();
197
+ const ttl = Math.floor(now.getTime() / 1000) + FOURTEEN_DAYS_SECONDS;
198
+ await ddb.send(new lib_dynamodb_1.PutCommand({
199
+ TableName: tableName,
200
+ Item: {
201
+ PK: `INVITE#${inviteId}`,
202
+ SK: 'META',
203
+ inviteId,
204
+ status: 'pending',
205
+ senderFingerprint: fingerprint,
206
+ recipientFingerprint: parsed.recipientFingerprint,
207
+ projectTenantId: parsed.projectTenantId,
208
+ encryptedPayload: parsed.encryptedPayload,
209
+ role: parsed.role,
210
+ createdAt,
211
+ expiresAt,
212
+ ttl,
213
+ },
214
+ }));
215
+ await (0, audit_js_1.logAuditEvent)(ddb, tableName, tenantId, {
216
+ eventType: 'invite-created',
217
+ fingerprint,
218
+ metadata: {
219
+ inviteId,
220
+ recipientFingerprint: parsed.recipientFingerprint,
221
+ projectTenantId: parsed.projectTenantId,
222
+ role: parsed.role,
223
+ },
224
+ });
225
+ logger_js_1.logger.info('Invite created', { tenantId, inviteId });
226
+ return {
227
+ statusCode: 201,
228
+ headers: JSON_HEADERS,
229
+ body: JSON.stringify({ inviteId, status: 'pending' }),
230
+ };
231
+ }
232
+ /**
233
+ * GET /v1/invites - List pending invites for the authenticated user
234
+ */
235
+ async function handleListInvites(tenantId, fingerprint, ddb, tableName) {
236
+ const now = new Date().toISOString();
237
+ const result = await ddb.send(new lib_dynamodb_1.QueryCommand({
238
+ TableName: tableName,
239
+ IndexName: 'GSI-RecipientFingerprint',
240
+ KeyConditionExpression: 'recipientFingerprint = :fp',
241
+ FilterExpression: '#status = :pending AND expiresAt > :now',
242
+ ExpressionAttributeNames: {
243
+ '#status': 'status',
244
+ },
245
+ ExpressionAttributeValues: {
246
+ ':fp': fingerprint,
247
+ ':pending': 'pending',
248
+ ':now': now,
249
+ },
250
+ }));
251
+ const invites = (result.Items ?? []).map((item) => ({
252
+ inviteId: item['inviteId'],
253
+ senderFingerprint: item['senderFingerprint'],
254
+ projectTenantId: item['projectTenantId'],
255
+ role: item['role'],
256
+ createdAt: item['createdAt'],
257
+ }));
258
+ return {
259
+ statusCode: 200,
260
+ headers: JSON_HEADERS,
261
+ body: JSON.stringify({ invites }),
262
+ };
263
+ }
264
+ /**
265
+ * POST /v1/invites/{id}/accept - Accept an invite
266
+ */
267
+ async function handleAcceptInvite(tenantId, fingerprint, inviteId, ddb, tableName) {
268
+ const result = await ddb.send(new lib_dynamodb_1.GetCommand({
269
+ TableName: tableName,
270
+ Key: {
271
+ PK: `INVITE#${inviteId}`,
272
+ SK: 'META',
273
+ },
274
+ }));
275
+ if (!result.Item) {
276
+ return {
277
+ statusCode: 404,
278
+ headers: JSON_HEADERS,
279
+ body: JSON.stringify({ error: 'not_found', message: 'Invite not found' }),
280
+ };
281
+ }
282
+ const invite = result.Item;
283
+ // Check recipient matches
284
+ if (invite['recipientFingerprint'] !== fingerprint) {
285
+ return {
286
+ statusCode: 403,
287
+ headers: JSON_HEADERS,
288
+ body: JSON.stringify({ error: 'forbidden', message: 'Not authorized to accept this invite' }),
289
+ };
290
+ }
291
+ // Idempotent: already accepted
292
+ if (invite['status'] === 'accepted') {
293
+ return {
294
+ statusCode: 200,
295
+ headers: JSON_HEADERS,
296
+ body: JSON.stringify({
297
+ status: 'already_accepted',
298
+ encryptedPayload: invite['encryptedPayload'],
299
+ projectTenantId: invite['projectTenantId'],
300
+ }),
301
+ };
302
+ }
303
+ // Check status is pending
304
+ if (invite['status'] !== 'pending') {
305
+ return {
306
+ statusCode: 409,
307
+ headers: JSON_HEADERS,
308
+ body: JSON.stringify({ error: 'conflict', message: `Invite is ${invite['status']}` }),
309
+ };
310
+ }
311
+ // Check not expired
312
+ if (new Date(invite['expiresAt']) < new Date()) {
313
+ return {
314
+ statusCode: 410,
315
+ headers: JSON_HEADERS,
316
+ body: JSON.stringify({ error: 'expired', message: 'Invite has expired' }),
317
+ };
318
+ }
319
+ const now = new Date();
320
+ const acceptedAt = now.toISOString();
321
+ // Schedule cleanup: TTL 24 hours after acceptance
322
+ const cleanupTtl = Math.floor(now.getTime() / 1000) + TWENTY_FOUR_HOURS_SECONDS;
323
+ await ddb.send(new lib_dynamodb_1.UpdateCommand({
324
+ TableName: tableName,
325
+ Key: {
326
+ PK: `INVITE#${inviteId}`,
327
+ SK: 'META',
328
+ },
329
+ UpdateExpression: 'SET #status = :accepted, acceptedAt = :acceptedAt, #ttl = :ttl',
330
+ ExpressionAttributeNames: {
331
+ '#status': 'status',
332
+ '#ttl': 'ttl',
333
+ },
334
+ ExpressionAttributeValues: {
335
+ ':accepted': 'accepted',
336
+ ':acceptedAt': acceptedAt,
337
+ ':ttl': cleanupTtl,
338
+ },
339
+ }));
340
+ await (0, audit_js_1.logAuditEvent)(ddb, tableName, tenantId, {
341
+ eventType: 'invite-accepted',
342
+ fingerprint,
343
+ metadata: {
344
+ inviteId,
345
+ projectTenantId: invite['projectTenantId'],
346
+ },
347
+ });
348
+ logger_js_1.logger.info('Invite accepted', { tenantId, inviteId });
349
+ return {
350
+ statusCode: 200,
351
+ headers: JSON_HEADERS,
352
+ body: JSON.stringify({
353
+ status: 'accepted',
354
+ encryptedPayload: invite['encryptedPayload'],
355
+ projectTenantId: invite['projectTenantId'],
356
+ }),
357
+ };
358
+ }
359
+ /**
360
+ * POST /v1/invites/{id}/decline - Decline an invite
361
+ */
362
+ async function handleDeclineInvite(tenantId, fingerprint, inviteId, body, ddb, tableName) {
363
+ const result = await ddb.send(new lib_dynamodb_1.GetCommand({
364
+ TableName: tableName,
365
+ Key: {
366
+ PK: `INVITE#${inviteId}`,
367
+ SK: 'META',
368
+ },
369
+ }));
370
+ if (!result.Item) {
371
+ return {
372
+ statusCode: 404,
373
+ headers: JSON_HEADERS,
374
+ body: JSON.stringify({ error: 'not_found', message: 'Invite not found' }),
375
+ };
376
+ }
377
+ const invite = result.Item;
378
+ // Check recipient matches
379
+ if (invite['recipientFingerprint'] !== fingerprint) {
380
+ return {
381
+ statusCode: 403,
382
+ headers: JSON_HEADERS,
383
+ body: JSON.stringify({ error: 'forbidden', message: 'Not authorized to decline this invite' }),
384
+ };
385
+ }
386
+ // Check status is pending
387
+ if (invite['status'] !== 'pending') {
388
+ return {
389
+ statusCode: 409,
390
+ headers: JSON_HEADERS,
391
+ body: JSON.stringify({ error: 'conflict', message: `Invite is already ${invite['status']}` }),
392
+ };
393
+ }
394
+ await ddb.send(new lib_dynamodb_1.UpdateCommand({
395
+ TableName: tableName,
396
+ Key: {
397
+ PK: `INVITE#${inviteId}`,
398
+ SK: 'META',
399
+ },
400
+ UpdateExpression: 'SET #status = :declined, declinedAt = :declinedAt',
401
+ ExpressionAttributeNames: {
402
+ '#status': 'status',
403
+ },
404
+ ExpressionAttributeValues: {
405
+ ':declined': 'declined',
406
+ ':declinedAt': new Date().toISOString(),
407
+ },
408
+ }));
409
+ // Handle optional block
410
+ let parsed = {};
411
+ if (body) {
412
+ try {
413
+ parsed = JSON.parse(body);
414
+ }
415
+ catch {
416
+ // Ignore invalid JSON in decline body — blocking is optional
417
+ }
418
+ }
419
+ if (parsed.block && parsed.senderFingerprint) {
420
+ await ddb.send(new lib_dynamodb_1.PutCommand({
421
+ TableName: tableName,
422
+ Item: {
423
+ PK: `TENANT#${tenantId}`,
424
+ SK: `BLOCK#${parsed.senderFingerprint}`,
425
+ blockedAt: new Date().toISOString(),
426
+ },
427
+ }));
428
+ logger_js_1.logger.info('Sender blocked', { tenantId, senderFingerprint: parsed.senderFingerprint });
429
+ }
430
+ await (0, audit_js_1.logAuditEvent)(ddb, tableName, tenantId, {
431
+ eventType: 'invite-declined',
432
+ fingerprint,
433
+ metadata: {
434
+ inviteId,
435
+ blocked: parsed.block ?? false,
436
+ },
437
+ });
438
+ logger_js_1.logger.info('Invite declined', { tenantId, inviteId });
439
+ return {
440
+ statusCode: 200,
441
+ headers: JSON_HEADERS,
442
+ body: JSON.stringify({ status: 'declined' }),
443
+ };
444
+ }
445
+ //# sourceMappingURL=invites.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"invites.js","sourceRoot":"","sources":["../../../../lib/handler/routes/invites.ts"],"names":[],"mappings":"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"}