@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,331 @@
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, EnduserSession } from "../../../sdk";
39
+ import { assert, log_header, } from "@tellescope/testing";
40
+ import { authenticate_enduser_via_token, setup_tests } from "../../setup";
41
+ var host = process.env.API_URL || 'http://localhost:8080';
42
+ var businessId = '60398b1131a295e64f084ff6';
43
+ var RAND = function () { return Math.random().toString(36).slice(2, 10); };
44
+ var VICTIM_STATE = 'CA';
45
+ var ATTACKER_STATE_WRITE = 'NY';
46
+ /**
47
+ * Regression test: `form_fields.booking_info` must not mint a booking token for another patient.
48
+ *
49
+ * `form_fields.booking_info` resolved its target patient as
50
+ * `DB.endusers.findById(enduserId || req.session.id)` with no ownership check for enduser
51
+ * sessions. The enduser DB branch builds the endusers collection with `enduserAccess: true`
52
+ * (database.ts), so a FOREIGN in-tenant id resolves — and the handler then writes
53
+ * `enduserFields.state` onto that record and calls `login_enduser` with
54
+ * `sessionScopes: ['appointment-booking']`, returning a live 24h token for the victim inside
55
+ * `bookingURL`. booking_info is enduser-callable AND granted to the 'public-form' scope, so a
56
+ * portal patient or an anonymous form-filler could mint a working session as any co-tenant patient.
57
+ *
58
+ * The fix mirrors `prepare_form_response` (api.ts): reject when an enduser session supplies an
59
+ * `enduserId` other than its own, before the booking-page lookup and before the `state` write.
60
+ *
61
+ * RED (pre-fix): A1 and A2 fail — the exploit returns 200 with a bookingURL whose token decodes to
62
+ * the VICTIM's id, and the victim's `state` is overwritten. B/C (positive controls) pass pre-fix.
63
+ * GREEN (post-fix): all six checks pass.
64
+ *
65
+ * Checks are collected and printed before any assert runs: the testing harness has
66
+ * EXIT_ON_FIRST_ERROR, so asserting inline would kill the process before the evidence table and
67
+ * before `finally` cleanup.
68
+ */
69
+ export var booking_info_idor_tests = function (_a) {
70
+ var sdk = _a.sdk;
71
+ return __awaiter(void 0, void 0, void 0, function () {
72
+ var checks, record, token_enduser_id, templateId, bookingPageId, enduserIds, template, bookingPage, attacker, victim, attackerSDK, a1Detail, a1Pass, r, mintedFor, e_1, a2Attempt, e_2, victimAfter, b1Detail, b1Pass, r, mintedFor, e_3, b2Detail, b2Pass, r, mintedFor, e_4, c1Detail, c1Pass, r, mintedFor, e_5, c2Detail, c2Pass, r, e_6, _i, checks_1, c, _b, checks_2, c, _c, enduserIds_1, id, _d, _e, _f;
73
+ return __generator(this, function (_g) {
74
+ switch (_g.label) {
75
+ case 0:
76
+ log_header("booking_info must not mint an appointment-booking token for another enduser");
77
+ checks = [];
78
+ record = function (label, pass, detail) { return checks.push({ label: label, pass: pass, detail: detail }); };
79
+ token_enduser_id = function (bookingURL) {
80
+ var _a;
81
+ var token = (_a = /[?&]token=([^&]+)/.exec(bookingURL || '')) === null || _a === void 0 ? void 0 : _a[1];
82
+ var payload = token === null || token === void 0 ? void 0 : token.split('.')[1];
83
+ if (!payload)
84
+ return '';
85
+ try {
86
+ return JSON.parse(Buffer.from(payload, 'base64').toString()).id;
87
+ }
88
+ catch (_b) {
89
+ return '';
90
+ }
91
+ };
92
+ templateId = '';
93
+ bookingPageId = '';
94
+ enduserIds = [];
95
+ _g.label = 1;
96
+ case 1:
97
+ _g.trys.push([1, , 32, 47]);
98
+ return [4 /*yield*/, sdk.api.calendar_event_templates.createOne({
99
+ title: "F0179 template ".concat(RAND()), durationInMinutes: 30,
100
+ })];
101
+ case 2:
102
+ template = _g.sent();
103
+ templateId = template.id;
104
+ return [4 /*yield*/, sdk.api.appointment_booking_pages.createOne({
105
+ title: "F0179 booking page ".concat(RAND()),
106
+ calendarEventTemplateIds: [templateId],
107
+ locationIds: [],
108
+ })];
109
+ case 3:
110
+ bookingPage = _g.sent();
111
+ bookingPageId = bookingPage.id;
112
+ return [4 /*yield*/, sdk.api.endusers.createOne({
113
+ email: "f0179-attacker-".concat(RAND(), "@tellescope.example"), fname: 'F0179', lname: 'Attacker',
114
+ })];
115
+ case 4:
116
+ attacker = _g.sent();
117
+ enduserIds.push(attacker.id);
118
+ return [4 /*yield*/, sdk.api.endusers.createOne({
119
+ email: "f0179-victim-".concat(RAND(), "@tellescope.example"), fname: 'F0179', lname: 'Victim',
120
+ state: VICTIM_STATE,
121
+ })];
122
+ case 5:
123
+ victim = _g.sent();
124
+ enduserIds.push(victim.id);
125
+ attackerSDK = new EnduserSession({ host: host, businessId: businessId });
126
+ return [4 /*yield*/, authenticate_enduser_via_token(sdk, attackerSDK, { id: attacker.id })
127
+ /* ===== A: the exploit — enduser mints a booking session as another patient ===== */
128
+ ];
129
+ case 6:
130
+ _g.sent();
131
+ a1Detail = '';
132
+ a1Pass = false;
133
+ _g.label = 7;
134
+ case 7:
135
+ _g.trys.push([7, 9, , 10]);
136
+ return [4 /*yield*/, attackerSDK.api.form_fields.booking_info({ bookingPageId: bookingPageId, enduserId: victim.id })];
137
+ case 8:
138
+ r = _g.sent();
139
+ mintedFor = token_enduser_id(r.bookingURL);
140
+ a1Detail = ("EXPLOITED: 200 with a bookingURL; token subject=".concat(mintedFor, " ")
141
+ + "(victim=".concat(victim.id, ", attacker=").concat(attacker.id, ")")
142
+ + (mintedFor === victim.id ? ' — a live appointment-booking session AS THE VICTIM' : ''));
143
+ return [3 /*break*/, 10];
144
+ case 9:
145
+ e_1 = _g.sent();
146
+ a1Pass = true;
147
+ a1Detail = "rejected: ".concat((e_1 === null || e_1 === void 0 ? void 0 : e_1.message) || (e_1 === null || e_1 === void 0 ? void 0 : e_1.toString()));
148
+ return [3 /*break*/, 10];
149
+ case 10:
150
+ record('A1: enduser cannot mint a booking token for another enduser', a1Pass, a1Detail);
151
+ a2Attempt = '';
152
+ _g.label = 11;
153
+ case 11:
154
+ _g.trys.push([11, 13, , 14]);
155
+ return [4 /*yield*/, attackerSDK.api.form_fields.booking_info({
156
+ bookingPageId: bookingPageId,
157
+ enduserId: victim.id, enduserFields: { state: ATTACKER_STATE_WRITE },
158
+ })];
159
+ case 12:
160
+ _g.sent();
161
+ a2Attempt = 'call returned 200';
162
+ return [3 /*break*/, 14];
163
+ case 13:
164
+ e_2 = _g.sent();
165
+ a2Attempt = "call rejected: ".concat((e_2 === null || e_2 === void 0 ? void 0 : e_2.message) || (e_2 === null || e_2 === void 0 ? void 0 : e_2.toString()));
166
+ return [3 /*break*/, 14];
167
+ case 14: return [4 /*yield*/, sdk.api.endusers.getOne(victim.id)];
168
+ case 15:
169
+ victimAfter = _g.sent();
170
+ record('A2: enduser cannot write `state` onto another enduser via enduserFields', victimAfter.state === VICTIM_STATE, "".concat(a2Attempt, "; victim.state=").concat(victimAfter.state, " (expected ").concat(VICTIM_STATE, ")"));
171
+ b1Detail = '';
172
+ b1Pass = false;
173
+ _g.label = 16;
174
+ case 16:
175
+ _g.trys.push([16, 18, , 19]);
176
+ return [4 /*yield*/, attackerSDK.api.form_fields.booking_info({ bookingPageId: bookingPageId })];
177
+ case 17:
178
+ r = _g.sent();
179
+ mintedFor = token_enduser_id(r.bookingURL);
180
+ b1Pass = mintedFor === attacker.id;
181
+ b1Detail = "token subject=".concat(mintedFor, " (self=").concat(attacker.id, ")");
182
+ return [3 /*break*/, 19];
183
+ case 18:
184
+ e_3 = _g.sent();
185
+ b1Detail = "unexpectedly rejected: ".concat((e_3 === null || e_3 === void 0 ? void 0 : e_3.message) || (e_3 === null || e_3 === void 0 ? void 0 : e_3.toString()));
186
+ return [3 /*break*/, 19];
187
+ case 19:
188
+ record('B1: enduser can still load booking info with no enduserId', b1Pass, b1Detail);
189
+ b2Detail = '';
190
+ b2Pass = false;
191
+ _g.label = 20;
192
+ case 20:
193
+ _g.trys.push([20, 22, , 23]);
194
+ return [4 /*yield*/, attackerSDK.api.form_fields.booking_info({ bookingPageId: bookingPageId, enduserId: attacker.id })];
195
+ case 21:
196
+ r = _g.sent();
197
+ mintedFor = token_enduser_id(r.bookingURL);
198
+ b2Pass = mintedFor === attacker.id;
199
+ b2Detail = "token subject=".concat(mintedFor, " (self=").concat(attacker.id, ")");
200
+ return [3 /*break*/, 23];
201
+ case 22:
202
+ e_4 = _g.sent();
203
+ b2Detail = "unexpectedly rejected: ".concat((e_4 === null || e_4 === void 0 ? void 0 : e_4.message) || (e_4 === null || e_4 === void 0 ? void 0 : e_4.toString()));
204
+ return [3 /*break*/, 23];
205
+ case 23:
206
+ record('B2: enduser can still load booking info for its OWN enduserId', b2Pass, b2Detail);
207
+ c1Detail = '';
208
+ c1Pass = false;
209
+ _g.label = 24;
210
+ case 24:
211
+ _g.trys.push([24, 26, , 27]);
212
+ return [4 /*yield*/, sdk.api.form_fields.booking_info({ bookingPageId: bookingPageId, enduserId: victim.id })];
213
+ case 25:
214
+ r = _g.sent();
215
+ mintedFor = token_enduser_id(r.bookingURL);
216
+ c1Pass = mintedFor === victim.id;
217
+ c1Detail = "token subject=".concat(mintedFor, " (target=").concat(victim.id, ")");
218
+ return [3 /*break*/, 27];
219
+ case 26:
220
+ e_5 = _g.sent();
221
+ c1Detail = "unexpectedly rejected: ".concat((e_5 === null || e_5 === void 0 ? void 0 : e_5.message) || (e_5 === null || e_5 === void 0 ? void 0 : e_5.toString()));
222
+ return [3 /*break*/, 27];
223
+ case 27:
224
+ record('C1: staff can still load booking info for a specific enduser', c1Pass, c1Detail);
225
+ c2Detail = '';
226
+ c2Pass = false;
227
+ _g.label = 28;
228
+ case 28:
229
+ _g.trys.push([28, 30, , 31]);
230
+ return [4 /*yield*/, sdk.api.form_fields.booking_info({ bookingPageId: bookingPageId })];
231
+ case 29:
232
+ r = _g.sent();
233
+ c2Pass = !!r.bookingURL && !!r.warningMessage;
234
+ c2Detail = "warningMessage=".concat(JSON.stringify(r.warningMessage), " bookingURL=").concat(!!r.bookingURL);
235
+ return [3 /*break*/, 31];
236
+ case 30:
237
+ e_6 = _g.sent();
238
+ c2Detail = "unexpectedly rejected: ".concat((e_6 === null || e_6 === void 0 ? void 0 : e_6.message) || (e_6 === null || e_6 === void 0 ? void 0 : e_6.toString()));
239
+ return [3 /*break*/, 31];
240
+ case 31:
241
+ record('C2: staff test-contact preview branch still works', c2Pass, c2Detail);
242
+ /* ===== report: print full table first, then assert (harness exits on first failure) ===== */
243
+ console.log('\n check summary:');
244
+ for (_i = 0, checks_1 = checks; _i < checks_1.length; _i++) {
245
+ c = checks_1[_i];
246
+ console.log(" ".concat(c.pass ? 'PASS' : 'FAIL', " ").concat(c.label, " \u2014 ").concat(c.detail));
247
+ }
248
+ console.log('');
249
+ for (_b = 0, checks_2 = checks; _b < checks_2.length; _b++) {
250
+ c = checks_2[_b];
251
+ assert(c.pass, "".concat(c.label, " \u2014 ").concat(c.detail), c.label);
252
+ }
253
+ return [3 /*break*/, 47];
254
+ case 32:
255
+ _c = 0, enduserIds_1 = enduserIds;
256
+ _g.label = 33;
257
+ case 33:
258
+ if (!(_c < enduserIds_1.length)) return [3 /*break*/, 38];
259
+ id = enduserIds_1[_c];
260
+ _g.label = 34;
261
+ case 34:
262
+ _g.trys.push([34, 36, , 37]);
263
+ return [4 /*yield*/, sdk.api.endusers.deleteOne(id)];
264
+ case 35:
265
+ _g.sent();
266
+ return [3 /*break*/, 37];
267
+ case 36:
268
+ _d = _g.sent();
269
+ return [3 /*break*/, 37];
270
+ case 37:
271
+ _c++;
272
+ return [3 /*break*/, 33];
273
+ case 38:
274
+ if (!bookingPageId) return [3 /*break*/, 42];
275
+ _g.label = 39;
276
+ case 39:
277
+ _g.trys.push([39, 41, , 42]);
278
+ return [4 /*yield*/, sdk.api.appointment_booking_pages.deleteOne(bookingPageId)];
279
+ case 40:
280
+ _g.sent();
281
+ return [3 /*break*/, 42];
282
+ case 41:
283
+ _e = _g.sent();
284
+ return [3 /*break*/, 42];
285
+ case 42:
286
+ if (!templateId) return [3 /*break*/, 46];
287
+ _g.label = 43;
288
+ case 43:
289
+ _g.trys.push([43, 45, , 46]);
290
+ return [4 /*yield*/, sdk.api.calendar_event_templates.deleteOne(templateId)];
291
+ case 44:
292
+ _g.sent();
293
+ return [3 /*break*/, 46];
294
+ case 45:
295
+ _f = _g.sent();
296
+ return [3 /*break*/, 46];
297
+ case 46: return [7 /*endfinally*/];
298
+ case 47: return [2 /*return*/];
299
+ }
300
+ });
301
+ });
302
+ };
303
+ // Allow running this test file independently
304
+ if (require.main === module) {
305
+ console.log("\uD83C\uDF10 Using API URL: ".concat(host));
306
+ var sdk_1 = new Session({ host: host });
307
+ var sdkNonAdmin_1 = new Session({ host: host });
308
+ var runTests = function () { return __awaiter(void 0, void 0, void 0, function () {
309
+ return __generator(this, function (_a) {
310
+ switch (_a.label) {
311
+ case 0: return [4 /*yield*/, setup_tests(sdk_1, sdkNonAdmin_1)];
312
+ case 1:
313
+ _a.sent();
314
+ return [4 /*yield*/, booking_info_idor_tests({ sdk: sdk_1, sdkNonAdmin: sdkNonAdmin_1 })];
315
+ case 2:
316
+ _a.sent();
317
+ return [2 /*return*/];
318
+ }
319
+ });
320
+ }); };
321
+ runTests()
322
+ .then(function () {
323
+ console.log("✅ booking_info IDOR test suite completed successfully");
324
+ process.exit(0);
325
+ })
326
+ .catch(function (error) {
327
+ console.error("❌ booking_info IDOR test suite failed:", error);
328
+ process.exit(1);
329
+ });
330
+ }
331
+ //# sourceMappingURL=booking-info-idor-token-mint.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"booking-info-idor-token-mint.test.js","sourceRoot":"","sources":["../../../../../src/tests/api_tests/security/booking-info-idor-token-mint.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ import { Session } from "../../../sdk";
2
+ /**
3
+ * Tenant-boundary guard for cascade_role_rename (relates to a prior internal review,
4
+ * which was investigated and closed as a FALSE POSITIVE — see that file for the code trace).
5
+ *
6
+ * The `cascade_role_rename` side-effect handler
7
+ * ([event_handlers_v2/role_based_access_permissions.ts](packages/private/api/api/v1/event_handlers_v2/role_based_access_permissions.ts))
8
+ * runs when a `role_based_access_permissions` doc's `role` field changes. It finds every user
9
+ * with the old role name (via `DBUnrestricted.users`) and rewrites their `roles` array, then
10
+ * deauthenticates them. An earlier review hypothesized this query was globally cross-tenant. It is NOT:
11
+ * `DBUnrestricted` bypasses per-user/per-role RBAC but is STILL scoped to the acting session's
12
+ * `businessId` (see `modifyFilterForAccessConstraint` injecting `{ businessId }` at
13
+ * database.ts:1761-1763, reached via the `unrestricted: true` branch at database.ts:2137-2144).
14
+ *
15
+ * This test locks that boundary in place so a future refactor of `DBUnrestricted` semantics
16
+ * can't silently turn the cascade into a cross-tenant write:
17
+ * 1. Tenant A creates a role `ROLE_OLD` and assigns it to a Tenant A user (positive control).
18
+ * 2. Tenant B (separate businessId) has a user whose roles include the SAME `ROLE_OLD`.
19
+ * 3. Tenant A renames the role `ROLE_OLD` -> `ROLE_NEW`.
20
+ * 4. Assert the Tenant B user's roles are UNCHANGED (still `[ROLE_OLD]`) <-- guards the tenant boundary.
21
+ * 5. Assert the Tenant A user's roles ARE renamed to `[ROLE_NEW]` <-- same-tenant cascade works.
22
+ *
23
+ * Expected on current (correct) code: BOTH assertions pass. A regression that drops the
24
+ * `businessId` scoping would flip assertion #4 to red (Tenant B user becomes `[ROLE_NEW]`).
25
+ *
26
+ * A collision-proof unique role name (timestamped) is used so the test never touches real roles.
27
+ */
28
+ export declare const cascade_role_rename_cross_tenant_tests: ({ sdk }: {
29
+ sdk: Session;
30
+ sdkNonAdmin: Session;
31
+ }) => Promise<void>;
32
+ //# sourceMappingURL=cascade-role-rename-cross-tenant.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cascade-role-rename-cross-tenant.test.d.ts","sourceRoot":"","sources":["../../../../../src/tests/api_tests/security/cascade-role-rename-cross-tenant.test.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAetC;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,sCAAsC;SAA2B,OAAO;iBAAe,OAAO;mBA+F1G,CAAA"}
@@ -0,0 +1,233 @@
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 } from "../../../sdk";
50
+ import { assert, log_header, wait, } from "@tellescope/testing";
51
+ import { setup_tests } from "../../setup";
52
+ import { PROVIDER_PERMISSIONS } from "@tellescope/constants";
53
+ var host = process.env.API_URL || 'http://localhost:8080';
54
+ // Separate tenant (different businessId), reusing the same hardcoded apiKey that
55
+ // multi_tenant_tests relies on in tests.ts.
56
+ var OTHER_TENANT_API_KEY = "ba745e25162bb95a795c5fa1af70df188d93c4d3aac9c48b34a5c8c9dd7b80f7";
57
+ /**
58
+ * Tenant-boundary guard for cascade_role_rename (relates to a prior internal review,
59
+ * which was investigated and closed as a FALSE POSITIVE — see that file for the code trace).
60
+ *
61
+ * The `cascade_role_rename` side-effect handler
62
+ * ([event_handlers_v2/role_based_access_permissions.ts](packages/private/api/api/v1/event_handlers_v2/role_based_access_permissions.ts))
63
+ * runs when a `role_based_access_permissions` doc's `role` field changes. It finds every user
64
+ * with the old role name (via `DBUnrestricted.users`) and rewrites their `roles` array, then
65
+ * deauthenticates them. An earlier review hypothesized this query was globally cross-tenant. It is NOT:
66
+ * `DBUnrestricted` bypasses per-user/per-role RBAC but is STILL scoped to the acting session's
67
+ * `businessId` (see `modifyFilterForAccessConstraint` injecting `{ businessId }` at
68
+ * database.ts:1761-1763, reached via the `unrestricted: true` branch at database.ts:2137-2144).
69
+ *
70
+ * This test locks that boundary in place so a future refactor of `DBUnrestricted` semantics
71
+ * can't silently turn the cascade into a cross-tenant write:
72
+ * 1. Tenant A creates a role `ROLE_OLD` and assigns it to a Tenant A user (positive control).
73
+ * 2. Tenant B (separate businessId) has a user whose roles include the SAME `ROLE_OLD`.
74
+ * 3. Tenant A renames the role `ROLE_OLD` -> `ROLE_NEW`.
75
+ * 4. Assert the Tenant B user's roles are UNCHANGED (still `[ROLE_OLD]`) <-- guards the tenant boundary.
76
+ * 5. Assert the Tenant A user's roles ARE renamed to `[ROLE_NEW]` <-- same-tenant cascade works.
77
+ *
78
+ * Expected on current (correct) code: BOTH assertions pass. A regression that drops the
79
+ * `businessId` scoping would flip assertion #4 to red (Tenant B user becomes `[ROLE_NEW]`).
80
+ *
81
+ * A collision-proof unique role name (timestamped) is used so the test never touches real roles.
82
+ */
83
+ export var cascade_role_rename_cross_tenant_tests = function (_a) {
84
+ var sdk = _a.sdk;
85
+ return __awaiter(void 0, void 0, void 0, function () {
86
+ var stamp, ROLE_OLD, ROLE_NEW, sdkOther, rbapId, controlUserId, victimUserId, tenantABusinessId, rbap, controlUser, victimUser, victimBefore, controlBefore, victimAfter, controlAfter, _b, _c, _d;
87
+ return __generator(this, function (_e) {
88
+ switch (_e.label) {
89
+ case 0:
90
+ log_header("cascade role rename cross-tenant regression");
91
+ stamp = Date.now();
92
+ ROLE_OLD = "XTenantRename_".concat(stamp);
93
+ ROLE_NEW = "".concat(ROLE_OLD, "_renamed");
94
+ sdkOther = new Session({ host: host, apiKey: OTHER_TENANT_API_KEY });
95
+ _e.label = 1;
96
+ case 1:
97
+ _e.trys.push([1, , 13, 26]);
98
+ tenantABusinessId = sdk.userInfo.businessId;
99
+ return [4 /*yield*/, sdk.api.role_based_access_permissions.createOne({
100
+ role: ROLE_OLD,
101
+ permissions: __assign({}, PROVIDER_PERMISSIONS),
102
+ })];
103
+ case 2:
104
+ rbap = _e.sent();
105
+ rbapId = rbap.id;
106
+ return [4 /*yield*/, sdk.api.users.createOne({
107
+ email: "f0053-control-".concat(stamp, "@example.com"),
108
+ notificationEmailsDisabled: true,
109
+ })];
110
+ case 3:
111
+ controlUser = _e.sent();
112
+ controlUserId = controlUser.id;
113
+ return [4 /*yield*/, sdk.api.users.updateOne(controlUserId, { roles: [ROLE_OLD] }, { replaceObjectFields: true })
114
+ // 3. Tenant B: create a throwaway victim user holding the SAME ROLE_OLD.
115
+ ];
116
+ case 4:
117
+ _e.sent();
118
+ return [4 /*yield*/, sdkOther.api.users.createOne({
119
+ email: "f0053-victim-".concat(stamp, "@example.com"),
120
+ notificationEmailsDisabled: true,
121
+ })];
122
+ case 5:
123
+ victimUser = _e.sent();
124
+ victimUserId = victimUser.id;
125
+ return [4 /*yield*/, sdkOther.api.users.updateOne(victimUserId, { roles: [ROLE_OLD] }, { replaceObjectFields: true })
126
+ // 4. Setup sanity: tenants are distinct and both users actually hold ROLE_OLD before the rename.
127
+ // (Distinguishes a setup failure from the security assertion below.)
128
+ ];
129
+ case 6:
130
+ _e.sent();
131
+ // 4. Setup sanity: tenants are distinct and both users actually hold ROLE_OLD before the rename.
132
+ // (Distinguishes a setup failure from the security assertion below.)
133
+ assert(victimUser.businessId !== tenantABusinessId, "Victim user shares businessId with Tenant A (".concat(victimUser.businessId, ") \u2014 not a cross-tenant scenario"), 'setup: tenants are distinct');
134
+ return [4 /*yield*/, sdkOther.api.users.getOne(victimUserId)];
135
+ case 7:
136
+ victimBefore = _e.sent();
137
+ return [4 /*yield*/, sdk.api.users.getOne(controlUserId)];
138
+ case 8:
139
+ controlBefore = _e.sent();
140
+ assert(JSON.stringify(victimBefore.roles) === JSON.stringify([ROLE_OLD])
141
+ && JSON.stringify(controlBefore.roles) === JSON.stringify([ROLE_OLD]), "Setup failed: expected both users to hold [".concat(ROLE_OLD, "] (victim=").concat(JSON.stringify(victimBefore.roles), ", control=").concat(JSON.stringify(controlBefore.roles), ")"), 'setup: both users hold ROLE_OLD');
142
+ // 5. Tenant A renames the role. This triggers cascade_role_rename.
143
+ return [4 /*yield*/, sdk.api.role_based_access_permissions.updateOne(rbapId, { role: ROLE_NEW })];
144
+ case 9:
145
+ // 5. Tenant A renames the role. This triggers cascade_role_rename.
146
+ _e.sent();
147
+ return [4 /*yield*/, wait(undefined, 1500)
148
+ // 6. SECURITY ASSERTION — the Tenant B victim must be untouched by Tenant A's rename.
149
+ ]; // let the side effect run
150
+ case 10:
151
+ _e.sent(); // let the side effect run
152
+ return [4 /*yield*/, sdkOther.api.users.getOne(victimUserId)];
153
+ case 11:
154
+ victimAfter = _e.sent();
155
+ assert(JSON.stringify(victimAfter.roles) === JSON.stringify([ROLE_OLD]), "CROSS-TENANT LEAK: Tenant B victim roles changed to ".concat(JSON.stringify(victimAfter.roles), " ")
156
+ + "after Tenant A renamed its role. Expected [".concat(ROLE_OLD, "]."), 'Tenant B user roles unaffected by other-tenant role rename');
157
+ return [4 /*yield*/, sdk.api.users.getOne(controlUserId)];
158
+ case 12:
159
+ controlAfter = _e.sent();
160
+ assert(JSON.stringify(controlAfter.roles) === JSON.stringify([ROLE_NEW]), "Same-tenant cascade broken: Tenant A control roles are ".concat(JSON.stringify(controlAfter.roles), ", ")
161
+ + "expected [".concat(ROLE_NEW, "]."), 'Tenant A user roles renamed by same-tenant cascade');
162
+ return [3 /*break*/, 26];
163
+ case 13:
164
+ if (!victimUserId) return [3 /*break*/, 17];
165
+ _e.label = 14;
166
+ case 14:
167
+ _e.trys.push([14, 16, , 17]);
168
+ return [4 /*yield*/, sdkOther.api.users.deleteOne(victimUserId)];
169
+ case 15:
170
+ _e.sent();
171
+ return [3 /*break*/, 17];
172
+ case 16:
173
+ _b = _e.sent();
174
+ return [3 /*break*/, 17];
175
+ case 17:
176
+ if (!controlUserId) return [3 /*break*/, 21];
177
+ _e.label = 18;
178
+ case 18:
179
+ _e.trys.push([18, 20, , 21]);
180
+ return [4 /*yield*/, sdk.api.users.deleteOne(controlUserId)];
181
+ case 19:
182
+ _e.sent();
183
+ return [3 /*break*/, 21];
184
+ case 20:
185
+ _c = _e.sent();
186
+ return [3 /*break*/, 21];
187
+ case 21:
188
+ if (!rbapId) return [3 /*break*/, 25];
189
+ _e.label = 22;
190
+ case 22:
191
+ _e.trys.push([22, 24, , 25]);
192
+ return [4 /*yield*/, sdk.api.role_based_access_permissions.deleteOne(rbapId)];
193
+ case 23:
194
+ _e.sent();
195
+ return [3 /*break*/, 25];
196
+ case 24:
197
+ _d = _e.sent();
198
+ return [3 /*break*/, 25];
199
+ case 25: return [7 /*endfinally*/];
200
+ case 26: return [2 /*return*/];
201
+ }
202
+ });
203
+ });
204
+ };
205
+ // Allow running this test file independently
206
+ if (require.main === module) {
207
+ console.log("\uD83C\uDF10 Using API URL: ".concat(host));
208
+ var sdk_1 = new Session({ host: host });
209
+ var sdkNonAdmin_1 = new Session({ host: host });
210
+ var runTests = function () { return __awaiter(void 0, void 0, void 0, function () {
211
+ return __generator(this, function (_a) {
212
+ switch (_a.label) {
213
+ case 0: return [4 /*yield*/, setup_tests(sdk_1, sdkNonAdmin_1)];
214
+ case 1:
215
+ _a.sent();
216
+ return [4 /*yield*/, cascade_role_rename_cross_tenant_tests({ sdk: sdk_1, sdkNonAdmin: sdkNonAdmin_1 })];
217
+ case 2:
218
+ _a.sent();
219
+ return [2 /*return*/];
220
+ }
221
+ });
222
+ }); };
223
+ runTests()
224
+ .then(function () {
225
+ console.log("✅ cascade role rename cross-tenant test suite completed successfully");
226
+ process.exit(0);
227
+ })
228
+ .catch(function (error) {
229
+ console.error("❌ cascade role rename cross-tenant test suite failed:", error);
230
+ process.exit(1);
231
+ });
232
+ }
233
+ //# sourceMappingURL=cascade-role-rename-cross-tenant.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cascade-role-rename-cross-tenant.test.js","sourceRoot":"","sources":["../../../../../src/tests/api_tests/security/cascade-role-rename-cross-tenant.test.ts"],"names":[],"mappings":"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"}