@tellescope/sdk 1.256.14 → 1.256.16

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 (293) hide show
  1. package/lib/cjs/sdk.d.ts +2 -2
  2. package/lib/cjs/tests/api_tests/auto_merge_form_submission.test.js +1 -1
  3. package/lib/cjs/tests/api_tests/auto_merge_form_submission.test.js.map +1 -1
  4. package/lib/cjs/tests/api_tests/enduser_observations_auto_review.test.d.ts +5 -0
  5. package/lib/cjs/tests/api_tests/enduser_observations_auto_review.test.d.ts.map +1 -0
  6. package/lib/cjs/tests/api_tests/enduser_observations_auto_review.test.js +388 -0
  7. package/lib/cjs/tests/api_tests/enduser_observations_auto_review.test.js.map +1 -0
  8. package/lib/cjs/tests/api_tests/integrations_redacted.test.js +3 -3
  9. package/lib/cjs/tests/api_tests/integrations_redacted.test.js.map +1 -1
  10. package/lib/cjs/tests/api_tests/organization_signup.test.d.ts +1 -1
  11. package/lib/cjs/tests/api_tests/organization_signup.test.js +1 -1
  12. package/lib/cjs/tests/api_tests/purchase_made_trigger.test.d.ts.map +1 -1
  13. package/lib/cjs/tests/api_tests/purchase_made_trigger.test.js +103 -162
  14. package/lib/cjs/tests/api_tests/purchase_made_trigger.test.js.map +1 -1
  15. package/lib/cjs/tests/api_tests/security/F-0200-form-logic-js-execution.test.d.ts +33 -0
  16. package/lib/cjs/tests/api_tests/security/F-0200-form-logic-js-execution.test.d.ts.map +1 -0
  17. package/lib/cjs/tests/api_tests/security/F-0200-form-logic-js-execution.test.js +249 -0
  18. package/lib/cjs/tests/api_tests/security/F-0200-form-logic-js-execution.test.js.map +1 -0
  19. package/lib/cjs/tests/api_tests/security/add-to-journey-foreign-enduserid.test.d.ts +42 -0
  20. package/lib/cjs/tests/api_tests/security/add-to-journey-foreign-enduserid.test.d.ts.map +1 -0
  21. package/lib/cjs/tests/api_tests/security/add-to-journey-foreign-enduserid.test.js +281 -0
  22. package/lib/cjs/tests/api_tests/security/add-to-journey-foreign-enduserid.test.js.map +1 -0
  23. package/lib/cjs/tests/api_tests/security/ai-conversations-rbac.test.d.ts +38 -0
  24. package/lib/cjs/tests/api_tests/security/ai-conversations-rbac.test.d.ts.map +1 -0
  25. package/lib/cjs/tests/api_tests/security/ai-conversations-rbac.test.js +390 -0
  26. package/lib/cjs/tests/api_tests/security/ai-conversations-rbac.test.js.map +1 -0
  27. package/lib/cjs/tests/api_tests/security/allowed-paths-confinement.test.d.ts +6 -0
  28. package/lib/cjs/tests/api_tests/security/allowed-paths-confinement.test.d.ts.map +1 -0
  29. package/lib/cjs/tests/api_tests/security/allowed-paths-confinement.test.js +1003 -0
  30. package/lib/cjs/tests/api_tests/security/allowed-paths-confinement.test.js.map +1 -0
  31. package/lib/cjs/tests/api_tests/security/automated-actions-process-gate.test.d.ts +42 -0
  32. package/lib/cjs/tests/api_tests/security/automated-actions-process-gate.test.d.ts.map +1 -0
  33. package/lib/cjs/tests/api_tests/security/automated-actions-process-gate.test.js +323 -0
  34. package/lib/cjs/tests/api_tests/security/automated-actions-process-gate.test.js.map +1 -0
  35. package/lib/cjs/tests/api_tests/security/booking-info-idor-token-mint.test.d.ts +29 -0
  36. package/lib/cjs/tests/api_tests/security/booking-info-idor-token-mint.test.d.ts.map +1 -0
  37. package/lib/cjs/tests/api_tests/security/booking-info-idor-token-mint.test.js +335 -0
  38. package/lib/cjs/tests/api_tests/security/booking-info-idor-token-mint.test.js.map +1 -0
  39. package/lib/cjs/tests/api_tests/security/cascade-role-rename-cross-tenant.test.d.ts +32 -0
  40. package/lib/cjs/tests/api_tests/security/cascade-role-rename-cross-tenant.test.d.ts.map +1 -0
  41. package/lib/cjs/tests/api_tests/security/cascade-role-rename-cross-tenant.test.js +237 -0
  42. package/lib/cjs/tests/api_tests/security/cascade-role-rename-cross-tenant.test.js.map +1 -0
  43. package/lib/cjs/tests/api_tests/security/data-sync-redaction-bypass.test.d.ts +28 -0
  44. package/lib/cjs/tests/api_tests/security/data-sync-redaction-bypass.test.d.ts.map +1 -0
  45. package/lib/cjs/tests/api_tests/security/data-sync-redaction-bypass.test.js +349 -0
  46. package/lib/cjs/tests/api_tests/security/data-sync-redaction-bypass.test.js.map +1 -0
  47. package/lib/cjs/tests/api_tests/security/develop-health-benefit-verification-rbac.test.d.ts +30 -0
  48. package/lib/cjs/tests/api_tests/security/develop-health-benefit-verification-rbac.test.d.ts.map +1 -0
  49. package/lib/cjs/tests/api_tests/security/develop-health-benefit-verification-rbac.test.js +314 -0
  50. package/lib/cjs/tests/api_tests/security/develop-health-benefit-verification-rbac.test.js.map +1 -0
  51. package/lib/cjs/tests/api_tests/security/enduser-cross-create.test.d.ts +21 -0
  52. package/lib/cjs/tests/api_tests/security/enduser-cross-create.test.d.ts.map +1 -0
  53. package/lib/cjs/tests/api_tests/security/enduser-cross-create.test.js +362 -0
  54. package/lib/cjs/tests/api_tests/security/enduser-cross-create.test.js.map +1 -0
  55. package/lib/cjs/tests/api_tests/security/enduser-write-restrictions.test.d.ts +21 -0
  56. package/lib/cjs/tests/api_tests/security/enduser-write-restrictions.test.d.ts.map +1 -0
  57. package/lib/cjs/tests/api_tests/security/enduser-write-restrictions.test.js +366 -0
  58. package/lib/cjs/tests/api_tests/security/enduser-write-restrictions.test.js.map +1 -0
  59. package/lib/cjs/tests/api_tests/security/file-link-session-confinement.test.d.ts +5 -0
  60. package/lib/cjs/tests/api_tests/security/file-link-session-confinement.test.d.ts.map +1 -0
  61. package/lib/cjs/tests/api_tests/security/file-link-session-confinement.test.js +357 -0
  62. package/lib/cjs/tests/api_tests/security/file-link-session-confinement.test.js.map +1 -0
  63. package/lib/cjs/tests/api_tests/security/form-logic-js-execution.test.d.ts +32 -0
  64. package/lib/cjs/tests/api_tests/security/form-logic-js-execution.test.d.ts.map +1 -0
  65. package/lib/cjs/tests/api_tests/security/form-logic-js-execution.test.js +248 -0
  66. package/lib/cjs/tests/api_tests/security/form-logic-js-execution.test.js.map +1 -0
  67. package/lib/cjs/tests/api_tests/security/globalunique-conflict-redaction.test.d.ts +19 -0
  68. package/lib/cjs/tests/api_tests/security/globalunique-conflict-redaction.test.d.ts.map +1 -0
  69. package/lib/cjs/tests/api_tests/security/globalunique-conflict-redaction.test.js +138 -0
  70. package/lib/cjs/tests/api_tests/security/globalunique-conflict-redaction.test.js.map +1 -0
  71. package/lib/cjs/tests/api_tests/security/handle-incoming-communication-cross-tenant.test.d.ts +24 -0
  72. package/lib/cjs/tests/api_tests/security/handle-incoming-communication-cross-tenant.test.d.ts.map +1 -0
  73. package/lib/cjs/tests/api_tests/security/handle-incoming-communication-cross-tenant.test.js +201 -0
  74. package/lib/cjs/tests/api_tests/security/handle-incoming-communication-cross-tenant.test.js.map +1 -0
  75. package/lib/cjs/tests/api_tests/security/invite-user-enumeration.test.d.ts +29 -0
  76. package/lib/cjs/tests/api_tests/security/invite-user-enumeration.test.d.ts.map +1 -0
  77. package/lib/cjs/tests/api_tests/security/invite-user-enumeration.test.js +278 -0
  78. package/lib/cjs/tests/api_tests/security/invite-user-enumeration.test.js.map +1 -0
  79. package/lib/cjs/tests/api_tests/security/load-inbox-redaction.test.d.ts +17 -0
  80. package/lib/cjs/tests/api_tests/security/load-inbox-redaction.test.d.ts.map +1 -0
  81. package/lib/cjs/tests/api_tests/security/load-inbox-redaction.test.js +155 -0
  82. package/lib/cjs/tests/api_tests/security/load-inbox-redaction.test.js.map +1 -0
  83. package/lib/cjs/tests/api_tests/security/prototype-pollution.test.d.ts +2 -0
  84. package/lib/cjs/tests/api_tests/security/prototype-pollution.test.d.ts.map +1 -0
  85. package/lib/cjs/tests/api_tests/security/prototype-pollution.test.js +88 -0
  86. package/lib/cjs/tests/api_tests/security/prototype-pollution.test.js.map +1 -0
  87. package/lib/cjs/tests/api_tests/security/proxy-image-unauth-ssrf.test.d.ts +34 -0
  88. package/lib/cjs/tests/api_tests/security/proxy-image-unauth-ssrf.test.d.ts.map +1 -0
  89. package/lib/cjs/tests/api_tests/security/proxy-image-unauth-ssrf.test.js +230 -0
  90. package/lib/cjs/tests/api_tests/security/proxy-image-unauth-ssrf.test.js.map +1 -0
  91. package/lib/cjs/tests/api_tests/security/sanitize-user-html-with-iframes.test.d.ts +2 -0
  92. package/lib/cjs/tests/api_tests/security/sanitize-user-html-with-iframes.test.d.ts.map +1 -0
  93. package/lib/cjs/tests/api_tests/security/sanitize-user-html-with-iframes.test.js +242 -0
  94. package/lib/cjs/tests/api_tests/security/sanitize-user-html-with-iframes.test.js.map +1 -0
  95. package/lib/cjs/tests/api_tests/security/sanitize-user-html.test.d.ts +2 -0
  96. package/lib/cjs/tests/api_tests/security/sanitize-user-html.test.d.ts.map +1 -0
  97. package/lib/cjs/tests/api_tests/security/sanitize-user-html.test.js +148 -0
  98. package/lib/cjs/tests/api_tests/security/sanitize-user-html.test.js.map +1 -0
  99. package/lib/cjs/tests/api_tests/security/schema-adminonly-enforcement.test.d.ts +45 -0
  100. package/lib/cjs/tests/api_tests/security/schema-adminonly-enforcement.test.d.ts.map +1 -0
  101. package/lib/cjs/tests/api_tests/security/schema-adminonly-enforcement.test.js +388 -0
  102. package/lib/cjs/tests/api_tests/security/schema-adminonly-enforcement.test.js.map +1 -0
  103. package/lib/cjs/tests/api_tests/security/self-admin-role-assignment.test.d.ts +38 -0
  104. package/lib/cjs/tests/api_tests/security/self-admin-role-assignment.test.d.ts.map +1 -0
  105. package/lib/cjs/tests/api_tests/security/self-admin-role-assignment.test.js +222 -0
  106. package/lib/cjs/tests/api_tests/security/self-admin-role-assignment.test.js.map +1 -0
  107. package/lib/cjs/tests/api_tests/security/startlinktoken-enduser-staff-escalation.test.d.ts +6 -0
  108. package/lib/cjs/tests/api_tests/security/startlinktoken-enduser-staff-escalation.test.d.ts.map +1 -0
  109. package/lib/cjs/tests/api_tests/security/startlinktoken-enduser-staff-escalation.test.js +354 -0
  110. package/lib/cjs/tests/api_tests/security/startlinktoken-enduser-staff-escalation.test.js.map +1 -0
  111. package/lib/cjs/tests/api_tests/security/webhook-outbound-ssrf.test.d.ts +28 -0
  112. package/lib/cjs/tests/api_tests/security/webhook-outbound-ssrf.test.d.ts.map +1 -0
  113. package/lib/cjs/tests/api_tests/security/webhook-outbound-ssrf.test.js +442 -0
  114. package/lib/cjs/tests/api_tests/security/webhook-outbound-ssrf.test.js.map +1 -0
  115. package/lib/cjs/tests/api_tests/security/webhook-timeout.test.d.ts +19 -0
  116. package/lib/cjs/tests/api_tests/security/webhook-timeout.test.d.ts.map +1 -0
  117. package/lib/cjs/tests/api_tests/security/webhook-timeout.test.js +156 -0
  118. package/lib/cjs/tests/api_tests/security/webhook-timeout.test.js.map +1 -0
  119. package/lib/cjs/tests/api_tests/webhook_error_handling.test.js +2 -2
  120. package/lib/cjs/tests/api_tests/webhook_error_handling.test.js.map +1 -1
  121. package/lib/cjs/tests/tests.d.ts.map +1 -1
  122. package/lib/cjs/tests/tests.js +60 -46
  123. package/lib/cjs/tests/tests.js.map +1 -1
  124. package/lib/cjs/tests/unit_tests/openapi_spec_freshness.test.d.ts +1 -1
  125. package/lib/cjs/tests/unit_tests/openapi_spec_freshness.test.js +1 -1
  126. package/lib/cjs/tsconfig.cjs.tsbuildinfo +1 -0
  127. package/lib/esm/enduser.d.ts +0 -1
  128. package/lib/esm/enduser.d.ts.map +1 -1
  129. package/lib/esm/sdk.d.ts +4 -5
  130. package/lib/esm/sdk.d.ts.map +1 -1
  131. package/lib/esm/session.d.ts +0 -1
  132. package/lib/esm/session.d.ts.map +1 -1
  133. package/lib/esm/tests/api_tests/auto_merge_form_submission.test.js +1 -1
  134. package/lib/esm/tests/api_tests/auto_merge_form_submission.test.js.map +1 -1
  135. package/lib/esm/tests/api_tests/enduser_observations_auto_review.test.d.ts +5 -0
  136. package/lib/esm/tests/api_tests/enduser_observations_auto_review.test.d.ts.map +1 -0
  137. package/lib/esm/tests/api_tests/enduser_observations_auto_review.test.js +383 -0
  138. package/lib/esm/tests/api_tests/enduser_observations_auto_review.test.js.map +1 -0
  139. package/lib/esm/tests/api_tests/integrations_redacted.test.js +3 -3
  140. package/lib/esm/tests/api_tests/integrations_redacted.test.js.map +1 -1
  141. package/lib/esm/tests/api_tests/organization_signup.test.d.ts +1 -1
  142. package/lib/esm/tests/api_tests/organization_signup.test.js +1 -1
  143. package/lib/esm/tests/api_tests/purchase_made_trigger.test.d.ts.map +1 -1
  144. package/lib/esm/tests/api_tests/purchase_made_trigger.test.js +104 -163
  145. package/lib/esm/tests/api_tests/purchase_made_trigger.test.js.map +1 -1
  146. package/lib/esm/tests/api_tests/security/F-0200-form-logic-js-execution.test.d.ts +33 -0
  147. package/lib/esm/tests/api_tests/security/F-0200-form-logic-js-execution.test.d.ts.map +1 -0
  148. package/lib/esm/tests/api_tests/security/F-0200-form-logic-js-execution.test.js +244 -0
  149. package/lib/esm/tests/api_tests/security/F-0200-form-logic-js-execution.test.js.map +1 -0
  150. package/lib/esm/tests/api_tests/security/add-to-journey-foreign-enduserid.test.d.ts +42 -0
  151. package/lib/esm/tests/api_tests/security/add-to-journey-foreign-enduserid.test.d.ts.map +1 -0
  152. package/lib/esm/tests/api_tests/security/add-to-journey-foreign-enduserid.test.js +276 -0
  153. package/lib/esm/tests/api_tests/security/add-to-journey-foreign-enduserid.test.js.map +1 -0
  154. package/lib/esm/tests/api_tests/security/ai-conversations-rbac.test.d.ts +38 -0
  155. package/lib/esm/tests/api_tests/security/ai-conversations-rbac.test.d.ts.map +1 -0
  156. package/lib/esm/tests/api_tests/security/ai-conversations-rbac.test.js +386 -0
  157. package/lib/esm/tests/api_tests/security/ai-conversations-rbac.test.js.map +1 -0
  158. package/lib/esm/tests/api_tests/security/allowed-paths-confinement.test.d.ts +6 -0
  159. package/lib/esm/tests/api_tests/security/allowed-paths-confinement.test.d.ts.map +1 -0
  160. package/lib/esm/tests/api_tests/security/allowed-paths-confinement.test.js +996 -0
  161. package/lib/esm/tests/api_tests/security/allowed-paths-confinement.test.js.map +1 -0
  162. package/lib/esm/tests/api_tests/security/automated-actions-process-gate.test.d.ts +42 -0
  163. package/lib/esm/tests/api_tests/security/automated-actions-process-gate.test.d.ts.map +1 -0
  164. package/lib/esm/tests/api_tests/security/automated-actions-process-gate.test.js +316 -0
  165. package/lib/esm/tests/api_tests/security/automated-actions-process-gate.test.js.map +1 -0
  166. package/lib/esm/tests/api_tests/security/booking-info-idor-token-mint.test.d.ts +29 -0
  167. package/lib/esm/tests/api_tests/security/booking-info-idor-token-mint.test.d.ts.map +1 -0
  168. package/lib/esm/tests/api_tests/security/booking-info-idor-token-mint.test.js +331 -0
  169. package/lib/esm/tests/api_tests/security/booking-info-idor-token-mint.test.js.map +1 -0
  170. package/lib/esm/tests/api_tests/security/cascade-role-rename-cross-tenant.test.d.ts +32 -0
  171. package/lib/esm/tests/api_tests/security/cascade-role-rename-cross-tenant.test.d.ts.map +1 -0
  172. package/lib/esm/tests/api_tests/security/cascade-role-rename-cross-tenant.test.js +233 -0
  173. package/lib/esm/tests/api_tests/security/cascade-role-rename-cross-tenant.test.js.map +1 -0
  174. package/lib/esm/tests/api_tests/security/data-sync-redaction-bypass.test.d.ts +28 -0
  175. package/lib/esm/tests/api_tests/security/data-sync-redaction-bypass.test.d.ts.map +1 -0
  176. package/lib/esm/tests/api_tests/security/data-sync-redaction-bypass.test.js +345 -0
  177. package/lib/esm/tests/api_tests/security/data-sync-redaction-bypass.test.js.map +1 -0
  178. package/lib/esm/tests/api_tests/security/develop-health-benefit-verification-rbac.test.d.ts +30 -0
  179. package/lib/esm/tests/api_tests/security/develop-health-benefit-verification-rbac.test.d.ts.map +1 -0
  180. package/lib/esm/tests/api_tests/security/develop-health-benefit-verification-rbac.test.js +310 -0
  181. package/lib/esm/tests/api_tests/security/develop-health-benefit-verification-rbac.test.js.map +1 -0
  182. package/lib/esm/tests/api_tests/security/enduser-cross-create.test.d.ts +21 -0
  183. package/lib/esm/tests/api_tests/security/enduser-cross-create.test.d.ts.map +1 -0
  184. package/lib/esm/tests/api_tests/security/enduser-cross-create.test.js +358 -0
  185. package/lib/esm/tests/api_tests/security/enduser-cross-create.test.js.map +1 -0
  186. package/lib/esm/tests/api_tests/security/enduser-write-restrictions.test.d.ts +21 -0
  187. package/lib/esm/tests/api_tests/security/enduser-write-restrictions.test.d.ts.map +1 -0
  188. package/lib/esm/tests/api_tests/security/enduser-write-restrictions.test.js +362 -0
  189. package/lib/esm/tests/api_tests/security/enduser-write-restrictions.test.js.map +1 -0
  190. package/lib/esm/tests/api_tests/security/file-link-session-confinement.test.d.ts +5 -0
  191. package/lib/esm/tests/api_tests/security/file-link-session-confinement.test.d.ts.map +1 -0
  192. package/lib/esm/tests/api_tests/security/file-link-session-confinement.test.js +349 -0
  193. package/lib/esm/tests/api_tests/security/file-link-session-confinement.test.js.map +1 -0
  194. package/lib/esm/tests/api_tests/security/form-logic-js-execution.test.d.ts +32 -0
  195. package/lib/esm/tests/api_tests/security/form-logic-js-execution.test.d.ts.map +1 -0
  196. package/lib/esm/tests/api_tests/security/form-logic-js-execution.test.js +243 -0
  197. package/lib/esm/tests/api_tests/security/form-logic-js-execution.test.js.map +1 -0
  198. package/lib/esm/tests/api_tests/security/globalunique-conflict-redaction.test.d.ts +19 -0
  199. package/lib/esm/tests/api_tests/security/globalunique-conflict-redaction.test.d.ts.map +1 -0
  200. package/lib/esm/tests/api_tests/security/globalunique-conflict-redaction.test.js +134 -0
  201. package/lib/esm/tests/api_tests/security/globalunique-conflict-redaction.test.js.map +1 -0
  202. package/lib/esm/tests/api_tests/security/handle-incoming-communication-cross-tenant.test.d.ts +24 -0
  203. package/lib/esm/tests/api_tests/security/handle-incoming-communication-cross-tenant.test.d.ts.map +1 -0
  204. package/lib/esm/tests/api_tests/security/handle-incoming-communication-cross-tenant.test.js +194 -0
  205. package/lib/esm/tests/api_tests/security/handle-incoming-communication-cross-tenant.test.js.map +1 -0
  206. package/lib/esm/tests/api_tests/security/invite-user-enumeration.test.d.ts +29 -0
  207. package/lib/esm/tests/api_tests/security/invite-user-enumeration.test.d.ts.map +1 -0
  208. package/lib/esm/tests/api_tests/security/invite-user-enumeration.test.js +271 -0
  209. package/lib/esm/tests/api_tests/security/invite-user-enumeration.test.js.map +1 -0
  210. package/lib/esm/tests/api_tests/security/load-inbox-redaction.test.d.ts +17 -0
  211. package/lib/esm/tests/api_tests/security/load-inbox-redaction.test.d.ts.map +1 -0
  212. package/lib/esm/tests/api_tests/security/load-inbox-redaction.test.js +151 -0
  213. package/lib/esm/tests/api_tests/security/load-inbox-redaction.test.js.map +1 -0
  214. package/lib/esm/tests/api_tests/security/prototype-pollution.test.d.ts +2 -0
  215. package/lib/esm/tests/api_tests/security/prototype-pollution.test.d.ts.map +1 -0
  216. package/lib/esm/tests/api_tests/security/prototype-pollution.test.js +84 -0
  217. package/lib/esm/tests/api_tests/security/prototype-pollution.test.js.map +1 -0
  218. package/lib/esm/tests/api_tests/security/proxy-image-unauth-ssrf.test.d.ts +34 -0
  219. package/lib/esm/tests/api_tests/security/proxy-image-unauth-ssrf.test.d.ts.map +1 -0
  220. package/lib/esm/tests/api_tests/security/proxy-image-unauth-ssrf.test.js +223 -0
  221. package/lib/esm/tests/api_tests/security/proxy-image-unauth-ssrf.test.js.map +1 -0
  222. package/lib/esm/tests/api_tests/security/sanitize-user-html-with-iframes.test.d.ts +2 -0
  223. package/lib/esm/tests/api_tests/security/sanitize-user-html-with-iframes.test.d.ts.map +1 -0
  224. package/lib/esm/tests/api_tests/security/sanitize-user-html-with-iframes.test.js +238 -0
  225. package/lib/esm/tests/api_tests/security/sanitize-user-html-with-iframes.test.js.map +1 -0
  226. package/lib/esm/tests/api_tests/security/sanitize-user-html.test.d.ts +2 -0
  227. package/lib/esm/tests/api_tests/security/sanitize-user-html.test.d.ts.map +1 -0
  228. package/lib/esm/tests/api_tests/security/sanitize-user-html.test.js +144 -0
  229. package/lib/esm/tests/api_tests/security/sanitize-user-html.test.js.map +1 -0
  230. package/lib/esm/tests/api_tests/security/schema-adminonly-enforcement.test.d.ts +45 -0
  231. package/lib/esm/tests/api_tests/security/schema-adminonly-enforcement.test.d.ts.map +1 -0
  232. package/lib/esm/tests/api_tests/security/schema-adminonly-enforcement.test.js +381 -0
  233. package/lib/esm/tests/api_tests/security/schema-adminonly-enforcement.test.js.map +1 -0
  234. package/lib/esm/tests/api_tests/security/self-admin-role-assignment.test.d.ts +38 -0
  235. package/lib/esm/tests/api_tests/security/self-admin-role-assignment.test.d.ts.map +1 -0
  236. package/lib/esm/tests/api_tests/security/self-admin-role-assignment.test.js +218 -0
  237. package/lib/esm/tests/api_tests/security/self-admin-role-assignment.test.js.map +1 -0
  238. package/lib/esm/tests/api_tests/security/startlinktoken-enduser-staff-escalation.test.d.ts +6 -0
  239. package/lib/esm/tests/api_tests/security/startlinktoken-enduser-staff-escalation.test.d.ts.map +1 -0
  240. package/lib/esm/tests/api_tests/security/startlinktoken-enduser-staff-escalation.test.js +350 -0
  241. package/lib/esm/tests/api_tests/security/startlinktoken-enduser-staff-escalation.test.js.map +1 -0
  242. package/lib/esm/tests/api_tests/security/webhook-outbound-ssrf.test.d.ts +28 -0
  243. package/lib/esm/tests/api_tests/security/webhook-outbound-ssrf.test.d.ts.map +1 -0
  244. package/lib/esm/tests/api_tests/security/webhook-outbound-ssrf.test.js +435 -0
  245. package/lib/esm/tests/api_tests/security/webhook-outbound-ssrf.test.js.map +1 -0
  246. package/lib/esm/tests/api_tests/security/webhook-timeout.test.d.ts +19 -0
  247. package/lib/esm/tests/api_tests/security/webhook-timeout.test.d.ts.map +1 -0
  248. package/lib/esm/tests/api_tests/security/webhook-timeout.test.js +149 -0
  249. package/lib/esm/tests/api_tests/security/webhook-timeout.test.js.map +1 -0
  250. package/lib/esm/tests/api_tests/webhook_error_handling.test.js +2 -2
  251. package/lib/esm/tests/api_tests/webhook_error_handling.test.js.map +1 -1
  252. package/lib/esm/tests/tests.d.ts.map +1 -1
  253. package/lib/esm/tests/tests.js +38 -24
  254. package/lib/esm/tests/tests.js.map +1 -1
  255. package/lib/esm/tests/unit_tests/openapi_spec_freshness.test.d.ts +1 -1
  256. package/lib/esm/tests/unit_tests/openapi_spec_freshness.test.js +1 -1
  257. package/lib/tsconfig.tsbuildinfo +1 -1
  258. package/package.json +10 -10
  259. package/src/tests/api_tests/auto_merge_form_submission.test.ts +1 -1
  260. package/src/tests/api_tests/enduser_observations_auto_review.test.ts +358 -0
  261. package/src/tests/api_tests/integrations_redacted.test.ts +1 -1
  262. package/src/tests/api_tests/organization_signup.test.ts +2 -2
  263. package/src/tests/api_tests/purchase_made_trigger.test.ts +29 -41
  264. package/src/tests/api_tests/security/{F-0196-add-to-journey-foreign-enduserid.test.ts → add-to-journey-foreign-enduserid.test.ts} +6 -7
  265. package/src/tests/api_tests/security/{F-0005-ai-conversations-rbac.test.ts → ai-conversations-rbac.test.ts} +14 -14
  266. package/src/tests/api_tests/security/{F-0166-allowed-paths-wildcard-bypass.test.ts → allowed-paths-confinement.test.ts} +11 -11
  267. package/src/tests/api_tests/security/{F-0192-automated-actions-process-gate.test.ts → automated-actions-process-gate.test.ts} +6 -7
  268. package/src/tests/api_tests/security/{F-0179-booking-info-idor-token-mint.test.ts → booking-info-idor-token-mint.test.ts} +5 -6
  269. package/src/tests/api_tests/security/{F-0053-cascade-role-rename-cross-tenant.test.ts → cascade-role-rename-cross-tenant.test.ts} +10 -10
  270. package/src/tests/api_tests/security/{F-0001-data-sync-redaction-bypass.test.ts → data-sync-redaction-bypass.test.ts} +9 -9
  271. package/src/tests/api_tests/security/{F-0006-develop-health-benefit-verification-rbac.test.ts → develop-health-benefit-verification-rbac.test.ts} +7 -8
  272. package/src/tests/api_tests/security/{F-0116-F-0119-enduser-cross-create.test.ts → enduser-cross-create.test.ts} +25 -25
  273. package/src/tests/api_tests/security/{F-0106-F-0110-enduser-write-restrictions.test.ts → enduser-write-restrictions.test.ts} +12 -14
  274. package/src/tests/api_tests/security/file-link-session-confinement.test.ts +291 -0
  275. package/src/tests/api_tests/security/form-logic-js-execution.test.ts +183 -0
  276. package/src/tests/api_tests/security/{F-0145-globalunique-leak.test.ts → globalunique-conflict-redaction.test.ts} +5 -6
  277. package/src/tests/api_tests/security/{F-0008-handle-incoming-communication-cross-tenant.test.ts → handle-incoming-communication-cross-tenant.test.ts} +8 -8
  278. package/src/tests/api_tests/security/{F-0007-invite-user-enumeration.test.ts → invite-user-enumeration.test.ts} +8 -8
  279. package/src/tests/api_tests/security/{F-0151-load-inbox-redaction.test.ts → load-inbox-redaction.test.ts} +5 -6
  280. package/src/tests/api_tests/security/{F-0016-prototype-pollution.test.ts → prototype-pollution.test.ts} +4 -4
  281. package/src/tests/api_tests/security/{F-0025-proxy-image-unauth-ssrf.test.ts → proxy-image-unauth-ssrf.test.ts} +11 -12
  282. package/src/tests/api_tests/security/{F-0013-sanitize-user-html-with-iframes.test.ts → sanitize-user-html-with-iframes.test.ts} +5 -5
  283. package/src/tests/api_tests/security/{F-0013-sanitize-user-html.test.ts → sanitize-user-html.test.ts} +4 -4
  284. package/src/tests/api_tests/security/{F-0191-schema-adminonly-enforcement.test.ts → schema-adminonly-enforcement.test.ts} +6 -7
  285. package/src/tests/api_tests/security/{F-0076-self-admin-role-assignment.test.ts → self-admin-role-assignment.test.ts} +13 -13
  286. package/src/tests/api_tests/security/{F-0185-startlinktoken-enduser-staff-escalation.test.ts → startlinktoken-enduser-staff-escalation.test.ts} +6 -6
  287. package/src/tests/api_tests/security/{F-0015-webhook-outbound-ssrf.test.ts → webhook-outbound-ssrf.test.ts} +13 -14
  288. package/src/tests/api_tests/security/{F-0155-webhook-timeout.test.ts → webhook-timeout.test.ts} +6 -7
  289. package/src/tests/api_tests/webhook_error_handling.test.ts +1 -1
  290. package/src/tests/tests.ts +43 -24
  291. package/src/tests/unit_tests/openapi_spec_freshness.test.ts +1 -1
  292. package/test_generated.pdf +0 -0
  293. package/src/tests/api_tests/security/readonly-enduser-preview.test.ts +0 -301
@@ -0,0 +1,28 @@
1
+ import { Session } from "../../../sdk";
2
+ /**
3
+ * Regression tests: outbound webhook delivery must refuse internal destinations.
4
+ *
5
+ * Outbound webhooks request customer-configured URLs that are validated only for SYNTAX
6
+ * (urlValidator -> validator.isURL, which happily accepts http://10.0.0.1/). Four call sites are
7
+ * affected: api/modules/webhooks.ts:145, :214, :270, and the five-method block at api/v1/api.ts:9723.
8
+ *
9
+ * Two properties make this worse than a blind SSRF:
10
+ * - A non-2xx response body is stored in log.response, and webhook_logs is surfaced to customers for
11
+ * debugging — so an internal endpoint's error body is readable by the tenant that configured it.
12
+ * - The automation send-webhook action builds its URL at runtime through five nested template
13
+ * replacers over action.info.url, so patient-controlled field values can reach the destination.
14
+ *
15
+ * And critically: axios@0.30.2 follows redirects by default (maxRedirects: 5). A pre-flight check on
16
+ * the configured URL is therefore NOT sufficient — a receiver can simply 302 to an internal address
17
+ * after validation has already passed. T4 exists to prove exactly that, which is why the fix has to
18
+ * validate at connect time (a guarded agent) rather than as a string check.
19
+ *
20
+ * Each test below asserts ABSENCE ("the sentinel was never contacted"), which passes trivially if the
21
+ * request never happened at all — a missing allowlist entry, a webhook that never fired, a broken
22
+ * subscription. So each is paired with a positive control that proves the attempt really was made.
23
+ */
24
+ export declare const webhook_outbound_ssrf_tests: ({ sdk }: {
25
+ sdk: Session;
26
+ sdkNonAdmin: Session;
27
+ }) => Promise<void>;
28
+ //# sourceMappingURL=webhook-outbound-ssrf.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhook-outbound-ssrf.test.d.ts","sourceRoot":"","sources":["../../../../../src/tests/api_tests/security/webhook-outbound-ssrf.test.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAyEtC;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,2BAA2B;SAA2B,OAAO;iBAAe,OAAO;mBA0K/F,CAAA"}
@@ -0,0 +1,442 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __generator = (this && this.__generator) || function (thisArg, body) {
12
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
13
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14
+ function verb(n) { return function (v) { return step([n, v]); }; }
15
+ function step(op) {
16
+ if (f) throw new TypeError("Generator is already executing.");
17
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
18
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
19
+ if (y = 0, t) op = [op[0] & 2, t.value];
20
+ switch (op[0]) {
21
+ case 0: case 1: t = op; break;
22
+ case 4: _.label++; return { value: op[1], done: false };
23
+ case 5: _.label++; y = op[1]; op = [0]; continue;
24
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
25
+ default:
26
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30
+ if (t[2]) _.ops.pop();
31
+ _.trys.pop(); continue;
32
+ }
33
+ op = body.call(thisArg, _);
34
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36
+ }
37
+ };
38
+ var __importDefault = (this && this.__importDefault) || function (mod) {
39
+ return (mod && mod.__esModule) ? mod : { "default": mod };
40
+ };
41
+ Object.defineProperty(exports, "__esModule", { value: true });
42
+ exports.webhook_outbound_ssrf_tests = void 0;
43
+ require('source-map-support').install();
44
+ var http_1 = __importDefault(require("http"));
45
+ var os_1 = __importDefault(require("os"));
46
+ var sdk_1 = require("../../../sdk");
47
+ var testing_1 = require("@tellescope/testing");
48
+ var setup_1 = require("../../setup");
49
+ var host = process.env.API_URL || 'http://localhost:8080';
50
+ var LOCAL_HOSTNAMES = ['localhost', '127.0.0.1', '::1'];
51
+ var TEST_SECRET = "f0015 outbound ssrf test secret";
52
+ /**
53
+ * The sentinel — the destination that must NEVER be reached — is bound to this machine's own RFC1918
54
+ * address rather than to loopback, and that choice is load-bearing.
55
+ *
56
+ * Loopback is deliberately permitted outside prod/staging (see api/modules/outbound_url.ts), because
57
+ * several test suites bind their receivers with `listen(0, '127.0.0.1')` and an ephemeral port cannot be
58
+ * allowlisted ahead of time. A loopback sentinel would therefore be ALLOWED in exactly the environment
59
+ * where this test runs, and "the sentinel was not contacted" would pass by allowance while proving
60
+ * nothing.
61
+ *
62
+ * RFC1918 is refused in every environment, so binding there keeps the assertion meaningful AND keeps a
63
+ * real listener present — which is what lets us prove non-delivery by observation rather than by
64
+ * reading a log message.
65
+ */
66
+ var first_private_ipv4 = function () {
67
+ for (var _i = 0, _a = Object.values(os_1.default.networkInterfaces()); _i < _a.length; _i++) {
68
+ var addresses = _a[_i];
69
+ for (var _b = 0, _c = addresses !== null && addresses !== void 0 ? addresses : []; _b < _c.length; _b++) {
70
+ var address = _c[_b];
71
+ if (address.family !== 'IPv4' || address.internal)
72
+ continue;
73
+ if (/^10\./.test(address.address))
74
+ return address.address;
75
+ if (/^192\.168\./.test(address.address))
76
+ return address.address;
77
+ if (/^172\.(1[6-9]|2\d|3[01])\./.test(address.address))
78
+ return address.address;
79
+ }
80
+ }
81
+ return undefined;
82
+ };
83
+ /**
84
+ * 127.0.0.1 only means "the machine running this test" when the API is also local. Against staging or
85
+ * prod it is the API server itself — the sentinel would never be contacted, every assertion here would
86
+ * pass for the wrong reason, and we would be creating a real webhook in a live tenant. Fail loudly.
87
+ */
88
+ var assert_local_api = function () {
89
+ var hostname = new URL(host).hostname;
90
+ if (!LOCAL_HOSTNAMES.includes(hostname)) {
91
+ throw new Error("SSRF tests must run against a local API (got ".concat(host, "). ")
92
+ + "127.0.0.1 would resolve to the API server rather than this machine, and this test configures a webhook.");
93
+ }
94
+ };
95
+ var listen = function (server, address) { return new Promise(function (resolve, reject) {
96
+ server.once('error', reject);
97
+ server.listen(0, address, function () { return resolve(); }); // ephemeral port — nothing here needs a fixed one
98
+ }); };
99
+ var port_of = function (server) { return server.address().port; };
100
+ /** Webhook delivery is fire-and-forget, so absence has to be established by waiting. */
101
+ var settle = function (ms) { return new Promise(function (resolve) { return setTimeout(resolve, ms); }); };
102
+ var wait_until = function (predicate, ms) { return __awaiter(void 0, void 0, void 0, function () {
103
+ var deadline;
104
+ return __generator(this, function (_a) {
105
+ switch (_a.label) {
106
+ case 0:
107
+ deadline = Date.now() + ms;
108
+ _a.label = 1;
109
+ case 1:
110
+ if (!(Date.now() < deadline)) return [3 /*break*/, 3];
111
+ if (predicate())
112
+ return [2 /*return*/, true];
113
+ return [4 /*yield*/, settle(100)];
114
+ case 2:
115
+ _a.sent();
116
+ return [3 /*break*/, 1];
117
+ case 3: return [2 /*return*/, predicate()];
118
+ }
119
+ });
120
+ }); };
121
+ /**
122
+ * Regression tests: outbound webhook delivery must refuse internal destinations.
123
+ *
124
+ * Outbound webhooks request customer-configured URLs that are validated only for SYNTAX
125
+ * (urlValidator -> validator.isURL, which happily accepts http://10.0.0.1/). Four call sites are
126
+ * affected: api/modules/webhooks.ts:145, :214, :270, and the five-method block at api/v1/api.ts:9723.
127
+ *
128
+ * Two properties make this worse than a blind SSRF:
129
+ * - A non-2xx response body is stored in log.response, and webhook_logs is surfaced to customers for
130
+ * debugging — so an internal endpoint's error body is readable by the tenant that configured it.
131
+ * - The automation send-webhook action builds its URL at runtime through five nested template
132
+ * replacers over action.info.url, so patient-controlled field values can reach the destination.
133
+ *
134
+ * And critically: axios@0.30.2 follows redirects by default (maxRedirects: 5). A pre-flight check on
135
+ * the configured URL is therefore NOT sufficient — a receiver can simply 302 to an internal address
136
+ * after validation has already passed. T4 exists to prove exactly that, which is why the fix has to
137
+ * validate at connect time (a guarded agent) rather than as a string check.
138
+ *
139
+ * Each test below asserts ABSENCE ("the sentinel was never contacted"), which passes trivially if the
140
+ * request never happened at all — a missing allowlist entry, a webhook that never fired, a broken
141
+ * subscription. So each is paired with a positive control that proves the attempt really was made.
142
+ */
143
+ var webhook_outbound_ssrf_tests = function (_a) {
144
+ var sdk = _a.sdk;
145
+ return __awaiter(void 0, void 0, void 0, function () {
146
+ var SENTINEL, privateIP, sentinelHits, okHits, redirectHits, sentinelURL, sentinel, allowed, enduserId, templateEnduserId, configuredWebhook, sentinelPort, okURL_1, redirectURL_1, enduser_1, send_automation_webhook_to_1, templateEnduser_1, webhooks, _i, _b, w, _c, _d, _e;
147
+ return __generator(this, function (_f) {
148
+ switch (_f.label) {
149
+ case 0:
150
+ (0, testing_1.log_header)("outbound webhook SSRF");
151
+ assert_local_api();
152
+ SENTINEL = "f0015-sentinel-".concat(Date.now(), "-").concat(Math.random().toString(36).slice(2));
153
+ privateIP = first_private_ipv4();
154
+ if (!privateIP) {
155
+ // Degrade loudly rather than silently passing. Everything below needs a bindable address that the
156
+ // guard refuses in every environment, and loopback does not qualify (see the note above).
157
+ (0, testing_1.assert)(false, 'SKIPPED: no non-loopback RFC1918 interface on this host, so the SSRF sentinel cannot be '
158
+ + 'bound anywhere the guard refuses. Run on a host with a private network interface.', 'outbound SSRF');
159
+ return [2 /*return*/];
160
+ }
161
+ sentinelHits = 0 // must NEVER be reached once fixed
162
+ ;
163
+ okHits = 0 // permitted target: must stay reachable
164
+ ;
165
+ redirectHits = 0 // permitted hop 1 of the redirect chain
166
+ ;
167
+ sentinelURL = '';
168
+ sentinel = http_1.default.createServer(function (_, res) {
169
+ sentinelHits++;
170
+ res.writeHead(200, { 'content-type': 'application/json' });
171
+ res.end(JSON.stringify({ sentinel: SENTINEL, credentials: 'internal-only' }));
172
+ });
173
+ allowed = http_1.default.createServer(function (req, res) {
174
+ if ((req.url || '').startsWith('/redirect-to-internal')) {
175
+ redirectHits++;
176
+ // Hop 1 is permitted and genuinely succeeds; hop 2 points somewhere that is not.
177
+ res.writeHead(302, { location: sentinelURL });
178
+ res.end();
179
+ return;
180
+ }
181
+ okHits++;
182
+ res.writeHead(200, { 'content-type': 'application/json' });
183
+ res.end(JSON.stringify({ ok: true }));
184
+ });
185
+ configuredWebhook = false;
186
+ _f.label = 1;
187
+ case 1:
188
+ _f.trys.push([1, , 14, 31]);
189
+ return [4 /*yield*/, listen(sentinel, privateIP)];
190
+ case 2:
191
+ _f.sent();
192
+ sentinelPort = port_of(sentinel);
193
+ sentinelURL = "http://".concat(privateIP, ":").concat(sentinelPort, "/ssrf-sentinel");
194
+ return [4 /*yield*/, listen(allowed, '127.0.0.1')];
195
+ case 3:
196
+ _f.sent();
197
+ okURL_1 = "http://127.0.0.1:".concat(port_of(allowed), "/webhook-ok");
198
+ redirectURL_1 = "http://127.0.0.1:".concat(port_of(allowed), "/redirect-to-internal");
199
+ return [4 /*yield*/, sdk.api.endusers.createOne({
200
+ email: "f0015-".concat(Date.now(), "@example.com"), fname: 'F0015', lname: 'Ssrf',
201
+ })];
202
+ case 4:
203
+ enduser_1 = _f.sent();
204
+ enduserId = enduser_1.id;
205
+ send_automation_webhook_to_1 = function (url, forEnduserId) {
206
+ if (forEnduserId === void 0) { forEnduserId = enduser_1.id; }
207
+ return __awaiter(void 0, void 0, void 0, function () {
208
+ var outcome;
209
+ return __generator(this, function (_a) {
210
+ switch (_a.label) {
211
+ case 0:
212
+ sentinelHits = 0;
213
+ okHits = 0;
214
+ redirectHits = 0;
215
+ return [4 /*yield*/, sdk.api.webhooks.send_automation_webhook({
216
+ enduserId: forEnduserId,
217
+ action: { info: { url: url } },
218
+ }).then(function () { return 'resolved'; }).catch(function () { return 'rejected'; })
219
+ // The action awaits its own axios call, but give redirect chains a moment to land.
220
+ ];
221
+ case 1:
222
+ outcome = _a.sent();
223
+ // The action awaits its own axios call, but give redirect chains a moment to land.
224
+ return [4 /*yield*/, settle(750)];
225
+ case 2:
226
+ // The action awaits its own axios call, but give redirect chains a moment to land.
227
+ _a.sent();
228
+ return [2 /*return*/, { outcome: outcome, sentinelHits: sentinelHits, okHits: okHits, redirectHits: redirectHits }];
229
+ }
230
+ });
231
+ });
232
+ };
233
+ // ---------------------------------------------------------------------------------------------
234
+ // T6 first: the positive control for the whole file. If an allowlisted target does not receive the
235
+ // webhook, every "sentinel not contacted" assertion below is meaningless.
236
+ // ---------------------------------------------------------------------------------------------
237
+ return [4 /*yield*/, (0, testing_1.async_test)('automation webhook to a permitted target still delivers (regression baseline)', function () { return send_automation_webhook_to_1(okURL_1); }, { onResult: function (r) { return r.okHits === 1 && r.sentinelHits === 0; } })
238
+ // T3 — direct non-allowlisted private destination.
239
+ ];
240
+ case 5:
241
+ // ---------------------------------------------------------------------------------------------
242
+ // T6 first: the positive control for the whole file. If an allowlisted target does not receive the
243
+ // webhook, every "sentinel not contacted" assertion below is meaningless.
244
+ // ---------------------------------------------------------------------------------------------
245
+ _f.sent();
246
+ // T3 — direct non-allowlisted private destination.
247
+ return [4 /*yield*/, (0, testing_1.async_test)('automation webhook does not reach a private destination', function () { return send_automation_webhook_to_1(sentinelURL); }, { onResult: function (r) { return r.sentinelHits === 0; } })
248
+ // T4 — the redirect bypass. THE test that justifies a connect-time guard over a pre-flight check.
249
+ ];
250
+ case 6:
251
+ // T3 — direct non-allowlisted private destination.
252
+ _f.sent();
253
+ // T4 — the redirect bypass. THE test that justifies a connect-time guard over a pre-flight check.
254
+ return [4 /*yield*/, (0, testing_1.async_test)('automation webhook does not follow a redirect from a permitted host into a private one', function () { return send_automation_webhook_to_1(redirectURL_1); }, {
255
+ // redirectHits === 1 is the positive control: hop 1 was allowlisted and really was reached, so
256
+ // sentinelHits === 0 can only mean hop 2 was refused — not that the request never happened.
257
+ onResult: function (r) { return r.redirectHits === 1 && r.sentinelHits === 0; },
258
+ })
259
+ // T5 — the destination arrives via template interpolation, so validation must run AFTER the
260
+ // replacers rather than against the stored config. {{enduser.<key>}} resolves from enduser.fields.
261
+ ];
262
+ case 7:
263
+ // T4 — the redirect bypass. THE test that justifies a connect-time guard over a pre-flight check.
264
+ _f.sent();
265
+ return [4 /*yield*/, sdk.api.endusers.createOne({
266
+ email: "f0015-tpl-".concat(Date.now(), "@example.com"),
267
+ fname: 'F0015', lname: 'Template',
268
+ fields: { ssrfTarget: "".concat(privateIP, ":").concat(sentinelPort) },
269
+ })];
270
+ case 8:
271
+ templateEnduser_1 = _f.sent();
272
+ templateEnduserId = templateEnduser_1.id;
273
+ return [4 /*yield*/, (0, testing_1.async_test)('automation webhook validates the URL after template interpolation, not before', function () { return send_automation_webhook_to_1('http://{{enduser.ssrfTarget}}/ssrf-sentinel', templateEnduser_1.id); }, { onResult: function (r) { return r.sentinelHits === 0; } })
274
+ // ---------------------------------------------------------------------------------------------
275
+ // The configured-webhook delivery path (api/modules/webhooks.ts:145), which is a different code
276
+ // path from the automation action above. Paired: allowlisted target proves the subscription and
277
+ // trigger plumbing works, then the same plumbing pointed at the sentinel must not reach it.
278
+ // ---------------------------------------------------------------------------------------------
279
+ // CUDSubscription is an object of booleans, not a list of verbs (see webhooks_tests.ts fullSubscription).
280
+ ];
281
+ case 9:
282
+ _f.sent();
283
+ // ---------------------------------------------------------------------------------------------
284
+ // The configured-webhook delivery path (api/modules/webhooks.ts:145), which is a different code
285
+ // path from the automation action above. Paired: allowlisted target proves the subscription and
286
+ // trigger plumbing works, then the same plumbing pointed at the sentinel must not reach it.
287
+ // ---------------------------------------------------------------------------------------------
288
+ // CUDSubscription is an object of booleans, not a list of verbs (see webhooks_tests.ts fullSubscription).
289
+ return [4 /*yield*/, sdk.api.webhooks.configure({
290
+ url: okURL_1, secret: TEST_SECRET, subscriptions: { endusers: { create: true } },
291
+ })];
292
+ case 10:
293
+ // ---------------------------------------------------------------------------------------------
294
+ // The configured-webhook delivery path (api/modules/webhooks.ts:145), which is a different code
295
+ // path from the automation action above. Paired: allowlisted target proves the subscription and
296
+ // trigger plumbing works, then the same plumbing pointed at the sentinel must not reach it.
297
+ // ---------------------------------------------------------------------------------------------
298
+ // CUDSubscription is an object of booleans, not a list of verbs (see webhooks_tests.ts fullSubscription).
299
+ _f.sent();
300
+ configuredWebhook = true;
301
+ return [4 /*yield*/, (0, testing_1.async_test)('configured webhook to a permitted target still delivers (positive control)', function () { return __awaiter(void 0, void 0, void 0, function () {
302
+ var e, delivered;
303
+ return __generator(this, function (_a) {
304
+ switch (_a.label) {
305
+ case 0:
306
+ sentinelHits = 0;
307
+ okHits = 0;
308
+ return [4 /*yield*/, sdk.api.endusers.createOne({ email: "f0015-ok-".concat(Date.now(), "@example.com") })];
309
+ case 1:
310
+ e = _a.sent();
311
+ return [4 /*yield*/, wait_until(function () { return okHits > 0; }, 8000)];
312
+ case 2:
313
+ delivered = _a.sent();
314
+ return [4 /*yield*/, sdk.api.endusers.deleteOne(e.id).catch(function () { })];
315
+ case 3:
316
+ _a.sent();
317
+ return [2 /*return*/, { delivered: delivered, okHits: okHits, sentinelHits: sentinelHits }];
318
+ }
319
+ });
320
+ }); }, { onResult: function (r) { return r.delivered === true && r.sentinelHits === 0; } })
321
+ // Repoint the same configuration at the sentinel, keeping the subscription intact.
322
+ ];
323
+ case 11:
324
+ _f.sent();
325
+ // Repoint the same configuration at the sentinel, keeping the subscription intact.
326
+ return [4 /*yield*/, sdk.api.webhooks.update({ url: sentinelURL })];
327
+ case 12:
328
+ // Repoint the same configuration at the sentinel, keeping the subscription intact.
329
+ _f.sent();
330
+ return [4 /*yield*/, (0, testing_1.async_test)('configured webhook does not deliver to a private destination', function () { return __awaiter(void 0, void 0, void 0, function () {
331
+ var e;
332
+ return __generator(this, function (_a) {
333
+ switch (_a.label) {
334
+ case 0:
335
+ sentinelHits = 0;
336
+ okHits = 0;
337
+ return [4 /*yield*/, sdk.api.endusers.createOne({ email: "f0015-blocked-".concat(Date.now(), "@example.com") })
338
+ // Wait out the window a real delivery would have landed in, then assert it did not.
339
+ ];
340
+ case 1:
341
+ e = _a.sent();
342
+ // Wait out the window a real delivery would have landed in, then assert it did not.
343
+ return [4 /*yield*/, settle(6000)];
344
+ case 2:
345
+ // Wait out the window a real delivery would have landed in, then assert it did not.
346
+ _a.sent();
347
+ return [4 /*yield*/, sdk.api.endusers.deleteOne(e.id).catch(function () { })];
348
+ case 3:
349
+ _a.sent();
350
+ return [2 /*return*/, { sentinelHits: sentinelHits }];
351
+ }
352
+ });
353
+ }); }, { onResult: function (r) { return r.sentinelHits === 0; } })];
354
+ case 13:
355
+ _f.sent();
356
+ return [3 /*break*/, 31];
357
+ case 14:
358
+ if (!configuredWebhook) return [3 /*break*/, 22];
359
+ _f.label = 15;
360
+ case 15:
361
+ _f.trys.push([15, 21, , 22]);
362
+ return [4 /*yield*/, sdk.api.webhooks.getSome({})];
363
+ case 16:
364
+ webhooks = (_f.sent()).webhooks;
365
+ _i = 0, _b = (webhooks !== null && webhooks !== void 0 ? webhooks : []);
366
+ _f.label = 17;
367
+ case 17:
368
+ if (!(_i < _b.length)) return [3 /*break*/, 20];
369
+ w = _b[_i];
370
+ return [4 /*yield*/, sdk.api.webhooks.deleteOne(w.id).catch(function () { })];
371
+ case 18:
372
+ _f.sent();
373
+ _f.label = 19;
374
+ case 19:
375
+ _i++;
376
+ return [3 /*break*/, 17];
377
+ case 20: return [3 /*break*/, 22];
378
+ case 21:
379
+ _c = _f.sent();
380
+ return [3 /*break*/, 22];
381
+ case 22:
382
+ if (!enduserId) return [3 /*break*/, 26];
383
+ _f.label = 23;
384
+ case 23:
385
+ _f.trys.push([23, 25, , 26]);
386
+ return [4 /*yield*/, sdk.api.endusers.deleteOne(enduserId)];
387
+ case 24:
388
+ _f.sent();
389
+ return [3 /*break*/, 26];
390
+ case 25:
391
+ _d = _f.sent();
392
+ return [3 /*break*/, 26];
393
+ case 26:
394
+ if (!templateEnduserId) return [3 /*break*/, 30];
395
+ _f.label = 27;
396
+ case 27:
397
+ _f.trys.push([27, 29, , 30]);
398
+ return [4 /*yield*/, sdk.api.endusers.deleteOne(templateEnduserId)];
399
+ case 28:
400
+ _f.sent();
401
+ return [3 /*break*/, 30];
402
+ case 29:
403
+ _e = _f.sent();
404
+ return [3 /*break*/, 30];
405
+ case 30:
406
+ sentinel.close();
407
+ allowed.close();
408
+ return [7 /*endfinally*/];
409
+ case 31: return [2 /*return*/];
410
+ }
411
+ });
412
+ });
413
+ };
414
+ exports.webhook_outbound_ssrf_tests = webhook_outbound_ssrf_tests;
415
+ if (require.main === module) {
416
+ console.log("\uD83C\uDF10 Using API URL: ".concat(host));
417
+ var sdk_2 = new sdk_1.Session({ host: host });
418
+ var sdkNonAdmin_1 = new sdk_1.Session({ host: host });
419
+ var runTests = function () { return __awaiter(void 0, void 0, void 0, function () {
420
+ return __generator(this, function (_a) {
421
+ switch (_a.label) {
422
+ case 0: return [4 /*yield*/, (0, setup_1.setup_tests)(sdk_2, sdkNonAdmin_1)];
423
+ case 1:
424
+ _a.sent();
425
+ return [4 /*yield*/, (0, exports.webhook_outbound_ssrf_tests)({ sdk: sdk_2, sdkNonAdmin: sdkNonAdmin_1 })];
426
+ case 2:
427
+ _a.sent();
428
+ return [2 /*return*/];
429
+ }
430
+ });
431
+ }); };
432
+ runTests()
433
+ .then(function () {
434
+ console.log("✅ outbound webhook SSRF test suite completed successfully");
435
+ process.exit(0);
436
+ })
437
+ .catch(function (error) {
438
+ console.error("❌ outbound webhook SSRF test suite failed:", error);
439
+ process.exit(1);
440
+ });
441
+ }
442
+ //# sourceMappingURL=webhook-outbound-ssrf.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhook-outbound-ssrf.test.js","sourceRoot":"","sources":["../../../../../src/tests/api_tests/security/webhook-outbound-ssrf.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import { Session } from "../../../sdk";
2
+ /**
3
+ * Regression test: outbound webhook delivery must time out rather than hang.
4
+ *
5
+ * Outbound webhook delivery used axios.post(url, ...) with no `timeout` (axios default = infinite).
6
+ * A tenant-controlled receiver that accepts the connection and never responds hangs the awaited
7
+ * request indefinitely (slow-loris → worker exhaustion). Fix: timeout: 15_000 on the axios calls.
8
+ *
9
+ * Repro: stand up a local HTTP server that accepts the connection but NEVER responds, point
10
+ * send_automation_webhook (which awaits the axios call) at it, and race the call against a 20s
11
+ * client timer.
12
+ * - green (fixed): server times out at ~15s → handler returns 400 → SDK call rejects < 20s
13
+ * - red (unfixed): the call is still pending at 20s → client timer wins
14
+ */
15
+ export declare const webhook_timeout_tests: ({ sdk }: {
16
+ sdk: Session;
17
+ sdkNonAdmin: Session;
18
+ }) => Promise<void>;
19
+ //# sourceMappingURL=webhook-timeout.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhook-timeout.test.d.ts","sourceRoot":"","sources":["../../../../../src/tests/api_tests/security/webhook-timeout.test.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAYtC;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,qBAAqB;SAA2B,OAAO;iBAAe,OAAO;mBAkCzF,CAAA"}