@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,218 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ var __generator = (this && this.__generator) || function (thisArg, body) {
11
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
12
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
13
+ function verb(n) { return function (v) { return step([n, v]); }; }
14
+ function step(op) {
15
+ if (f) throw new TypeError("Generator is already executing.");
16
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
17
+ 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;
18
+ if (y = 0, t) op = [op[0] & 2, t.value];
19
+ switch (op[0]) {
20
+ case 0: case 1: t = op; break;
21
+ case 4: _.label++; return { value: op[1], done: false };
22
+ case 5: _.label++; y = op[1]; op = [0]; continue;
23
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
24
+ default:
25
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
26
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
27
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
28
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
29
+ if (t[2]) _.ops.pop();
30
+ _.trys.pop(); continue;
31
+ }
32
+ op = body.call(thisArg, _);
33
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
34
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
35
+ }
36
+ };
37
+ require('source-map-support').install();
38
+ import { Session } from "../../../sdk";
39
+ import { assert, log_header, wait, } from "@tellescope/testing";
40
+ import { setup_tests } from "../../setup";
41
+ var host = process.env.API_URL || 'http://localhost:8080';
42
+ /**
43
+ * Self-role privilege-escalation guard (relates to a prior internal review, which was
44
+ * investigated and closed as a FALSE POSITIVE — see that file for the full code trace).
45
+ *
46
+ * An earlier review hypothesized that a non-admin staff user could `PATCH /v1/users/{their-own-id}` with
47
+ * `{ roles: ['Admin'] }` and self-promote to Admin, because the FIRST `users` relationship
48
+ * constraint ("Only admin users can set the admin role",
49
+ * [schema.ts:3446](packages/public/schema/src/schema.ts#L3446)) has a self-exception
50
+ * (`if (_id === session.id) return`).
51
+ *
52
+ * That analysis missed the SECOND constraint, "Only admin users can update user roles"
53
+ * ([schema.ts:3486](packages/public/schema/src/schema.ts#L3486)), which has NO self-exception.
54
+ * Relationship constraints are AND-evaluated — `validateRelationshipConstraints`
55
+ * ([routing.ts:1240-1252](packages/private/api/api/modules/routing.ts#L1240)) loops the whole
56
+ * array and throws 400 on the FIRST evaluator that returns a string. So a non-admin self-update
57
+ * that includes `roles` passes constraint #1 (self-exception) but is rejected by constraint #2.
58
+ * The self-promotion is blocked.
59
+ *
60
+ * This test locks that boundary in place so a future refactor of the role constraints can't
61
+ * silently reintroduce the escalation. A dedicated throwaway non-admin user is used as the
62
+ * "attacker" (we never mutate the shared sdkNonAdmin's roles):
63
+ * 1. Admin creates a throwaway user and assigns it a non-admin role (`['Provider']`).
64
+ * 2. Authenticate AS that user via a freshly-minted auth token.
65
+ * 3. As the attacker, attempt four self-role mutations — ['Admin'], ['Provider','Admin'],
66
+ * an arbitrary role, and [] — and assert EACH is blocked. <-- the security assertions
67
+ * 4. Confirm (as admin) the attacker's roles are still ['Provider'] — nothing slipped through.
68
+ * 5. Positive control: admin CAN update the throwaway user's roles. <-- guards against an
69
+ * over-restrictive regression that would block legitimate admin role management.
70
+ *
71
+ * Expected on current (correct) code: all assertions pass. A regression that made the self-update
72
+ * path role-writable by non-admins would flip the step-3/step-4 assertions to red.
73
+ */
74
+ export var self_admin_role_assignment_tests = function (_a) {
75
+ var sdk = _a.sdk;
76
+ return __awaiter(void 0, void 0, void 0, function () {
77
+ var stamp, NON_ADMIN_ROLE, expect_blocked, attackerId, attacker, attackerBefore, sdkAttacker_1, _b, attackerAfter, afterAdminUpdate, _c;
78
+ var _d;
79
+ var _e;
80
+ return __generator(this, function (_f) {
81
+ switch (_f.label) {
82
+ case 0:
83
+ log_header("self-admin role assignment privilege-escalation regression");
84
+ stamp = Date.now();
85
+ NON_ADMIN_ROLE = 'Provider';
86
+ expect_blocked = function (fn, description) { return __awaiter(void 0, void 0, void 0, function () {
87
+ var e_1;
88
+ return __generator(this, function (_a) {
89
+ switch (_a.label) {
90
+ case 0:
91
+ _a.trys.push([0, 2, , 3]);
92
+ return [4 /*yield*/, fn()];
93
+ case 1:
94
+ _a.sent();
95
+ assert(false, "".concat(description, " - SELF-ROLE ESCALATION SUCCEEDED (expected it to be blocked)"));
96
+ return [3 /*break*/, 3];
97
+ case 2:
98
+ e_1 = _a.sent();
99
+ // CRUD relationship-constraint failures surface as 400 { message, info } via SDK parseError.
100
+ assert((e_1 === null || e_1 === void 0 ? void 0 : e_1.code) === 400 || (e_1 === null || e_1 === void 0 ? void 0 : e_1.statusCode) === 400 || typeof (e_1 === null || e_1 === void 0 ? void 0 : e_1.message) === 'string', "".concat(description, " - expected a block error, got: ").concat(JSON.stringify(e_1)), description);
101
+ return [3 /*break*/, 3];
102
+ case 3: return [2 /*return*/];
103
+ }
104
+ });
105
+ }); };
106
+ _f.label = 1;
107
+ case 1:
108
+ _f.trys.push([1, , 15, 20]);
109
+ return [4 /*yield*/, sdk.api.users.createOne({
110
+ email: "f0076-attacker-".concat(stamp, "@example.com"),
111
+ notificationEmailsDisabled: true,
112
+ verifiedEmail: true,
113
+ })];
114
+ case 2:
115
+ attacker = _f.sent();
116
+ attackerId = attacker.id;
117
+ return [4 /*yield*/, sdk.api.users.updateOne(attackerId, { roles: [NON_ADMIN_ROLE] }, { replaceObjectFields: true })];
118
+ case 3:
119
+ _f.sent();
120
+ return [4 /*yield*/, wait(undefined, 2000)
121
+ // Setup sanity: the attacker holds exactly the non-admin role and is NOT an admin.
122
+ ]; // role change triggers a logout; let it propagate before minting a token
123
+ case 4:
124
+ _f.sent(); // role change triggers a logout; let it propagate before minting a token
125
+ return [4 /*yield*/, sdk.api.users.getOne(attackerId)];
126
+ case 5:
127
+ attackerBefore = _f.sent();
128
+ assert(JSON.stringify(attackerBefore.roles) === JSON.stringify([NON_ADMIN_ROLE]), "Setup failed: expected attacker to hold [".concat(NON_ADMIN_ROLE, "], got ").concat(JSON.stringify(attackerBefore.roles)), 'setup: attacker holds a non-admin role');
129
+ _b = Session.bind;
130
+ _d = {
131
+ host: host
132
+ };
133
+ return [4 /*yield*/, sdk.api.users.generate_auth_token({ id: attackerId })];
134
+ case 6:
135
+ sdkAttacker_1 = new (_b.apply(Session, [void 0, (_d.authToken = (_f.sent()).authToken,
136
+ _d)]))();
137
+ return [4 /*yield*/, sdkAttacker_1.refresh_session()]; // populate userInfo from the freshly-minted token
138
+ case 7:
139
+ _f.sent(); // populate userInfo from the freshly-minted token
140
+ assert(sdkAttacker_1.userInfo.id === attackerId && !((_e = sdkAttacker_1.userInfo.roles) !== null && _e !== void 0 ? _e : []).includes('Admin'), "Setup failed: attacker session is not the expected non-admin user", 'setup: authenticated as the non-admin attacker');
141
+ // 3. SECURITY ASSERTIONS — every self-role mutation by the non-admin must be blocked.
142
+ return [4 /*yield*/, expect_blocked(function () { return sdkAttacker_1.api.users.updateOne(attackerId, { roles: ['Admin'] }, { replaceObjectFields: true }); }, 'non-admin self-update to [Admin] is blocked')];
143
+ case 8:
144
+ // 3. SECURITY ASSERTIONS — every self-role mutation by the non-admin must be blocked.
145
+ _f.sent();
146
+ return [4 /*yield*/, expect_blocked(function () { return sdkAttacker_1.api.users.updateOne(attackerId, { roles: [NON_ADMIN_ROLE, 'Admin'] }, { replaceObjectFields: true }); }, 'non-admin self-update to [Provider, Admin] is blocked')];
147
+ case 9:
148
+ _f.sent();
149
+ return [4 /*yield*/, expect_blocked(function () { return sdkAttacker_1.api.users.updateOne(attackerId, { roles: ["Arbitrary_".concat(stamp)] }, { replaceObjectFields: true }); }, 'non-admin self-update to an arbitrary role is blocked')];
150
+ case 10:
151
+ _f.sent();
152
+ return [4 /*yield*/, expect_blocked(function () { return sdkAttacker_1.api.users.updateOne(attackerId, { roles: [] }, { replaceObjectFields: true }); }, 'non-admin self-update to [] (would grant defaults) is blocked')
153
+ // 4. STATE ASSERTION — nothing slipped through; roles are still the original non-admin role.
154
+ ];
155
+ case 11:
156
+ _f.sent();
157
+ return [4 /*yield*/, sdk.api.users.getOne(attackerId)];
158
+ case 12:
159
+ attackerAfter = _f.sent();
160
+ assert(JSON.stringify(attackerAfter.roles) === JSON.stringify([NON_ADMIN_ROLE]), "ESCALATION LEAK: attacker roles changed to ".concat(JSON.stringify(attackerAfter.roles), " ")
161
+ + "after self-update attempts. Expected [".concat(NON_ADMIN_ROLE, "]."), 'attacker roles unchanged after all self-escalation attempts');
162
+ // 5. POSITIVE CONTROL — an Admin CAN update the user's roles (mechanism is not over-restricted).
163
+ return [4 /*yield*/, sdk.api.users.updateOne(attackerId, { roles: [NON_ADMIN_ROLE] }, { replaceObjectFields: true })];
164
+ case 13:
165
+ // 5. POSITIVE CONTROL — an Admin CAN update the user's roles (mechanism is not over-restricted).
166
+ _f.sent();
167
+ return [4 /*yield*/, sdk.api.users.getOne(attackerId)];
168
+ case 14:
169
+ afterAdminUpdate = _f.sent();
170
+ assert(JSON.stringify(afterAdminUpdate.roles) === JSON.stringify([NON_ADMIN_ROLE]), "Admin role update failed: roles are ".concat(JSON.stringify(afterAdminUpdate.roles), ", expected [").concat(NON_ADMIN_ROLE, "]"), 'admin can manage user roles (positive control)');
171
+ return [3 /*break*/, 20];
172
+ case 15:
173
+ if (!attackerId) return [3 /*break*/, 19];
174
+ _f.label = 16;
175
+ case 16:
176
+ _f.trys.push([16, 18, , 19]);
177
+ return [4 /*yield*/, sdk.api.users.deleteOne(attackerId)];
178
+ case 17:
179
+ _f.sent();
180
+ return [3 /*break*/, 19];
181
+ case 18:
182
+ _c = _f.sent();
183
+ return [3 /*break*/, 19];
184
+ case 19: return [7 /*endfinally*/];
185
+ case 20: return [2 /*return*/];
186
+ }
187
+ });
188
+ });
189
+ };
190
+ // Allow running this test file independently
191
+ if (require.main === module) {
192
+ console.log("\uD83C\uDF10 Using API URL: ".concat(host));
193
+ var sdk_1 = new Session({ host: host });
194
+ var sdkNonAdmin_1 = new Session({ host: host });
195
+ var runTests = function () { return __awaiter(void 0, void 0, void 0, function () {
196
+ return __generator(this, function (_a) {
197
+ switch (_a.label) {
198
+ case 0: return [4 /*yield*/, setup_tests(sdk_1, sdkNonAdmin_1)];
199
+ case 1:
200
+ _a.sent();
201
+ return [4 /*yield*/, self_admin_role_assignment_tests({ sdk: sdk_1, sdkNonAdmin: sdkNonAdmin_1 })];
202
+ case 2:
203
+ _a.sent();
204
+ return [2 /*return*/];
205
+ }
206
+ });
207
+ }); };
208
+ runTests()
209
+ .then(function () {
210
+ console.log("✅ self-admin role assignment test suite completed successfully");
211
+ process.exit(0);
212
+ })
213
+ .catch(function (error) {
214
+ console.error("❌ self-admin role assignment test suite failed:", error);
215
+ process.exit(1);
216
+ });
217
+ }
218
+ //# sourceMappingURL=self-admin-role-assignment.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"self-admin-role-assignment.test.js","sourceRoot":"","sources":["../../../../../src/tests/api_tests/security/self-admin-role-assignment.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { Session } from "../../../sdk";
2
+ export declare const startlinktoken_escalation_tests: ({ sdk }: {
3
+ sdk: Session;
4
+ sdkNonAdmin: Session;
5
+ }) => Promise<void>;
6
+ //# sourceMappingURL=startlinktoken-enduser-staff-escalation.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"startlinktoken-enduser-staff-escalation.test.d.ts","sourceRoot":"","sources":["../../../../../src/tests/api_tests/security/startlinktoken-enduser-staff-escalation.test.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAkB,MAAM,cAAc,CAAA;AAuCtD,eAAO,MAAM,+BAA+B;SAA2B,OAAO;iBAAe,OAAO;mBA+GnG,CAAA"}
@@ -0,0 +1,350 @@
1
+ var __assign = (this && this.__assign) || function () {
2
+ __assign = Object.assign || function(t) {
3
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
4
+ s = arguments[i];
5
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
6
+ t[p] = s[p];
7
+ }
8
+ return t;
9
+ };
10
+ return __assign.apply(this, arguments);
11
+ };
12
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
13
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
14
+ return new (P || (P = Promise))(function (resolve, reject) {
15
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
16
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
17
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
18
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
19
+ });
20
+ };
21
+ var __generator = (this && this.__generator) || function (thisArg, body) {
22
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
23
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
24
+ function verb(n) { return function (v) { return step([n, v]); }; }
25
+ function step(op) {
26
+ if (f) throw new TypeError("Generator is already executing.");
27
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
28
+ 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;
29
+ if (y = 0, t) op = [op[0] & 2, t.value];
30
+ switch (op[0]) {
31
+ case 0: case 1: t = op; break;
32
+ case 4: _.label++; return { value: op[1], done: false };
33
+ case 5: _.label++; y = op[1]; op = [0]; continue;
34
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
35
+ default:
36
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
37
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
38
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
39
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
40
+ if (t[2]) _.ops.pop();
41
+ _.trys.pop(); continue;
42
+ }
43
+ op = body.call(thisArg, _);
44
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
45
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
46
+ }
47
+ };
48
+ require('source-map-support').install();
49
+ import { Session, EnduserSession } from "../../../sdk";
50
+ import { assert, log_header } from "@tellescope/testing";
51
+ import { setup_tests, authenticate_enduser_via_token } from "../../setup";
52
+ import { PROVIDER_PERMISSIONS } from "@tellescope/constants";
53
+ var host = process.env.API_URL || 'http://localhost:8080';
54
+ /**
55
+ * Regression test — `calendar_events.startLinkToken` privilege escalation.
56
+ *
57
+ * startLinkToken is a DOCUMENTED feature ("Video Call Start Links"): a tenant's staff / API-key
58
+ * integration PATCHes a CalendarEvent to set a random token, then sends the host user the
59
+ * `/video/startlink?token=...` link, which `session_for_start_link` exchanges for a scope-limited
60
+ * User (staff) authToken for the first `type:'user'` attendee, MFA bypassed. Nothing in the codebase
61
+ * reads the token value back (the redeem matches server-side; the integration holds its own copy), so
62
+ * the field is write-only-by-design.
63
+ *
64
+ * TWO escalation vectors let a patient (or a low-privilege staff user) obtain the host's session:
65
+ * WRITE — `enduserActions.update` + no `enduserUpdatesDisabled` let an enduser attendee PATCH
66
+ * `startLinkToken` to a value they choose, then redeem it.
67
+ * READ — no `redactions` let an enduser attendee (or a non-admin staff user with calendar read)
68
+ * read a LEGITIMATELY staff-set token and redeem it, with no write.
69
+ *
70
+ * Complete fix = TWO flags on schema.ts `startLinkToken`:
71
+ * enduserUpdatesDisabled: true (closes WRITE; preserves the staff/API-key write the feature needs)
72
+ * redactions: ['all'] (closes READ for endusers AND non-admin users; safe — nothing reads
73
+ * the value back). NOT `readonly` (would break the staff write — A2).
74
+ *
75
+ * Checks (collected, then asserted, so a RED run shows every failing vector):
76
+ * A1 enduser attendee PATCH of startLinkToken is REJECTED (WRITE gate)
77
+ * A2 a staff-set token still redeems for the host's session (feature preserved)
78
+ * A3 an enduser-set token (if the write lands) does NOT redeem (defence-in-depth)
79
+ * A4 an enduser attendee does NOT receive startLinkToken on read (READ gate, endusers)
80
+ * A5 a non-admin staff user does NOT receive startLinkToken on read (READ gate, users)
81
+ *
82
+ * No vendor, no Bedrock; the "host" is a throwaway user. Cleans up every created record.
83
+ */
84
+ var RAND = function () { return Math.random().toString(36).slice(2, 10); };
85
+ export var startlinktoken_escalation_tests = function (_a) {
86
+ var sdk = _a.sdk;
87
+ return __awaiter(void 0, void 0, void 0, function () {
88
+ var businessId, userIds, enduserIds, eventIds, roleIds, checks, record, host_user, patient, event_1, patientSDK, attackerToken, wrote, writeErr, err_1, adminView, redeemed, _b, staffToken, staffWriteErr, e_1, legit, e_2, enduserRead, _c, rbap, nonAdmin, authToken, nonAdminSDK, staffRead, _d, _i, checks_1, c, _e, checks_2, c, _f, eventIds_1, id, _g, _h, enduserIds_1, id, _j, _k, userIds_1, id, _l, _m, roleIds_1, id, _o;
89
+ var _p, _q, _r, _s, _t;
90
+ return __generator(this, function (_u) {
91
+ switch (_u.label) {
92
+ case 0:
93
+ log_header("startLinkToken enduser-writable / readable → staff session escalation");
94
+ businessId = sdk.userInfo.businessId;
95
+ userIds = [];
96
+ enduserIds = [];
97
+ eventIds = [];
98
+ roleIds = [];
99
+ checks = [];
100
+ record = function (label, pass, detail) { return checks.push({ label: label, pass: pass, detail: detail }); };
101
+ _u.label = 1;
102
+ case 1:
103
+ _u.trys.push([1, , 38, 63]);
104
+ return [4 /*yield*/, sdk.api.users.createOne({
105
+ email: "f0185-host-".concat(RAND(), "@tellescope.example"), fname: 'F0185', lname: 'Host',
106
+ verifiedEmail: true, notificationEmailsDisabled: true,
107
+ })];
108
+ case 2:
109
+ host_user = _u.sent();
110
+ userIds.push(host_user.id);
111
+ return [4 /*yield*/, sdk.api.endusers.createOne({
112
+ email: "f0185-patient-".concat(RAND(), "@tellescope.example"), fname: 'F0185', lname: 'Patient',
113
+ })];
114
+ case 3:
115
+ patient = _u.sent();
116
+ enduserIds.push(patient.id);
117
+ return [4 /*yield*/, sdk.api.calendar_events.createOne({
118
+ title: 'appointment', durationInMinutes: 30, startTimeInMS: Date.now() + 3600000,
119
+ attendees: [{ type: 'user', id: host_user.id }, { type: 'enduser', id: patient.id }],
120
+ })];
121
+ case 4:
122
+ event_1 = _u.sent();
123
+ eventIds.push(event_1.id);
124
+ patientSDK = new EnduserSession({ host: host, businessId: businessId });
125
+ return [4 /*yield*/, authenticate_enduser_via_token(sdk, patientSDK, { id: patient.id })
126
+ // ---- A1: WRITE gate — enduser attendee cannot PATCH startLinkToken ----
127
+ ];
128
+ case 5:
129
+ _u.sent();
130
+ attackerToken = "f0185-attacker-".concat(RAND()).concat(RAND());
131
+ wrote = false, writeErr = '';
132
+ _u.label = 6;
133
+ case 6:
134
+ _u.trys.push([6, 8, , 9]);
135
+ return [4 /*yield*/, patientSDK.api.calendar_events.updateOne(event_1.id, { startLinkToken: attackerToken })];
136
+ case 7:
137
+ _u.sent();
138
+ wrote = true;
139
+ return [3 /*break*/, 9];
140
+ case 8:
141
+ err_1 = _u.sent();
142
+ writeErr = (_p = err_1 === null || err_1 === void 0 ? void 0 : err_1.message) !== null && _p !== void 0 ? _p : String(err_1);
143
+ return [3 /*break*/, 9];
144
+ case 9:
145
+ record('A1: enduser cannot write startLinkToken', !wrote, wrote ? 'PATCH ACCEPTED — patient set a staff start-link token' : "rejected (".concat(writeErr, ")"));
146
+ return [4 /*yield*/, sdk.api.calendar_events.getOne(event_1.id)];
147
+ case 10:
148
+ adminView = _u.sent();
149
+ if (!(adminView.startLinkToken === attackerToken)) return [3 /*break*/, 15];
150
+ redeemed = null;
151
+ _u.label = 11;
152
+ case 11:
153
+ _u.trys.push([11, 13, , 14]);
154
+ return [4 /*yield*/, new Session({ host: host }).api.calendar_events.session_for_start_link({ token: attackerToken })];
155
+ case 12:
156
+ redeemed = _u.sent();
157
+ return [3 /*break*/, 14];
158
+ case 13:
159
+ _b = _u.sent();
160
+ return [3 /*break*/, 14];
161
+ case 14:
162
+ record('A3: enduser-set token does not mint a staff session', !(redeemed === null || redeemed === void 0 ? void 0 : redeemed.authToken), (redeemed === null || redeemed === void 0 ? void 0 : redeemed.authToken) ? "minted a STAFF authToken for host ".concat(host_user.id) : 'not redeemable');
163
+ return [3 /*break*/, 16];
164
+ case 15:
165
+ record('A3: enduser-set token does not mint a staff session', true, '(n/a — write blocked, value never landed)');
166
+ _u.label = 16;
167
+ case 16:
168
+ staffToken = "f0185-staff-".concat(RAND()).concat(RAND());
169
+ staffWriteErr = '';
170
+ _u.label = 17;
171
+ case 17:
172
+ _u.trys.push([17, 19, , 20]);
173
+ return [4 /*yield*/, sdk.api.calendar_events.updateOne(event_1.id, { startLinkToken: staffToken })];
174
+ case 18:
175
+ _u.sent();
176
+ return [3 /*break*/, 20];
177
+ case 19:
178
+ e_1 = _u.sent();
179
+ staffWriteErr = (_q = e_1 === null || e_1 === void 0 ? void 0 : e_1.message) !== null && _q !== void 0 ? _q : String(e_1);
180
+ return [3 /*break*/, 20];
181
+ case 20:
182
+ legit = null;
183
+ _u.label = 21;
184
+ case 21:
185
+ _u.trys.push([21, 23, , 24]);
186
+ return [4 /*yield*/, new Session({ host: host }).api.calendar_events.session_for_start_link({ token: staffToken })];
187
+ case 22:
188
+ legit = _u.sent();
189
+ return [3 /*break*/, 24];
190
+ case 23:
191
+ e_2 = _u.sent();
192
+ legit = { error: (_r = e_2 === null || e_2 === void 0 ? void 0 : e_2.message) !== null && _r !== void 0 ? _r : String(e_2) };
193
+ return [3 /*break*/, 24];
194
+ case 24:
195
+ record('A2: staff-set start link still works', !!(legit === null || legit === void 0 ? void 0 : legit.authToken) && legit.eventId === event_1.id, "staffWrite=".concat(staffWriteErr ? 'REJECTED(' + staffWriteErr + ')' : 'ok', " authToken=").concat(!!(legit === null || legit === void 0 ? void 0 : legit.authToken), " eventId=").concat(legit === null || legit === void 0 ? void 0 : legit.eventId, " ").concat((legit === null || legit === void 0 ? void 0 : legit.error) ? '(' + legit.error + ')' : ''));
196
+ enduserRead = null;
197
+ _u.label = 25;
198
+ case 25:
199
+ _u.trys.push([25, 27, , 28]);
200
+ return [4 /*yield*/, patientSDK.api.calendar_events.getOne(event_1.id)];
201
+ case 26:
202
+ enduserRead = _u.sent();
203
+ return [3 /*break*/, 28];
204
+ case 27:
205
+ _c = _u.sent();
206
+ return [3 /*break*/, 28];
207
+ case 28:
208
+ record('A4: startLinkToken redacted from enduser reads', !enduserRead || enduserRead.startLinkToken === undefined, "enduser read startLinkToken=".concat((_s = enduserRead === null || enduserRead === void 0 ? void 0 : enduserRead.startLinkToken) !== null && _s !== void 0 ? _s : '(absent)', " \u2014 could redeem a staff-set token"));
209
+ return [4 /*yield*/, sdk.api.role_based_access_permissions.createOne({
210
+ role: "F0185NonAdmin-".concat(RAND()),
211
+ // Non-admin (non-Admin-role) staff with tenant-wide calendar READ — enough to load the event,
212
+ // so the assertion isolates redaction (not access). Spread a valid full permissions shape.
213
+ permissions: __assign(__assign({}, PROVIDER_PERMISSIONS), { calendar_events: __assign(__assign({}, PROVIDER_PERMISSIONS.calendar_events), { read: 'All', readMany: 'All' }) }),
214
+ }).catch(function (e) { var _a; console.warn('A5 role create failed:', (_a = e === null || e === void 0 ? void 0 : e.message) !== null && _a !== void 0 ? _a : e); return null; })];
215
+ case 29:
216
+ rbap = _u.sent();
217
+ if (!rbap) return [3 /*break*/, 36];
218
+ roleIds.push(rbap.id);
219
+ return [4 /*yield*/, sdk.api.users.createOne({
220
+ email: "f0185-nonadmin-".concat(RAND(), "@tellescope.example"), fname: 'F0185', lname: 'NonAdmin',
221
+ verifiedEmail: true, notificationEmailsDisabled: true, roles: [rbap.role],
222
+ })];
223
+ case 30:
224
+ nonAdmin = _u.sent();
225
+ userIds.push(nonAdmin.id);
226
+ return [4 /*yield*/, sdk.api.users.generate_auth_token({ id: nonAdmin.id })];
227
+ case 31:
228
+ authToken = (_u.sent()).authToken;
229
+ nonAdminSDK = new Session({ host: host, authToken: authToken });
230
+ staffRead = null;
231
+ _u.label = 32;
232
+ case 32:
233
+ _u.trys.push([32, 34, , 35]);
234
+ return [4 /*yield*/, nonAdminSDK.api.calendar_events.getOne(event_1.id)];
235
+ case 33:
236
+ staffRead = _u.sent();
237
+ return [3 /*break*/, 35];
238
+ case 34:
239
+ _d = _u.sent();
240
+ return [3 /*break*/, 35];
241
+ case 35:
242
+ record('A5: startLinkToken redacted from non-admin user reads', !staffRead || staffRead.startLinkToken === undefined, "non-admin user read startLinkToken=".concat((_t = staffRead === null || staffRead === void 0 ? void 0 : staffRead.startLinkToken) !== null && _t !== void 0 ? _t : '(absent)', " \u2014 staff\u2192host escalation via read"));
243
+ return [3 /*break*/, 37];
244
+ case 36:
245
+ record('A5: startLinkToken redacted from non-admin user reads', true, '(n/a — could not create a non-admin role in this env)');
246
+ _u.label = 37;
247
+ case 37:
248
+ // Report the full table before asserting (the harness exits on the first failed assert).
249
+ console.log('\n check summary:');
250
+ for (_i = 0, checks_1 = checks; _i < checks_1.length; _i++) {
251
+ c = checks_1[_i];
252
+ console.log(" ".concat(c.pass ? 'PASS' : 'FAIL', " ").concat(c.label, " \u2014 ").concat(c.detail));
253
+ }
254
+ console.log('');
255
+ for (_e = 0, checks_2 = checks; _e < checks_2.length; _e++) {
256
+ c = checks_2[_e];
257
+ assert(c.pass, "".concat(c.label, " \u2014 ").concat(c.detail), c.label);
258
+ }
259
+ return [3 /*break*/, 63];
260
+ case 38:
261
+ _f = 0, eventIds_1 = eventIds;
262
+ _u.label = 39;
263
+ case 39:
264
+ if (!(_f < eventIds_1.length)) return [3 /*break*/, 44];
265
+ id = eventIds_1[_f];
266
+ _u.label = 40;
267
+ case 40:
268
+ _u.trys.push([40, 42, , 43]);
269
+ return [4 /*yield*/, sdk.api.calendar_events.deleteOne(id)];
270
+ case 41:
271
+ _u.sent();
272
+ return [3 /*break*/, 43];
273
+ case 42:
274
+ _g = _u.sent();
275
+ return [3 /*break*/, 43];
276
+ case 43:
277
+ _f++;
278
+ return [3 /*break*/, 39];
279
+ case 44:
280
+ _h = 0, enduserIds_1 = enduserIds;
281
+ _u.label = 45;
282
+ case 45:
283
+ if (!(_h < enduserIds_1.length)) return [3 /*break*/, 50];
284
+ id = enduserIds_1[_h];
285
+ _u.label = 46;
286
+ case 46:
287
+ _u.trys.push([46, 48, , 49]);
288
+ return [4 /*yield*/, sdk.api.endusers.deleteOne(id)];
289
+ case 47:
290
+ _u.sent();
291
+ return [3 /*break*/, 49];
292
+ case 48:
293
+ _j = _u.sent();
294
+ return [3 /*break*/, 49];
295
+ case 49:
296
+ _h++;
297
+ return [3 /*break*/, 45];
298
+ case 50:
299
+ _k = 0, userIds_1 = userIds;
300
+ _u.label = 51;
301
+ case 51:
302
+ if (!(_k < userIds_1.length)) return [3 /*break*/, 56];
303
+ id = userIds_1[_k];
304
+ _u.label = 52;
305
+ case 52:
306
+ _u.trys.push([52, 54, , 55]);
307
+ return [4 /*yield*/, sdk.api.users.deleteOne(id)];
308
+ case 53:
309
+ _u.sent();
310
+ return [3 /*break*/, 55];
311
+ case 54:
312
+ _l = _u.sent();
313
+ return [3 /*break*/, 55];
314
+ case 55:
315
+ _k++;
316
+ return [3 /*break*/, 51];
317
+ case 56:
318
+ _m = 0, roleIds_1 = roleIds;
319
+ _u.label = 57;
320
+ case 57:
321
+ if (!(_m < roleIds_1.length)) return [3 /*break*/, 62];
322
+ id = roleIds_1[_m];
323
+ _u.label = 58;
324
+ case 58:
325
+ _u.trys.push([58, 60, , 61]);
326
+ return [4 /*yield*/, sdk.api.role_based_access_permissions.deleteOne(id)];
327
+ case 59:
328
+ _u.sent();
329
+ return [3 /*break*/, 61];
330
+ case 60:
331
+ _o = _u.sent();
332
+ return [3 /*break*/, 61];
333
+ case 61:
334
+ _m++;
335
+ return [3 /*break*/, 57];
336
+ case 62: return [7 /*endfinally*/];
337
+ case 63: return [2 /*return*/];
338
+ }
339
+ });
340
+ });
341
+ };
342
+ if (require.main === module) {
343
+ var sdk_1 = new Session({ host: host });
344
+ var sdkNonAdmin_1 = new Session({ host: host });
345
+ setup_tests(sdk_1, sdkNonAdmin_1)
346
+ .then(function () { return startlinktoken_escalation_tests({ sdk: sdk_1, sdkNonAdmin: sdkNonAdmin_1 }); })
347
+ .then(function () { console.log("✅ startLinkToken escalation test suite completed successfully"); process.exit(0); })
348
+ .catch(function (error) { console.error("❌ startLinkToken escalation test suite failed:", error); process.exit(1); });
349
+ }
350
+ //# sourceMappingURL=startlinktoken-enduser-staff-escalation.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"startlinktoken-enduser-staff-escalation.test.js","sourceRoot":"","sources":["../../../../../src/tests/api_tests/security/startlinktoken-enduser-staff-escalation.test.ts"],"names":[],"mappings":"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"}
@@ -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"}