@de-otio/trellis 0.4.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 (1150) hide show
  1. package/dist/db.d.ts +36 -0
  2. package/dist/db.d.ts.map +1 -0
  3. package/dist/db.js +39 -0
  4. package/dist/db.js.map +1 -0
  5. package/dist/env.d.ts +107 -0
  6. package/dist/env.d.ts.map +1 -0
  7. package/dist/env.js +268 -0
  8. package/dist/env.js.map +1 -0
  9. package/dist/extensions.d.ts +15 -0
  10. package/dist/extensions.d.ts.map +1 -0
  11. package/dist/extensions.js +35 -0
  12. package/dist/extensions.js.map +1 -0
  13. package/dist/index.d.ts +8 -0
  14. package/dist/index.d.ts.map +1 -0
  15. package/dist/index.js +15 -0
  16. package/dist/index.js.map +1 -0
  17. package/dist/lambda/cleanup-cron.d.ts +2 -0
  18. package/dist/lambda/cleanup-cron.d.ts.map +1 -0
  19. package/dist/lambda/cleanup-cron.js +38 -0
  20. package/dist/lambda/cleanup-cron.js.map +1 -0
  21. package/dist/lambda/create-auth-challenge.d.ts +2 -0
  22. package/dist/lambda/create-auth-challenge.d.ts.map +1 -0
  23. package/dist/lambda/create-auth-challenge.js +108 -0
  24. package/dist/lambda/create-auth-challenge.js.map +1 -0
  25. package/dist/lambda/custom-message.d.ts +3 -0
  26. package/dist/lambda/custom-message.d.ts.map +1 -0
  27. package/dist/lambda/custom-message.js +29 -0
  28. package/dist/lambda/custom-message.js.map +1 -0
  29. package/dist/lambda/define-auth-challenge.d.ts +2 -0
  30. package/dist/lambda/define-auth-challenge.d.ts.map +1 -0
  31. package/dist/lambda/define-auth-challenge.js +27 -0
  32. package/dist/lambda/define-auth-challenge.js.map +1 -0
  33. package/dist/lambda/delete-account-worker.d.ts +3 -0
  34. package/dist/lambda/delete-account-worker.d.ts.map +1 -0
  35. package/dist/lambda/delete-account-worker.js +122 -0
  36. package/dist/lambda/delete-account-worker.js.map +1 -0
  37. package/dist/lambda/diagnostics-proxy.d.ts +6 -0
  38. package/dist/lambda/diagnostics-proxy.d.ts.map +1 -0
  39. package/dist/lambda/diagnostics-proxy.js +154 -0
  40. package/dist/lambda/diagnostics-proxy.js.map +1 -0
  41. package/dist/lambda/e2e-sweeper.d.ts +18 -0
  42. package/dist/lambda/e2e-sweeper.d.ts.map +1 -0
  43. package/dist/lambda/e2e-sweeper.js +127 -0
  44. package/dist/lambda/e2e-sweeper.js.map +1 -0
  45. package/dist/lambda/federation-outbox-worker.d.ts +3 -0
  46. package/dist/lambda/federation-outbox-worker.d.ts.map +1 -0
  47. package/dist/lambda/federation-outbox-worker.js +11 -0
  48. package/dist/lambda/federation-outbox-worker.js.map +1 -0
  49. package/dist/lambda/followers-events-worker.d.ts +3 -0
  50. package/dist/lambda/followers-events-worker.d.ts.map +1 -0
  51. package/dist/lambda/followers-events-worker.js +11 -0
  52. package/dist/lambda/followers-events-worker.js.map +1 -0
  53. package/dist/lambda/hourly-cron.d.ts +2 -0
  54. package/dist/lambda/hourly-cron.d.ts.map +1 -0
  55. package/dist/lambda/hourly-cron.js +101 -0
  56. package/dist/lambda/hourly-cron.js.map +1 -0
  57. package/dist/lambda/link-check-worker.d.ts +3 -0
  58. package/dist/lambda/link-check-worker.d.ts.map +1 -0
  59. package/dist/lambda/link-check-worker.js +11 -0
  60. package/dist/lambda/link-check-worker.js.map +1 -0
  61. package/dist/lambda/maintenance-cron.d.ts +2 -0
  62. package/dist/lambda/maintenance-cron.d.ts.map +1 -0
  63. package/dist/lambda/maintenance-cron.js +127 -0
  64. package/dist/lambda/maintenance-cron.js.map +1 -0
  65. package/dist/lambda/media-processing-worker.d.ts +3 -0
  66. package/dist/lambda/media-processing-worker.d.ts.map +1 -0
  67. package/dist/lambda/media-processing-worker.js +95 -0
  68. package/dist/lambda/media-processing-worker.js.map +1 -0
  69. package/dist/lambda/media-reconciliation-worker.d.ts +3 -0
  70. package/dist/lambda/media-reconciliation-worker.d.ts.map +1 -0
  71. package/dist/lambda/media-reconciliation-worker.js +11 -0
  72. package/dist/lambda/media-reconciliation-worker.js.map +1 -0
  73. package/dist/lambda/nightly-cron.d.ts +2 -0
  74. package/dist/lambda/nightly-cron.d.ts.map +1 -0
  75. package/dist/lambda/nightly-cron.js +348 -0
  76. package/dist/lambda/nightly-cron.js.map +1 -0
  77. package/dist/lambda/post-confirmation.d.ts +3 -0
  78. package/dist/lambda/post-confirmation.d.ts.map +1 -0
  79. package/dist/lambda/post-confirmation.js +79 -0
  80. package/dist/lambda/post-confirmation.js.map +1 -0
  81. package/dist/lambda/pre-signup.d.ts +3 -0
  82. package/dist/lambda/pre-signup.d.ts.map +1 -0
  83. package/dist/lambda/pre-signup.js +35 -0
  84. package/dist/lambda/pre-signup.js.map +1 -0
  85. package/dist/lambda/pre-token-generation.d.ts +3 -0
  86. package/dist/lambda/pre-token-generation.d.ts.map +1 -0
  87. package/dist/lambda/pre-token-generation.js +79 -0
  88. package/dist/lambda/pre-token-generation.js.map +1 -0
  89. package/dist/lambda/tools/check-health.d.ts +6 -0
  90. package/dist/lambda/tools/check-health.d.ts.map +1 -0
  91. package/dist/lambda/tools/check-health.js +24 -0
  92. package/dist/lambda/tools/check-health.js.map +1 -0
  93. package/dist/lambda/tools/describe-services.d.ts +20 -0
  94. package/dist/lambda/tools/describe-services.d.ts.map +1 -0
  95. package/dist/lambda/tools/describe-services.js +41 -0
  96. package/dist/lambda/tools/describe-services.js.map +1 -0
  97. package/dist/lambda/tools/get-cost-report.d.ts +16 -0
  98. package/dist/lambda/tools/get-cost-report.d.ts.map +1 -0
  99. package/dist/lambda/tools/get-cost-report.js +54 -0
  100. package/dist/lambda/tools/get-cost-report.js.map +1 -0
  101. package/dist/lambda/tools/get-errors.d.ts +11 -0
  102. package/dist/lambda/tools/get-errors.d.ts.map +1 -0
  103. package/dist/lambda/tools/get-errors.js +62 -0
  104. package/dist/lambda/tools/get-errors.js.map +1 -0
  105. package/dist/lambda/tools/get-feature-flags.d.ts +8 -0
  106. package/dist/lambda/tools/get-feature-flags.d.ts.map +1 -0
  107. package/dist/lambda/tools/get-feature-flags.js +23 -0
  108. package/dist/lambda/tools/get-feature-flags.js.map +1 -0
  109. package/dist/lambda/tools/get-queue-status.d.ts +9 -0
  110. package/dist/lambda/tools/get-queue-status.d.ts.map +1 -0
  111. package/dist/lambda/tools/get-queue-status.js +46 -0
  112. package/dist/lambda/tools/get-queue-status.js.map +1 -0
  113. package/dist/lambda/tools/search-logs.d.ts +19 -0
  114. package/dist/lambda/tools/search-logs.d.ts.map +1 -0
  115. package/dist/lambda/tools/search-logs.js +55 -0
  116. package/dist/lambda/tools/search-logs.js.map +1 -0
  117. package/dist/lambda/tools/send-alert.d.ts +8 -0
  118. package/dist/lambda/tools/send-alert.d.ts.map +1 -0
  119. package/dist/lambda/tools/send-alert.js +29 -0
  120. package/dist/lambda/tools/send-alert.js.map +1 -0
  121. package/dist/lambda/verify-auth-challenge.d.ts +2 -0
  122. package/dist/lambda/verify-auth-challenge.d.ts.map +1 -0
  123. package/dist/lambda/verify-auth-challenge.js +35 -0
  124. package/dist/lambda/verify-auth-challenge.js.map +1 -0
  125. package/dist/lib/abuse-metrics.d.ts +44 -0
  126. package/dist/lib/abuse-metrics.d.ts.map +1 -0
  127. package/dist/lib/abuse-metrics.js +322 -0
  128. package/dist/lib/abuse-metrics.js.map +1 -0
  129. package/dist/lib/activitypub/activity-processor.d.ts +89 -0
  130. package/dist/lib/activitypub/activity-processor.d.ts.map +1 -0
  131. package/dist/lib/activitypub/activity-processor.js +709 -0
  132. package/dist/lib/activitypub/activity-processor.js.map +1 -0
  133. package/dist/lib/activitypub/activity-service.d.ts +47 -0
  134. package/dist/lib/activitypub/activity-service.d.ts.map +1 -0
  135. package/dist/lib/activitypub/activity-service.js +165 -0
  136. package/dist/lib/activitypub/activity-service.js.map +1 -0
  137. package/dist/lib/activitypub/actor.d.ts +44 -0
  138. package/dist/lib/activitypub/actor.d.ts.map +1 -0
  139. package/dist/lib/activitypub/actor.js +116 -0
  140. package/dist/lib/activitypub/actor.js.map +1 -0
  141. package/dist/lib/activitypub/audience-service.d.ts +52 -0
  142. package/dist/lib/activitypub/audience-service.d.ts.map +1 -0
  143. package/dist/lib/activitypub/audience-service.js +245 -0
  144. package/dist/lib/activitypub/audience-service.js.map +1 -0
  145. package/dist/lib/activitypub/crypto.d.ts +42 -0
  146. package/dist/lib/activitypub/crypto.d.ts.map +1 -0
  147. package/dist/lib/activitypub/crypto.js +129 -0
  148. package/dist/lib/activitypub/crypto.js.map +1 -0
  149. package/dist/lib/activitypub/delivery-service.d.ts +44 -0
  150. package/dist/lib/activitypub/delivery-service.d.ts.map +1 -0
  151. package/dist/lib/activitypub/delivery-service.js +259 -0
  152. package/dist/lib/activitypub/delivery-service.js.map +1 -0
  153. package/dist/lib/activitypub/dispatchers/entity-actor.d.ts +50 -0
  154. package/dist/lib/activitypub/dispatchers/entity-actor.d.ts.map +1 -0
  155. package/dist/lib/activitypub/dispatchers/entity-actor.js +247 -0
  156. package/dist/lib/activitypub/dispatchers/entity-actor.js.map +1 -0
  157. package/dist/lib/activitypub/dispatchers/group-actor.d.ts +47 -0
  158. package/dist/lib/activitypub/dispatchers/group-actor.d.ts.map +1 -0
  159. package/dist/lib/activitypub/dispatchers/group-actor.js +202 -0
  160. package/dist/lib/activitypub/dispatchers/group-actor.js.map +1 -0
  161. package/dist/lib/activitypub/dispatchers/user-actor.d.ts +47 -0
  162. package/dist/lib/activitypub/dispatchers/user-actor.d.ts.map +1 -0
  163. package/dist/lib/activitypub/dispatchers/user-actor.js +207 -0
  164. package/dist/lib/activitypub/dispatchers/user-actor.js.map +1 -0
  165. package/dist/lib/activitypub/dm-service.d.ts +35 -0
  166. package/dist/lib/activitypub/dm-service.d.ts.map +1 -0
  167. package/dist/lib/activitypub/dm-service.js +73 -0
  168. package/dist/lib/activitypub/dm-service.js.map +1 -0
  169. package/dist/lib/activitypub/entity-profile-service.d.ts +43 -0
  170. package/dist/lib/activitypub/entity-profile-service.d.ts.map +1 -0
  171. package/dist/lib/activitypub/entity-profile-service.js +80 -0
  172. package/dist/lib/activitypub/entity-profile-service.js.map +1 -0
  173. package/dist/lib/activitypub/fedify/config.d.ts +15 -0
  174. package/dist/lib/activitypub/fedify/config.d.ts.map +1 -0
  175. package/dist/lib/activitypub/fedify/config.js +38 -0
  176. package/dist/lib/activitypub/fedify/config.js.map +1 -0
  177. package/dist/lib/activitypub/fedify/context.d.ts +21 -0
  178. package/dist/lib/activitypub/fedify/context.d.ts.map +1 -0
  179. package/dist/lib/activitypub/fedify/context.js +67 -0
  180. package/dist/lib/activitypub/fedify/context.js.map +1 -0
  181. package/dist/lib/activitypub/fedify/runtime.d.ts +18 -0
  182. package/dist/lib/activitypub/fedify/runtime.d.ts.map +1 -0
  183. package/dist/lib/activitypub/fedify/runtime.js +26 -0
  184. package/dist/lib/activitypub/fedify/runtime.js.map +1 -0
  185. package/dist/lib/activitypub/friendship-service.d.ts +15 -0
  186. package/dist/lib/activitypub/friendship-service.d.ts.map +1 -0
  187. package/dist/lib/activitypub/friendship-service.js +26 -0
  188. package/dist/lib/activitypub/friendship-service.js.map +1 -0
  189. package/dist/lib/activitypub/group-service.d.ts +83 -0
  190. package/dist/lib/activitypub/group-service.d.ts.map +1 -0
  191. package/dist/lib/activitypub/group-service.js +301 -0
  192. package/dist/lib/activitypub/group-service.js.map +1 -0
  193. package/dist/lib/activitypub/http-signatures.d.ts +41 -0
  194. package/dist/lib/activitypub/http-signatures.d.ts.map +1 -0
  195. package/dist/lib/activitypub/http-signatures.js +284 -0
  196. package/dist/lib/activitypub/http-signatures.js.map +1 -0
  197. package/dist/lib/activitypub/jsonld.d.ts +39 -0
  198. package/dist/lib/activitypub/jsonld.d.ts.map +1 -0
  199. package/dist/lib/activitypub/jsonld.js +97 -0
  200. package/dist/lib/activitypub/jsonld.js.map +1 -0
  201. package/dist/lib/activitypub/listeners/friends-collection.d.ts +20 -0
  202. package/dist/lib/activitypub/listeners/friends-collection.d.ts.map +1 -0
  203. package/dist/lib/activitypub/listeners/friends-collection.js +105 -0
  204. package/dist/lib/activitypub/listeners/friends-collection.js.map +1 -0
  205. package/dist/lib/activitypub/listeners/http-signatures.d.ts +29 -0
  206. package/dist/lib/activitypub/listeners/http-signatures.d.ts.map +1 -0
  207. package/dist/lib/activitypub/listeners/http-signatures.js +208 -0
  208. package/dist/lib/activitypub/listeners/http-signatures.js.map +1 -0
  209. package/dist/lib/activitypub/listeners/inbox.d.ts +34 -0
  210. package/dist/lib/activitypub/listeners/inbox.d.ts.map +1 -0
  211. package/dist/lib/activitypub/listeners/inbox.js +226 -0
  212. package/dist/lib/activitypub/listeners/inbox.js.map +1 -0
  213. package/dist/lib/activitypub/listeners/outbox.d.ts +20 -0
  214. package/dist/lib/activitypub/listeners/outbox.d.ts.map +1 -0
  215. package/dist/lib/activitypub/listeners/outbox.js +117 -0
  216. package/dist/lib/activitypub/listeners/outbox.js.map +1 -0
  217. package/dist/lib/activitypub/remote-fetch-service.d.ts +108 -0
  218. package/dist/lib/activitypub/remote-fetch-service.d.ts.map +1 -0
  219. package/dist/lib/activitypub/remote-fetch-service.js +364 -0
  220. package/dist/lib/activitypub/remote-fetch-service.js.map +1 -0
  221. package/dist/lib/activitypub/services/abuse-prevention.d.ts +52 -0
  222. package/dist/lib/activitypub/services/abuse-prevention.d.ts.map +1 -0
  223. package/dist/lib/activitypub/services/abuse-prevention.js +118 -0
  224. package/dist/lib/activitypub/services/abuse-prevention.js.map +1 -0
  225. package/dist/lib/activitypub/services/dm-service-fedify.d.ts +46 -0
  226. package/dist/lib/activitypub/services/dm-service-fedify.d.ts.map +1 -0
  227. package/dist/lib/activitypub/services/dm-service-fedify.js +168 -0
  228. package/dist/lib/activitypub/services/dm-service-fedify.js.map +1 -0
  229. package/dist/lib/activitypub/services/fedify-converters.d.ts +51 -0
  230. package/dist/lib/activitypub/services/fedify-converters.d.ts.map +1 -0
  231. package/dist/lib/activitypub/services/fedify-converters.js +109 -0
  232. package/dist/lib/activitypub/services/fedify-converters.js.map +1 -0
  233. package/dist/lib/activitypub/services/fedify-delivery.d.ts +41 -0
  234. package/dist/lib/activitypub/services/fedify-delivery.d.ts.map +1 -0
  235. package/dist/lib/activitypub/services/fedify-delivery.js +186 -0
  236. package/dist/lib/activitypub/services/fedify-delivery.js.map +1 -0
  237. package/dist/lib/activitypub/services/follow-activity-service.d.ts +34 -0
  238. package/dist/lib/activitypub/services/follow-activity-service.d.ts.map +1 -0
  239. package/dist/lib/activitypub/services/follow-activity-service.js +64 -0
  240. package/dist/lib/activitypub/services/follow-activity-service.js.map +1 -0
  241. package/dist/lib/activitypub/services/post-service-fedify.d.ts +49 -0
  242. package/dist/lib/activitypub/services/post-service-fedify.d.ts.map +1 -0
  243. package/dist/lib/activitypub/services/post-service-fedify.js +281 -0
  244. package/dist/lib/activitypub/services/post-service-fedify.js.map +1 -0
  245. package/dist/lib/activitypub/services/remote-activity-handler.d.ts +22 -0
  246. package/dist/lib/activitypub/services/remote-activity-handler.d.ts.map +1 -0
  247. package/dist/lib/activitypub/services/remote-activity-handler.js +136 -0
  248. package/dist/lib/activitypub/services/remote-activity-handler.js.map +1 -0
  249. package/dist/lib/activitypub/standalone-mode.d.ts +34 -0
  250. package/dist/lib/activitypub/standalone-mode.d.ts.map +1 -0
  251. package/dist/lib/activitypub/standalone-mode.js +127 -0
  252. package/dist/lib/activitypub/standalone-mode.js.map +1 -0
  253. package/dist/lib/activitypub/webfinger/server.d.ts +16 -0
  254. package/dist/lib/activitypub/webfinger/server.d.ts.map +1 -0
  255. package/dist/lib/activitypub/webfinger/server.js +221 -0
  256. package/dist/lib/activitypub/webfinger/server.js.map +1 -0
  257. package/dist/lib/age-gate-middleware.d.ts +19 -0
  258. package/dist/lib/age-gate-middleware.d.ts.map +1 -0
  259. package/dist/lib/age-gate-middleware.js +26 -0
  260. package/dist/lib/age-gate-middleware.js.map +1 -0
  261. package/dist/lib/age-gate.d.ts +37 -0
  262. package/dist/lib/age-gate.d.ts.map +1 -0
  263. package/dist/lib/age-gate.js +96 -0
  264. package/dist/lib/age-gate.js.map +1 -0
  265. package/dist/lib/age-tier-transition.d.ts +21 -0
  266. package/dist/lib/age-tier-transition.d.ts.map +1 -0
  267. package/dist/lib/age-tier-transition.js +190 -0
  268. package/dist/lib/age-tier-transition.js.map +1 -0
  269. package/dist/lib/audit-logger.d.ts +142 -0
  270. package/dist/lib/audit-logger.d.ts.map +1 -0
  271. package/dist/lib/audit-logger.js +326 -0
  272. package/dist/lib/audit-logger.js.map +1 -0
  273. package/dist/lib/auth/cognito-jwt.d.ts +20 -0
  274. package/dist/lib/auth/cognito-jwt.d.ts.map +1 -0
  275. package/dist/lib/auth/cognito-jwt.js +56 -0
  276. package/dist/lib/auth/cognito-jwt.js.map +1 -0
  277. package/dist/lib/auth-context-manager.d.ts +116 -0
  278. package/dist/lib/auth-context-manager.d.ts.map +1 -0
  279. package/dist/lib/auth-context-manager.js +130 -0
  280. package/dist/lib/auth-context-manager.js.map +1 -0
  281. package/dist/lib/auth-handler.d.ts +19 -0
  282. package/dist/lib/auth-handler.d.ts.map +1 -0
  283. package/dist/lib/auth-handler.js +76 -0
  284. package/dist/lib/auth-handler.js.map +1 -0
  285. package/dist/lib/badge-handler.d.ts +20 -0
  286. package/dist/lib/badge-handler.d.ts.map +1 -0
  287. package/dist/lib/badge-handler.js +142 -0
  288. package/dist/lib/badge-handler.js.map +1 -0
  289. package/dist/lib/circle-handler.d.ts +22 -0
  290. package/dist/lib/circle-handler.d.ts.map +1 -0
  291. package/dist/lib/circle-handler.js +224 -0
  292. package/dist/lib/circle-handler.js.map +1 -0
  293. package/dist/lib/circuit-breaker.d.ts +27 -0
  294. package/dist/lib/circuit-breaker.d.ts.map +1 -0
  295. package/dist/lib/circuit-breaker.js +63 -0
  296. package/dist/lib/circuit-breaker.js.map +1 -0
  297. package/dist/lib/comment-handler.d.ts +77 -0
  298. package/dist/lib/comment-handler.d.ts.map +1 -0
  299. package/dist/lib/comment-handler.js +953 -0
  300. package/dist/lib/comment-handler.js.map +1 -0
  301. package/dist/lib/connection-code-handler.d.ts +17 -0
  302. package/dist/lib/connection-code-handler.d.ts.map +1 -0
  303. package/dist/lib/connection-code-handler.js +293 -0
  304. package/dist/lib/connection-code-handler.js.map +1 -0
  305. package/dist/lib/content-discovery.d.ts +113 -0
  306. package/dist/lib/content-discovery.d.ts.map +1 -0
  307. package/dist/lib/content-discovery.js +519 -0
  308. package/dist/lib/content-discovery.js.map +1 -0
  309. package/dist/lib/context-aware-data-access.d.ts +89 -0
  310. package/dist/lib/context-aware-data-access.d.ts.map +1 -0
  311. package/dist/lib/context-aware-data-access.js +97 -0
  312. package/dist/lib/context-aware-data-access.js.map +1 -0
  313. package/dist/lib/cors-handler.d.ts +29 -0
  314. package/dist/lib/cors-handler.d.ts.map +1 -0
  315. package/dist/lib/cors-handler.js +225 -0
  316. package/dist/lib/cors-handler.js.map +1 -0
  317. package/dist/lib/cost-accumulator.d.ts +58 -0
  318. package/dist/lib/cost-accumulator.d.ts.map +1 -0
  319. package/dist/lib/cost-accumulator.js +173 -0
  320. package/dist/lib/cost-accumulator.js.map +1 -0
  321. package/dist/lib/crypto/encryption-service.d.ts +100 -0
  322. package/dist/lib/crypto/encryption-service.d.ts.map +1 -0
  323. package/dist/lib/crypto/encryption-service.js +293 -0
  324. package/dist/lib/crypto/encryption-service.js.map +1 -0
  325. package/dist/lib/crypto/index.d.ts +22 -0
  326. package/dist/lib/crypto/index.d.ts.map +1 -0
  327. package/dist/lib/crypto/index.js +28 -0
  328. package/dist/lib/crypto/index.js.map +1 -0
  329. package/dist/lib/crypto/types.d.ts +71 -0
  330. package/dist/lib/crypto/types.d.ts.map +1 -0
  331. package/dist/lib/crypto/types.js +3 -0
  332. package/dist/lib/crypto/types.js.map +1 -0
  333. package/dist/lib/crypto/versioning.d.ts +112 -0
  334. package/dist/lib/crypto/versioning.d.ts.map +1 -0
  335. package/dist/lib/crypto/versioning.js +148 -0
  336. package/dist/lib/crypto/versioning.js.map +1 -0
  337. package/dist/lib/crypto/voting/elgamal-encryption.d.ts +156 -0
  338. package/dist/lib/crypto/voting/elgamal-encryption.d.ts.map +1 -0
  339. package/dist/lib/crypto/voting/elgamal-encryption.js +172 -0
  340. package/dist/lib/crypto/voting/elgamal-encryption.js.map +1 -0
  341. package/dist/lib/crypto/voting/encryption-scheme.d.ts +138 -0
  342. package/dist/lib/crypto/voting/encryption-scheme.d.ts.map +1 -0
  343. package/dist/lib/crypto/voting/encryption-scheme.js +13 -0
  344. package/dist/lib/crypto/voting/encryption-scheme.js.map +1 -0
  345. package/dist/lib/crypto/voting/hash-utils.d.ts +58 -0
  346. package/dist/lib/crypto/voting/hash-utils.d.ts.map +1 -0
  347. package/dist/lib/crypto/voting/hash-utils.js +73 -0
  348. package/dist/lib/crypto/voting/hash-utils.js.map +1 -0
  349. package/dist/lib/crypto/voting/hybrid-encryption.d.ts +109 -0
  350. package/dist/lib/crypto/voting/hybrid-encryption.d.ts.map +1 -0
  351. package/dist/lib/crypto/voting/hybrid-encryption.js +134 -0
  352. package/dist/lib/crypto/voting/hybrid-encryption.js.map +1 -0
  353. package/dist/lib/crypto/voting/index.d.ts +18 -0
  354. package/dist/lib/crypto/voting/index.d.ts.map +1 -0
  355. package/dist/lib/crypto/voting/index.js +27 -0
  356. package/dist/lib/crypto/voting/index.js.map +1 -0
  357. package/dist/lib/crypto/voting/post-quantum-encryption.d.ts +107 -0
  358. package/dist/lib/crypto/voting/post-quantum-encryption.d.ts.map +1 -0
  359. package/dist/lib/crypto/voting/post-quantum-encryption.js +123 -0
  360. package/dist/lib/crypto/voting/post-quantum-encryption.js.map +1 -0
  361. package/dist/lib/csrf.d.ts +95 -0
  362. package/dist/lib/csrf.d.ts.map +1 -0
  363. package/dist/lib/csrf.js +174 -0
  364. package/dist/lib/csrf.js.map +1 -0
  365. package/dist/lib/data-router.d.ts +209 -0
  366. package/dist/lib/data-router.d.ts.map +1 -0
  367. package/dist/lib/data-router.js +792 -0
  368. package/dist/lib/data-router.js.map +1 -0
  369. package/dist/lib/database-circuit-breaker.d.ts +75 -0
  370. package/dist/lib/database-circuit-breaker.d.ts.map +1 -0
  371. package/dist/lib/database-circuit-breaker.js +155 -0
  372. package/dist/lib/database-circuit-breaker.js.map +1 -0
  373. package/dist/lib/database-config.d.ts +20 -0
  374. package/dist/lib/database-config.d.ts.map +1 -0
  375. package/dist/lib/database-config.js +46 -0
  376. package/dist/lib/database-config.js.map +1 -0
  377. package/dist/lib/database-connection-manager.d.ts +99 -0
  378. package/dist/lib/database-connection-manager.d.ts.map +1 -0
  379. package/dist/lib/database-connection-manager.js +495 -0
  380. package/dist/lib/database-connection-manager.js.map +1 -0
  381. package/dist/lib/database-monitor.d.ts +89 -0
  382. package/dist/lib/database-monitor.d.ts.map +1 -0
  383. package/dist/lib/database-monitor.js +199 -0
  384. package/dist/lib/database-monitor.js.map +1 -0
  385. package/dist/lib/database-rate-limiter.d.ts +41 -0
  386. package/dist/lib/database-rate-limiter.d.ts.map +1 -0
  387. package/dist/lib/database-rate-limiter.js +90 -0
  388. package/dist/lib/database-rate-limiter.js.map +1 -0
  389. package/dist/lib/database-wrapper-helper.d.ts +44 -0
  390. package/dist/lib/database-wrapper-helper.d.ts.map +1 -0
  391. package/dist/lib/database-wrapper-helper.js +104 -0
  392. package/dist/lib/database-wrapper-helper.js.map +1 -0
  393. package/dist/lib/database-wrapper.d.ts +51 -0
  394. package/dist/lib/database-wrapper.d.ts.map +1 -0
  395. package/dist/lib/database-wrapper.js +109 -0
  396. package/dist/lib/database-wrapper.js.map +1 -0
  397. package/dist/lib/db-query-helper.d.ts +130 -0
  398. package/dist/lib/db-query-helper.d.ts.map +1 -0
  399. package/dist/lib/db-query-helper.js +105 -0
  400. package/dist/lib/db-query-helper.js.map +1 -0
  401. package/dist/lib/discovery-handler.d.ts +19 -0
  402. package/dist/lib/discovery-handler.d.ts.map +1 -0
  403. package/dist/lib/discovery-handler.js +195 -0
  404. package/dist/lib/discovery-handler.js.map +1 -0
  405. package/dist/lib/domain-reputation-service.d.ts +112 -0
  406. package/dist/lib/domain-reputation-service.d.ts.map +1 -0
  407. package/dist/lib/domain-reputation-service.js +344 -0
  408. package/dist/lib/domain-reputation-service.js.map +1 -0
  409. package/dist/lib/email-privacy.d.ts +54 -0
  410. package/dist/lib/email-privacy.d.ts.map +1 -0
  411. package/dist/lib/email-privacy.js +72 -0
  412. package/dist/lib/email-privacy.js.map +1 -0
  413. package/dist/lib/email-provider.d.ts +133 -0
  414. package/dist/lib/email-provider.d.ts.map +1 -0
  415. package/dist/lib/email-provider.js +391 -0
  416. package/dist/lib/email-provider.js.map +1 -0
  417. package/dist/lib/encryption-key-service.d.ts +115 -0
  418. package/dist/lib/encryption-key-service.d.ts.map +1 -0
  419. package/dist/lib/encryption-key-service.js +272 -0
  420. package/dist/lib/encryption-key-service.js.map +1 -0
  421. package/dist/lib/entity-handler.d.ts +59 -0
  422. package/dist/lib/entity-handler.d.ts.map +1 -0
  423. package/dist/lib/entity-handler.js +866 -0
  424. package/dist/lib/entity-handler.js.map +1 -0
  425. package/dist/lib/entity-relationship-handler.d.ts +19 -0
  426. package/dist/lib/entity-relationship-handler.d.ts.map +1 -0
  427. package/dist/lib/entity-relationship-handler.js +242 -0
  428. package/dist/lib/entity-relationship-handler.js.map +1 -0
  429. package/dist/lib/entity-tagging-errors.d.ts +32 -0
  430. package/dist/lib/entity-tagging-errors.d.ts.map +1 -0
  431. package/dist/lib/entity-tagging-errors.js +53 -0
  432. package/dist/lib/entity-tagging-errors.js.map +1 -0
  433. package/dist/lib/entity-tagging-validator.d.ts +47 -0
  434. package/dist/lib/entity-tagging-validator.d.ts.map +1 -0
  435. package/dist/lib/entity-tagging-validator.js +84 -0
  436. package/dist/lib/entity-tagging-validator.js.map +1 -0
  437. package/dist/lib/exif-stripper.d.ts +37 -0
  438. package/dist/lib/exif-stripper.d.ts.map +1 -0
  439. package/dist/lib/exif-stripper.js +62 -0
  440. package/dist/lib/exif-stripper.js.map +1 -0
  441. package/dist/lib/extension-context.d.ts +19 -0
  442. package/dist/lib/extension-context.d.ts.map +1 -0
  443. package/dist/lib/extension-context.js +78 -0
  444. package/dist/lib/extension-context.js.map +1 -0
  445. package/dist/lib/extension-route-wrapper.d.ts +21 -0
  446. package/dist/lib/extension-route-wrapper.d.ts.map +1 -0
  447. package/dist/lib/extension-route-wrapper.js +113 -0
  448. package/dist/lib/extension-route-wrapper.js.map +1 -0
  449. package/dist/lib/extension-validator.d.ts +12 -0
  450. package/dist/lib/extension-validator.d.ts.map +1 -0
  451. package/dist/lib/extension-validator.js +60 -0
  452. package/dist/lib/extension-validator.js.map +1 -0
  453. package/dist/lib/feature-flags.d.ts +56 -0
  454. package/dist/lib/feature-flags.d.ts.map +1 -0
  455. package/dist/lib/feature-flags.js +140 -0
  456. package/dist/lib/feature-flags.js.map +1 -0
  457. package/dist/lib/feature-toggle-service.d.ts +48 -0
  458. package/dist/lib/feature-toggle-service.d.ts.map +1 -0
  459. package/dist/lib/feature-toggle-service.js +167 -0
  460. package/dist/lib/feature-toggle-service.js.map +1 -0
  461. package/dist/lib/feed-handler.d.ts +152 -0
  462. package/dist/lib/feed-handler.d.ts.map +1 -0
  463. package/dist/lib/feed-handler.js +784 -0
  464. package/dist/lib/feed-handler.js.map +1 -0
  465. package/dist/lib/feed-pagination.d.ts +42 -0
  466. package/dist/lib/feed-pagination.d.ts.map +1 -0
  467. package/dist/lib/feed-pagination.js +54 -0
  468. package/dist/lib/feed-pagination.js.map +1 -0
  469. package/dist/lib/feed-personalization.d.ts +52 -0
  470. package/dist/lib/feed-personalization.d.ts.map +1 -0
  471. package/dist/lib/feed-personalization.js +105 -0
  472. package/dist/lib/feed-personalization.js.map +1 -0
  473. package/dist/lib/followers-events.d.ts +37 -0
  474. package/dist/lib/followers-events.d.ts.map +1 -0
  475. package/dist/lib/followers-events.js +149 -0
  476. package/dist/lib/followers-events.js.map +1 -0
  477. package/dist/lib/followers-handler.d.ts +21 -0
  478. package/dist/lib/followers-handler.d.ts.map +1 -0
  479. package/dist/lib/followers-handler.js +35 -0
  480. package/dist/lib/followers-handler.js.map +1 -0
  481. package/dist/lib/friends-handler.d.ts +78 -0
  482. package/dist/lib/friends-handler.d.ts.map +1 -0
  483. package/dist/lib/friends-handler.js +390 -0
  484. package/dist/lib/friends-handler.js.map +1 -0
  485. package/dist/lib/graph/dual-write-service.d.ts +116 -0
  486. package/dist/lib/graph/dual-write-service.d.ts.map +1 -0
  487. package/dist/lib/graph/dual-write-service.js +332 -0
  488. package/dist/lib/graph/dual-write-service.js.map +1 -0
  489. package/dist/lib/graph/dual-write.d.ts +396 -0
  490. package/dist/lib/graph/dual-write.d.ts.map +1 -0
  491. package/dist/lib/graph/dual-write.js +53 -0
  492. package/dist/lib/graph/dual-write.js.map +1 -0
  493. package/dist/lib/graph/errors.d.ts +90 -0
  494. package/dist/lib/graph/errors.d.ts.map +1 -0
  495. package/dist/lib/graph/errors.js +131 -0
  496. package/dist/lib/graph/errors.js.map +1 -0
  497. package/dist/lib/graph/graph-factory.d.ts +64 -0
  498. package/dist/lib/graph/graph-factory.d.ts.map +1 -0
  499. package/dist/lib/graph/graph-factory.js +190 -0
  500. package/dist/lib/graph/graph-factory.js.map +1 -0
  501. package/dist/lib/graph/graph-schema-init.d.ts +31 -0
  502. package/dist/lib/graph/graph-schema-init.d.ts.map +1 -0
  503. package/dist/lib/graph/graph-schema-init.js +105 -0
  504. package/dist/lib/graph/graph-schema-init.js.map +1 -0
  505. package/dist/lib/graph/graph-service.d.ts +479 -0
  506. package/dist/lib/graph/graph-service.d.ts.map +1 -0
  507. package/dist/lib/graph/graph-service.js +21 -0
  508. package/dist/lib/graph/graph-service.js.map +1 -0
  509. package/dist/lib/graph/index.d.ts +40 -0
  510. package/dist/lib/graph/index.d.ts.map +1 -0
  511. package/dist/lib/graph/index.js +74 -0
  512. package/dist/lib/graph/index.js.map +1 -0
  513. package/dist/lib/graph/neo4j-graph-service.d.ts +186 -0
  514. package/dist/lib/graph/neo4j-graph-service.d.ts.map +1 -0
  515. package/dist/lib/graph/neo4j-graph-service.js +1625 -0
  516. package/dist/lib/graph/neo4j-graph-service.js.map +1 -0
  517. package/dist/lib/graph/reconciliation-service.d.ts +113 -0
  518. package/dist/lib/graph/reconciliation-service.d.ts.map +1 -0
  519. package/dist/lib/graph/reconciliation-service.js +533 -0
  520. package/dist/lib/graph/reconciliation-service.js.map +1 -0
  521. package/dist/lib/graph/scoring-engine.d.ts +154 -0
  522. package/dist/lib/graph/scoring-engine.d.ts.map +1 -0
  523. package/dist/lib/graph/scoring-engine.js +286 -0
  524. package/dist/lib/graph/scoring-engine.js.map +1 -0
  525. package/dist/lib/graph/types.d.ts +480 -0
  526. package/dist/lib/graph/types.d.ts.map +1 -0
  527. package/dist/lib/graph/types.js +10 -0
  528. package/dist/lib/graph/types.js.map +1 -0
  529. package/dist/lib/hook-dispatcher.d.ts +21 -0
  530. package/dist/lib/hook-dispatcher.d.ts.map +1 -0
  531. package/dist/lib/hook-dispatcher.js +62 -0
  532. package/dist/lib/hook-dispatcher.js.map +1 -0
  533. package/dist/lib/id-generator.d.ts +29 -0
  534. package/dist/lib/id-generator.d.ts.map +1 -0
  535. package/dist/lib/id-generator.js +51 -0
  536. package/dist/lib/id-generator.js.map +1 -0
  537. package/dist/lib/input-sanitizer.d.ts +55 -0
  538. package/dist/lib/input-sanitizer.d.ts.map +1 -0
  539. package/dist/lib/input-sanitizer.js +167 -0
  540. package/dist/lib/input-sanitizer.js.map +1 -0
  541. package/dist/lib/internal-docs-dashboard.json +112 -0
  542. package/dist/lib/internal-docs-handler.d.ts +60 -0
  543. package/dist/lib/internal-docs-handler.d.ts.map +1 -0
  544. package/dist/lib/internal-docs-handler.js +570 -0
  545. package/dist/lib/internal-docs-handler.js.map +1 -0
  546. package/dist/lib/internal-docs-navigation.d.ts +42 -0
  547. package/dist/lib/internal-docs-navigation.d.ts.map +1 -0
  548. package/dist/lib/internal-docs-navigation.js +73 -0
  549. package/dist/lib/internal-docs-navigation.js.map +1 -0
  550. package/dist/lib/internal-docs-navigation.json +169 -0
  551. package/dist/lib/invitation-handler.d.ts +133 -0
  552. package/dist/lib/invitation-handler.d.ts.map +1 -0
  553. package/dist/lib/invitation-handler.js +1335 -0
  554. package/dist/lib/invitation-handler.js.map +1 -0
  555. package/dist/lib/ip-scrubber.d.ts +59 -0
  556. package/dist/lib/ip-scrubber.d.ts.map +1 -0
  557. package/dist/lib/ip-scrubber.js +101 -0
  558. package/dist/lib/ip-scrubber.js.map +1 -0
  559. package/dist/lib/kv/dynamodb-kv.d.ts +39 -0
  560. package/dist/lib/kv/dynamodb-kv.d.ts.map +1 -0
  561. package/dist/lib/kv/dynamodb-kv.js +239 -0
  562. package/dist/lib/kv/dynamodb-kv.js.map +1 -0
  563. package/dist/lib/link-security-handler.d.ts +140 -0
  564. package/dist/lib/link-security-handler.d.ts.map +1 -0
  565. package/dist/lib/link-security-handler.js +460 -0
  566. package/dist/lib/link-security-handler.js.map +1 -0
  567. package/dist/lib/logger.d.ts +100 -0
  568. package/dist/lib/logger.d.ts.map +1 -0
  569. package/dist/lib/logger.js +201 -0
  570. package/dist/lib/logger.js.map +1 -0
  571. package/dist/lib/media-cleanup-handler.d.ts +46 -0
  572. package/dist/lib/media-cleanup-handler.d.ts.map +1 -0
  573. package/dist/lib/media-cleanup-handler.js +190 -0
  574. package/dist/lib/media-cleanup-handler.js.map +1 -0
  575. package/dist/lib/media-handler.d.ts +150 -0
  576. package/dist/lib/media-handler.d.ts.map +1 -0
  577. package/dist/lib/media-handler.js +1544 -0
  578. package/dist/lib/media-handler.js.map +1 -0
  579. package/dist/lib/media-metadata-extractor.d.ts +71 -0
  580. package/dist/lib/media-metadata-extractor.d.ts.map +1 -0
  581. package/dist/lib/media-metadata-extractor.js +278 -0
  582. package/dist/lib/media-metadata-extractor.js.map +1 -0
  583. package/dist/lib/media-metrics.d.ts +57 -0
  584. package/dist/lib/media-metrics.d.ts.map +1 -0
  585. package/dist/lib/media-metrics.js +202 -0
  586. package/dist/lib/media-metrics.js.map +1 -0
  587. package/dist/lib/metadata/index.d.ts +6 -0
  588. package/dist/lib/metadata/index.d.ts.map +1 -0
  589. package/dist/lib/metadata/index.js +22 -0
  590. package/dist/lib/metadata/index.js.map +1 -0
  591. package/dist/lib/metadata/metadata-config.d.ts +17 -0
  592. package/dist/lib/metadata/metadata-config.d.ts.map +1 -0
  593. package/dist/lib/metadata/metadata-config.js +23 -0
  594. package/dist/lib/metadata/metadata-config.js.map +1 -0
  595. package/dist/lib/metadata/metadata-errors.d.ts +18 -0
  596. package/dist/lib/metadata/metadata-errors.d.ts.map +1 -0
  597. package/dist/lib/metadata/metadata-errors.js +26 -0
  598. package/dist/lib/metadata/metadata-errors.js.map +1 -0
  599. package/dist/lib/metadata/metadata-extractor.d.ts +17 -0
  600. package/dist/lib/metadata/metadata-extractor.d.ts.map +1 -0
  601. package/dist/lib/metadata/metadata-extractor.js +264 -0
  602. package/dist/lib/metadata/metadata-extractor.js.map +1 -0
  603. package/dist/lib/metadata/metadata-sanitizer.d.ts +9 -0
  604. package/dist/lib/metadata/metadata-sanitizer.d.ts.map +1 -0
  605. package/dist/lib/metadata/metadata-sanitizer.js +100 -0
  606. package/dist/lib/metadata/metadata-sanitizer.js.map +1 -0
  607. package/dist/lib/metadata/metadata-schemas.d.ts +131 -0
  608. package/dist/lib/metadata/metadata-schemas.d.ts.map +1 -0
  609. package/dist/lib/metadata/metadata-schemas.js +71 -0
  610. package/dist/lib/metadata/metadata-schemas.js.map +1 -0
  611. package/dist/lib/mfa/mfa-handler.d.ts +60 -0
  612. package/dist/lib/mfa/mfa-handler.d.ts.map +1 -0
  613. package/dist/lib/mfa/mfa-handler.js +150 -0
  614. package/dist/lib/mfa/mfa-handler.js.map +1 -0
  615. package/dist/lib/mfa/totp-service.d.ts +41 -0
  616. package/dist/lib/mfa/totp-service.d.ts.map +1 -0
  617. package/dist/lib/mfa/totp-service.js +183 -0
  618. package/dist/lib/mfa/totp-service.js.map +1 -0
  619. package/dist/lib/middleware/comment-rate-limit.d.ts +19 -0
  620. package/dist/lib/middleware/comment-rate-limit.d.ts.map +1 -0
  621. package/dist/lib/middleware/comment-rate-limit.js +113 -0
  622. package/dist/lib/middleware/comment-rate-limit.js.map +1 -0
  623. package/dist/lib/middleware/feature-toggle-rate-limit.d.ts +53 -0
  624. package/dist/lib/middleware/feature-toggle-rate-limit.d.ts.map +1 -0
  625. package/dist/lib/middleware/feature-toggle-rate-limit.js +164 -0
  626. package/dist/lib/middleware/feature-toggle-rate-limit.js.map +1 -0
  627. package/dist/lib/middleware.d.ts +70 -0
  628. package/dist/lib/middleware.d.ts.map +1 -0
  629. package/dist/lib/middleware.js +375 -0
  630. package/dist/lib/middleware.js.map +1 -0
  631. package/dist/lib/moderation-handler.d.ts +55 -0
  632. package/dist/lib/moderation-handler.d.ts.map +1 -0
  633. package/dist/lib/moderation-handler.js +230 -0
  634. package/dist/lib/moderation-handler.js.map +1 -0
  635. package/dist/lib/notification-handler.d.ts +65 -0
  636. package/dist/lib/notification-handler.d.ts.map +1 -0
  637. package/dist/lib/notification-handler.js +236 -0
  638. package/dist/lib/notification-handler.js.map +1 -0
  639. package/dist/lib/notification-preferences-handler.d.ts +27 -0
  640. package/dist/lib/notification-preferences-handler.d.ts.map +1 -0
  641. package/dist/lib/notification-preferences-handler.js +119 -0
  642. package/dist/lib/notification-preferences-handler.js.map +1 -0
  643. package/dist/lib/openai-budget.d.ts +45 -0
  644. package/dist/lib/openai-budget.d.ts.map +1 -0
  645. package/dist/lib/openai-budget.js +175 -0
  646. package/dist/lib/openai-budget.js.map +1 -0
  647. package/dist/lib/orphaned-media-handler.d.ts +60 -0
  648. package/dist/lib/orphaned-media-handler.d.ts.map +1 -0
  649. package/dist/lib/orphaned-media-handler.js +487 -0
  650. package/dist/lib/orphaned-media-handler.js.map +1 -0
  651. package/dist/lib/parental-control-handler.d.ts +42 -0
  652. package/dist/lib/parental-control-handler.d.ts.map +1 -0
  653. package/dist/lib/parental-control-handler.js +327 -0
  654. package/dist/lib/parental-control-handler.js.map +1 -0
  655. package/dist/lib/parental-link-handler.d.ts +38 -0
  656. package/dist/lib/parental-link-handler.d.ts.map +1 -0
  657. package/dist/lib/parental-link-handler.js +217 -0
  658. package/dist/lib/parental-link-handler.js.map +1 -0
  659. package/dist/lib/performance-metrics.d.ts +125 -0
  660. package/dist/lib/performance-metrics.d.ts.map +1 -0
  661. package/dist/lib/performance-metrics.js +277 -0
  662. package/dist/lib/performance-metrics.js.map +1 -0
  663. package/dist/lib/post-handler.d.ts +94 -0
  664. package/dist/lib/post-handler.d.ts.map +1 -0
  665. package/dist/lib/post-handler.js +1346 -0
  666. package/dist/lib/post-handler.js.map +1 -0
  667. package/dist/lib/privacy-defaults.d.ts +32 -0
  668. package/dist/lib/privacy-defaults.d.ts.map +1 -0
  669. package/dist/lib/privacy-defaults.js +85 -0
  670. package/dist/lib/privacy-defaults.js.map +1 -0
  671. package/dist/lib/privacy-handler.d.ts +43 -0
  672. package/dist/lib/privacy-handler.d.ts.map +1 -0
  673. package/dist/lib/privacy-handler.js +124 -0
  674. package/dist/lib/privacy-handler.js.map +1 -0
  675. package/dist/lib/queue/sqs-queue.d.ts +16 -0
  676. package/dist/lib/queue/sqs-queue.d.ts.map +1 -0
  677. package/dist/lib/queue/sqs-queue.js +39 -0
  678. package/dist/lib/queue/sqs-queue.js.map +1 -0
  679. package/dist/lib/queue-consumers/media-reconciliation-consumer.d.ts +9 -0
  680. package/dist/lib/queue-consumers/media-reconciliation-consumer.d.ts.map +1 -0
  681. package/dist/lib/queue-consumers/media-reconciliation-consumer.js +37 -0
  682. package/dist/lib/queue-consumers/media-reconciliation-consumer.js.map +1 -0
  683. package/dist/lib/quiet-hours.d.ts +33 -0
  684. package/dist/lib/quiet-hours.d.ts.map +1 -0
  685. package/dist/lib/quiet-hours.js +51 -0
  686. package/dist/lib/quiet-hours.js.map +1 -0
  687. package/dist/lib/rate-limit.d.ts +95 -0
  688. package/dist/lib/rate-limit.d.ts.map +1 -0
  689. package/dist/lib/rate-limit.js +247 -0
  690. package/dist/lib/rate-limit.js.map +1 -0
  691. package/dist/lib/reaction-handler.d.ts +68 -0
  692. package/dist/lib/reaction-handler.d.ts.map +1 -0
  693. package/dist/lib/reaction-handler.js +858 -0
  694. package/dist/lib/reaction-handler.js.map +1 -0
  695. package/dist/lib/recaptcha.d.ts +16 -0
  696. package/dist/lib/recaptcha.d.ts.map +1 -0
  697. package/dist/lib/recaptcha.js +71 -0
  698. package/dist/lib/recaptcha.js.map +1 -0
  699. package/dist/lib/redirect-resolver.d.ts +78 -0
  700. package/dist/lib/redirect-resolver.d.ts.map +1 -0
  701. package/dist/lib/redirect-resolver.js +276 -0
  702. package/dist/lib/redirect-resolver.js.map +1 -0
  703. package/dist/lib/region-config.d.ts +179 -0
  704. package/dist/lib/region-config.d.ts.map +1 -0
  705. package/dist/lib/region-config.js +474 -0
  706. package/dist/lib/region-config.js.map +1 -0
  707. package/dist/lib/region-detection.d.ts +110 -0
  708. package/dist/lib/region-detection.d.ts.map +1 -0
  709. package/dist/lib/region-detection.js +408 -0
  710. package/dist/lib/region-detection.js.map +1 -0
  711. package/dist/lib/relationship-handler.d.ts +19 -0
  712. package/dist/lib/relationship-handler.d.ts.map +1 -0
  713. package/dist/lib/relationship-handler.js +233 -0
  714. package/dist/lib/relationship-handler.js.map +1 -0
  715. package/dist/lib/request-context.d.ts +103 -0
  716. package/dist/lib/request-context.d.ts.map +1 -0
  717. package/dist/lib/request-context.js +179 -0
  718. package/dist/lib/request-context.js.map +1 -0
  719. package/dist/lib/route-helpers.d.ts +74 -0
  720. package/dist/lib/route-helpers.d.ts.map +1 -0
  721. package/dist/lib/route-helpers.js +190 -0
  722. package/dist/lib/route-helpers.js.map +1 -0
  723. package/dist/lib/route-matcher.d.ts +24 -0
  724. package/dist/lib/route-matcher.d.ts.map +1 -0
  725. package/dist/lib/route-matcher.js +96 -0
  726. package/dist/lib/route-matcher.js.map +1 -0
  727. package/dist/lib/router.d.ts +26 -0
  728. package/dist/lib/router.d.ts.map +1 -0
  729. package/dist/lib/router.js +90 -0
  730. package/dist/lib/router.js.map +1 -0
  731. package/dist/lib/routes/activitypub/actor.d.ts +12 -0
  732. package/dist/lib/routes/activitypub/actor.d.ts.map +1 -0
  733. package/dist/lib/routes/activitypub/actor.js +141 -0
  734. package/dist/lib/routes/activitypub/actor.js.map +1 -0
  735. package/dist/lib/routes/activitypub/audiences.d.ts +12 -0
  736. package/dist/lib/routes/activitypub/audiences.d.ts.map +1 -0
  737. package/dist/lib/routes/activitypub/audiences.js +325 -0
  738. package/dist/lib/routes/activitypub/audiences.js.map +1 -0
  739. package/dist/lib/routes/activitypub/collections.d.ts +12 -0
  740. package/dist/lib/routes/activitypub/collections.d.ts.map +1 -0
  741. package/dist/lib/routes/activitypub/collections.js +127 -0
  742. package/dist/lib/routes/activitypub/collections.js.map +1 -0
  743. package/dist/lib/routes/activitypub/entity-profile.d.ts +9 -0
  744. package/dist/lib/routes/activitypub/entity-profile.d.ts.map +1 -0
  745. package/dist/lib/routes/activitypub/entity-profile.js +136 -0
  746. package/dist/lib/routes/activitypub/entity-profile.js.map +1 -0
  747. package/dist/lib/routes/activitypub/friends.d.ts +15 -0
  748. package/dist/lib/routes/activitypub/friends.d.ts.map +1 -0
  749. package/dist/lib/routes/activitypub/friends.js +33 -0
  750. package/dist/lib/routes/activitypub/friends.js.map +1 -0
  751. package/dist/lib/routes/activitypub/group.d.ts +8 -0
  752. package/dist/lib/routes/activitypub/group.d.ts.map +1 -0
  753. package/dist/lib/routes/activitypub/group.js +436 -0
  754. package/dist/lib/routes/activitypub/group.js.map +1 -0
  755. package/dist/lib/routes/activitypub/inbox.d.ts +15 -0
  756. package/dist/lib/routes/activitypub/inbox.d.ts.map +1 -0
  757. package/dist/lib/routes/activitypub/inbox.js +125 -0
  758. package/dist/lib/routes/activitypub/inbox.js.map +1 -0
  759. package/dist/lib/routes/activitypub/messages.d.ts +12 -0
  760. package/dist/lib/routes/activitypub/messages.d.ts.map +1 -0
  761. package/dist/lib/routes/activitypub/messages.js +374 -0
  762. package/dist/lib/routes/activitypub/messages.js.map +1 -0
  763. package/dist/lib/routes/activitypub/outbox.d.ts +15 -0
  764. package/dist/lib/routes/activitypub/outbox.d.ts.map +1 -0
  765. package/dist/lib/routes/activitypub/outbox.js +33 -0
  766. package/dist/lib/routes/activitypub/outbox.js.map +1 -0
  767. package/dist/lib/routes/activitypub/post.d.ts +12 -0
  768. package/dist/lib/routes/activitypub/post.d.ts.map +1 -0
  769. package/dist/lib/routes/activitypub/post.js +213 -0
  770. package/dist/lib/routes/activitypub/post.js.map +1 -0
  771. package/dist/lib/routes/activitypub/webfinger.d.ts +11 -0
  772. package/dist/lib/routes/activitypub/webfinger.d.ts.map +1 -0
  773. package/dist/lib/routes/activitypub/webfinger.js +27 -0
  774. package/dist/lib/routes/activitypub/webfinger.js.map +1 -0
  775. package/dist/lib/routes/admin-costs.d.ts +8 -0
  776. package/dist/lib/routes/admin-costs.d.ts.map +1 -0
  777. package/dist/lib/routes/admin-costs.js +89 -0
  778. package/dist/lib/routes/admin-costs.js.map +1 -0
  779. package/dist/lib/routes/admin.d.ts +6 -0
  780. package/dist/lib/routes/admin.d.ts.map +1 -0
  781. package/dist/lib/routes/admin.js +1450 -0
  782. package/dist/lib/routes/admin.js.map +1 -0
  783. package/dist/lib/routes/auth.d.ts +6 -0
  784. package/dist/lib/routes/auth.d.ts.map +1 -0
  785. package/dist/lib/routes/auth.js +49 -0
  786. package/dist/lib/routes/auth.js.map +1 -0
  787. package/dist/lib/routes/badges.d.ts +6 -0
  788. package/dist/lib/routes/badges.d.ts.map +1 -0
  789. package/dist/lib/routes/badges.js +66 -0
  790. package/dist/lib/routes/badges.js.map +1 -0
  791. package/dist/lib/routes/circles.d.ts +8 -0
  792. package/dist/lib/routes/circles.d.ts.map +1 -0
  793. package/dist/lib/routes/circles.js +135 -0
  794. package/dist/lib/routes/circles.js.map +1 -0
  795. package/dist/lib/routes/comments.d.ts +6 -0
  796. package/dist/lib/routes/comments.d.ts.map +1 -0
  797. package/dist/lib/routes/comments.js +228 -0
  798. package/dist/lib/routes/comments.js.map +1 -0
  799. package/dist/lib/routes/connection-codes.d.ts +8 -0
  800. package/dist/lib/routes/connection-codes.d.ts.map +1 -0
  801. package/dist/lib/routes/connection-codes.js +84 -0
  802. package/dist/lib/routes/connection-codes.js.map +1 -0
  803. package/dist/lib/routes/content-discovery.d.ts +11 -0
  804. package/dist/lib/routes/content-discovery.d.ts.map +1 -0
  805. package/dist/lib/routes/content-discovery.js +211 -0
  806. package/dist/lib/routes/content-discovery.js.map +1 -0
  807. package/dist/lib/routes/dashboard.d.ts +8 -0
  808. package/dist/lib/routes/dashboard.d.ts.map +1 -0
  809. package/dist/lib/routes/dashboard.js +1139 -0
  810. package/dist/lib/routes/dashboard.js.map +1 -0
  811. package/dist/lib/routes/deletion.d.ts +6 -0
  812. package/dist/lib/routes/deletion.d.ts.map +1 -0
  813. package/dist/lib/routes/deletion.js +213 -0
  814. package/dist/lib/routes/deletion.js.map +1 -0
  815. package/dist/lib/routes/discovery.d.ts +8 -0
  816. package/dist/lib/routes/discovery.d.ts.map +1 -0
  817. package/dist/lib/routes/discovery.js +67 -0
  818. package/dist/lib/routes/discovery.js.map +1 -0
  819. package/dist/lib/routes/employees.d.ts +6 -0
  820. package/dist/lib/routes/employees.d.ts.map +1 -0
  821. package/dist/lib/routes/employees.js +82 -0
  822. package/dist/lib/routes/employees.js.map +1 -0
  823. package/dist/lib/routes/entities.d.ts +8 -0
  824. package/dist/lib/routes/entities.d.ts.map +1 -0
  825. package/dist/lib/routes/entities.js +467 -0
  826. package/dist/lib/routes/entities.js.map +1 -0
  827. package/dist/lib/routes/entity-relationships.d.ts +8 -0
  828. package/dist/lib/routes/entity-relationships.d.ts.map +1 -0
  829. package/dist/lib/routes/entity-relationships.js +118 -0
  830. package/dist/lib/routes/entity-relationships.js.map +1 -0
  831. package/dist/lib/routes/export.d.ts +6 -0
  832. package/dist/lib/routes/export.d.ts.map +1 -0
  833. package/dist/lib/routes/export.js +118 -0
  834. package/dist/lib/routes/export.js.map +1 -0
  835. package/dist/lib/routes/feature-flags.d.ts +8 -0
  836. package/dist/lib/routes/feature-flags.d.ts.map +1 -0
  837. package/dist/lib/routes/feature-flags.js +75 -0
  838. package/dist/lib/routes/feature-flags.js.map +1 -0
  839. package/dist/lib/routes/feeds.d.ts +6 -0
  840. package/dist/lib/routes/feeds.d.ts.map +1 -0
  841. package/dist/lib/routes/feeds.js +131 -0
  842. package/dist/lib/routes/feeds.js.map +1 -0
  843. package/dist/lib/routes/followers.d.ts +6 -0
  844. package/dist/lib/routes/followers.d.ts.map +1 -0
  845. package/dist/lib/routes/followers.js +405 -0
  846. package/dist/lib/routes/followers.js.map +1 -0
  847. package/dist/lib/routes/friends.d.ts +6 -0
  848. package/dist/lib/routes/friends.d.ts.map +1 -0
  849. package/dist/lib/routes/friends.js +116 -0
  850. package/dist/lib/routes/friends.js.map +1 -0
  851. package/dist/lib/routes/health.d.ts +6 -0
  852. package/dist/lib/routes/health.d.ts.map +1 -0
  853. package/dist/lib/routes/health.js +129 -0
  854. package/dist/lib/routes/health.js.map +1 -0
  855. package/dist/lib/routes/index.d.ts +21 -0
  856. package/dist/lib/routes/index.d.ts.map +1 -0
  857. package/dist/lib/routes/index.js +212 -0
  858. package/dist/lib/routes/index.js.map +1 -0
  859. package/dist/lib/routes/internal-docs.d.ts +6 -0
  860. package/dist/lib/routes/internal-docs.d.ts.map +1 -0
  861. package/dist/lib/routes/internal-docs.js +44 -0
  862. package/dist/lib/routes/internal-docs.js.map +1 -0
  863. package/dist/lib/routes/invitations.d.ts +6 -0
  864. package/dist/lib/routes/invitations.d.ts.map +1 -0
  865. package/dist/lib/routes/invitations.js +67 -0
  866. package/dist/lib/routes/invitations.js.map +1 -0
  867. package/dist/lib/routes/link-reports.d.ts +11 -0
  868. package/dist/lib/routes/link-reports.d.ts.map +1 -0
  869. package/dist/lib/routes/link-reports.js +287 -0
  870. package/dist/lib/routes/link-reports.js.map +1 -0
  871. package/dist/lib/routes/map.d.ts +6 -0
  872. package/dist/lib/routes/map.d.ts.map +1 -0
  873. package/dist/lib/routes/map.js +21 -0
  874. package/dist/lib/routes/map.js.map +1 -0
  875. package/dist/lib/routes/media-metadata-visibility.d.ts +3 -0
  876. package/dist/lib/routes/media-metadata-visibility.d.ts.map +1 -0
  877. package/dist/lib/routes/media-metadata-visibility.js +184 -0
  878. package/dist/lib/routes/media-metadata-visibility.js.map +1 -0
  879. package/dist/lib/routes/media.d.ts +9 -0
  880. package/dist/lib/routes/media.d.ts.map +1 -0
  881. package/dist/lib/routes/media.js +1910 -0
  882. package/dist/lib/routes/media.js.map +1 -0
  883. package/dist/lib/routes/mfa.d.ts +8 -0
  884. package/dist/lib/routes/mfa.d.ts.map +1 -0
  885. package/dist/lib/routes/mfa.js +193 -0
  886. package/dist/lib/routes/mfa.js.map +1 -0
  887. package/dist/lib/routes/notifications.d.ts +9 -0
  888. package/dist/lib/routes/notifications.d.ts.map +1 -0
  889. package/dist/lib/routes/notifications.js +230 -0
  890. package/dist/lib/routes/notifications.js.map +1 -0
  891. package/dist/lib/routes/orphaned-media-health.d.ts +9 -0
  892. package/dist/lib/routes/orphaned-media-health.d.ts.map +1 -0
  893. package/dist/lib/routes/orphaned-media-health.js +121 -0
  894. package/dist/lib/routes/orphaned-media-health.js.map +1 -0
  895. package/dist/lib/routes/orphaned-media.d.ts +8 -0
  896. package/dist/lib/routes/orphaned-media.d.ts.map +1 -0
  897. package/dist/lib/routes/orphaned-media.js +111 -0
  898. package/dist/lib/routes/orphaned-media.js.map +1 -0
  899. package/dist/lib/routes/out.d.ts +17 -0
  900. package/dist/lib/routes/out.d.ts.map +1 -0
  901. package/dist/lib/routes/out.js +339 -0
  902. package/dist/lib/routes/out.js.map +1 -0
  903. package/dist/lib/routes/parental-controls.d.ts +8 -0
  904. package/dist/lib/routes/parental-controls.d.ts.map +1 -0
  905. package/dist/lib/routes/parental-controls.js +282 -0
  906. package/dist/lib/routes/parental-controls.js.map +1 -0
  907. package/dist/lib/routes/posts.d.ts +6 -0
  908. package/dist/lib/routes/posts.d.ts.map +1 -0
  909. package/dist/lib/routes/posts.js +518 -0
  910. package/dist/lib/routes/posts.js.map +1 -0
  911. package/dist/lib/routes/privacy.d.ts +6 -0
  912. package/dist/lib/routes/privacy.d.ts.map +1 -0
  913. package/dist/lib/routes/privacy.js +66 -0
  914. package/dist/lib/routes/privacy.js.map +1 -0
  915. package/dist/lib/routes/products.d.ts +9 -0
  916. package/dist/lib/routes/products.d.ts.map +1 -0
  917. package/dist/lib/routes/products.js +224 -0
  918. package/dist/lib/routes/products.js.map +1 -0
  919. package/dist/lib/routes/relationships.d.ts +8 -0
  920. package/dist/lib/routes/relationships.d.ts.map +1 -0
  921. package/dist/lib/routes/relationships.js +118 -0
  922. package/dist/lib/routes/relationships.js.map +1 -0
  923. package/dist/lib/routes/sentiments.d.ts +6 -0
  924. package/dist/lib/routes/sentiments.d.ts.map +1 -0
  925. package/dist/lib/routes/sentiments.js +285 -0
  926. package/dist/lib/routes/sentiments.js.map +1 -0
  927. package/dist/lib/routes/taxonomy-analytics.d.ts +8 -0
  928. package/dist/lib/routes/taxonomy-analytics.d.ts.map +1 -0
  929. package/dist/lib/routes/taxonomy-analytics.js +151 -0
  930. package/dist/lib/routes/taxonomy-analytics.js.map +1 -0
  931. package/dist/lib/routes/taxonomy.d.ts +15 -0
  932. package/dist/lib/routes/taxonomy.d.ts.map +1 -0
  933. package/dist/lib/routes/taxonomy.js +370 -0
  934. package/dist/lib/routes/taxonomy.js.map +1 -0
  935. package/dist/lib/routes/types.d.ts +46 -0
  936. package/dist/lib/routes/types.d.ts.map +1 -0
  937. package/dist/lib/routes/types.js +8 -0
  938. package/dist/lib/routes/types.js.map +1 -0
  939. package/dist/lib/routes/upload-sessions.d.ts +9 -0
  940. package/dist/lib/routes/upload-sessions.d.ts.map +1 -0
  941. package/dist/lib/routes/upload-sessions.js +268 -0
  942. package/dist/lib/routes/upload-sessions.js.map +1 -0
  943. package/dist/lib/routes/user.d.ts +8 -0
  944. package/dist/lib/routes/user.d.ts.map +1 -0
  945. package/dist/lib/routes/user.js +287 -0
  946. package/dist/lib/routes/user.js.map +1 -0
  947. package/dist/lib/routes-all.d.ts +9 -0
  948. package/dist/lib/routes-all.d.ts.map +1 -0
  949. package/dist/lib/routes-all.js +170 -0
  950. package/dist/lib/routes-all.js.map +1 -0
  951. package/dist/lib/routes.d.ts +10 -0
  952. package/dist/lib/routes.d.ts.map +1 -0
  953. package/dist/lib/routes.js +16 -0
  954. package/dist/lib/routes.js.map +1 -0
  955. package/dist/lib/scaling-health.d.ts +48 -0
  956. package/dist/lib/scaling-health.d.ts.map +1 -0
  957. package/dist/lib/scaling-health.js +363 -0
  958. package/dist/lib/scaling-health.js.map +1 -0
  959. package/dist/lib/scheduled/media-stale-cleanup.d.ts +11 -0
  960. package/dist/lib/scheduled/media-stale-cleanup.d.ts.map +1 -0
  961. package/dist/lib/scheduled/media-stale-cleanup.js +79 -0
  962. package/dist/lib/scheduled/media-stale-cleanup.js.map +1 -0
  963. package/dist/lib/scheduled/orphaned-media-monitor.d.ts +97 -0
  964. package/dist/lib/scheduled/orphaned-media-monitor.d.ts.map +1 -0
  965. package/dist/lib/scheduled/orphaned-media-monitor.js +399 -0
  966. package/dist/lib/scheduled/orphaned-media-monitor.js.map +1 -0
  967. package/dist/lib/schemas.d.ts +314 -0
  968. package/dist/lib/schemas.d.ts.map +1 -0
  969. package/dist/lib/schemas.js +235 -0
  970. package/dist/lib/schemas.js.map +1 -0
  971. package/dist/lib/secret-resolver.d.ts +88 -0
  972. package/dist/lib/secret-resolver.d.ts.map +1 -0
  973. package/dist/lib/secret-resolver.js +183 -0
  974. package/dist/lib/secret-resolver.js.map +1 -0
  975. package/dist/lib/security-event-cleaner.d.ts +61 -0
  976. package/dist/lib/security-event-cleaner.d.ts.map +1 -0
  977. package/dist/lib/security-event-cleaner.js +74 -0
  978. package/dist/lib/security-event-cleaner.js.map +1 -0
  979. package/dist/lib/security-headers.d.ts +36 -0
  980. package/dist/lib/security-headers.d.ts.map +1 -0
  981. package/dist/lib/security-headers.js +87 -0
  982. package/dist/lib/security-headers.js.map +1 -0
  983. package/dist/lib/security-monitor.d.ts +92 -0
  984. package/dist/lib/security-monitor.d.ts.map +1 -0
  985. package/dist/lib/security-monitor.js +287 -0
  986. package/dist/lib/security-monitor.js.map +1 -0
  987. package/dist/lib/sentiment-digest.d.ts +19 -0
  988. package/dist/lib/sentiment-digest.d.ts.map +1 -0
  989. package/dist/lib/sentiment-digest.js +99 -0
  990. package/dist/lib/sentiment-digest.js.map +1 -0
  991. package/dist/lib/sentiment-display.d.ts +20 -0
  992. package/dist/lib/sentiment-display.d.ts.map +1 -0
  993. package/dist/lib/sentiment-display.js +38 -0
  994. package/dist/lib/sentiment-display.js.map +1 -0
  995. package/dist/lib/services/image-normalizer.d.ts +15 -0
  996. package/dist/lib/services/image-normalizer.d.ts.map +1 -0
  997. package/dist/lib/services/image-normalizer.js +22 -0
  998. package/dist/lib/services/image-normalizer.js.map +1 -0
  999. package/dist/lib/services/media-reconciliation-service.d.ts +25 -0
  1000. package/dist/lib/services/media-reconciliation-service.d.ts.map +1 -0
  1001. package/dist/lib/services/media-reconciliation-service.js +191 -0
  1002. package/dist/lib/services/media-reconciliation-service.js.map +1 -0
  1003. package/dist/lib/services/media-upload-service.d.ts +25 -0
  1004. package/dist/lib/services/media-upload-service.d.ts.map +1 -0
  1005. package/dist/lib/services/media-upload-service.js +240 -0
  1006. package/dist/lib/services/media-upload-service.js.map +1 -0
  1007. package/dist/lib/services/user-data-deletion.d.ts +30 -0
  1008. package/dist/lib/services/user-data-deletion.d.ts.map +1 -0
  1009. package/dist/lib/services/user-data-deletion.js +118 -0
  1010. package/dist/lib/services/user-data-deletion.js.map +1 -0
  1011. package/dist/lib/session-awareness.d.ts +35 -0
  1012. package/dist/lib/session-awareness.d.ts.map +1 -0
  1013. package/dist/lib/session-awareness.js +79 -0
  1014. package/dist/lib/session-awareness.js.map +1 -0
  1015. package/dist/lib/session-config.d.ts +87 -0
  1016. package/dist/lib/session-config.d.ts.map +1 -0
  1017. package/dist/lib/session-config.js +165 -0
  1018. package/dist/lib/session-config.js.map +1 -0
  1019. package/dist/lib/session-manager.d.ts +103 -0
  1020. package/dist/lib/session-manager.d.ts.map +1 -0
  1021. package/dist/lib/session-manager.js +492 -0
  1022. package/dist/lib/session-manager.js.map +1 -0
  1023. package/dist/lib/sso-auth-handler.d.ts +12 -0
  1024. package/dist/lib/sso-auth-handler.d.ts.map +1 -0
  1025. package/dist/lib/sso-auth-handler.js +24 -0
  1026. package/dist/lib/sso-auth-handler.js.map +1 -0
  1027. package/dist/lib/storage/s3-storage.d.ts +29 -0
  1028. package/dist/lib/storage/s3-storage.d.ts.map +1 -0
  1029. package/dist/lib/storage/s3-storage.js +135 -0
  1030. package/dist/lib/storage/s3-storage.js.map +1 -0
  1031. package/dist/lib/tag-suggestions-handler.d.ts +52 -0
  1032. package/dist/lib/tag-suggestions-handler.d.ts.map +1 -0
  1033. package/dist/lib/tag-suggestions-handler.js +195 -0
  1034. package/dist/lib/tag-suggestions-handler.js.map +1 -0
  1035. package/dist/lib/taxonomy-handler-factory.d.ts +18 -0
  1036. package/dist/lib/taxonomy-handler-factory.d.ts.map +1 -0
  1037. package/dist/lib/taxonomy-handler-factory.js +29 -0
  1038. package/dist/lib/taxonomy-handler-factory.js.map +1 -0
  1039. package/dist/lib/taxonomy-handler.d.ts +142 -0
  1040. package/dist/lib/taxonomy-handler.d.ts.map +1 -0
  1041. package/dist/lib/taxonomy-handler.js +636 -0
  1042. package/dist/lib/taxonomy-handler.js.map +1 -0
  1043. package/dist/lib/taxonomy-metrics.d.ts +76 -0
  1044. package/dist/lib/taxonomy-metrics.d.ts.map +1 -0
  1045. package/dist/lib/taxonomy-metrics.js +201 -0
  1046. package/dist/lib/taxonomy-metrics.js.map +1 -0
  1047. package/dist/lib/taxonomy-search-metrics.d.ts +45 -0
  1048. package/dist/lib/taxonomy-search-metrics.d.ts.map +1 -0
  1049. package/dist/lib/taxonomy-search-metrics.js +75 -0
  1050. package/dist/lib/taxonomy-search-metrics.js.map +1 -0
  1051. package/dist/lib/tenant-context.d.ts +35 -0
  1052. package/dist/lib/tenant-context.d.ts.map +1 -0
  1053. package/dist/lib/tenant-context.js +54 -0
  1054. package/dist/lib/tenant-context.js.map +1 -0
  1055. package/dist/lib/terminology.d.ts +25 -0
  1056. package/dist/lib/terminology.d.ts.map +1 -0
  1057. package/dist/lib/terminology.js +44 -0
  1058. package/dist/lib/terminology.js.map +1 -0
  1059. package/dist/lib/theme.d.ts +29 -0
  1060. package/dist/lib/theme.d.ts.map +1 -0
  1061. package/dist/lib/theme.js +38 -0
  1062. package/dist/lib/theme.js.map +1 -0
  1063. package/dist/lib/threat-intel-service.d.ts +67 -0
  1064. package/dist/lib/threat-intel-service.d.ts.map +1 -0
  1065. package/dist/lib/threat-intel-service.js +193 -0
  1066. package/dist/lib/threat-intel-service.js.map +1 -0
  1067. package/dist/lib/types/media-reconciliation.d.ts +64 -0
  1068. package/dist/lib/types/media-reconciliation.d.ts.map +1 -0
  1069. package/dist/lib/types/media-reconciliation.js +8 -0
  1070. package/dist/lib/types/media-reconciliation.js.map +1 -0
  1071. package/dist/lib/upload-session-handler.d.ts +56 -0
  1072. package/dist/lib/upload-session-handler.d.ts.map +1 -0
  1073. package/dist/lib/upload-session-handler.js +312 -0
  1074. package/dist/lib/upload-session-handler.js.map +1 -0
  1075. package/dist/lib/user-badge.d.ts +56 -0
  1076. package/dist/lib/user-badge.d.ts.map +1 -0
  1077. package/dist/lib/user-badge.js +92 -0
  1078. package/dist/lib/user-badge.js.map +1 -0
  1079. package/dist/lib/user-deletion-handler-enhanced.d.ts +96 -0
  1080. package/dist/lib/user-deletion-handler-enhanced.d.ts.map +1 -0
  1081. package/dist/lib/user-deletion-handler-enhanced.js +401 -0
  1082. package/dist/lib/user-deletion-handler-enhanced.js.map +1 -0
  1083. package/dist/lib/user-deprovisioning.d.ts +43 -0
  1084. package/dist/lib/user-deprovisioning.d.ts.map +1 -0
  1085. package/dist/lib/user-deprovisioning.js +138 -0
  1086. package/dist/lib/user-deprovisioning.js.map +1 -0
  1087. package/dist/lib/user-export-handler.d.ts +172 -0
  1088. package/dist/lib/user-export-handler.d.ts.map +1 -0
  1089. package/dist/lib/user-export-handler.js +435 -0
  1090. package/dist/lib/user-export-handler.js.map +1 -0
  1091. package/dist/lib/validate-request.d.ts +46 -0
  1092. package/dist/lib/validate-request.d.ts.map +1 -0
  1093. package/dist/lib/validate-request.js +127 -0
  1094. package/dist/lib/validate-request.js.map +1 -0
  1095. package/dist/lib/validation/feature-toggle-schemas.d.ts +410 -0
  1096. package/dist/lib/validation/feature-toggle-schemas.d.ts.map +1 -0
  1097. package/dist/lib/validation/feature-toggle-schemas.js +274 -0
  1098. package/dist/lib/validation/feature-toggle-schemas.js.map +1 -0
  1099. package/dist/lib/validation/validate-request.d.ts +75 -0
  1100. package/dist/lib/validation/validate-request.d.ts.map +1 -0
  1101. package/dist/lib/validation/validate-request.js +183 -0
  1102. package/dist/lib/validation/validate-request.js.map +1 -0
  1103. package/dist/lib/validation.d.ts +50 -0
  1104. package/dist/lib/validation.d.ts.map +1 -0
  1105. package/dist/lib/validation.js +122 -0
  1106. package/dist/lib/validation.js.map +1 -0
  1107. package/dist/lib/version.d.ts +36 -0
  1108. package/dist/lib/version.d.ts.map +1 -0
  1109. package/dist/lib/version.js +44 -0
  1110. package/dist/lib/version.js.map +1 -0
  1111. package/dist/server.d.ts +13 -0
  1112. package/dist/server.d.ts.map +1 -0
  1113. package/dist/server.js +254 -0
  1114. package/dist/server.js.map +1 -0
  1115. package/dist/types/cloudflare-compat.d.ts +134 -0
  1116. package/dist/types/cloudflare-compat.d.ts.map +1 -0
  1117. package/dist/types/cloudflare-compat.js +7 -0
  1118. package/dist/types/cloudflare-compat.js.map +1 -0
  1119. package/dist/worker.d.ts +16 -0
  1120. package/dist/worker.d.ts.map +1 -0
  1121. package/dist/worker.js +21 -0
  1122. package/dist/worker.js.map +1 -0
  1123. package/package.json +91 -0
  1124. package/src/lambda/cleanup-cron.ts +37 -0
  1125. package/src/lambda/create-auth-challenge.ts +112 -0
  1126. package/src/lambda/custom-message.ts +30 -0
  1127. package/src/lambda/define-auth-challenge.ts +24 -0
  1128. package/src/lambda/delete-account-worker.ts +96 -0
  1129. package/src/lambda/diagnostics-proxy.ts +139 -0
  1130. package/src/lambda/e2e-sweeper.ts +140 -0
  1131. package/src/lambda/federation-outbox-worker.ts +8 -0
  1132. package/src/lambda/followers-events-worker.ts +8 -0
  1133. package/src/lambda/hourly-cron.ts +103 -0
  1134. package/src/lambda/link-check-worker.ts +8 -0
  1135. package/src/lambda/maintenance-cron.ts +95 -0
  1136. package/src/lambda/media-processing-worker.ts +68 -0
  1137. package/src/lambda/media-reconciliation-worker.ts +8 -0
  1138. package/src/lambda/nightly-cron.ts +338 -0
  1139. package/src/lambda/post-confirmation.ts +80 -0
  1140. package/src/lambda/pre-signup.ts +39 -0
  1141. package/src/lambda/pre-token-generation.ts +93 -0
  1142. package/src/lambda/tools/check-health.ts +22 -0
  1143. package/src/lambda/tools/describe-services.ts +45 -0
  1144. package/src/lambda/tools/get-cost-report.ts +64 -0
  1145. package/src/lambda/tools/get-errors.ts +78 -0
  1146. package/src/lambda/tools/get-feature-flags.ts +27 -0
  1147. package/src/lambda/tools/get-queue-status.ts +60 -0
  1148. package/src/lambda/tools/search-logs.ts +75 -0
  1149. package/src/lambda/tools/send-alert.ts +37 -0
  1150. package/src/lambda/verify-auth-challenge.ts +37 -0
@@ -0,0 +1,1335 @@
1
+ "use strict";
2
+ /**
3
+ * Invitation Handler
4
+ *
5
+ * Handles user-to-user invitations for invitation-only sign-up mode.
6
+ * Users can create invitation codes that others can use to sign up.
7
+ */
8
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
9
+ if (k2 === undefined) k2 = k;
10
+ var desc = Object.getOwnPropertyDescriptor(m, k);
11
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
12
+ desc = { enumerable: true, get: function() { return m[k]; } };
13
+ }
14
+ Object.defineProperty(o, k2, desc);
15
+ }) : (function(o, m, k, k2) {
16
+ if (k2 === undefined) k2 = k;
17
+ o[k2] = m[k];
18
+ }));
19
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
20
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
21
+ }) : function(o, v) {
22
+ o["default"] = v;
23
+ });
24
+ var __importStar = (this && this.__importStar) || (function () {
25
+ var ownKeys = function(o) {
26
+ ownKeys = Object.getOwnPropertyNames || function (o) {
27
+ var ar = [];
28
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
29
+ return ar;
30
+ };
31
+ return ownKeys(o);
32
+ };
33
+ return function (mod) {
34
+ if (mod && mod.__esModule) return mod;
35
+ var result = {};
36
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
37
+ __setModuleDefault(result, mod);
38
+ return result;
39
+ };
40
+ })();
41
+ Object.defineProperty(exports, "__esModule", { value: true });
42
+ exports.InvitationHandler = void 0;
43
+ const db_1 = require("../db");
44
+ const feature_toggle_service_1 = require("./feature-toggle-service");
45
+ const logger_1 = require("./logger");
46
+ const rate_limit_1 = require("./rate-limit");
47
+ const secret_resolver_1 = require("./secret-resolver");
48
+ const security_headers_1 = require("./security-headers");
49
+ const session_manager_1 = require("./session-manager");
50
+ /**
51
+ * Invitation Handler class
52
+ */
53
+ class InvitationHandler {
54
+ sessionManager;
55
+ securityHeaders;
56
+ rateLimiter;
57
+ logger;
58
+ constructor(env) {
59
+ this.sessionManager = new session_manager_1.SessionManager();
60
+ this.securityHeaders = new security_headers_1.SecurityHeaders();
61
+ this.rateLimiter = new rate_limit_1.RateLimiter();
62
+ this.logger = logger_1.Logger.getInstance(env);
63
+ }
64
+ /**
65
+ * Generate a cryptographically secure session token for tracking who scanned an invitation
66
+ * SECURITY: Uses crypto.getRandomValues() for CSPRNG to prevent spoofing
67
+ */
68
+ generateSessionToken() {
69
+ // Generate 32 random bytes (256 bits of entropy)
70
+ const randomBytes = new Uint8Array(32);
71
+ crypto.getRandomValues(randomBytes);
72
+ // Convert to base64url for URL-safe encoding
73
+ // Use base64url encoding (RFC 4648) which is safe for URLs
74
+ // Cloudflare Workers support btoa, but we'll use a more compatible approach
75
+ let base64 = "";
76
+ for (let i = 0; i < randomBytes.length; i += 3) {
77
+ const a = randomBytes[i];
78
+ const b = randomBytes[i + 1] || 0;
79
+ const c = randomBytes[i + 2] || 0;
80
+ const bitmap = (a << 16) | (b << 8) | c;
81
+ base64 += String.fromCharCode((bitmap >> 18) & 63, (bitmap >> 12) & 63, (bitmap >> 6) & 63, bitmap & 63);
82
+ }
83
+ // Convert to base64 and then to base64url
84
+ // Cloudflare Workers always have btoa available
85
+ const base64String = btoa(base64);
86
+ const base64url = base64String
87
+ .replace(/\+/g, "-")
88
+ .replace(/\//g, "_")
89
+ .replace(/=/g, "");
90
+ return `inv_${base64url}`;
91
+ }
92
+ /**
93
+ * Store session token in KV for validation during signup
94
+ * Key: invitation-session:{code}, Value: { token, email?, expiresAt }
95
+ * TTL: 1 hour (3600 seconds)
96
+ */
97
+ async storeSessionToken(code, token, email, env) {
98
+ if (!env.INVITATIONS_KV) {
99
+ // If KV not available, we can't store tokens - this is a fallback scenario
100
+ this.logger.warn("[InvitationHandler] INVITATIONS_KV not available, cannot store session token");
101
+ return;
102
+ }
103
+ const expiresAt = new Date(Date.now() + 3600 * 1000); // 1 hour from now
104
+ const key = `invitation-session:${code.toUpperCase()}`;
105
+ const value = JSON.stringify({
106
+ token,
107
+ email: email || null,
108
+ expiresAt: expiresAt.toISOString(),
109
+ });
110
+ await env.INVITATIONS_KV.put(key, value, {
111
+ expirationTtl: 3600, // 1 hour
112
+ });
113
+ }
114
+ /**
115
+ * Validate session token for an invitation code
116
+ * Returns the stored email if token is valid, null otherwise
117
+ */
118
+ async validateSessionToken(code, token, env) {
119
+ if (!env.INVITATIONS_KV) {
120
+ // If KV not available, we can't validate tokens - allow for backward compatibility
121
+ this.logger.warn("[InvitationHandler] INVITATIONS_KV not available, cannot validate session token");
122
+ return { valid: true }; // Allow for backward compatibility
123
+ }
124
+ const key = `invitation-session:${code.toUpperCase()}`;
125
+ const stored = await env.INVITATIONS_KV.get(key);
126
+ if (!stored) {
127
+ return { valid: false };
128
+ }
129
+ try {
130
+ const data = JSON.parse(stored);
131
+ // Check if token matches
132
+ if (data.token !== token) {
133
+ return { valid: false };
134
+ }
135
+ // Check if expired
136
+ if (data.expiresAt && new Date(data.expiresAt) < new Date()) {
137
+ return { valid: false };
138
+ }
139
+ return { valid: true, email: data.email || null };
140
+ }
141
+ catch (error) {
142
+ this.logger.error("[InvitationHandler] Error parsing session token data:", error);
143
+ return { valid: false };
144
+ }
145
+ }
146
+ /**
147
+ * Generate a cryptographically secure random invitation code
148
+ * SECURITY: Uses crypto.getRandomValues() for CSPRNG (Cryptographically Secure Pseudo-Random Number Generator)
149
+ * Increased length to 10 characters for better security (1.1 trillion combinations)
150
+ */
151
+ generateInvitationCode() {
152
+ // SECURITY: Use crypto.getRandomValues() instead of Math.random() for cryptographic security
153
+ // Math.random() is predictable and not suitable for security-sensitive operations
154
+ const chars = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789"; // Exclude ambiguous chars (0, O, I, 1)
155
+ const codeLength = 10; // Increased from 8 to 10 for better security
156
+ // Use crypto.getRandomValues for secure random generation
157
+ const randomValues = new Uint32Array(codeLength);
158
+ crypto.getRandomValues(randomValues);
159
+ let code = "";
160
+ for (let i = 0; i < codeLength; i++) {
161
+ // Use modulo to map random value to character index
162
+ const index = randomValues[i] % chars.length;
163
+ code += chars[index];
164
+ }
165
+ return code;
166
+ }
167
+ /**
168
+ * Delete expired invitations for a user
169
+ *
170
+ * Automatically removes invitations that have expired (expiresAt < now).
171
+ * This keeps the database clean and ensures expired invitations don't count toward limits.
172
+ */
173
+ async deleteExpiredInvitations(userId, env, request) {
174
+ const { sharedDatabaseConnectionManager } = await Promise.resolve().then(() => __importStar(require("./database-connection-manager")));
175
+ const { withQueryTimeoutAndRetry, QueryTimeoutPresets } = await Promise.resolve().then(() => __importStar(require("./db-query-helper")));
176
+ const { detectRegionSync } = await Promise.resolve().then(() => __importStar(require("./region-detection")));
177
+ const dbManager = sharedDatabaseConnectionManager;
178
+ const regionRequest = request || new Request("https://api.example.com");
179
+ const region = detectRegionSync(regionRequest, env);
180
+ const now = new Date();
181
+ const deletedCount = await withQueryTimeoutAndRetry(dbManager, region, env, async (client) => {
182
+ const result = await client.invitation.deleteMany({
183
+ where: {
184
+ createdBy: userId,
185
+ used: false, // Only delete unused expired invitations
186
+ expiresAt: {
187
+ not: null, // Has expiration date
188
+ lt: now, // Expired
189
+ },
190
+ },
191
+ });
192
+ return result.count;
193
+ }, {
194
+ ...QueryTimeoutPresets.BACKGROUND, // Background cleanup, less urgent
195
+ defaultValue: 0,
196
+ context: {
197
+ operation: "deleteExpiredInvitations",
198
+ userId,
199
+ },
200
+ });
201
+ if (deletedCount > 0) {
202
+ this.logger.info(`[InvitationHandler] Deleted ${deletedCount} expired invitation(s) for user ${userId}`);
203
+ }
204
+ return deletedCount;
205
+ }
206
+ /**
207
+ * Check if user has reached the limit for simultaneously open invitations
208
+ *
209
+ * An invitation is considered "open" if it:
210
+ * - Has not been used (used = false)
211
+ * - Has not expired (expiresAt is null or in the future)
212
+ *
213
+ * This prevents abuse while allowing users to create more invitations
214
+ * by deleting unused ones.
215
+ *
216
+ * Automatically deletes expired invitations before checking the limit.
217
+ */
218
+ async checkOpenInvitationLimit(userId, maxOpen, env, request) {
219
+ // First, clean up expired invitations
220
+ await this.deleteExpiredInvitations(userId, env, request);
221
+ // Use DatabaseConnectionManager for clear state management
222
+ const { sharedDatabaseConnectionManager } = await Promise.resolve().then(() => __importStar(require("./database-connection-manager")));
223
+ const { withQueryTimeoutAndRetry, QueryTimeoutPresets } = await Promise.resolve().then(() => __importStar(require("./db-query-helper")));
224
+ const { detectRegionSync } = await Promise.resolve().then(() => __importStar(require("./region-detection")));
225
+ // Create connection manager instance
226
+ const dbManager = sharedDatabaseConnectionManager;
227
+ // Use provided request or create a dummy one for region detection
228
+ const regionRequest = request || new Request("https://api.example.com");
229
+ const region = detectRegionSync(regionRequest, env);
230
+ const now = new Date();
231
+ const count = await withQueryTimeoutAndRetry(dbManager, region, env, async (client) => {
232
+ return client.invitation.count({
233
+ where: {
234
+ createdBy: userId,
235
+ used: false, // Not used
236
+ OR: [
237
+ { expiresAt: null }, // No expiration
238
+ { expiresAt: { gt: now } }, // Not expired yet
239
+ ],
240
+ },
241
+ });
242
+ }, {
243
+ ...QueryTimeoutPresets.USER_FACING,
244
+ defaultValue: 0,
245
+ context: {
246
+ operation: "checkOpenInvitationLimit",
247
+ userId,
248
+ },
249
+ });
250
+ return {
251
+ allowed: count < maxOpen,
252
+ count,
253
+ limit: maxOpen,
254
+ };
255
+ }
256
+ /**
257
+ * Create a new invitation
258
+ * POST /api/invitations
259
+ *
260
+ * Requires authentication. Users can have up to 10 simultaneously open invitations.
261
+ * An invitation is "open" if it's not used and not expired.
262
+ * Users can delete unused invitations to create new ones.
263
+ * SECURITY: Checks sign-up mode - if disabled, prevents invitation creation.
264
+ */
265
+ async handleCreateInvitation(request, env) {
266
+ try {
267
+ // Check authentication
268
+ const { Secrets } = await Promise.resolve().then(() => __importStar(require("./secret-resolver")));
269
+ const sessionSecret = Secrets.getSessionSecret(env);
270
+ const session = await this.sessionManager.getSession(request, sessionSecret, env);
271
+ if (!session) {
272
+ return this.securityHeaders.createSecureResponse(JSON.stringify({ error: "Unauthorized" }), { status: 401, headers: { "content-type": "application/json" } });
273
+ }
274
+ // Use DatabaseConnectionManager for all database operations with timeout protection
275
+ const { sharedDatabaseConnectionManager } = await Promise.resolve().then(() => __importStar(require("./database-connection-manager")));
276
+ const { withQueryTimeoutAndRetry, QueryTimeoutPresets } = await Promise.resolve().then(() => __importStar(require("./db-query-helper")));
277
+ const { detectRegionSync } = await Promise.resolve().then(() => __importStar(require("./region-detection")));
278
+ const dbManager = sharedDatabaseConnectionManager;
279
+ const region = detectRegionSync(request, env);
280
+ // SECURITY: Check sign-up mode - if disabled, prevent invitation creation
281
+ const signupToggle = await withQueryTimeoutAndRetry(dbManager, region, env, async (client) => {
282
+ const toggleService = new feature_toggle_service_1.FeatureToggleService(client);
283
+ return await toggleService.getToggle("user_signup_mode");
284
+ }, {
285
+ ...QueryTimeoutPresets.CRITICAL, // Critical for security checks
286
+ defaultValue: null, // If timeout, assume open mode (fail open for availability)
287
+ context: {
288
+ operation: "handleCreateInvitation_checkSignupMode",
289
+ userId: session.userId,
290
+ },
291
+ });
292
+ let signupMode = "open";
293
+ if (signupToggle?.description) {
294
+ const modeMatch = signupToggle.description.match(/user_signup_mode:(open|invitation_only|disabled)/);
295
+ if (modeMatch) {
296
+ signupMode = modeMatch[1];
297
+ }
298
+ }
299
+ else if (signupToggle?.enabled === false) {
300
+ signupMode = "disabled";
301
+ }
302
+ // CRITICAL: If sign-up is disabled, prevent invitation creation
303
+ if (signupMode === "disabled") {
304
+ return this.securityHeaders.createSecureResponse(JSON.stringify({
305
+ error: "Sign-up disabled",
306
+ message: "User sign-up is currently disabled. Invitations cannot be created.",
307
+ }), { status: 403, headers: { "content-type": "application/json" } });
308
+ }
309
+ // Check if user exists and is not suspended
310
+ const user = await withQueryTimeoutAndRetry(dbManager, region, env, async (client) => {
311
+ return await client.user.findUnique({
312
+ where: { id: session.userId },
313
+ select: { suspended: true },
314
+ });
315
+ }, {
316
+ ...QueryTimeoutPresets.CRITICAL, // Critical for security checks
317
+ defaultValue: null, // If timeout, assume user not found
318
+ context: {
319
+ operation: "handleCreateInvitation_checkUser",
320
+ userId: session.userId,
321
+ },
322
+ });
323
+ if (!user) {
324
+ return this.securityHeaders.createSecureResponse(JSON.stringify({ error: "User not found" }), { status: 404, headers: { "content-type": "application/json" } });
325
+ }
326
+ if (user.suspended) {
327
+ return this.securityHeaders.createSecureResponse(JSON.stringify({ error: "Account suspended" }), { status: 403, headers: { "content-type": "application/json" } });
328
+ }
329
+ // SECURITY: Rate limit invitation creation (10 per hour per user)
330
+ const rateLimitResult = this.rateLimiter.checkRateLimit(request, "/api/invitations", 10, // 10 invitations
331
+ 3600, // per hour
332
+ session.userId, undefined, session.userId);
333
+ if (!rateLimitResult.allowed) {
334
+ return this.securityHeaders.createSecureResponse(JSON.stringify({
335
+ error: "Rate limit exceeded",
336
+ message: "Too many invitation creation requests. Please try again later.",
337
+ retryAfter: Math.ceil((rateLimitResult.resetAt - Date.now()) / 1000),
338
+ }), {
339
+ status: 429,
340
+ headers: {
341
+ "content-type": "application/json",
342
+ "Retry-After": Math.ceil((rateLimitResult.resetAt - Date.now()) / 1000).toString(),
343
+ },
344
+ });
345
+ }
346
+ // Validate request body with Zod schema
347
+ const { validateRequest } = await Promise.resolve().then(() => __importStar(require("./validate-request")));
348
+ const { createInvitationSchema } = await Promise.resolve().then(() => __importStar(require("./schemas")));
349
+ const validation = await validateRequest(request, createInvitationSchema);
350
+ if (!validation.success) {
351
+ return this.securityHeaders.addSecurityHeaders(validation.error);
352
+ }
353
+ const { email, expiresInDays, recaptchaToken } = validation.data;
354
+ // SECURITY: Verify reCAPTCHA token if provided
355
+ if (recaptchaToken && env.RECAPTCHA_SECRET_KEY) {
356
+ const { verifyRecaptcha } = await Promise.resolve().then(() => __importStar(require("./recaptcha")));
357
+ const recaptchaResult = await verifyRecaptcha(recaptchaToken, env.RECAPTCHA_SECRET_KEY);
358
+ if (!recaptchaResult.valid) {
359
+ this.logger.warn("[InvitationHandler] reCAPTCHA verification failed:", recaptchaResult.error);
360
+ return this.securityHeaders.createSecureResponse(JSON.stringify({
361
+ error: "reCAPTCHA verification failed",
362
+ message: recaptchaResult.error ||
363
+ "Please complete the reCAPTCHA verification.",
364
+ }), { status: 400, headers: { "content-type": "application/json" } });
365
+ }
366
+ }
367
+ else if (!recaptchaToken && env.RECAPTCHA_SECRET_KEY) {
368
+ // If reCAPTCHA is configured but token is missing, require it
369
+ return this.securityHeaders.createSecureResponse(JSON.stringify({
370
+ error: "reCAPTCHA verification required",
371
+ message: "Please complete the reCAPTCHA verification.",
372
+ }), { status: 400, headers: { "content-type": "application/json" } });
373
+ }
374
+ // Email is already validated and sanitized by Zod schema (lowercase, email format)
375
+ // expiresInDays is validated by Zod (1-365 range, default 30)
376
+ // Check limit for simultaneously open invitations
377
+ const maxOpen = 10;
378
+ const limitCheck = await this.checkOpenInvitationLimit(session.userId, maxOpen, env, request);
379
+ if (!limitCheck.allowed) {
380
+ return this.securityHeaders.createSecureResponse(JSON.stringify({
381
+ error: "Invitation limit reached",
382
+ message: `You have ${limitCheck.count} open invitations. The limit is ${limitCheck.limit} simultaneously open invitations. Please delete unused invitations to create new ones.`,
383
+ count: limitCheck.count,
384
+ limit: limitCheck.limit,
385
+ }), { status: 429, headers: { "content-type": "application/json" } });
386
+ }
387
+ if (email) {
388
+ // Create invitation with email
389
+ return await this.createInvitationWithEmail(session.userId, email, expiresInDays, limitCheck, env, request);
390
+ }
391
+ else {
392
+ // Create invitation without email (limit check already done above)
393
+ // No email restriction - create general invitation
394
+ return await this.createInvitationWithEmail(session.userId, null, expiresInDays, limitCheck, env, request);
395
+ }
396
+ }
397
+ catch (error) {
398
+ this.logger.error("[InvitationHandler] Error creating invitation:", error);
399
+ return this.securityHeaders.createSecureResponse(JSON.stringify({ error: "Internal server error" }), { status: 500, headers: { "content-type": "application/json" } });
400
+ }
401
+ }
402
+ /**
403
+ * Internal helper to create invitation (extracted for code reuse)
404
+ */
405
+ async createInvitationWithEmail(userId, email, expiresInDays, limitCheck, env, request) {
406
+ try {
407
+ // Use DatabaseConnectionManager for timeout and retry protection
408
+ const { sharedDatabaseConnectionManager } = await Promise.resolve().then(() => __importStar(require("./database-connection-manager")));
409
+ const { withQueryTimeoutAndRetry, QueryTimeoutPresets } = await Promise.resolve().then(() => __importStar(require("./db-query-helper")));
410
+ const { detectRegionSync } = await Promise.resolve().then(() => __importStar(require("./region-detection")));
411
+ const dbManager = sharedDatabaseConnectionManager;
412
+ const regionRequest = request || new Request("https://api.example.com");
413
+ const region = detectRegionSync(regionRequest, env);
414
+ // SECURITY: Generate cryptographically secure unique invitation code
415
+ let code;
416
+ let attempts = 0;
417
+ const maxAttempts = 10;
418
+ // Check for existing code with timeout protection
419
+ do {
420
+ code = this.generateInvitationCode();
421
+ // SECURITY: Prisma uses parameterized queries - SQL injection safe
422
+ const existing = await withQueryTimeoutAndRetry(dbManager, region, env, async (client) => {
423
+ return await client.invitation.findUnique({
424
+ where: { code },
425
+ });
426
+ }, {
427
+ ...QueryTimeoutPresets.USER_FACING, // 3s initial, 2s retry
428
+ defaultValue: null, // Return null on timeout (treat as not found)
429
+ context: {
430
+ operation: "createInvitationWithEmail_checkCode",
431
+ userId,
432
+ },
433
+ });
434
+ if (!existing)
435
+ break;
436
+ attempts++;
437
+ } while (attempts < maxAttempts);
438
+ if (attempts >= maxAttempts) {
439
+ // SECURITY: Don't reveal internal details - generic error
440
+ return this.securityHeaders.createSecureResponse(JSON.stringify({
441
+ error: "Failed to create invitation. Please try again.",
442
+ }), { status: 500, headers: { "content-type": "application/json" } });
443
+ }
444
+ // SECURITY: Validate and calculate expiration date
445
+ let expiresAt = null;
446
+ if (expiresInDays) {
447
+ // Already validated above (1-365 days)
448
+ expiresAt = new Date();
449
+ expiresAt.setDate(expiresAt.getDate() + expiresInDays);
450
+ }
451
+ else {
452
+ // Default: 30 days
453
+ expiresAt = new Date();
454
+ expiresAt.setDate(expiresAt.getDate() + 30);
455
+ }
456
+ // SECURITY: Create invitation using Prisma (parameterized queries prevent SQL injection)
457
+ // Use timeout protection for the create operation
458
+ const invitation = await withQueryTimeoutAndRetry(dbManager, region, env, async (client) => {
459
+ return await client.invitation.create({
460
+ data: {
461
+ code,
462
+ createdBy: userId,
463
+ email: email, // Already sanitized (lowercase, validated)
464
+ expiresAt,
465
+ },
466
+ select: {
467
+ id: true,
468
+ code: true,
469
+ createdBy: true,
470
+ email: true,
471
+ used: true,
472
+ usedBy: true,
473
+ usedAt: true,
474
+ scannedAt: true,
475
+ expiresAt: true,
476
+ createdAt: true,
477
+ },
478
+ });
479
+ }, {
480
+ ...QueryTimeoutPresets.USER_FACING, // 3s initial, 2s retry
481
+ context: {
482
+ operation: "createInvitationWithEmail_create",
483
+ userId,
484
+ },
485
+ });
486
+ return this.securityHeaders.createSecureResponse(JSON.stringify({
487
+ invitation: {
488
+ id: invitation.id,
489
+ code: invitation.code,
490
+ createdBy: invitation.createdBy,
491
+ email: invitation.email,
492
+ used: invitation.used,
493
+ usedBy: invitation.usedBy,
494
+ usedByEmail: null, // Not applicable for newly created invitation
495
+ usedAt: invitation.usedAt?.toISOString(),
496
+ scannedAt: invitation.scannedAt?.toISOString(),
497
+ expiresAt: invitation.expiresAt?.toISOString(),
498
+ createdAt: invitation.createdAt.toISOString(),
499
+ },
500
+ remainingToday: limitCheck.limit - limitCheck.count - 1,
501
+ }), { status: 201, headers: { "content-type": "application/json" } });
502
+ }
503
+ catch (error) {
504
+ this.logger.error("[InvitationHandler] Error creating invitation:", error);
505
+ // SECURITY: Don't expose internal error details
506
+ return this.securityHeaders.createSecureResponse(JSON.stringify({ error: "Internal server error" }), { status: 500, headers: { "content-type": "application/json" } });
507
+ }
508
+ }
509
+ /**
510
+ * Get inviter info for friend confirmation
511
+ * GET /api/invitations/inviter-info
512
+ *
513
+ * Returns the inviter information for a newly signed up user.
514
+ */
515
+ async handleGetInviterInfo(request, env) {
516
+ try {
517
+ // Check authentication
518
+ const { Secrets } = await Promise.resolve().then(() => __importStar(require("./secret-resolver")));
519
+ const sessionSecret = Secrets.getSessionSecret(env);
520
+ const session = await this.sessionManager.getSession(request, sessionSecret, env);
521
+ if (!session) {
522
+ return this.securityHeaders.createSecureResponse(JSON.stringify({ error: "Unauthorized" }), { status: 401, headers: { "content-type": "application/json" } });
523
+ }
524
+ // Get inviter info from KV
525
+ if (!env.INVITATIONS_KV) {
526
+ return this.securityHeaders.createSecureResponse(JSON.stringify({ inviterId: null, inviterEmail: null }), { status: 200, headers: { "content-type": "application/json" } });
527
+ }
528
+ const key = `inviter-info:${session.userId}`;
529
+ const stored = await env.INVITATIONS_KV.get(key);
530
+ if (!stored) {
531
+ return this.securityHeaders.createSecureResponse(JSON.stringify({ inviterId: null, inviterEmail: null }), { status: 200, headers: { "content-type": "application/json" } });
532
+ }
533
+ try {
534
+ const data = JSON.parse(stored);
535
+ // Delete after reading (one-time use)
536
+ await env.INVITATIONS_KV.delete(key);
537
+ return this.securityHeaders.createSecureResponse(JSON.stringify({
538
+ inviterId: data.inviterId,
539
+ inviterEmail: data.inviterEmail,
540
+ }), { status: 200, headers: { "content-type": "application/json" } });
541
+ }
542
+ catch (e) {
543
+ return this.securityHeaders.createSecureResponse(JSON.stringify({ inviterId: null, inviterEmail: null }), { status: 200, headers: { "content-type": "application/json" } });
544
+ }
545
+ }
546
+ catch (error) {
547
+ this.logger.error("[InvitationHandler] Error getting inviter info:", error);
548
+ return this.securityHeaders.createSecureResponse(JSON.stringify({ error: "Internal server error" }), { status: 500, headers: { "content-type": "application/json" } });
549
+ }
550
+ }
551
+ /**
552
+ * List user's invitations
553
+ * GET /api/invitations
554
+ *
555
+ * Returns all invitations created by the authenticated user.
556
+ */
557
+ async handleListInvitations(request, env) {
558
+ let session = null;
559
+ try {
560
+ // Check authentication
561
+ session = await this.sessionManager.getSession(request, secret_resolver_1.Secrets.getSessionSecret(env), env);
562
+ if (!session) {
563
+ return this.securityHeaders.createSecureResponse(JSON.stringify({ error: "Unauthorized" }), { status: 401, headers: { "content-type": "application/json" } });
564
+ }
565
+ // Use DatabaseConnectionManager for clear state management
566
+ const { sharedDatabaseConnectionManager } = await Promise.resolve().then(() => __importStar(require("./database-connection-manager")));
567
+ const { withQueryTimeoutAndRetry, QueryTimeoutPresets } = await Promise.resolve().then(() => __importStar(require("./db-query-helper")));
568
+ const { detectRegionSync } = await Promise.resolve().then(() => __importStar(require("./region-detection")));
569
+ // Create connection manager instance (manages its own pool state)
570
+ const dbManager = sharedDatabaseConnectionManager;
571
+ // Determine region from request
572
+ const region = detectRegionSync(request, env);
573
+ // Clean up expired invitations before listing
574
+ await this.deleteExpiredInvitations(session.userId, env, request);
575
+ // Execute query with timeout and retry logic
576
+ // queryFn receives a fresh PrismaClient on each call (including retry)
577
+ const invitations = await withQueryTimeoutAndRetry(dbManager, region, env, async (client) => {
578
+ // session is guaranteed to be non-null here (checked above)
579
+ const userId = session.userId;
580
+ const invitations = await client.invitation.findMany({
581
+ where: { createdBy: userId },
582
+ orderBy: { createdAt: "desc" },
583
+ take: 100,
584
+ select: {
585
+ id: true,
586
+ code: true,
587
+ createdBy: true,
588
+ email: true,
589
+ used: true,
590
+ usedBy: true,
591
+ usedAt: true,
592
+ scannedAt: true,
593
+ expiresAt: true,
594
+ createdAt: true,
595
+ },
596
+ });
597
+ // If any invitations are used, fetch user emails separately to avoid join overhead
598
+ const usedInvitationIds = invitations
599
+ .filter((inv) => inv.used && inv.usedBy)
600
+ .map((inv) => inv.usedBy)
601
+ .filter((id, index, self) => self.indexOf(id) === index);
602
+ let userEmailsMap = {};
603
+ if (usedInvitationIds.length > 0) {
604
+ const users = await client.user.findMany({
605
+ where: { id: { in: usedInvitationIds } },
606
+ select: { id: true, email: true },
607
+ });
608
+ userEmailsMap = Object.fromEntries(users.map((user) => [
609
+ user.id,
610
+ user.email,
611
+ ]));
612
+ }
613
+ return invitations.map((inv) => ({
614
+ ...inv,
615
+ user: inv.usedBy
616
+ ? { email: userEmailsMap[inv.usedBy] || null }
617
+ : null,
618
+ }));
619
+ }, {
620
+ ...QueryTimeoutPresets.USER_FACING, // 3s initial, 2s retry = 5s max total
621
+ defaultValue: [], // Return empty array on timeout (graceful degradation)
622
+ context: {
623
+ operation: "handleListInvitations",
624
+ userId: session.userId,
625
+ },
626
+ });
627
+ return this.securityHeaders.createSecureResponse(JSON.stringify({
628
+ invitations: invitations.map((inv) => ({
629
+ id: inv.id,
630
+ code: inv.code,
631
+ createdBy: inv.createdBy, // User ID who created the invitation
632
+ email: inv.email, // Email restriction (if invitation was created for specific email)
633
+ used: inv.used,
634
+ usedBy: inv.usedBy,
635
+ usedByEmail: inv.user?.email || null, // Email of user who accepted the invitation
636
+ usedAt: inv.usedAt?.toISOString(),
637
+ scannedAt: inv.scannedAt?.toISOString() || null, // Session token scan timestamp
638
+ expiresAt: inv.expiresAt?.toISOString(),
639
+ createdAt: inv.createdAt.toISOString(),
640
+ })),
641
+ }), { status: 200, headers: { "content-type": "application/json" } });
642
+ }
643
+ catch (error) {
644
+ this.logger.error("[InvitationHandler] Error listing invitations:", {
645
+ error: error.message,
646
+ errorCode: error.code,
647
+ stack: error.stack,
648
+ userId: session?.userId,
649
+ });
650
+ // Provide more specific error messages for timeout scenarios
651
+ let errorMessage = "Internal server error";
652
+ if (error.message?.includes("timeout")) {
653
+ errorMessage = "Request timed out. Please try again in a moment.";
654
+ }
655
+ return this.securityHeaders.createSecureResponse(JSON.stringify({ error: errorMessage }), { status: 500, headers: { "content-type": "application/json" } });
656
+ }
657
+ }
658
+ /**
659
+ * Delete an invitation
660
+ * DELETE /api/invitations/:id
661
+ *
662
+ * Allows the creator to delete their own invitation.
663
+ * Cannot delete invitations that are currently being used (scanned but not yet completed signup).
664
+ *
665
+ * SECURITY: Only the creator can delete their own invitations.
666
+ */
667
+ async handleDeleteInvitation(request, env) {
668
+ let release;
669
+ try {
670
+ // Check authentication
671
+ const { Secrets } = await Promise.resolve().then(() => __importStar(require("./secret-resolver")));
672
+ const sessionSecret = Secrets.getSessionSecret(env);
673
+ const session = await this.sessionManager.getSession(request, sessionSecret, env);
674
+ if (!session) {
675
+ return this.securityHeaders.createSecureResponse(JSON.stringify({ error: "Unauthorized" }), { status: 401, headers: { "content-type": "application/json" } });
676
+ }
677
+ // Extract invitation ID from URL path
678
+ const url = new URL(request.url);
679
+ const pathParts = url.pathname.split("/");
680
+ const invitationId = pathParts[pathParts.length - 1];
681
+ if (!invitationId) {
682
+ return this.securityHeaders.createSecureResponse(JSON.stringify({ error: "Invitation ID is required" }), { status: 400, headers: { "content-type": "application/json" } });
683
+ }
684
+ // Get fresh database client (may have been cleared by previous operations)
685
+ let db = (0, db_1.createPrisma)(env);
686
+ release = db.release;
687
+ // Find the invitation and verify ownership with timeout protection
688
+ // Add detailed logging to diagnose where the hang occurs
689
+ this.logger.info("[InvitationHandler] Delete: Starting findUnique query", {
690
+ invitationId,
691
+ userId: session.userId,
692
+ timestamp: new Date().toISOString(),
693
+ });
694
+ const findStartTime = Date.now();
695
+ const findQueryPromise = db.invitation.findUnique({
696
+ where: { id: invitationId },
697
+ select: {
698
+ id: true,
699
+ code: true,
700
+ createdBy: true,
701
+ used: true,
702
+ scannedAt: true,
703
+ },
704
+ });
705
+ const findTimeoutPromise = new Promise((_, reject) => {
706
+ setTimeout(() => {
707
+ const elapsed = Date.now() - findStartTime;
708
+ this.logger.error("[InvitationHandler] Delete: findUnique timeout", {
709
+ invitationId,
710
+ elapsedMs: elapsed,
711
+ timestamp: new Date().toISOString(),
712
+ });
713
+ reject(new Error(`Database query timeout after ${elapsed}ms`));
714
+ }, 5000); // 5 seconds - very aggressive timeout for diagnosis
715
+ });
716
+ let invitation;
717
+ try {
718
+ invitation = await Promise.race([findQueryPromise, findTimeoutPromise]);
719
+ const findElapsed = Date.now() - findStartTime;
720
+ this.logger.info("[InvitationHandler] Delete: findUnique completed", {
721
+ invitationId,
722
+ elapsedMs: findElapsed,
723
+ found: !!invitation,
724
+ });
725
+ }
726
+ catch (findError) {
727
+ this.logger.error("[InvitationHandler] Delete: findUnique failed", {
728
+ invitationId,
729
+ error: findError.message,
730
+ elapsedMs: Date.now() - findStartTime,
731
+ });
732
+ // If findUnique times out, the connection is likely stale
733
+ // Clear pool cache and retry once with fresh connection
734
+ await release();
735
+ const { sharedDatabaseConnectionManager } = await Promise.resolve().then(() => __importStar(require("./database-connection-manager")));
736
+ this.logger.warn("[InvitationHandler] Delete: Clearing pool cache and retrying...");
737
+ sharedDatabaseConnectionManager.clearPools();
738
+ db = (0, db_1.createPrisma)(env);
739
+ release = db.release;
740
+ // Retry findUnique with fresh connection (very short timeout)
741
+ const retryStartTime = Date.now();
742
+ const retryPromise = db.invitation.findUnique({
743
+ where: { id: invitationId },
744
+ select: {
745
+ id: true,
746
+ code: true,
747
+ createdBy: true,
748
+ used: true,
749
+ scannedAt: true,
750
+ },
751
+ });
752
+ const retryTimeout = new Promise((_, reject) => {
753
+ setTimeout(() => {
754
+ reject(new Error("Retry timeout"));
755
+ }, 3000); // 3 seconds for retry
756
+ });
757
+ try {
758
+ invitation = await Promise.race([retryPromise, retryTimeout]);
759
+ this.logger.info("[InvitationHandler] Delete: Retry succeeded", {
760
+ invitationId,
761
+ elapsedMs: Date.now() - retryStartTime,
762
+ });
763
+ }
764
+ catch (retryError) {
765
+ this.logger.error("[InvitationHandler] Delete: Retry also failed", {
766
+ invitationId,
767
+ error: retryError.message,
768
+ });
769
+ return this.securityHeaders.createSecureResponse(JSON.stringify({
770
+ error: "Database query timeout",
771
+ message: "Unable to access invitation. Please try again.",
772
+ }), { status: 503, headers: { "content-type": "application/json" } });
773
+ }
774
+ }
775
+ if (!invitation) {
776
+ return this.securityHeaders.createSecureResponse(JSON.stringify({ error: "Invitation not found" }), { status: 404, headers: { "content-type": "application/json" } });
777
+ }
778
+ // SECURITY: Only the creator can delete their own invitation
779
+ if (invitation.createdBy !== session.userId) {
780
+ return this.securityHeaders.createSecureResponse(JSON.stringify({
781
+ error: "Forbidden: You can only delete your own invitations",
782
+ }), { status: 403, headers: { "content-type": "application/json" } });
783
+ }
784
+ // Check if invitation is currently being used (scanned but not yet completed)
785
+ // We should prevent deletion if someone is in the process of signing up
786
+ if (invitation.scannedAt && !invitation.used) {
787
+ return this.securityHeaders.createSecureResponse(JSON.stringify({
788
+ error: "Cannot delete invitation that is currently being used",
789
+ message: "This invitation has been scanned and is in the process of being used. Please wait for the signup to complete or expire.",
790
+ }), { status: 409, headers: { "content-type": "application/json" } });
791
+ }
792
+ // Delete the invitation with timeout protection
793
+ // Add detailed logging to diagnose where the hang occurs
794
+ this.logger.info("[InvitationHandler] Delete: Starting delete query", {
795
+ invitationId,
796
+ timestamp: new Date().toISOString(),
797
+ });
798
+ const deleteStartTime = Date.now();
799
+ const deleteQueryPromise = db.invitation.delete({
800
+ where: { id: invitationId },
801
+ });
802
+ const deleteTimeoutPromise = new Promise((_, reject) => {
803
+ setTimeout(() => {
804
+ const elapsed = Date.now() - deleteStartTime;
805
+ this.logger.error("[InvitationHandler] Delete: delete timeout", {
806
+ invitationId,
807
+ elapsedMs: elapsed,
808
+ timestamp: new Date().toISOString(),
809
+ });
810
+ reject(new Error(`Database delete timeout after ${elapsed}ms - invitation may be locked by another transaction`));
811
+ }, 5000); // 5 seconds - very aggressive timeout for diagnosis
812
+ });
813
+ try {
814
+ await Promise.race([deleteQueryPromise, deleteTimeoutPromise]);
815
+ const deleteElapsed = Date.now() - deleteStartTime;
816
+ this.logger.info("[InvitationHandler] Delete: delete completed", {
817
+ invitationId,
818
+ elapsedMs: deleteElapsed,
819
+ });
820
+ }
821
+ catch (error) {
822
+ // Log additional context for debugging lock contention
823
+ const elapsed = Date.now() - deleteStartTime;
824
+ this.logger.error("[InvitationHandler] Delete failed:", {
825
+ invitationId,
826
+ error: error.message,
827
+ errorCode: error.code,
828
+ elapsedMs: elapsed,
829
+ hint: "This may indicate row-level lock contention, stale connection, or database issue",
830
+ });
831
+ throw error;
832
+ }
833
+ // Clean up any related KV entries (session tokens)
834
+ if (env.INVITATIONS_KV) {
835
+ const sessionKey = `invitation-session:${invitation.code}`;
836
+ const codeKey = `invitation_code:${invitation.code}`;
837
+ try {
838
+ await env.INVITATIONS_KV.delete(sessionKey);
839
+ // Also try to delete any email-based entries (we don't know which emails, so we can't clean those up)
840
+ // But the session token entry is the important one
841
+ }
842
+ catch (error) {
843
+ // KV deletion is best-effort, don't fail if it doesn't exist
844
+ this.logger.warn("[InvitationHandler] Failed to delete KV entry:", error);
845
+ }
846
+ }
847
+ return this.securityHeaders.createSecureResponse(JSON.stringify({
848
+ success: true,
849
+ message: "Invitation deleted successfully",
850
+ }), { status: 200, headers: { "content-type": "application/json" } });
851
+ }
852
+ catch (error) {
853
+ this.logger.error("[InvitationHandler] Error deleting invitation:", {
854
+ error: error.message,
855
+ errorCode: error.code,
856
+ stack: error.stack,
857
+ });
858
+ // Provide more specific error messages for timeout scenarios
859
+ let errorMessage = "Internal server error";
860
+ if (error.message?.includes("timeout")) {
861
+ errorMessage =
862
+ "Delete operation timed out. The invitation may be in use by another process. Please try again in a moment.";
863
+ }
864
+ else if (error.code === "P2025") {
865
+ // Prisma error code for record not found
866
+ errorMessage = "Invitation not found or already deleted";
867
+ }
868
+ return this.securityHeaders.createSecureResponse(JSON.stringify({ error: errorMessage }), { status: 500, headers: { "content-type": "application/json" } });
869
+ }
870
+ finally {
871
+ if (release) {
872
+ await release();
873
+ }
874
+ }
875
+ }
876
+ /**
877
+ * Validate an invitation code
878
+ * POST /api/invitations/validate
879
+ *
880
+ * Public endpoint to validate an invitation code before sign-up.
881
+ * Returns whether the code is valid and can be used.
882
+ *
883
+ * SECURITY: Rate limited to prevent brute force attacks.
884
+ */
885
+ async handleValidateInvitation(request, env) {
886
+ try {
887
+ // SECURITY: Rate limit validation attempts to prevent brute force (reduced to 10 per hour per IP)
888
+ const rateLimitResult = this.rateLimiter.checkRateLimit(request, "/api/invitations/validate", 10, // 10 validation attempts (reduced from 20)
889
+ 3600, // per hour
890
+ undefined, undefined, undefined);
891
+ if (!rateLimitResult.allowed) {
892
+ return this.securityHeaders.createSecureResponse(JSON.stringify({
893
+ valid: false,
894
+ error: "Too many validation attempts. Please try again later.",
895
+ }), {
896
+ status: 200, // Return 200 to not reveal rate limiting
897
+ headers: {
898
+ "content-type": "application/json",
899
+ "Retry-After": Math.ceil((rateLimitResult.resetAt - Date.now()) / 1000).toString(),
900
+ },
901
+ });
902
+ }
903
+ // Validate request body with Zod schema
904
+ const { validateRequest } = await Promise.resolve().then(() => __importStar(require("./validate-request")));
905
+ const { validateInvitationSchema } = await Promise.resolve().then(() => __importStar(require("./schemas")));
906
+ const validation = await validateRequest(request, validateInvitationSchema);
907
+ if (!validation.success) {
908
+ return this.securityHeaders.addSecurityHeaders(validation.error);
909
+ }
910
+ const { code: sanitizedCode, email } = validation.data;
911
+ // Code is already validated and sanitized by Zod schema (trimmed, uppercase, max 100 chars)
912
+ const db = (0, db_1.createPrisma)(env);
913
+ this.logger.info(`[InvitationHandler] Validating invitation code: ${sanitizedCode}, email: ${email || "none"}`);
914
+ // SECURITY: Check expiration BEFORE claiming to prevent wasted writes
915
+ // First, do a quick check without locking
916
+ const invitationCheck = await db.invitation.findUnique({
917
+ where: { code: sanitizedCode },
918
+ select: {
919
+ id: true,
920
+ used: true,
921
+ expiresAt: true,
922
+ email: true,
923
+ scannedAt: true,
924
+ },
925
+ });
926
+ this.logger.info("[InvitationHandler] Initial invitation check result:", invitationCheck
927
+ ? {
928
+ id: invitationCheck.id,
929
+ used: invitationCheck.used,
930
+ scannedAt: invitationCheck.scannedAt,
931
+ expiresAt: invitationCheck.expiresAt,
932
+ hasEmail: !!invitationCheck.email,
933
+ }
934
+ : "not found");
935
+ if (!invitationCheck) {
936
+ this.logger.warn("[InvitationHandler] Invitation not found:", sanitizedCode);
937
+ // SECURITY: Use generic error message to prevent code enumeration
938
+ return this.securityHeaders.createSecureResponse(JSON.stringify({
939
+ valid: false,
940
+ error: "Invalid or unavailable invitation code",
941
+ }), { status: 200, headers: { "content-type": "application/json" } });
942
+ }
943
+ // Check expiration first (before claiming)
944
+ if (invitationCheck.expiresAt && new Date() > invitationCheck.expiresAt) {
945
+ this.logger.warn(`[InvitationHandler] Invitation expired: ${sanitizedCode}, expires at ${invitationCheck.expiresAt}, now ${new Date()}`);
946
+ return this.securityHeaders.createSecureResponse(JSON.stringify({
947
+ valid: false,
948
+ error: "Invalid or unavailable invitation code",
949
+ }), { status: 200, headers: { "content-type": "application/json" } });
950
+ }
951
+ // Check if already used
952
+ if (invitationCheck.used) {
953
+ this.logger.warn("[InvitationHandler] Invitation already used:", sanitizedCode);
954
+ return this.securityHeaders.createSecureResponse(JSON.stringify({
955
+ valid: false,
956
+ error: "Invalid or unavailable invitation code",
957
+ }), { status: 200, headers: { "content-type": "application/json" } });
958
+ }
959
+ // SECURITY: If invitation is email-restricted, email is REQUIRED
960
+ if (invitationCheck.email && !email) {
961
+ return this.securityHeaders.createSecureResponse(JSON.stringify({
962
+ valid: false,
963
+ error: "Email address is required for this invitation code",
964
+ emailRequired: true,
965
+ }), { status: 200, headers: { "content-type": "application/json" } });
966
+ }
967
+ // SECURITY: For email-restricted invitations, email is REQUIRED and must match
968
+ // For open invitations, email is NOT collected during validation (only during signup)
969
+ let sanitizedEmail = undefined;
970
+ if (invitationCheck.email) {
971
+ // Email-restricted invitation - email is required
972
+ if (!email) {
973
+ return this.securityHeaders.createSecureResponse(JSON.stringify({
974
+ valid: false,
975
+ error: "Email address is required for this invitation code",
976
+ emailRequired: true,
977
+ }), { status: 200, headers: { "content-type": "application/json" } });
978
+ }
979
+ const trimmedEmail = email.trim().toLowerCase();
980
+ const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
981
+ if (emailRegex.test(trimmedEmail) && trimmedEmail.length <= 254) {
982
+ sanitizedEmail = trimmedEmail;
983
+ }
984
+ else {
985
+ return this.securityHeaders.createSecureResponse(JSON.stringify({
986
+ valid: false,
987
+ error: "Invalid email format",
988
+ }), { status: 200, headers: { "content-type": "application/json" } });
989
+ }
990
+ // SECURITY: Check if email matches restriction (case-insensitive comparison)
991
+ if (invitationCheck.email.toLowerCase() !== sanitizedEmail) {
992
+ // SECURITY: Don't reveal the restricted email to prevent enumeration
993
+ return this.securityHeaders.createSecureResponse(JSON.stringify({
994
+ valid: false,
995
+ error: "Invalid or unavailable invitation code",
996
+ }), { status: 200, headers: { "content-type": "application/json" } });
997
+ }
998
+ }
999
+ // For open invitations (no email restriction), we don't collect or store email during validation
1000
+ // Email will be collected and validated during actual signup
1001
+ // Check if already scanned - if so, return existing token if available
1002
+ let sessionToken;
1003
+ if (invitationCheck.scannedAt) {
1004
+ this.logger.info("[InvitationHandler] Invitation already scanned at:", invitationCheck.scannedAt);
1005
+ // Code was already scanned - check if we have a valid session token
1006
+ if (env.INVITATIONS_KV) {
1007
+ const key = `invitation-session:${sanitizedCode}`;
1008
+ const stored = await env.INVITATIONS_KV.get(key);
1009
+ this.logger.info(`[InvitationHandler] Checking KV for existing token, key: ${key}, found: ${!!stored}`);
1010
+ if (stored) {
1011
+ try {
1012
+ const data = JSON.parse(stored);
1013
+ // Return existing token if valid
1014
+ if (data.token &&
1015
+ (!data.expiresAt || new Date(data.expiresAt) > new Date())) {
1016
+ this.logger.info("[InvitationHandler] Returning existing valid token");
1017
+ return this.securityHeaders.createSecureResponse(JSON.stringify({
1018
+ valid: true,
1019
+ token: data.token,
1020
+ emailRestricted: !!invitationCheck.email,
1021
+ requiredEmail: invitationCheck.email || null,
1022
+ }), {
1023
+ status: 200,
1024
+ headers: { "content-type": "application/json" },
1025
+ });
1026
+ }
1027
+ else {
1028
+ this.logger.warn("[InvitationHandler] Stored token expired or invalid");
1029
+ }
1030
+ }
1031
+ catch (e) {
1032
+ this.logger.error("[InvitationHandler] Error parsing stored token data:", e);
1033
+ // Invalid stored data, continue to generate new token
1034
+ }
1035
+ }
1036
+ }
1037
+ // If no valid token found, code was scanned but token expired - reject
1038
+ this.logger.warn("[InvitationHandler] Invitation already scanned but no valid token found, rejecting");
1039
+ return this.securityHeaders.createSecureResponse(JSON.stringify({
1040
+ valid: false,
1041
+ error: "Invalid or unavailable invitation code",
1042
+ }), { status: 200, headers: { "content-type": "application/json" } });
1043
+ }
1044
+ this.logger.info("[InvitationHandler] Invitation not yet scanned, proceeding to claim");
1045
+ // First time scanning - atomically claim the invitation code with SELECT FOR UPDATE
1046
+ sessionToken = this.generateSessionToken();
1047
+ const now = new Date();
1048
+ // Use transaction to prevent race conditions
1049
+ // Note: Using findUnique + update instead of $queryRaw for better compatibility
1050
+ const claimed = await db.$transaction(async (tx) => {
1051
+ // Find the invitation by code
1052
+ const inv = await tx.invitation.findUnique({
1053
+ where: { code: sanitizedCode },
1054
+ select: {
1055
+ id: true,
1056
+ scannedAt: true,
1057
+ scannedBy: true,
1058
+ used: true,
1059
+ expiresAt: true,
1060
+ email: true,
1061
+ },
1062
+ });
1063
+ if (!inv) {
1064
+ this.logger.warn("[InvitationHandler] Invitation not found in transaction:", sanitizedCode);
1065
+ return { success: false, reason: "not_found" };
1066
+ }
1067
+ // Check all conditions
1068
+ if (inv.used) {
1069
+ this.logger.warn("[InvitationHandler] Invitation already used:", sanitizedCode);
1070
+ return { success: false, reason: "already_used" };
1071
+ }
1072
+ if (inv.scannedAt) {
1073
+ this.logger.warn(`[InvitationHandler] Invitation already scanned: ${sanitizedCode}, at ${inv.scannedAt}`);
1074
+ return { success: false, reason: "already_scanned" };
1075
+ }
1076
+ if (inv.expiresAt && new Date() > inv.expiresAt) {
1077
+ this.logger.warn(`[InvitationHandler] Invitation expired: ${sanitizedCode}, expires at ${inv.expiresAt}`);
1078
+ return { success: false, reason: "expired" };
1079
+ }
1080
+ // Claim it atomically - update will fail if record doesn't exist
1081
+ // The transaction provides atomicity, and we've already checked conditions above
1082
+ try {
1083
+ const updated = await tx.invitation.update({
1084
+ where: { code: sanitizedCode },
1085
+ data: {
1086
+ scannedAt: now,
1087
+ scannedBy: sessionToken, // Store token as scannedBy for reference
1088
+ },
1089
+ });
1090
+ this.logger.info(`[InvitationHandler] Successfully claimed invitation: ${sanitizedCode}, scannedAt: ${updated.scannedAt}`);
1091
+ return { success: true };
1092
+ }
1093
+ catch (error) {
1094
+ // If update failed (e.g., record was deleted or already updated), return failure
1095
+ // This handles race conditions where another request claimed it first
1096
+ this.logger.error(`[InvitationHandler] Failed to update invitation in transaction: ${sanitizedCode}, error: ${error.message}${error.code ? `, code: ${error.code}` : ""}`);
1097
+ return {
1098
+ success: false,
1099
+ reason: "update_failed",
1100
+ error: error.message,
1101
+ };
1102
+ }
1103
+ });
1104
+ if (!claimed.success) {
1105
+ this.logger.error(`[InvitationHandler] Failed to claim invitation: ${sanitizedCode}, reason: ${claimed.reason || "unknown"}${claimed.error ? `, error: ${claimed.error}` : ""}`);
1106
+ return this.securityHeaders.createSecureResponse(JSON.stringify({
1107
+ valid: false,
1108
+ error: "Invalid or unavailable invitation code",
1109
+ }), { status: 200, headers: { "content-type": "application/json" } });
1110
+ }
1111
+ // Store session token in KV for validation during signup
1112
+ await this.storeSessionToken(sanitizedCode, sessionToken, sanitizedEmail, env);
1113
+ return this.securityHeaders.createSecureResponse(JSON.stringify({
1114
+ valid: true,
1115
+ token: sessionToken,
1116
+ emailRestricted: !!invitationCheck.email,
1117
+ requiredEmail: invitationCheck.email || null,
1118
+ }), { status: 200, headers: { "content-type": "application/json" } });
1119
+ }
1120
+ catch (error) {
1121
+ this.logger.error("[InvitationHandler] Error validating invitation:", error);
1122
+ return this.securityHeaders.createSecureResponse(JSON.stringify({ error: "Internal server error" }), { status: 500, headers: { "content-type": "application/json" } });
1123
+ }
1124
+ }
1125
+ /**
1126
+ * Mark an invitation as used
1127
+ * Called internally when a user signs up with an invitation code
1128
+ *
1129
+ * SECURITY: Uses database transaction to prevent race conditions (multiple signups with same code)
1130
+ *
1131
+ * Also automatically creates a friendship between the inviter and the new user.
1132
+ */
1133
+ async markInvitationAsUsed(code, userId, token, email, env) {
1134
+ try {
1135
+ const db = (0, db_1.createPrisma)(env);
1136
+ // SECURITY: Sanitize code input
1137
+ const sanitizedCode = code.trim().toUpperCase();
1138
+ if (!/^[A-Z0-9]+$/.test(sanitizedCode)) {
1139
+ return { success: false, error: "Invalid invitation code format" };
1140
+ }
1141
+ // SECURITY: Validate session token if provided
1142
+ let tokenValidation = null;
1143
+ if (token) {
1144
+ tokenValidation = await this.validateSessionToken(sanitizedCode, token, env);
1145
+ if (!tokenValidation.valid) {
1146
+ return {
1147
+ success: false,
1148
+ error: "Invalid or expired invitation session. Please scan the QR code again.",
1149
+ };
1150
+ }
1151
+ // Note: Email match enforcement is handled below after we check if invitation is email-restricted
1152
+ // For open invitations (no email restriction), we allow email correction to handle typos
1153
+ }
1154
+ else {
1155
+ // SECURITY: If no token provided, check if code was scanned (backward compatibility)
1156
+ // This allows for email-based invitations that don't go through QR scanning
1157
+ // But we should still validate that the code exists and is valid
1158
+ }
1159
+ // SECURITY: Use transaction to prevent race conditions
1160
+ // Note: Using findUnique + update instead of $queryRaw for better compatibility
1161
+ const result = await db.$transaction(async (tx) => {
1162
+ // Find the invitation by code
1163
+ const invitation = await tx.invitation.findUnique({
1164
+ where: { code: sanitizedCode },
1165
+ select: {
1166
+ id: true,
1167
+ createdBy: true,
1168
+ expiresAt: true,
1169
+ used: true,
1170
+ email: true,
1171
+ },
1172
+ });
1173
+ if (!invitation) {
1174
+ return { success: false, error: "Invalid invitation code" };
1175
+ }
1176
+ if (invitation.used) {
1177
+ return {
1178
+ success: false,
1179
+ error: "Invitation code has already been used",
1180
+ };
1181
+ }
1182
+ if (invitation.expiresAt && new Date() > invitation.expiresAt) {
1183
+ return { success: false, error: "Invitation code has expired" };
1184
+ }
1185
+ // SECURITY: Check email restriction if invitation is restricted
1186
+ // For email-restricted invitations, enforce exact match
1187
+ // For open invitations (no email restriction), allow email correction to handle typos
1188
+ if (invitation.email &&
1189
+ invitation.email.toLowerCase() !== email.toLowerCase()) {
1190
+ return {
1191
+ success: false,
1192
+ error: "This invitation code is restricted to a different email address",
1193
+ };
1194
+ }
1195
+ // For open invitations, email is not stored in the session token during validation
1196
+ // The email provided during signup is the only email we use
1197
+ // No email validation needed for open invitations - they can use any valid email
1198
+ // Get creator information
1199
+ const creator = await tx.user.findUnique({
1200
+ where: { id: invitation.createdBy },
1201
+ select: {
1202
+ id: true,
1203
+ email: true,
1204
+ },
1205
+ });
1206
+ if (!creator) {
1207
+ return { success: false, error: "Invitation creator not found" };
1208
+ }
1209
+ // SECURITY: Atomic update - marks as used and links to user in single operation
1210
+ // The transaction provides atomicity, and we've already checked conditions above
1211
+ try {
1212
+ this.logger.info("[InvitationHandler] Marking invitation as used:", {
1213
+ invitationId: invitation.id,
1214
+ code: sanitizedCode,
1215
+ userId: userId,
1216
+ email: email,
1217
+ });
1218
+ const updated = await tx.invitation.update({
1219
+ where: { id: invitation.id },
1220
+ data: {
1221
+ used: true,
1222
+ usedBy: userId,
1223
+ usedAt: new Date(),
1224
+ },
1225
+ });
1226
+ this.logger.info("[InvitationHandler] Successfully marked invitation as used:", {
1227
+ invitationId: updated.id,
1228
+ used: updated.used,
1229
+ usedBy: updated.usedBy,
1230
+ usedAt: updated.usedAt,
1231
+ });
1232
+ return {
1233
+ success: true,
1234
+ inviterId: creator.id,
1235
+ inviterEmail: creator.email,
1236
+ };
1237
+ }
1238
+ catch (error) {
1239
+ // If update failed (e.g., record was deleted or already updated), return failure
1240
+ // This handles race conditions where another request used it first
1241
+ this.logger.error("[InvitationHandler] Failed to mark invitation as used:", {
1242
+ invitationId: invitation.id,
1243
+ code: sanitizedCode,
1244
+ error: error.message,
1245
+ errorCode: error.code,
1246
+ });
1247
+ return {
1248
+ success: false,
1249
+ error: "Invitation code has already been used",
1250
+ };
1251
+ }
1252
+ });
1253
+ if (!result.success) {
1254
+ return result;
1255
+ }
1256
+ // Don't create friendship automatically - return inviter info for frontend to prompt user
1257
+ // Friendship will be created after user confirms
1258
+ return result;
1259
+ }
1260
+ catch (error) {
1261
+ this.logger.error("[InvitationHandler] Error marking invitation as used:", error);
1262
+ return { success: false, error: "Internal server error" };
1263
+ }
1264
+ }
1265
+ /**
1266
+ * Create a friendship between the inviter and the new user
1267
+ * This is called automatically when an invitation is used
1268
+ */
1269
+ async createFriendshipFromInvitation(inviterId, inviterEmail, newUserId, newUserEmail, env) {
1270
+ if (!env.FRIENDS_KV) {
1271
+ this.logger.warn("[InvitationHandler] FRIENDS_KV not available, skipping friendship creation");
1272
+ return;
1273
+ }
1274
+ try {
1275
+ // Generate friendship ID
1276
+ const friendshipId = `friend_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
1277
+ const now = new Date().toISOString();
1278
+ // Create friendship object
1279
+ const friendship = {
1280
+ id: friendshipId,
1281
+ requesterId: newUserId,
1282
+ requesterEmail: newUserEmail,
1283
+ addresseeId: inviterId,
1284
+ addresseeEmail: inviterEmail,
1285
+ status: "ACCEPTED", // Automatically accepted since invitation was used
1286
+ createdAt: now,
1287
+ acceptedAt: now,
1288
+ };
1289
+ // Store bidirectional friendships in KV
1290
+ const requesterKey = `friendship:${newUserId}:${inviterId}`;
1291
+ const addresseeKey = `friendship:${inviterId}:${newUserId}`;
1292
+ await env.FRIENDS_KV.put(requesterKey, JSON.stringify(friendship));
1293
+ await env.FRIENDS_KV.put(addresseeKey, JSON.stringify({
1294
+ ...friendship,
1295
+ requesterId: inviterId,
1296
+ requesterEmail: inviterEmail,
1297
+ addresseeId: newUserId,
1298
+ addresseeEmail: newUserEmail,
1299
+ }));
1300
+ // Add to friends lists (with MAX_FRIENDS check)
1301
+ await this.addToFriendsList(newUserId, inviterId, env);
1302
+ await this.addToFriendsList(inviterId, newUserId, env);
1303
+ this.logger.info(`[InvitationHandler] Created friendship between ${newUserId} and ${inviterId} from invitation`);
1304
+ }
1305
+ catch (error) {
1306
+ // Log error but don't throw - friendship creation failure shouldn't prevent invitation from being marked as used
1307
+ this.logger.error("[InvitationHandler] Error creating friendship from invitation:", error);
1308
+ if (error.message?.includes("Maximum number of friends")) {
1309
+ this.logger.warn(`[InvitationHandler] Could not create friendship: ${error.message}`);
1310
+ }
1311
+ }
1312
+ }
1313
+ /**
1314
+ * Add friend to user's friends list (helper for maintaining list)
1315
+ * Throws error if MAX_FRIENDS limit is reached
1316
+ */
1317
+ async addToFriendsList(userId, friendId, env) {
1318
+ if (!env.FRIENDS_KV)
1319
+ return;
1320
+ const MAX_FRIENDS = 500; // Same limit as FriendsHandler
1321
+ const friendsListKey = `friends-list:${userId}`;
1322
+ const friendsListStr = await env.FRIENDS_KV.get(friendsListKey);
1323
+ const friendsList = friendsListStr ? JSON.parse(friendsListStr) : [];
1324
+ if (!friendsList.includes(friendId)) {
1325
+ // Check if user has reached the maximum number of friends
1326
+ if (friendsList.length >= MAX_FRIENDS) {
1327
+ throw new Error(`Maximum number of friends (${MAX_FRIENDS}) reached`);
1328
+ }
1329
+ friendsList.push(friendId);
1330
+ await env.FRIENDS_KV.put(friendsListKey, JSON.stringify(friendsList));
1331
+ }
1332
+ }
1333
+ }
1334
+ exports.InvitationHandler = InvitationHandler;
1335
+ //# sourceMappingURL=invitation-handler.js.map