happy2 0.0.5

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 (373) hide show
  1. package/README.md +82 -0
  2. package/package.json +74 -0
  3. package/packages/happy2-server/Dockerfile +18 -0
  4. package/packages/happy2-server/README.md +418 -0
  5. package/packages/happy2-server/bin/happy2.js +3 -0
  6. package/packages/happy2-server/dist/cli.d.ts +3 -0
  7. package/packages/happy2-server/dist/cli.d.ts.map +1 -0
  8. package/packages/happy2-server/dist/cli.js +44 -0
  9. package/packages/happy2-server/dist/cli.js.map +1 -0
  10. package/packages/happy2-server/dist/index.d.ts +24 -0
  11. package/packages/happy2-server/dist/index.d.ts.map +1 -0
  12. package/packages/happy2-server/dist/index.js +22 -0
  13. package/packages/happy2-server/dist/index.js.map +1 -0
  14. package/packages/happy2-server/dist/modules/agents/builtin-images.d.ts +8 -0
  15. package/packages/happy2-server/dist/modules/agents/builtin-images.d.ts.map +1 -0
  16. package/packages/happy2-server/dist/modules/agents/builtin-images.js +283 -0
  17. package/packages/happy2-server/dist/modules/agents/builtin-images.js.map +1 -0
  18. package/packages/happy2-server/dist/modules/agents/command.d.ts +3 -0
  19. package/packages/happy2-server/dist/modules/agents/command.d.ts.map +1 -0
  20. package/packages/happy2-server/dist/modules/agents/command.js +7 -0
  21. package/packages/happy2-server/dist/modules/agents/command.js.map +1 -0
  22. package/packages/happy2-server/dist/modules/agents/daemon.d.ts +106 -0
  23. package/packages/happy2-server/dist/modules/agents/daemon.d.ts.map +1 -0
  24. package/packages/happy2-server/dist/modules/agents/daemon.js +522 -0
  25. package/packages/happy2-server/dist/modules/agents/daemon.js.map +1 -0
  26. package/packages/happy2-server/dist/modules/agents/docker.d.ts +51 -0
  27. package/packages/happy2-server/dist/modules/agents/docker.d.ts.map +1 -0
  28. package/packages/happy2-server/dist/modules/agents/docker.js +256 -0
  29. package/packages/happy2-server/dist/modules/agents/docker.js.map +1 -0
  30. package/packages/happy2-server/dist/modules/agents/docker.test.d.ts +2 -0
  31. package/packages/happy2-server/dist/modules/agents/docker.test.d.ts.map +1 -0
  32. package/packages/happy2-server/dist/modules/agents/docker.test.js +155 -0
  33. package/packages/happy2-server/dist/modules/agents/docker.test.js.map +1 -0
  34. package/packages/happy2-server/dist/modules/agents/index.d.ts +5 -0
  35. package/packages/happy2-server/dist/modules/agents/index.d.ts.map +1 -0
  36. package/packages/happy2-server/dist/modules/agents/index.js +4 -0
  37. package/packages/happy2-server/dist/modules/agents/index.js.map +1 -0
  38. package/packages/happy2-server/dist/modules/agents/service.d.ts +140 -0
  39. package/packages/happy2-server/dist/modules/agents/service.d.ts.map +1 -0
  40. package/packages/happy2-server/dist/modules/agents/service.js +1283 -0
  41. package/packages/happy2-server/dist/modules/agents/service.js.map +1 -0
  42. package/packages/happy2-server/dist/modules/auth/cloudflare-access.d.ts +15 -0
  43. package/packages/happy2-server/dist/modules/auth/cloudflare-access.d.ts.map +1 -0
  44. package/packages/happy2-server/dist/modules/auth/cloudflare-access.js +49 -0
  45. package/packages/happy2-server/dist/modules/auth/cloudflare-access.js.map +1 -0
  46. package/packages/happy2-server/dist/modules/auth/crypto.d.ts +4 -0
  47. package/packages/happy2-server/dist/modules/auth/crypto.d.ts.map +1 -0
  48. package/packages/happy2-server/dist/modules/auth/crypto.js +31 -0
  49. package/packages/happy2-server/dist/modules/auth/crypto.js.map +1 -0
  50. package/packages/happy2-server/dist/modules/auth/crypto.test.d.ts +2 -0
  51. package/packages/happy2-server/dist/modules/auth/crypto.test.d.ts.map +1 -0
  52. package/packages/happy2-server/dist/modules/auth/crypto.test.js +11 -0
  53. package/packages/happy2-server/dist/modules/auth/crypto.test.js.map +1 -0
  54. package/packages/happy2-server/dist/modules/auth/email.d.ts +3 -0
  55. package/packages/happy2-server/dist/modules/auth/email.d.ts.map +1 -0
  56. package/packages/happy2-server/dist/modules/auth/email.js +22 -0
  57. package/packages/happy2-server/dist/modules/auth/email.js.map +1 -0
  58. package/packages/happy2-server/dist/modules/auth/metadata.d.ts +5 -0
  59. package/packages/happy2-server/dist/modules/auth/metadata.d.ts.map +1 -0
  60. package/packages/happy2-server/dist/modules/auth/metadata.js +28 -0
  61. package/packages/happy2-server/dist/modules/auth/metadata.js.map +1 -0
  62. package/packages/happy2-server/dist/modules/auth/metadata.test.d.ts +2 -0
  63. package/packages/happy2-server/dist/modules/auth/metadata.test.d.ts.map +1 -0
  64. package/packages/happy2-server/dist/modules/auth/metadata.test.js +10 -0
  65. package/packages/happy2-server/dist/modules/auth/metadata.test.js.map +1 -0
  66. package/packages/happy2-server/dist/modules/auth/methods.d.ts +10 -0
  67. package/packages/happy2-server/dist/modules/auth/methods.d.ts.map +1 -0
  68. package/packages/happy2-server/dist/modules/auth/methods.js +21 -0
  69. package/packages/happy2-server/dist/modules/auth/methods.js.map +1 -0
  70. package/packages/happy2-server/dist/modules/auth/methods.test.d.ts +2 -0
  71. package/packages/happy2-server/dist/modules/auth/methods.test.d.ts.map +1 -0
  72. package/packages/happy2-server/dist/modules/auth/methods.test.js +16 -0
  73. package/packages/happy2-server/dist/modules/auth/methods.test.js.map +1 -0
  74. package/packages/happy2-server/dist/modules/auth/oidc.d.ts +9 -0
  75. package/packages/happy2-server/dist/modules/auth/oidc.d.ts.map +1 -0
  76. package/packages/happy2-server/dist/modules/auth/oidc.js +68 -0
  77. package/packages/happy2-server/dist/modules/auth/oidc.js.map +1 -0
  78. package/packages/happy2-server/dist/modules/auth/service.d.ts +44 -0
  79. package/packages/happy2-server/dist/modules/auth/service.d.ts.map +1 -0
  80. package/packages/happy2-server/dist/modules/auth/service.js +208 -0
  81. package/packages/happy2-server/dist/modules/auth/service.js.map +1 -0
  82. package/packages/happy2-server/dist/modules/auth/tokens.d.ts +21 -0
  83. package/packages/happy2-server/dist/modules/auth/tokens.d.ts.map +1 -0
  84. package/packages/happy2-server/dist/modules/auth/tokens.js +79 -0
  85. package/packages/happy2-server/dist/modules/auth/tokens.js.map +1 -0
  86. package/packages/happy2-server/dist/modules/automation/repository.d.ts +127 -0
  87. package/packages/happy2-server/dist/modules/automation/repository.d.ts.map +1 -0
  88. package/packages/happy2-server/dist/modules/automation/repository.js +821 -0
  89. package/packages/happy2-server/dist/modules/automation/repository.js.map +1 -0
  90. package/packages/happy2-server/dist/modules/collaboration/repository.d.ts +839 -0
  91. package/packages/happy2-server/dist/modules/collaboration/repository.d.ts.map +1 -0
  92. package/packages/happy2-server/dist/modules/collaboration/repository.js +5795 -0
  93. package/packages/happy2-server/dist/modules/collaboration/repository.js.map +1 -0
  94. package/packages/happy2-server/dist/modules/collaboration/repository.test.d.ts +2 -0
  95. package/packages/happy2-server/dist/modules/collaboration/repository.test.d.ts.map +1 -0
  96. package/packages/happy2-server/dist/modules/collaboration/repository.test.js +620 -0
  97. package/packages/happy2-server/dist/modules/collaboration/repository.test.js.map +1 -0
  98. package/packages/happy2-server/dist/modules/collaboration/types.d.ts +243 -0
  99. package/packages/happy2-server/dist/modules/collaboration/types.d.ts.map +1 -0
  100. package/packages/happy2-server/dist/modules/collaboration/types.js +8 -0
  101. package/packages/happy2-server/dist/modules/collaboration/types.js.map +1 -0
  102. package/packages/happy2-server/dist/modules/config/defaults.d.ts +8 -0
  103. package/packages/happy2-server/dist/modules/config/defaults.d.ts.map +1 -0
  104. package/packages/happy2-server/dist/modules/config/defaults.js +70 -0
  105. package/packages/happy2-server/dist/modules/config/defaults.js.map +1 -0
  106. package/packages/happy2-server/dist/modules/config/defaults.test.d.ts +2 -0
  107. package/packages/happy2-server/dist/modules/config/defaults.test.d.ts.map +1 -0
  108. package/packages/happy2-server/dist/modules/config/defaults.test.js +27 -0
  109. package/packages/happy2-server/dist/modules/config/defaults.test.js.map +1 -0
  110. package/packages/happy2-server/dist/modules/config/environment.d.ts +4 -0
  111. package/packages/happy2-server/dist/modules/config/environment.d.ts.map +1 -0
  112. package/packages/happy2-server/dist/modules/config/environment.js +92 -0
  113. package/packages/happy2-server/dist/modules/config/environment.js.map +1 -0
  114. package/packages/happy2-server/dist/modules/config/loader.d.ts +5 -0
  115. package/packages/happy2-server/dist/modules/config/loader.d.ts.map +1 -0
  116. package/packages/happy2-server/dist/modules/config/loader.js +251 -0
  117. package/packages/happy2-server/dist/modules/config/loader.js.map +1 -0
  118. package/packages/happy2-server/dist/modules/config/loader.test.d.ts +2 -0
  119. package/packages/happy2-server/dist/modules/config/loader.test.d.ts.map +1 -0
  120. package/packages/happy2-server/dist/modules/config/loader.test.js +108 -0
  121. package/packages/happy2-server/dist/modules/config/loader.test.js.map +1 -0
  122. package/packages/happy2-server/dist/modules/config/paths.d.ts +7 -0
  123. package/packages/happy2-server/dist/modules/config/paths.d.ts.map +1 -0
  124. package/packages/happy2-server/dist/modules/config/paths.js +15 -0
  125. package/packages/happy2-server/dist/modules/config/paths.js.map +1 -0
  126. package/packages/happy2-server/dist/modules/config/paths.test.d.ts +2 -0
  127. package/packages/happy2-server/dist/modules/config/paths.test.d.ts.map +1 -0
  128. package/packages/happy2-server/dist/modules/config/paths.test.js +22 -0
  129. package/packages/happy2-server/dist/modules/config/paths.test.js.map +1 -0
  130. package/packages/happy2-server/dist/modules/config/runtime.d.ts +6 -0
  131. package/packages/happy2-server/dist/modules/config/runtime.d.ts.map +1 -0
  132. package/packages/happy2-server/dist/modules/config/runtime.js +14 -0
  133. package/packages/happy2-server/dist/modules/config/runtime.js.map +1 -0
  134. package/packages/happy2-server/dist/modules/config/type.d.ts +88 -0
  135. package/packages/happy2-server/dist/modules/config/type.d.ts.map +1 -0
  136. package/packages/happy2-server/dist/modules/config/type.js +2 -0
  137. package/packages/happy2-server/dist/modules/config/type.js.map +1 -0
  138. package/packages/happy2-server/dist/modules/database.d.ts +105 -0
  139. package/packages/happy2-server/dist/modules/database.d.ts.map +1 -0
  140. package/packages/happy2-server/dist/modules/database.js +583 -0
  141. package/packages/happy2-server/dist/modules/database.js.map +1 -0
  142. package/packages/happy2-server/dist/modules/drizzle.d.ts +11 -0
  143. package/packages/happy2-server/dist/modules/drizzle.d.ts.map +1 -0
  144. package/packages/happy2-server/dist/modules/drizzle.js +31 -0
  145. package/packages/happy2-server/dist/modules/drizzle.js.map +1 -0
  146. package/packages/happy2-server/dist/modules/files/lock.d.ts +3 -0
  147. package/packages/happy2-server/dist/modules/files/lock.d.ts.map +1 -0
  148. package/packages/happy2-server/dist/modules/files/lock.js +83 -0
  149. package/packages/happy2-server/dist/modules/files/lock.js.map +1 -0
  150. package/packages/happy2-server/dist/modules/files/media.d.ts +18 -0
  151. package/packages/happy2-server/dist/modules/files/media.d.ts.map +1 -0
  152. package/packages/happy2-server/dist/modules/files/media.js +352 -0
  153. package/packages/happy2-server/dist/modules/files/media.js.map +1 -0
  154. package/packages/happy2-server/dist/modules/files/provider.d.ts +130 -0
  155. package/packages/happy2-server/dist/modules/files/provider.d.ts.map +1 -0
  156. package/packages/happy2-server/dist/modules/files/provider.js +448 -0
  157. package/packages/happy2-server/dist/modules/files/provider.js.map +1 -0
  158. package/packages/happy2-server/dist/modules/files/quota.d.ts +58 -0
  159. package/packages/happy2-server/dist/modules/files/quota.d.ts.map +1 -0
  160. package/packages/happy2-server/dist/modules/files/quota.js +180 -0
  161. package/packages/happy2-server/dist/modules/files/quota.js.map +1 -0
  162. package/packages/happy2-server/dist/modules/files/routes.test.d.ts +2 -0
  163. package/packages/happy2-server/dist/modules/files/routes.test.d.ts.map +1 -0
  164. package/packages/happy2-server/dist/modules/files/routes.test.js +163 -0
  165. package/packages/happy2-server/dist/modules/files/routes.test.js.map +1 -0
  166. package/packages/happy2-server/dist/modules/files/scanner.d.ts +27 -0
  167. package/packages/happy2-server/dist/modules/files/scanner.d.ts.map +1 -0
  168. package/packages/happy2-server/dist/modules/files/scanner.js +66 -0
  169. package/packages/happy2-server/dist/modules/files/scanner.js.map +1 -0
  170. package/packages/happy2-server/dist/modules/files/storage.d.ts +95 -0
  171. package/packages/happy2-server/dist/modules/files/storage.d.ts.map +1 -0
  172. package/packages/happy2-server/dist/modules/files/storage.js +855 -0
  173. package/packages/happy2-server/dist/modules/files/storage.js.map +1 -0
  174. package/packages/happy2-server/dist/modules/files/storage.test.d.ts +2 -0
  175. package/packages/happy2-server/dist/modules/files/storage.test.d.ts.map +1 -0
  176. package/packages/happy2-server/dist/modules/files/storage.test.js +170 -0
  177. package/packages/happy2-server/dist/modules/files/storage.test.js.map +1 -0
  178. package/packages/happy2-server/dist/modules/integrations/index.d.ts +6 -0
  179. package/packages/happy2-server/dist/modules/integrations/index.d.ts.map +1 -0
  180. package/packages/happy2-server/dist/modules/integrations/index.js +6 -0
  181. package/packages/happy2-server/dist/modules/integrations/index.js.map +1 -0
  182. package/packages/happy2-server/dist/modules/integrations/repository.d.ts +136 -0
  183. package/packages/happy2-server/dist/modules/integrations/repository.d.ts.map +1 -0
  184. package/packages/happy2-server/dist/modules/integrations/repository.js +1229 -0
  185. package/packages/happy2-server/dist/modules/integrations/repository.js.map +1 -0
  186. package/packages/happy2-server/dist/modules/integrations/repository.test.d.ts +2 -0
  187. package/packages/happy2-server/dist/modules/integrations/repository.test.d.ts.map +1 -0
  188. package/packages/happy2-server/dist/modules/integrations/repository.test.js +345 -0
  189. package/packages/happy2-server/dist/modules/integrations/repository.test.js.map +1 -0
  190. package/packages/happy2-server/dist/modules/integrations/routes.test.d.ts +2 -0
  191. package/packages/happy2-server/dist/modules/integrations/routes.test.d.ts.map +1 -0
  192. package/packages/happy2-server/dist/modules/integrations/routes.test.js +161 -0
  193. package/packages/happy2-server/dist/modules/integrations/routes.test.js.map +1 -0
  194. package/packages/happy2-server/dist/modules/integrations/secrets.d.ts +19 -0
  195. package/packages/happy2-server/dist/modules/integrations/secrets.d.ts.map +1 -0
  196. package/packages/happy2-server/dist/modules/integrations/secrets.js +69 -0
  197. package/packages/happy2-server/dist/modules/integrations/secrets.js.map +1 -0
  198. package/packages/happy2-server/dist/modules/integrations/ssrf.d.ts +32 -0
  199. package/packages/happy2-server/dist/modules/integrations/ssrf.d.ts.map +1 -0
  200. package/packages/happy2-server/dist/modules/integrations/ssrf.js +185 -0
  201. package/packages/happy2-server/dist/modules/integrations/ssrf.js.map +1 -0
  202. package/packages/happy2-server/dist/modules/integrations/ssrf.test.d.ts +2 -0
  203. package/packages/happy2-server/dist/modules/integrations/ssrf.test.d.ts.map +1 -0
  204. package/packages/happy2-server/dist/modules/integrations/ssrf.test.js +56 -0
  205. package/packages/happy2-server/dist/modules/integrations/ssrf.test.js.map +1 -0
  206. package/packages/happy2-server/dist/modules/integrations/transport.d.ts +21 -0
  207. package/packages/happy2-server/dist/modules/integrations/transport.d.ts.map +1 -0
  208. package/packages/happy2-server/dist/modules/integrations/transport.js +108 -0
  209. package/packages/happy2-server/dist/modules/integrations/transport.js.map +1 -0
  210. package/packages/happy2-server/dist/modules/integrations/transport.test.d.ts +2 -0
  211. package/packages/happy2-server/dist/modules/integrations/transport.test.d.ts.map +1 -0
  212. package/packages/happy2-server/dist/modules/integrations/transport.test.js +66 -0
  213. package/packages/happy2-server/dist/modules/integrations/transport.test.js.map +1 -0
  214. package/packages/happy2-server/dist/modules/integrations/types.d.ts +155 -0
  215. package/packages/happy2-server/dist/modules/integrations/types.d.ts.map +1 -0
  216. package/packages/happy2-server/dist/modules/integrations/types.js +26 -0
  217. package/packages/happy2-server/dist/modules/integrations/types.js.map +1 -0
  218. package/packages/happy2-server/dist/modules/operations/export-worker.d.ts +16 -0
  219. package/packages/happy2-server/dist/modules/operations/export-worker.d.ts.map +1 -0
  220. package/packages/happy2-server/dist/modules/operations/export-worker.js +56 -0
  221. package/packages/happy2-server/dist/modules/operations/export-worker.js.map +1 -0
  222. package/packages/happy2-server/dist/modules/operations/repository.d.ts +215 -0
  223. package/packages/happy2-server/dist/modules/operations/repository.d.ts.map +1 -0
  224. package/packages/happy2-server/dist/modules/operations/repository.js +2011 -0
  225. package/packages/happy2-server/dist/modules/operations/repository.js.map +1 -0
  226. package/packages/happy2-server/dist/modules/operations/repository.test.d.ts +2 -0
  227. package/packages/happy2-server/dist/modules/operations/repository.test.d.ts.map +1 -0
  228. package/packages/happy2-server/dist/modules/operations/repository.test.js +610 -0
  229. package/packages/happy2-server/dist/modules/operations/repository.test.js.map +1 -0
  230. package/packages/happy2-server/dist/modules/operations/types.d.ts +144 -0
  231. package/packages/happy2-server/dist/modules/operations/types.d.ts.map +1 -0
  232. package/packages/happy2-server/dist/modules/operations/types.js +9 -0
  233. package/packages/happy2-server/dist/modules/operations/types.js.map +1 -0
  234. package/packages/happy2-server/dist/modules/realtime/events.d.ts +99 -0
  235. package/packages/happy2-server/dist/modules/realtime/events.d.ts.map +1 -0
  236. package/packages/happy2-server/dist/modules/realtime/events.js +173 -0
  237. package/packages/happy2-server/dist/modules/realtime/events.js.map +1 -0
  238. package/packages/happy2-server/dist/modules/realtime/index.d.ts +4 -0
  239. package/packages/happy2-server/dist/modules/realtime/index.d.ts.map +1 -0
  240. package/packages/happy2-server/dist/modules/realtime/index.js +4 -0
  241. package/packages/happy2-server/dist/modules/realtime/index.js.map +1 -0
  242. package/packages/happy2-server/dist/modules/realtime/local.d.ts +37 -0
  243. package/packages/happy2-server/dist/modules/realtime/local.d.ts.map +1 -0
  244. package/packages/happy2-server/dist/modules/realtime/local.js +181 -0
  245. package/packages/happy2-server/dist/modules/realtime/local.js.map +1 -0
  246. package/packages/happy2-server/dist/modules/realtime/local.test.d.ts +2 -0
  247. package/packages/happy2-server/dist/modules/realtime/local.test.d.ts.map +1 -0
  248. package/packages/happy2-server/dist/modules/realtime/local.test.js +186 -0
  249. package/packages/happy2-server/dist/modules/realtime/local.test.js.map +1 -0
  250. package/packages/happy2-server/dist/modules/realtime/pubsub.d.ts +26 -0
  251. package/packages/happy2-server/dist/modules/realtime/pubsub.d.ts.map +1 -0
  252. package/packages/happy2-server/dist/modules/realtime/pubsub.js +7 -0
  253. package/packages/happy2-server/dist/modules/realtime/pubsub.js.map +1 -0
  254. package/packages/happy2-server/dist/modules/request/database-idempotency.d.ts +15 -0
  255. package/packages/happy2-server/dist/modules/request/database-idempotency.d.ts.map +1 -0
  256. package/packages/happy2-server/dist/modules/request/database-idempotency.js +141 -0
  257. package/packages/happy2-server/dist/modules/request/database-idempotency.js.map +1 -0
  258. package/packages/happy2-server/dist/modules/request/idempotency-hook.d.ts +12 -0
  259. package/packages/happy2-server/dist/modules/request/idempotency-hook.d.ts.map +1 -0
  260. package/packages/happy2-server/dist/modules/request/idempotency-hook.js +98 -0
  261. package/packages/happy2-server/dist/modules/request/idempotency-hook.js.map +1 -0
  262. package/packages/happy2-server/dist/modules/request/idempotency.d.ts +146 -0
  263. package/packages/happy2-server/dist/modules/request/idempotency.d.ts.map +1 -0
  264. package/packages/happy2-server/dist/modules/request/idempotency.js +312 -0
  265. package/packages/happy2-server/dist/modules/request/idempotency.js.map +1 -0
  266. package/packages/happy2-server/dist/modules/request/idempotency.test.d.ts +2 -0
  267. package/packages/happy2-server/dist/modules/request/idempotency.test.d.ts.map +1 -0
  268. package/packages/happy2-server/dist/modules/request/idempotency.test.js +191 -0
  269. package/packages/happy2-server/dist/modules/request/idempotency.test.js.map +1 -0
  270. package/packages/happy2-server/dist/modules/request/index.d.ts +5 -0
  271. package/packages/happy2-server/dist/modules/request/index.d.ts.map +1 -0
  272. package/packages/happy2-server/dist/modules/request/index.js +5 -0
  273. package/packages/happy2-server/dist/modules/request/index.js.map +1 -0
  274. package/packages/happy2-server/dist/modules/request/rate-limit.d.ts +100 -0
  275. package/packages/happy2-server/dist/modules/request/rate-limit.d.ts.map +1 -0
  276. package/packages/happy2-server/dist/modules/request/rate-limit.js +239 -0
  277. package/packages/happy2-server/dist/modules/request/rate-limit.js.map +1 -0
  278. package/packages/happy2-server/dist/modules/request/rate-limit.test.d.ts +2 -0
  279. package/packages/happy2-server/dist/modules/request/rate-limit.test.d.ts.map +1 -0
  280. package/packages/happy2-server/dist/modules/request/rate-limit.test.js +123 -0
  281. package/packages/happy2-server/dist/modules/request/rate-limit.test.js.map +1 -0
  282. package/packages/happy2-server/dist/modules/schema.d.ts +31454 -0
  283. package/packages/happy2-server/dist/modules/schema.d.ts.map +1 -0
  284. package/packages/happy2-server/dist/modules/schema.js +1081 -0
  285. package/packages/happy2-server/dist/modules/schema.js.map +1 -0
  286. package/packages/happy2-server/dist/modules/workspace/index.d.ts +3 -0
  287. package/packages/happy2-server/dist/modules/workspace/index.d.ts.map +1 -0
  288. package/packages/happy2-server/dist/modules/workspace/index.js +3 -0
  289. package/packages/happy2-server/dist/modules/workspace/index.js.map +1 -0
  290. package/packages/happy2-server/dist/modules/workspace/service.d.ts +54 -0
  291. package/packages/happy2-server/dist/modules/workspace/service.d.ts.map +1 -0
  292. package/packages/happy2-server/dist/modules/workspace/service.js +997 -0
  293. package/packages/happy2-server/dist/modules/workspace/service.js.map +1 -0
  294. package/packages/happy2-server/dist/modules/workspace/types.d.ts +58 -0
  295. package/packages/happy2-server/dist/modules/workspace/types.d.ts.map +1 -0
  296. package/packages/happy2-server/dist/modules/workspace/types.js +11 -0
  297. package/packages/happy2-server/dist/modules/workspace/types.js.map +1 -0
  298. package/packages/happy2-server/dist/routes/agents.d.ts +5 -0
  299. package/packages/happy2-server/dist/routes/agents.d.ts.map +1 -0
  300. package/packages/happy2-server/dist/routes/agents.js +225 -0
  301. package/packages/happy2-server/dist/routes/agents.js.map +1 -0
  302. package/packages/happy2-server/dist/routes/auth.d.ts +5 -0
  303. package/packages/happy2-server/dist/routes/auth.d.ts.map +1 -0
  304. package/packages/happy2-server/dist/routes/auth.js +128 -0
  305. package/packages/happy2-server/dist/routes/auth.js.map +1 -0
  306. package/packages/happy2-server/dist/routes/automation.d.ts +6 -0
  307. package/packages/happy2-server/dist/routes/automation.d.ts.map +1 -0
  308. package/packages/happy2-server/dist/routes/automation.js +315 -0
  309. package/packages/happy2-server/dist/routes/automation.js.map +1 -0
  310. package/packages/happy2-server/dist/routes/basic.d.ts +3 -0
  311. package/packages/happy2-server/dist/routes/basic.d.ts.map +1 -0
  312. package/packages/happy2-server/dist/routes/basic.js +5 -0
  313. package/packages/happy2-server/dist/routes/basic.js.map +1 -0
  314. package/packages/happy2-server/dist/routes/collaboration.d.ts +7 -0
  315. package/packages/happy2-server/dist/routes/collaboration.d.ts.map +1 -0
  316. package/packages/happy2-server/dist/routes/collaboration.js +1285 -0
  317. package/packages/happy2-server/dist/routes/collaboration.js.map +1 -0
  318. package/packages/happy2-server/dist/routes/files.d.ts +9 -0
  319. package/packages/happy2-server/dist/routes/files.d.ts.map +1 -0
  320. package/packages/happy2-server/dist/routes/files.js +397 -0
  321. package/packages/happy2-server/dist/routes/files.js.map +1 -0
  322. package/packages/happy2-server/dist/routes/integrations.d.ts +6 -0
  323. package/packages/happy2-server/dist/routes/integrations.d.ts.map +1 -0
  324. package/packages/happy2-server/dist/routes/integrations.js +486 -0
  325. package/packages/happy2-server/dist/routes/integrations.js.map +1 -0
  326. package/packages/happy2-server/dist/routes/operations.d.ts +5 -0
  327. package/packages/happy2-server/dist/routes/operations.d.ts.map +1 -0
  328. package/packages/happy2-server/dist/routes/operations.js +588 -0
  329. package/packages/happy2-server/dist/routes/operations.js.map +1 -0
  330. package/packages/happy2-server/dist/routes/operations.test.d.ts +2 -0
  331. package/packages/happy2-server/dist/routes/operations.test.d.ts.map +1 -0
  332. package/packages/happy2-server/dist/routes/operations.test.js +106 -0
  333. package/packages/happy2-server/dist/routes/operations.test.js.map +1 -0
  334. package/packages/happy2-server/dist/routes/sync.d.ts +6 -0
  335. package/packages/happy2-server/dist/routes/sync.d.ts.map +1 -0
  336. package/packages/happy2-server/dist/routes/sync.js +549 -0
  337. package/packages/happy2-server/dist/routes/sync.js.map +1 -0
  338. package/packages/happy2-server/dist/routes/workspace.d.ts +5 -0
  339. package/packages/happy2-server/dist/routes/workspace.d.ts.map +1 -0
  340. package/packages/happy2-server/dist/routes/workspace.js +240 -0
  341. package/packages/happy2-server/dist/routes/workspace.js.map +1 -0
  342. package/packages/happy2-server/dist/runner.d.ts +3 -0
  343. package/packages/happy2-server/dist/runner.d.ts.map +1 -0
  344. package/packages/happy2-server/dist/runner.js +30 -0
  345. package/packages/happy2-server/dist/runner.js.map +1 -0
  346. package/packages/happy2-server/dist/server.d.ts +32 -0
  347. package/packages/happy2-server/dist/server.d.ts.map +1 -0
  348. package/packages/happy2-server/dist/server.js +284 -0
  349. package/packages/happy2-server/dist/server.js.map +1 -0
  350. package/packages/happy2-server/dist/standalone.d.ts +13 -0
  351. package/packages/happy2-server/dist/standalone.d.ts.map +1 -0
  352. package/packages/happy2-server/dist/standalone.js +99 -0
  353. package/packages/happy2-server/dist/standalone.js.map +1 -0
  354. package/packages/happy2-server/dist/web/assets/figtree-latin-wght-normal-D_ZTVpCC.woff2 +0 -0
  355. package/packages/happy2-server/dist/web/assets/happy-otter-Q2O_g-DT.png +0 -0
  356. package/packages/happy2-server/dist/web/assets/index-COvbX8JP.css +2 -0
  357. package/packages/happy2-server/dist/web/assets/index-DdpugxMO.js +57 -0
  358. package/packages/happy2-server/dist/web/assets/jetbrains-mono-latin-wght-normal-B9CIFXIH.woff2 +0 -0
  359. package/packages/happy2-server/dist/web/assets/onboarding-CRUpq9xl.png +0 -0
  360. package/packages/happy2-server/dist/web/index.html +13 -0
  361. package/packages/happy2-server/drizzle/0000_initial.sql +13 -0
  362. package/packages/happy2-server/drizzle/0001_accounts_profiles_files.sql +42 -0
  363. package/packages/happy2-server/drizzle/0002_file_visibility_and_uploader.sql +5 -0
  364. package/packages/happy2-server/drizzle/0003_collaboration.sql +565 -0
  365. package/packages/happy2-server/drizzle/0004_collaboration_expansion.sql +1099 -0
  366. package/packages/happy2-server/drizzle/0005_ai_agents.sql +85 -0
  367. package/packages/happy2-server/drizzle/0006_rig_global_event_queue.sql +10 -0
  368. package/packages/happy2-server/drizzle/0007_rename_server_identity.sql +3 -0
  369. package/packages/happy2-server/drizzle/0008_agent_message_streaming.sql +47 -0
  370. package/packages/happy2-server/drizzle/0009_chat_workspace_binding_lookup.sql +2 -0
  371. package/packages/happy2-server/drizzle/0010_rig_secret_assignments.sql +21 -0
  372. package/packages/happy2-server/drizzle/meta/_journal.json +83 -0
  373. package/packages/happy2-server/happy2.example.toml +104 -0
@@ -0,0 +1,161 @@
1
+ import Fastify from "fastify";
2
+ import { describe, expect, it, vi } from "vitest";
3
+ import { registerIntegrationRoutes } from "../../routes/integrations.js";
4
+ describe("integration HTTP routes", () => {
5
+ it("requires a product user and maps admin creation results", async () => {
6
+ const change = {
7
+ sequence: "8",
8
+ kind: "bot.created",
9
+ entityId: "bot_1",
10
+ };
11
+ const repository = fakeRepository({
12
+ createBot: vi.fn(async () => ({
13
+ value: {
14
+ id: "bot_1",
15
+ name: "Build Bot",
16
+ username: "build_bot",
17
+ active: true,
18
+ createdAt: "2026-01-01T00:00:00.000Z",
19
+ updatedAt: "2026-01-01T00:00:00.000Z",
20
+ },
21
+ change,
22
+ })),
23
+ });
24
+ const onChange = vi.fn(async () => { });
25
+ const app = buildRouteServer(repository, { incomingWebhook: sink(), onChange });
26
+ expect((await app.inject({
27
+ method: "POST",
28
+ url: "/v0/admin/bots/createBot",
29
+ payload: { name: "Build Bot", username: "build_bot" },
30
+ })).statusCode).toBe(401);
31
+ const created = await app.inject({
32
+ method: "POST",
33
+ url: "/v0/admin/bots/createBot",
34
+ headers: { "x-test-user": "admin_1" },
35
+ payload: { name: "Build Bot", username: "build_bot" },
36
+ });
37
+ expect(created.statusCode).toBe(201);
38
+ expect(created.json()).toMatchObject({ bot: { id: "bot_1" }, sync: change });
39
+ expect(repository.createBot).toHaveBeenCalledWith({
40
+ actorUserId: "admin_1",
41
+ name: "Build Bot",
42
+ username: "build_bot",
43
+ description: undefined,
44
+ photoFileId: undefined,
45
+ ownerUserId: undefined,
46
+ });
47
+ expect(onChange).toHaveBeenCalledWith(change);
48
+ await app.close();
49
+ });
50
+ it("returns credentials once and rejects unexpected fields", async () => {
51
+ const repository = fakeRepository({
52
+ createApiCredential: vi.fn(async () => ({
53
+ credential: {
54
+ id: "credential_1",
55
+ integrationId: "integration_1",
56
+ name: "CI",
57
+ tokenPrefix: "happy2_api_abc",
58
+ scopes: ["messages:write"],
59
+ createdAt: "2026-01-01T00:00:00.000Z",
60
+ },
61
+ token: "happy2_api_secret_returned_once",
62
+ })),
63
+ });
64
+ const app = buildRouteServer(repository);
65
+ const created = await app.inject({
66
+ method: "POST",
67
+ url: "/v0/admin/integrations/integration_1/createCredential",
68
+ headers: { "x-test-user": "admin_1" },
69
+ payload: { name: "CI", scopes: ["messages:write"] },
70
+ });
71
+ expect(created.statusCode).toBe(201);
72
+ expect(created.json()).toMatchObject({
73
+ token: "happy2_api_secret_returned_once",
74
+ credential: { id: "credential_1" },
75
+ });
76
+ const unsafeSecretCache = await app.inject({
77
+ method: "POST",
78
+ url: "/v0/admin/integrations/integration_1/createCredential",
79
+ headers: { "x-test-user": "admin_1", "idempotency-key": "do-not-cache-secret" },
80
+ payload: { name: "CI", scopes: ["messages:write"] },
81
+ });
82
+ expect(unsafeSecretCache.statusCode).toBe(400);
83
+ expect(repository.createApiCredential).toHaveBeenCalledTimes(1);
84
+ const invalid = await app.inject({
85
+ method: "POST",
86
+ url: "/v0/admin/integrations/integration_1/createCredential",
87
+ headers: { "x-test-user": "admin_1" },
88
+ payload: { name: "CI", secret: "must-not-be-accepted" },
89
+ });
90
+ expect(invalid.statusCode).toBe(400);
91
+ expect(invalid.json()).toMatchObject({ error: "invalid_request" });
92
+ await app.close();
93
+ });
94
+ it("accepts incoming webhook secrets only in the dedicated header", async () => {
95
+ const incomingWebhook = sink();
96
+ const invokeIncomingWebhook = vi.fn(async (token, text, callback, idempotencyKey) => callback.sendMessage({
97
+ actorUserId: "admin_1",
98
+ integrationId: "integration_1",
99
+ subscriptionId: "subscription_1",
100
+ botId: "bot_1",
101
+ chatId: "chat_1",
102
+ text: `${token}:${text}`,
103
+ idempotencyKey,
104
+ }));
105
+ const repository = fakeRepository({ invokeIncomingWebhook });
106
+ const app = buildRouteServer(repository, { incomingWebhook });
107
+ const missing = await app.inject({
108
+ method: "POST",
109
+ url: "/v0/integrations/incomingWebhook",
110
+ payload: { text: "hello" },
111
+ });
112
+ expect(missing.statusCode).toBe(401);
113
+ const accepted = await app.inject({
114
+ method: "POST",
115
+ url: "/v0/integrations/incomingWebhook",
116
+ headers: {
117
+ "x-happy2-webhook-token": "happy2_hook_secret",
118
+ "idempotency-key": "deploy-event-42",
119
+ },
120
+ payload: { text: "hello" },
121
+ });
122
+ expect(accepted.statusCode).toBe(201);
123
+ expect(accepted.json()).toEqual({ messageId: "message_1" });
124
+ expect(invokeIncomingWebhook).toHaveBeenCalledWith("happy2_hook_secret", "hello", incomingWebhook, "deploy-event-42");
125
+ expect(incomingWebhook.sendMessage).toHaveBeenCalledWith(expect.objectContaining({
126
+ botId: "bot_1",
127
+ chatId: "chat_1",
128
+ text: "happy2_hook_secret:hello",
129
+ idempotencyKey: "deploy-event-42",
130
+ }));
131
+ const invalidKey = await app.inject({
132
+ method: "POST",
133
+ url: "/v0/integrations/incomingWebhook",
134
+ headers: {
135
+ "x-happy2-webhook-token": "happy2_hook_secret",
136
+ "idempotency-key": "contains spaces",
137
+ },
138
+ payload: { text: "hello" },
139
+ });
140
+ expect(invalidKey.statusCode).toBe(400);
141
+ await app.close();
142
+ });
143
+ });
144
+ function buildRouteServer(repository, callbacks = { incomingWebhook: sink() }) {
145
+ const app = Fastify({ logger: false });
146
+ const auth = {
147
+ authenticate: vi.fn(async (request) => {
148
+ const userId = request.headers["x-test-user"];
149
+ return typeof userId === "string" ? { user: { id: userId } } : undefined;
150
+ }),
151
+ };
152
+ registerIntegrationRoutes(app, auth, repository, callbacks);
153
+ return app;
154
+ }
155
+ function sink() {
156
+ return { sendMessage: vi.fn(async () => ({ messageId: "message_1" })) };
157
+ }
158
+ function fakeRepository(overrides) {
159
+ return overrides;
160
+ }
161
+ //# sourceMappingURL=routes.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routes.test.js","sourceRoot":"","sources":["../../../sources/modules/integrations/routes.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ export interface SecretProtector {
2
+ protect(secret: string): Promise<string>;
3
+ reveal(ciphertext: string): Promise<string>;
4
+ }
5
+ /** AES-GCM envelope used for signing secrets that must be recovered by delivery workers. */
6
+ export declare class AesGcmSecretProtector implements SecretProtector {
7
+ private readonly key;
8
+ constructor(key: Uint8Array);
9
+ static fromBase64(value: string): AesGcmSecretProtector;
10
+ protect(secret: string): Promise<string>;
11
+ reveal(envelope: string): Promise<string>;
12
+ }
13
+ export declare function generateApiToken(): string;
14
+ export declare function generateIncomingWebhookToken(): string;
15
+ export declare function generateSigningSecret(): string;
16
+ export declare function tokenPrefix(token: string): string;
17
+ export declare function secretHash(secret: string): string;
18
+ export declare function hashesEqual(left: string, right: string): boolean;
19
+ //# sourceMappingURL=secrets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secrets.d.ts","sourceRoot":"","sources":["../../../sources/modules/integrations/secrets.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,eAAe;IAC5B,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACzC,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CAC/C;AAED,4FAA4F;AAC5F,qBAAa,qBAAsB,YAAW,eAAe;IACzD,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAE7B,YAAY,GAAG,EAAE,UAAU,EAG1B;IAED,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,qBAAqB,CAGtD;IAEK,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAQ7C;IAEK,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAyB9C;CACJ;AAED,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AAED,wBAAgB,4BAA4B,IAAI,MAAM,CAErD;AAED,wBAAgB,qBAAqB,IAAI,MAAM,CAE9C;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAGhE"}
@@ -0,0 +1,69 @@
1
+ import { createCipheriv, createDecipheriv, createHash, randomBytes, timingSafeEqual, } from "node:crypto";
2
+ const CIPHER = "aes-256-gcm";
3
+ const CONTEXT = Buffer.from("happy2:integration-signing-secret:v1", "utf8");
4
+ /** AES-GCM envelope used for signing secrets that must be recovered by delivery workers. */
5
+ export class AesGcmSecretProtector {
6
+ key;
7
+ constructor(key) {
8
+ if (key.byteLength !== 32)
9
+ throw new TypeError("Integration secret key must be 32 bytes");
10
+ this.key = Buffer.from(key);
11
+ }
12
+ static fromBase64(value) {
13
+ if (!value)
14
+ throw new TypeError("Integration secret key is required");
15
+ return new AesGcmSecretProtector(Buffer.from(value, "base64url"));
16
+ }
17
+ async protect(secret) {
18
+ if (!secret)
19
+ throw new TypeError("Secret must not be empty");
20
+ const nonce = randomBytes(12);
21
+ const cipher = createCipheriv(CIPHER, this.key, nonce);
22
+ cipher.setAAD(CONTEXT);
23
+ const ciphertext = Buffer.concat([cipher.update(secret, "utf8"), cipher.final()]);
24
+ const tag = cipher.getAuthTag();
25
+ return `v1.${nonce.toString("base64url")}.${ciphertext.toString("base64url")}.${tag.toString("base64url")}`;
26
+ }
27
+ async reveal(envelope) {
28
+ const [version, nonceValue, ciphertextValue, tagValue, unexpected] = envelope.split(".");
29
+ if (version !== "v1" ||
30
+ !nonceValue ||
31
+ !ciphertextValue ||
32
+ !tagValue ||
33
+ unexpected !== undefined)
34
+ throw new Error("Invalid integration secret envelope");
35
+ try {
36
+ const decipher = createDecipheriv(CIPHER, this.key, Buffer.from(nonceValue, "base64url"));
37
+ decipher.setAAD(CONTEXT);
38
+ decipher.setAuthTag(Buffer.from(tagValue, "base64url"));
39
+ return Buffer.concat([
40
+ decipher.update(Buffer.from(ciphertextValue, "base64url")),
41
+ decipher.final(),
42
+ ]).toString("utf8");
43
+ }
44
+ catch {
45
+ throw new Error("Integration secret could not be authenticated");
46
+ }
47
+ }
48
+ }
49
+ export function generateApiToken() {
50
+ return `happy2_api_${randomBytes(32).toString("base64url")}`;
51
+ }
52
+ export function generateIncomingWebhookToken() {
53
+ return `happy2_hook_${randomBytes(32).toString("base64url")}`;
54
+ }
55
+ export function generateSigningSecret() {
56
+ return `happy2_sign_${randomBytes(32).toString("base64url")}`;
57
+ }
58
+ export function tokenPrefix(token) {
59
+ return token.slice(0, 20);
60
+ }
61
+ export function secretHash(secret) {
62
+ return createHash("sha256").update(secret, "utf8").digest("hex");
63
+ }
64
+ export function hashesEqual(left, right) {
65
+ if (!/^[a-f0-9]{64}$/.test(left) || !/^[a-f0-9]{64}$/.test(right))
66
+ return false;
67
+ return timingSafeEqual(Buffer.from(left, "hex"), Buffer.from(right, "hex"));
68
+ }
69
+ //# sourceMappingURL=secrets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secrets.js","sourceRoot":"","sources":["../../../sources/modules/integrations/secrets.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ export interface ResolvedWebhookUrl {
2
+ url: string;
3
+ addresses: ReadonlyArray<{
4
+ address: string;
5
+ family: 4 | 6;
6
+ }>;
7
+ }
8
+ export interface WebhookUrlPolicy {
9
+ validateForStorage(value: string): string;
10
+ resolveForDelivery(value: string): Promise<ResolvedWebhookUrl>;
11
+ }
12
+ export interface StrictWebhookUrlPolicyOptions {
13
+ allowedPorts?: readonly number[];
14
+ resolve?: (hostname: string) => Promise<ReadonlyArray<{
15
+ address: string;
16
+ family: 4 | 6;
17
+ }>>;
18
+ }
19
+ /**
20
+ * Rejects credentials, non-HTTPS URLs, local hostnames, non-approved ports, and
21
+ * every non-public resolved address. Delivery transports must pin their socket to
22
+ * one of the returned addresses so DNS rebinding cannot bypass this decision.
23
+ */
24
+ export declare class StrictWebhookUrlPolicy implements WebhookUrlPolicy {
25
+ private readonly allowedPorts;
26
+ private readonly resolve;
27
+ constructor(options?: StrictWebhookUrlPolicyOptions);
28
+ validateForStorage(value: string): string;
29
+ resolveForDelivery(value: string): Promise<ResolvedWebhookUrl>;
30
+ }
31
+ export declare function isPublicAddress(value: string): boolean;
32
+ //# sourceMappingURL=ssrf.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ssrf.d.ts","sourceRoot":"","sources":["../../../sources/modules/integrations/ssrf.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,kBAAkB;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,aAAa,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAA;KAAE,CAAC,CAAC;CAChE;AAED,MAAM,WAAW,gBAAgB;IAC7B,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IAC1C,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;CAClE;AAED,MAAM,WAAW,6BAA6B;IAC1C,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,aAAa,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAA;KAAE,CAAC,CAAC,CAAC;CAC9F;AAED;;;;GAIG;AACH,qBAAa,sBAAuB,YAAW,gBAAgB;IAC3D,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAc;IAC3C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAEwC;IAEhE,YAAY,OAAO,GAAE,6BAAkC,EAiBtD;IAED,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAwBxC;IAEK,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAUnE;CACJ;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAKtD"}
@@ -0,0 +1,185 @@
1
+ import { lookup } from "node:dns/promises";
2
+ import { isIP } from "node:net";
3
+ import { IntegrationError } from "./types.js";
4
+ /**
5
+ * Rejects credentials, non-HTTPS URLs, local hostnames, non-approved ports, and
6
+ * every non-public resolved address. Delivery transports must pin their socket to
7
+ * one of the returned addresses so DNS rebinding cannot bypass this decision.
8
+ */
9
+ export class StrictWebhookUrlPolicy {
10
+ allowedPorts;
11
+ resolve;
12
+ constructor(options = {}) {
13
+ const ports = options.allowedPorts ?? [443];
14
+ if (ports.length === 0 ||
15
+ ports.some((port) => !Number.isSafeInteger(port) || port < 1 || port > 65_535))
16
+ throw new TypeError("allowedPorts must contain valid TCP ports");
17
+ this.allowedPorts = new Set(ports);
18
+ this.resolve =
19
+ options.resolve ??
20
+ (async (hostname) => {
21
+ const results = await lookup(hostname, { all: true, verbatim: true });
22
+ return results.map(({ address, family }) => ({
23
+ address,
24
+ family: family === 6 ? 6 : 4,
25
+ }));
26
+ });
27
+ }
28
+ validateForStorage(value) {
29
+ let url;
30
+ try {
31
+ url = new URL(value);
32
+ }
33
+ catch {
34
+ throw new IntegrationError("invalid", "Webhook URL must be an absolute HTTPS URL");
35
+ }
36
+ if (url.protocol !== "https:")
37
+ throw new IntegrationError("invalid", "Webhook URL must use HTTPS");
38
+ if (url.username || url.password)
39
+ throw new IntegrationError("invalid", "Webhook URL must not contain credentials");
40
+ if (url.hash)
41
+ throw new IntegrationError("invalid", "Webhook URL must not contain a fragment");
42
+ const port = url.port ? Number(url.port) : 443;
43
+ if (!this.allowedPorts.has(port))
44
+ throw new IntegrationError("invalid", "Webhook URL uses a disallowed port");
45
+ const hostname = unbracket(url.hostname).replace(/\.$/, "").toLowerCase();
46
+ const literalFamily = isIP(hostname);
47
+ if (!hostname || (!literalFamily && isLocalHostname(hostname)))
48
+ throw new IntegrationError("invalid", "Webhook URL hostname is not public");
49
+ if (literalFamily && !isPublicAddress(hostname))
50
+ throw new IntegrationError("invalid", "Webhook URL address is not public");
51
+ return url.toString();
52
+ }
53
+ async resolveForDelivery(value) {
54
+ const normalized = this.validateForStorage(value);
55
+ const hostname = unbracket(new URL(normalized).hostname);
56
+ const literalFamily = isIP(hostname);
57
+ const addresses = literalFamily
58
+ ? [{ address: hostname, family: literalFamily }]
59
+ : await this.resolve(hostname);
60
+ if (addresses.length === 0 || addresses.some(({ address }) => !isPublicAddress(address)))
61
+ throw new IntegrationError("forbidden", "Webhook URL resolved to a non-public address");
62
+ return { url: normalized, addresses: deduplicate(addresses) };
63
+ }
64
+ }
65
+ export function isPublicAddress(value) {
66
+ const family = isIP(value);
67
+ if (family === 4)
68
+ return isPublicIpv4(value);
69
+ if (family === 6)
70
+ return isPublicIpv6(value);
71
+ return false;
72
+ }
73
+ function isLocalHostname(hostname) {
74
+ if (!hostname.includes("."))
75
+ return true;
76
+ return (hostname === "localhost" ||
77
+ hostname.endsWith(".localhost") ||
78
+ hostname.endsWith(".local") ||
79
+ hostname.endsWith(".internal") ||
80
+ hostname.endsWith(".home.arpa"));
81
+ }
82
+ function isPublicIpv4(value) {
83
+ const octets = value.split(".").map(Number);
84
+ if (octets.length !== 4 || octets.some((octet) => octet < 0 || octet > 255))
85
+ return false;
86
+ const [a, b, c] = octets;
87
+ if (a === 0 || a === 10 || a === 127 || a >= 224)
88
+ return false;
89
+ if (a === 100 && b >= 64 && b <= 127)
90
+ return false;
91
+ if (a === 169 && b === 254)
92
+ return false;
93
+ if (a === 172 && b >= 16 && b <= 31)
94
+ return false;
95
+ if (a === 192 && b === 168)
96
+ return false;
97
+ if (a === 198 && (b === 18 || b === 19))
98
+ return false;
99
+ // IETF special-purpose/documentation networks are not valid callback targets.
100
+ if (a === 192 && b === 0 && c === 0)
101
+ return false;
102
+ if (a === 192 && b === 0 && c === 2)
103
+ return false;
104
+ if (a === 198 && b === 51 && c === 100)
105
+ return false;
106
+ if (a === 203 && b === 0 && c === 113)
107
+ return false;
108
+ return true;
109
+ }
110
+ function isPublicIpv6(value) {
111
+ const bytes = ipv6Bytes(value);
112
+ if (!bytes)
113
+ return false;
114
+ const mapped = bytes.subarray(0, 10).every((byte) => byte === 0) &&
115
+ bytes[10] === 0xff &&
116
+ bytes[11] === 0xff;
117
+ if (mapped)
118
+ return isPublicIpv4(`${bytes[12]}.${bytes[13]}.${bytes[14]}.${bytes[15]}`);
119
+ // Restrict callbacks to global unicast 2000::/3 and reject special transition/docs ranges.
120
+ if ((bytes[0] & 0xe0) !== 0x20)
121
+ return false;
122
+ if (bytes[0] === 0x20 && bytes[1] === 0x01 && bytes[2] === 0x0d && bytes[3] === 0xb8)
123
+ return false;
124
+ if (bytes[0] === 0x20 && bytes[1] === 0x01 && bytes[2] === 0x00 && bytes[3] === 0x00)
125
+ return false;
126
+ if (bytes[0] === 0x20 && bytes[1] === 0x02)
127
+ return false;
128
+ return true;
129
+ }
130
+ function ipv6Bytes(value) {
131
+ const normalized = unbracket(value).split("%", 1)[0];
132
+ const halves = normalized.split("::");
133
+ if (halves.length > 2)
134
+ return undefined;
135
+ const left = parseIpv6Half(halves[0]);
136
+ const right = parseIpv6Half(halves[1] ?? "");
137
+ if (!left || !right)
138
+ return undefined;
139
+ const missing = 8 - left.length - right.length;
140
+ if ((halves.length === 1 && missing !== 0) || (halves.length === 2 && missing < 1))
141
+ return undefined;
142
+ const words = [...left, ...Array.from({ length: missing }, () => 0), ...right];
143
+ if (words.length !== 8)
144
+ return undefined;
145
+ const bytes = new Uint8Array(16);
146
+ words.forEach((word, index) => {
147
+ bytes[index * 2] = word >> 8;
148
+ bytes[index * 2 + 1] = word & 0xff;
149
+ });
150
+ return bytes;
151
+ }
152
+ function parseIpv6Half(value) {
153
+ if (!value)
154
+ return [];
155
+ const parts = value.split(":");
156
+ const words = [];
157
+ for (const [index, part] of parts.entries()) {
158
+ if (part.includes(".")) {
159
+ if (index !== parts.length - 1 || !isIP(part))
160
+ return undefined;
161
+ const octets = part.split(".").map(Number);
162
+ words.push((octets[0] << 8) | octets[1], (octets[2] << 8) | octets[3]);
163
+ }
164
+ else {
165
+ if (!/^[a-f0-9]{1,4}$/i.test(part))
166
+ return undefined;
167
+ words.push(Number.parseInt(part, 16));
168
+ }
169
+ }
170
+ return words;
171
+ }
172
+ function unbracket(hostname) {
173
+ return hostname.startsWith("[") && hostname.endsWith("]") ? hostname.slice(1, -1) : hostname;
174
+ }
175
+ function deduplicate(addresses) {
176
+ const seen = new Set();
177
+ return addresses.filter(({ address, family }) => {
178
+ const key = `${family}:${address}`;
179
+ if (seen.has(key))
180
+ return false;
181
+ seen.add(key);
182
+ return true;
183
+ });
184
+ }
185
+ //# sourceMappingURL=ssrf.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ssrf.js","sourceRoot":"","sources":["../../../sources/modules/integrations/ssrf.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=ssrf.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ssrf.test.d.ts","sourceRoot":"","sources":["../../../sources/modules/integrations/ssrf.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,56 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { isPublicAddress, StrictWebhookUrlPolicy } from "./ssrf.js";
3
+ describe("StrictWebhookUrlPolicy", () => {
4
+ it("rejects non-HTTPS, credentials, local names, private addresses, and custom ports", () => {
5
+ const policy = new StrictWebhookUrlPolicy();
6
+ for (const url of [
7
+ "http://hooks.example.com/events",
8
+ "https://user:password@hooks.example.com/events",
9
+ "https://localhost/events",
10
+ "https://service.internal/events",
11
+ "https://127.0.0.1/events",
12
+ "https://10.1.2.3/events",
13
+ "https://[::1]/events",
14
+ "https://hooks.example.com:8443/events",
15
+ ]) {
16
+ expect(() => policy.validateForStorage(url), url).toThrow();
17
+ }
18
+ expect(policy.validateForStorage("https://hooks.example.com/events?version=1")).toBe("https://hooks.example.com/events?version=1");
19
+ expect(policy.validateForStorage("https://[2606:4700:4700::1111]/events")).toBe("https://[2606:4700:4700::1111]/events");
20
+ });
21
+ it("rejects DNS answers if any address is non-public and deduplicates safe answers", async () => {
22
+ const unsafe = new StrictWebhookUrlPolicy({
23
+ resolve: async () => [
24
+ { address: "8.8.8.8", family: 4 },
25
+ { address: "192.168.1.8", family: 4 },
26
+ ],
27
+ });
28
+ await expect(unsafe.resolveForDelivery("https://hooks.example.com/event")).rejects.toThrow("non-public");
29
+ const safe = new StrictWebhookUrlPolicy({
30
+ resolve: async () => [
31
+ { address: "8.8.8.8", family: 4 },
32
+ { address: "8.8.8.8", family: 4 },
33
+ { address: "2606:4700:4700::1111", family: 6 },
34
+ ],
35
+ });
36
+ await expect(safe.resolveForDelivery("https://hooks.example.com/event")).resolves.toEqual({
37
+ url: "https://hooks.example.com/event",
38
+ addresses: [
39
+ { address: "8.8.8.8", family: 4 },
40
+ { address: "2606:4700:4700::1111", family: 6 },
41
+ ],
42
+ });
43
+ });
44
+ });
45
+ describe("isPublicAddress", () => {
46
+ it("recognizes public addresses without allowing private or transition ranges", () => {
47
+ expect(isPublicAddress("8.8.8.8")).toBe(true);
48
+ expect(isPublicAddress("192.168.0.1")).toBe(false);
49
+ expect(isPublicAddress("203.0.113.1")).toBe(false);
50
+ expect(isPublicAddress("2606:4700:4700::1111")).toBe(true);
51
+ expect(isPublicAddress("fd00::1")).toBe(false);
52
+ expect(isPublicAddress("2001:db8::1")).toBe(false);
53
+ expect(isPublicAddress("::ffff:127.0.0.1")).toBe(false);
54
+ });
55
+ });
56
+ //# sourceMappingURL=ssrf.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ssrf.test.js","sourceRoot":"","sources":["../../../sources/modules/integrations/ssrf.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import type { WebhookTransport, WebhookTransportRequest, WebhookTransportResponse } from "./types.js";
2
+ export interface NodeWebhookTransportOptions {
3
+ timeoutMs?: number;
4
+ maximumRequestBytes?: number;
5
+ maximumResponseBytes?: number;
6
+ userAgent?: string;
7
+ }
8
+ /**
9
+ * Standard-library webhook transport. It never follows redirects and overrides
10
+ * DNS lookup with an address approved by StrictWebhookUrlPolicy, preserving the
11
+ * original hostname for Host and TLS certificate/SNI verification.
12
+ */
13
+ export declare class NodeWebhookTransport implements WebhookTransport {
14
+ private readonly timeoutMs;
15
+ private readonly maximumRequestBytes;
16
+ private readonly maximumResponseBytes;
17
+ private readonly userAgent;
18
+ constructor(options?: NodeWebhookTransportOptions);
19
+ deliver(input: WebhookTransportRequest): Promise<WebhookTransportResponse>;
20
+ }
21
+ //# sourceMappingURL=transport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../../sources/modules/integrations/transport.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACR,gBAAgB,EAChB,uBAAuB,EACvB,wBAAwB,EAC3B,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,2BAA2B;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;GAIG;AACH,qBAAa,oBAAqB,YAAW,gBAAgB;IACzD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAS;IAC7C,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAS;IAC9C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IAEnC,YAAY,OAAO,GAAE,2BAAgC,EAepD;IAEK,OAAO,CAAC,KAAK,EAAE,uBAAuB,GAAG,OAAO,CAAC,wBAAwB,CAAC,CAuF/E;CACJ"}