@tellescope/sdk 1.256.14 → 1.256.15
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.
- package/lib/cjs/tests/api_tests/auto_merge_form_submission.test.js +1 -1
- package/lib/cjs/tests/api_tests/auto_merge_form_submission.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/enduser_observations_auto_review.test.d.ts +5 -0
- package/lib/cjs/tests/api_tests/enduser_observations_auto_review.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/enduser_observations_auto_review.test.js +388 -0
- package/lib/cjs/tests/api_tests/enduser_observations_auto_review.test.js.map +1 -0
- package/lib/cjs/tests/api_tests/integrations_redacted.test.js +3 -3
- package/lib/cjs/tests/api_tests/integrations_redacted.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/organization_signup.test.d.ts +1 -1
- package/lib/cjs/tests/api_tests/organization_signup.test.js +1 -1
- package/lib/cjs/tests/api_tests/purchase_made_trigger.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/purchase_made_trigger.test.js +103 -162
- package/lib/cjs/tests/api_tests/purchase_made_trigger.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/security/F-0200-form-logic-js-execution.test.d.ts +33 -0
- package/lib/cjs/tests/api_tests/security/F-0200-form-logic-js-execution.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/security/F-0200-form-logic-js-execution.test.js +249 -0
- package/lib/cjs/tests/api_tests/security/F-0200-form-logic-js-execution.test.js.map +1 -0
- package/lib/cjs/tests/api_tests/security/add-to-journey-foreign-enduserid.test.d.ts +42 -0
- package/lib/cjs/tests/api_tests/security/add-to-journey-foreign-enduserid.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/security/add-to-journey-foreign-enduserid.test.js +281 -0
- package/lib/cjs/tests/api_tests/security/add-to-journey-foreign-enduserid.test.js.map +1 -0
- package/lib/cjs/tests/api_tests/security/ai-conversations-rbac.test.d.ts +38 -0
- package/lib/cjs/tests/api_tests/security/ai-conversations-rbac.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/security/ai-conversations-rbac.test.js +390 -0
- package/lib/cjs/tests/api_tests/security/ai-conversations-rbac.test.js.map +1 -0
- package/lib/cjs/tests/api_tests/security/allowed-paths-confinement.test.d.ts +6 -0
- package/lib/cjs/tests/api_tests/security/allowed-paths-confinement.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/security/allowed-paths-confinement.test.js +1003 -0
- package/lib/cjs/tests/api_tests/security/allowed-paths-confinement.test.js.map +1 -0
- package/lib/cjs/tests/api_tests/security/automated-actions-process-gate.test.d.ts +42 -0
- package/lib/cjs/tests/api_tests/security/automated-actions-process-gate.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/security/automated-actions-process-gate.test.js +323 -0
- package/lib/cjs/tests/api_tests/security/automated-actions-process-gate.test.js.map +1 -0
- package/lib/cjs/tests/api_tests/security/booking-info-idor-token-mint.test.d.ts +29 -0
- package/lib/cjs/tests/api_tests/security/booking-info-idor-token-mint.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/security/booking-info-idor-token-mint.test.js +335 -0
- package/lib/cjs/tests/api_tests/security/booking-info-idor-token-mint.test.js.map +1 -0
- package/lib/cjs/tests/api_tests/security/cascade-role-rename-cross-tenant.test.d.ts +32 -0
- package/lib/cjs/tests/api_tests/security/cascade-role-rename-cross-tenant.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/security/cascade-role-rename-cross-tenant.test.js +237 -0
- package/lib/cjs/tests/api_tests/security/cascade-role-rename-cross-tenant.test.js.map +1 -0
- package/lib/cjs/tests/api_tests/security/data-sync-redaction-bypass.test.d.ts +28 -0
- package/lib/cjs/tests/api_tests/security/data-sync-redaction-bypass.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/security/data-sync-redaction-bypass.test.js +349 -0
- package/lib/cjs/tests/api_tests/security/data-sync-redaction-bypass.test.js.map +1 -0
- package/lib/cjs/tests/api_tests/security/develop-health-benefit-verification-rbac.test.d.ts +30 -0
- package/lib/cjs/tests/api_tests/security/develop-health-benefit-verification-rbac.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/security/develop-health-benefit-verification-rbac.test.js +314 -0
- package/lib/cjs/tests/api_tests/security/develop-health-benefit-verification-rbac.test.js.map +1 -0
- package/lib/cjs/tests/api_tests/security/enduser-cross-create.test.d.ts +21 -0
- package/lib/cjs/tests/api_tests/security/enduser-cross-create.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/security/enduser-cross-create.test.js +362 -0
- package/lib/cjs/tests/api_tests/security/enduser-cross-create.test.js.map +1 -0
- package/lib/cjs/tests/api_tests/security/enduser-write-restrictions.test.d.ts +21 -0
- package/lib/cjs/tests/api_tests/security/enduser-write-restrictions.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/security/enduser-write-restrictions.test.js +366 -0
- package/lib/cjs/tests/api_tests/security/enduser-write-restrictions.test.js.map +1 -0
- package/lib/cjs/tests/api_tests/security/form-logic-js-execution.test.d.ts +32 -0
- package/lib/cjs/tests/api_tests/security/form-logic-js-execution.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/security/form-logic-js-execution.test.js +248 -0
- package/lib/cjs/tests/api_tests/security/form-logic-js-execution.test.js.map +1 -0
- package/lib/cjs/tests/api_tests/security/globalunique-conflict-redaction.test.d.ts +19 -0
- package/lib/cjs/tests/api_tests/security/globalunique-conflict-redaction.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/security/globalunique-conflict-redaction.test.js +138 -0
- package/lib/cjs/tests/api_tests/security/globalunique-conflict-redaction.test.js.map +1 -0
- package/lib/cjs/tests/api_tests/security/handle-incoming-communication-cross-tenant.test.d.ts +24 -0
- package/lib/cjs/tests/api_tests/security/handle-incoming-communication-cross-tenant.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/security/handle-incoming-communication-cross-tenant.test.js +201 -0
- package/lib/cjs/tests/api_tests/security/handle-incoming-communication-cross-tenant.test.js.map +1 -0
- package/lib/cjs/tests/api_tests/security/invite-user-enumeration.test.d.ts +29 -0
- package/lib/cjs/tests/api_tests/security/invite-user-enumeration.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/security/invite-user-enumeration.test.js +278 -0
- package/lib/cjs/tests/api_tests/security/invite-user-enumeration.test.js.map +1 -0
- package/lib/cjs/tests/api_tests/security/load-inbox-redaction.test.d.ts +17 -0
- package/lib/cjs/tests/api_tests/security/load-inbox-redaction.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/security/load-inbox-redaction.test.js +155 -0
- package/lib/cjs/tests/api_tests/security/load-inbox-redaction.test.js.map +1 -0
- package/lib/cjs/tests/api_tests/security/prototype-pollution.test.d.ts +2 -0
- package/lib/cjs/tests/api_tests/security/prototype-pollution.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/security/prototype-pollution.test.js +88 -0
- package/lib/cjs/tests/api_tests/security/prototype-pollution.test.js.map +1 -0
- package/lib/cjs/tests/api_tests/security/proxy-image-unauth-ssrf.test.d.ts +34 -0
- package/lib/cjs/tests/api_tests/security/proxy-image-unauth-ssrf.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/security/proxy-image-unauth-ssrf.test.js +230 -0
- package/lib/cjs/tests/api_tests/security/proxy-image-unauth-ssrf.test.js.map +1 -0
- package/lib/cjs/tests/api_tests/security/sanitize-user-html-with-iframes.test.d.ts +2 -0
- package/lib/cjs/tests/api_tests/security/sanitize-user-html-with-iframes.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/security/sanitize-user-html-with-iframes.test.js +242 -0
- package/lib/cjs/tests/api_tests/security/sanitize-user-html-with-iframes.test.js.map +1 -0
- package/lib/cjs/tests/api_tests/security/sanitize-user-html.test.d.ts +2 -0
- package/lib/cjs/tests/api_tests/security/sanitize-user-html.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/security/sanitize-user-html.test.js +148 -0
- package/lib/cjs/tests/api_tests/security/sanitize-user-html.test.js.map +1 -0
- package/lib/cjs/tests/api_tests/security/schema-adminonly-enforcement.test.d.ts +45 -0
- package/lib/cjs/tests/api_tests/security/schema-adminonly-enforcement.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/security/schema-adminonly-enforcement.test.js +388 -0
- package/lib/cjs/tests/api_tests/security/schema-adminonly-enforcement.test.js.map +1 -0
- package/lib/cjs/tests/api_tests/security/self-admin-role-assignment.test.d.ts +38 -0
- package/lib/cjs/tests/api_tests/security/self-admin-role-assignment.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/security/self-admin-role-assignment.test.js +222 -0
- package/lib/cjs/tests/api_tests/security/self-admin-role-assignment.test.js.map +1 -0
- package/lib/cjs/tests/api_tests/security/startlinktoken-enduser-staff-escalation.test.d.ts +6 -0
- package/lib/cjs/tests/api_tests/security/startlinktoken-enduser-staff-escalation.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/security/startlinktoken-enduser-staff-escalation.test.js +354 -0
- package/lib/cjs/tests/api_tests/security/startlinktoken-enduser-staff-escalation.test.js.map +1 -0
- package/lib/cjs/tests/api_tests/security/webhook-outbound-ssrf.test.d.ts +28 -0
- package/lib/cjs/tests/api_tests/security/webhook-outbound-ssrf.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/security/webhook-outbound-ssrf.test.js +442 -0
- package/lib/cjs/tests/api_tests/security/webhook-outbound-ssrf.test.js.map +1 -0
- package/lib/cjs/tests/api_tests/security/webhook-timeout.test.d.ts +19 -0
- package/lib/cjs/tests/api_tests/security/webhook-timeout.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/security/webhook-timeout.test.js +156 -0
- package/lib/cjs/tests/api_tests/security/webhook-timeout.test.js.map +1 -0
- package/lib/cjs/tests/api_tests/webhook_error_handling.test.js +2 -2
- package/lib/cjs/tests/api_tests/webhook_error_handling.test.js.map +1 -1
- package/lib/cjs/tests/tests.d.ts.map +1 -1
- package/lib/cjs/tests/tests.js +58 -46
- package/lib/cjs/tests/tests.js.map +1 -1
- package/lib/cjs/tests/unit_tests/openapi_spec_freshness.test.d.ts +1 -1
- package/lib/cjs/tests/unit_tests/openapi_spec_freshness.test.js +1 -1
- package/lib/cjs/tsconfig.cjs.tsbuildinfo +1 -0
- package/lib/esm/enduser.d.ts +0 -1
- package/lib/esm/enduser.d.ts.map +1 -1
- package/lib/esm/sdk.d.ts +2 -3
- package/lib/esm/sdk.d.ts.map +1 -1
- package/lib/esm/session.d.ts +0 -1
- package/lib/esm/session.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/auto_merge_form_submission.test.js +1 -1
- package/lib/esm/tests/api_tests/auto_merge_form_submission.test.js.map +1 -1
- package/lib/esm/tests/api_tests/enduser_observations_auto_review.test.d.ts +5 -0
- package/lib/esm/tests/api_tests/enduser_observations_auto_review.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/enduser_observations_auto_review.test.js +383 -0
- package/lib/esm/tests/api_tests/enduser_observations_auto_review.test.js.map +1 -0
- package/lib/esm/tests/api_tests/integrations_redacted.test.js +3 -3
- package/lib/esm/tests/api_tests/integrations_redacted.test.js.map +1 -1
- package/lib/esm/tests/api_tests/organization_signup.test.d.ts +1 -1
- package/lib/esm/tests/api_tests/organization_signup.test.js +1 -1
- package/lib/esm/tests/api_tests/purchase_made_trigger.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/purchase_made_trigger.test.js +104 -163
- package/lib/esm/tests/api_tests/purchase_made_trigger.test.js.map +1 -1
- package/lib/esm/tests/api_tests/security/F-0200-form-logic-js-execution.test.d.ts +33 -0
- package/lib/esm/tests/api_tests/security/F-0200-form-logic-js-execution.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/security/F-0200-form-logic-js-execution.test.js +244 -0
- package/lib/esm/tests/api_tests/security/F-0200-form-logic-js-execution.test.js.map +1 -0
- package/lib/esm/tests/api_tests/security/add-to-journey-foreign-enduserid.test.d.ts +42 -0
- package/lib/esm/tests/api_tests/security/add-to-journey-foreign-enduserid.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/security/add-to-journey-foreign-enduserid.test.js +276 -0
- package/lib/esm/tests/api_tests/security/add-to-journey-foreign-enduserid.test.js.map +1 -0
- package/lib/esm/tests/api_tests/security/ai-conversations-rbac.test.d.ts +38 -0
- package/lib/esm/tests/api_tests/security/ai-conversations-rbac.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/security/ai-conversations-rbac.test.js +386 -0
- package/lib/esm/tests/api_tests/security/ai-conversations-rbac.test.js.map +1 -0
- package/lib/esm/tests/api_tests/security/allowed-paths-confinement.test.d.ts +6 -0
- package/lib/esm/tests/api_tests/security/allowed-paths-confinement.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/security/allowed-paths-confinement.test.js +996 -0
- package/lib/esm/tests/api_tests/security/allowed-paths-confinement.test.js.map +1 -0
- package/lib/esm/tests/api_tests/security/automated-actions-process-gate.test.d.ts +42 -0
- package/lib/esm/tests/api_tests/security/automated-actions-process-gate.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/security/automated-actions-process-gate.test.js +316 -0
- package/lib/esm/tests/api_tests/security/automated-actions-process-gate.test.js.map +1 -0
- package/lib/esm/tests/api_tests/security/booking-info-idor-token-mint.test.d.ts +29 -0
- package/lib/esm/tests/api_tests/security/booking-info-idor-token-mint.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/security/booking-info-idor-token-mint.test.js +331 -0
- package/lib/esm/tests/api_tests/security/booking-info-idor-token-mint.test.js.map +1 -0
- package/lib/esm/tests/api_tests/security/cascade-role-rename-cross-tenant.test.d.ts +32 -0
- package/lib/esm/tests/api_tests/security/cascade-role-rename-cross-tenant.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/security/cascade-role-rename-cross-tenant.test.js +233 -0
- package/lib/esm/tests/api_tests/security/cascade-role-rename-cross-tenant.test.js.map +1 -0
- package/lib/esm/tests/api_tests/security/data-sync-redaction-bypass.test.d.ts +28 -0
- package/lib/esm/tests/api_tests/security/data-sync-redaction-bypass.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/security/data-sync-redaction-bypass.test.js +345 -0
- package/lib/esm/tests/api_tests/security/data-sync-redaction-bypass.test.js.map +1 -0
- package/lib/esm/tests/api_tests/security/develop-health-benefit-verification-rbac.test.d.ts +30 -0
- package/lib/esm/tests/api_tests/security/develop-health-benefit-verification-rbac.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/security/develop-health-benefit-verification-rbac.test.js +310 -0
- package/lib/esm/tests/api_tests/security/develop-health-benefit-verification-rbac.test.js.map +1 -0
- package/lib/esm/tests/api_tests/security/enduser-cross-create.test.d.ts +21 -0
- package/lib/esm/tests/api_tests/security/enduser-cross-create.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/security/enduser-cross-create.test.js +358 -0
- package/lib/esm/tests/api_tests/security/enduser-cross-create.test.js.map +1 -0
- package/lib/esm/tests/api_tests/security/enduser-write-restrictions.test.d.ts +21 -0
- package/lib/esm/tests/api_tests/security/enduser-write-restrictions.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/security/enduser-write-restrictions.test.js +362 -0
- package/lib/esm/tests/api_tests/security/enduser-write-restrictions.test.js.map +1 -0
- package/lib/esm/tests/api_tests/security/form-logic-js-execution.test.d.ts +32 -0
- package/lib/esm/tests/api_tests/security/form-logic-js-execution.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/security/form-logic-js-execution.test.js +243 -0
- package/lib/esm/tests/api_tests/security/form-logic-js-execution.test.js.map +1 -0
- package/lib/esm/tests/api_tests/security/globalunique-conflict-redaction.test.d.ts +19 -0
- package/lib/esm/tests/api_tests/security/globalunique-conflict-redaction.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/security/globalunique-conflict-redaction.test.js +134 -0
- package/lib/esm/tests/api_tests/security/globalunique-conflict-redaction.test.js.map +1 -0
- package/lib/esm/tests/api_tests/security/handle-incoming-communication-cross-tenant.test.d.ts +24 -0
- package/lib/esm/tests/api_tests/security/handle-incoming-communication-cross-tenant.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/security/handle-incoming-communication-cross-tenant.test.js +194 -0
- package/lib/esm/tests/api_tests/security/handle-incoming-communication-cross-tenant.test.js.map +1 -0
- package/lib/esm/tests/api_tests/security/invite-user-enumeration.test.d.ts +29 -0
- package/lib/esm/tests/api_tests/security/invite-user-enumeration.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/security/invite-user-enumeration.test.js +271 -0
- package/lib/esm/tests/api_tests/security/invite-user-enumeration.test.js.map +1 -0
- package/lib/esm/tests/api_tests/security/load-inbox-redaction.test.d.ts +17 -0
- package/lib/esm/tests/api_tests/security/load-inbox-redaction.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/security/load-inbox-redaction.test.js +151 -0
- package/lib/esm/tests/api_tests/security/load-inbox-redaction.test.js.map +1 -0
- package/lib/esm/tests/api_tests/security/prototype-pollution.test.d.ts +2 -0
- package/lib/esm/tests/api_tests/security/prototype-pollution.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/security/prototype-pollution.test.js +84 -0
- package/lib/esm/tests/api_tests/security/prototype-pollution.test.js.map +1 -0
- package/lib/esm/tests/api_tests/security/proxy-image-unauth-ssrf.test.d.ts +34 -0
- package/lib/esm/tests/api_tests/security/proxy-image-unauth-ssrf.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/security/proxy-image-unauth-ssrf.test.js +223 -0
- package/lib/esm/tests/api_tests/security/proxy-image-unauth-ssrf.test.js.map +1 -0
- package/lib/esm/tests/api_tests/security/sanitize-user-html-with-iframes.test.d.ts +2 -0
- package/lib/esm/tests/api_tests/security/sanitize-user-html-with-iframes.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/security/sanitize-user-html-with-iframes.test.js +238 -0
- package/lib/esm/tests/api_tests/security/sanitize-user-html-with-iframes.test.js.map +1 -0
- package/lib/esm/tests/api_tests/security/sanitize-user-html.test.d.ts +2 -0
- package/lib/esm/tests/api_tests/security/sanitize-user-html.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/security/sanitize-user-html.test.js +144 -0
- package/lib/esm/tests/api_tests/security/sanitize-user-html.test.js.map +1 -0
- package/lib/esm/tests/api_tests/security/schema-adminonly-enforcement.test.d.ts +45 -0
- package/lib/esm/tests/api_tests/security/schema-adminonly-enforcement.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/security/schema-adminonly-enforcement.test.js +381 -0
- package/lib/esm/tests/api_tests/security/schema-adminonly-enforcement.test.js.map +1 -0
- package/lib/esm/tests/api_tests/security/self-admin-role-assignment.test.d.ts +38 -0
- package/lib/esm/tests/api_tests/security/self-admin-role-assignment.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/security/self-admin-role-assignment.test.js +218 -0
- package/lib/esm/tests/api_tests/security/self-admin-role-assignment.test.js.map +1 -0
- package/lib/esm/tests/api_tests/security/startlinktoken-enduser-staff-escalation.test.d.ts +6 -0
- package/lib/esm/tests/api_tests/security/startlinktoken-enduser-staff-escalation.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/security/startlinktoken-enduser-staff-escalation.test.js +350 -0
- package/lib/esm/tests/api_tests/security/startlinktoken-enduser-staff-escalation.test.js.map +1 -0
- package/lib/esm/tests/api_tests/security/webhook-outbound-ssrf.test.d.ts +28 -0
- package/lib/esm/tests/api_tests/security/webhook-outbound-ssrf.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/security/webhook-outbound-ssrf.test.js +435 -0
- package/lib/esm/tests/api_tests/security/webhook-outbound-ssrf.test.js.map +1 -0
- package/lib/esm/tests/api_tests/security/webhook-timeout.test.d.ts +19 -0
- package/lib/esm/tests/api_tests/security/webhook-timeout.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/security/webhook-timeout.test.js +149 -0
- package/lib/esm/tests/api_tests/security/webhook-timeout.test.js.map +1 -0
- package/lib/esm/tests/api_tests/webhook_error_handling.test.js +2 -2
- package/lib/esm/tests/api_tests/webhook_error_handling.test.js.map +1 -1
- package/lib/esm/tests/tests.d.ts.map +1 -1
- package/lib/esm/tests/tests.js +36 -24
- package/lib/esm/tests/tests.js.map +1 -1
- package/lib/esm/tests/unit_tests/openapi_spec_freshness.test.d.ts +1 -1
- package/lib/esm/tests/unit_tests/openapi_spec_freshness.test.js +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +10 -10
- package/src/tests/api_tests/auto_merge_form_submission.test.ts +1 -1
- package/src/tests/api_tests/enduser_observations_auto_review.test.ts +358 -0
- package/src/tests/api_tests/integrations_redacted.test.ts +1 -1
- package/src/tests/api_tests/organization_signup.test.ts +2 -2
- package/src/tests/api_tests/purchase_made_trigger.test.ts +29 -41
- package/src/tests/api_tests/security/{F-0196-add-to-journey-foreign-enduserid.test.ts → add-to-journey-foreign-enduserid.test.ts} +6 -7
- package/src/tests/api_tests/security/{F-0005-ai-conversations-rbac.test.ts → ai-conversations-rbac.test.ts} +14 -14
- package/src/tests/api_tests/security/{F-0166-allowed-paths-wildcard-bypass.test.ts → allowed-paths-confinement.test.ts} +11 -11
- package/src/tests/api_tests/security/{F-0192-automated-actions-process-gate.test.ts → automated-actions-process-gate.test.ts} +6 -7
- package/src/tests/api_tests/security/{F-0179-booking-info-idor-token-mint.test.ts → booking-info-idor-token-mint.test.ts} +5 -6
- package/src/tests/api_tests/security/{F-0053-cascade-role-rename-cross-tenant.test.ts → cascade-role-rename-cross-tenant.test.ts} +10 -10
- package/src/tests/api_tests/security/{F-0001-data-sync-redaction-bypass.test.ts → data-sync-redaction-bypass.test.ts} +9 -9
- package/src/tests/api_tests/security/{F-0006-develop-health-benefit-verification-rbac.test.ts → develop-health-benefit-verification-rbac.test.ts} +7 -8
- package/src/tests/api_tests/security/{F-0116-F-0119-enduser-cross-create.test.ts → enduser-cross-create.test.ts} +25 -25
- package/src/tests/api_tests/security/{F-0106-F-0110-enduser-write-restrictions.test.ts → enduser-write-restrictions.test.ts} +12 -14
- package/src/tests/api_tests/security/form-logic-js-execution.test.ts +183 -0
- package/src/tests/api_tests/security/{F-0145-globalunique-leak.test.ts → globalunique-conflict-redaction.test.ts} +5 -6
- package/src/tests/api_tests/security/{F-0008-handle-incoming-communication-cross-tenant.test.ts → handle-incoming-communication-cross-tenant.test.ts} +8 -8
- package/src/tests/api_tests/security/{F-0007-invite-user-enumeration.test.ts → invite-user-enumeration.test.ts} +8 -8
- package/src/tests/api_tests/security/{F-0151-load-inbox-redaction.test.ts → load-inbox-redaction.test.ts} +5 -6
- package/src/tests/api_tests/security/{F-0016-prototype-pollution.test.ts → prototype-pollution.test.ts} +4 -4
- package/src/tests/api_tests/security/{F-0025-proxy-image-unauth-ssrf.test.ts → proxy-image-unauth-ssrf.test.ts} +11 -12
- package/src/tests/api_tests/security/{F-0013-sanitize-user-html-with-iframes.test.ts → sanitize-user-html-with-iframes.test.ts} +5 -5
- package/src/tests/api_tests/security/{F-0013-sanitize-user-html.test.ts → sanitize-user-html.test.ts} +4 -4
- package/src/tests/api_tests/security/{F-0191-schema-adminonly-enforcement.test.ts → schema-adminonly-enforcement.test.ts} +6 -7
- package/src/tests/api_tests/security/{F-0076-self-admin-role-assignment.test.ts → self-admin-role-assignment.test.ts} +13 -13
- package/src/tests/api_tests/security/{F-0185-startlinktoken-enduser-staff-escalation.test.ts → startlinktoken-enduser-staff-escalation.test.ts} +6 -6
- package/src/tests/api_tests/security/{F-0015-webhook-outbound-ssrf.test.ts → webhook-outbound-ssrf.test.ts} +13 -14
- package/src/tests/api_tests/security/{F-0155-webhook-timeout.test.ts → webhook-timeout.test.ts} +6 -7
- package/src/tests/api_tests/webhook_error_handling.test.ts +1 -1
- package/src/tests/tests.ts +41 -24
- package/src/tests/unit_tests/openapi_spec_freshness.test.ts +1 -1
- package/test_generated.pdf +0 -0
- package/src/tests/api_tests/security/readonly-enduser-preview.test.ts +0 -301
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Session } from "../../sdk"
|
|
2
|
-
import { log_header,
|
|
2
|
+
import { log_header, async_test, poll_for_results } from "@tellescope/testing"
|
|
3
3
|
import { Enduser } from "@tellescope/types-client"
|
|
4
4
|
import { setup_tests } from "../setup"
|
|
5
5
|
|
|
@@ -8,6 +8,14 @@ const host = process.env.API_URL || "http://localhost:8080"
|
|
|
8
8
|
export const purchase_made_trigger_tests = async ({ sdk, sdkNonAdmin } : { sdk: Session, sdkNonAdmin: Session }) => {
|
|
9
9
|
log_header("Automation Trigger Tests (Purchase Made)")
|
|
10
10
|
|
|
11
|
+
// Trigger handling is fire-and-forget, and triggers apply newest-first, so the oldest matching
|
|
12
|
+
// trigger's tag lands last — a fixed sleep races it. Same approach as poll_for_tag in
|
|
13
|
+
// stripe_webhook_triggers.test.ts.
|
|
14
|
+
const enduser_with_tags = (enduserId: string, tags: string[]) => poll_for_results(
|
|
15
|
+
() => sdk.api.endusers.getOne(enduserId),
|
|
16
|
+
e => tags.every(t => e.tags?.includes(t)),
|
|
17
|
+
)
|
|
18
|
+
|
|
11
19
|
// Create products for testing
|
|
12
20
|
const product1 = await sdk.api.products.createOne({
|
|
13
21
|
title: 'Premium Course Package',
|
|
@@ -150,10 +158,9 @@ export const purchase_made_trigger_tests = async ({ sdk, sdkNonAdmin } : { sdk:
|
|
|
150
158
|
cost: { amount: 9999, currency: 'USD' },
|
|
151
159
|
processor: 'Stripe'
|
|
152
160
|
})
|
|
153
|
-
await wait(undefined, 500) // Brief wait for trigger processing
|
|
154
161
|
await async_test(
|
|
155
162
|
"Purchase Made - Any Purchase",
|
|
156
|
-
() =>
|
|
163
|
+
() => enduser_with_tags(enduser1.id, ['Purchase-Any']),
|
|
157
164
|
{ onResult: (e: Enduser) => !!e.tags?.includes('Purchase-Any') }
|
|
158
165
|
)
|
|
159
166
|
|
|
@@ -165,10 +172,9 @@ export const purchase_made_trigger_tests = async ({ sdk, sdkNonAdmin } : { sdk:
|
|
|
165
172
|
cost: { amount: 9999, currency: 'USD' },
|
|
166
173
|
processor: 'Stripe'
|
|
167
174
|
})
|
|
168
|
-
await wait(undefined, 500)
|
|
169
175
|
await async_test(
|
|
170
176
|
"Purchase Made - Exact Title Match",
|
|
171
|
-
() =>
|
|
177
|
+
() => enduser_with_tags(enduser2.id, ['Purchase-Exact-Title']),
|
|
172
178
|
{ onResult: (e: Enduser) => !!e.tags?.includes('Purchase-Exact-Title') }
|
|
173
179
|
)
|
|
174
180
|
|
|
@@ -180,10 +186,9 @@ export const purchase_made_trigger_tests = async ({ sdk, sdkNonAdmin } : { sdk:
|
|
|
180
186
|
cost: { amount: 4999, currency: 'USD' },
|
|
181
187
|
processor: 'Stripe'
|
|
182
188
|
})
|
|
183
|
-
await wait(undefined, 500)
|
|
184
189
|
await async_test(
|
|
185
190
|
"Purchase Made - Product ID Match",
|
|
186
|
-
() =>
|
|
191
|
+
() => enduser_with_tags(enduser3.id, ['Purchase-Product-ID']),
|
|
187
192
|
{ onResult: (e: Enduser) => !!e.tags?.includes('Purchase-Product-ID') }
|
|
188
193
|
)
|
|
189
194
|
|
|
@@ -195,10 +200,9 @@ export const purchase_made_trigger_tests = async ({ sdk, sdkNonAdmin } : { sdk:
|
|
|
195
200
|
cost: { amount: 9999, currency: 'USD' },
|
|
196
201
|
processor: 'Stripe'
|
|
197
202
|
})
|
|
198
|
-
await wait(undefined, 500)
|
|
199
203
|
await async_test(
|
|
200
204
|
"Purchase Made - Partial Title Match (case insensitive 'course')",
|
|
201
|
-
() =>
|
|
205
|
+
() => enduser_with_tags(enduser4.id, ['Purchase-Partial-Course']),
|
|
202
206
|
{ onResult: (e: Enduser) => !!e.tags?.includes('Purchase-Partial-Course') }
|
|
203
207
|
)
|
|
204
208
|
|
|
@@ -210,10 +214,9 @@ export const purchase_made_trigger_tests = async ({ sdk, sdkNonAdmin } : { sdk:
|
|
|
210
214
|
cost: { amount: 14999, currency: 'USD' },
|
|
211
215
|
processor: 'Stripe'
|
|
212
216
|
})
|
|
213
|
-
await wait(undefined, 500)
|
|
214
217
|
await async_test(
|
|
215
218
|
"Purchase Made - Partial Title Match (case insensitive 'ANALYTICS')",
|
|
216
|
-
() =>
|
|
219
|
+
() => enduser_with_tags(enduser5.id, ['Purchase-Partial-Analytics']),
|
|
217
220
|
{ onResult: (e: Enduser) => !!e.tags?.includes('Purchase-Partial-Analytics') }
|
|
218
221
|
)
|
|
219
222
|
|
|
@@ -225,10 +228,9 @@ export const purchase_made_trigger_tests = async ({ sdk, sdkNonAdmin } : { sdk:
|
|
|
225
228
|
cost: { amount: 4999, currency: 'USD' },
|
|
226
229
|
processor: 'Stripe'
|
|
227
230
|
})
|
|
228
|
-
await wait(undefined, 500)
|
|
229
231
|
await async_test(
|
|
230
232
|
"Purchase Made - No Partial Title Match",
|
|
231
|
-
() =>
|
|
233
|
+
() => enduser_with_tags(enduser6.id, ['Purchase-Any']),
|
|
232
234
|
{ onResult: (e: Enduser) => !!e.tags?.includes('Purchase-Any') && !e.tags?.includes('Purchase-Partial-Course') && !e.tags?.includes('Purchase-Partial-Analytics') }
|
|
233
235
|
)
|
|
234
236
|
|
|
@@ -240,10 +242,9 @@ export const purchase_made_trigger_tests = async ({ sdk, sdkNonAdmin } : { sdk:
|
|
|
240
242
|
cost: { amount: 9999, currency: 'USD' },
|
|
241
243
|
processor: 'Stripe'
|
|
242
244
|
})
|
|
243
|
-
await wait(undefined, 500)
|
|
244
245
|
await async_test(
|
|
245
246
|
"Purchase Made - Mixed Case Partial Title Match",
|
|
246
|
-
() =>
|
|
247
|
+
() => enduser_with_tags(enduser7.id, ['Purchase-Partial-Course']),
|
|
247
248
|
{ onResult: (e: Enduser) => !!e.tags?.includes('Purchase-Partial-Course') }
|
|
248
249
|
)
|
|
249
250
|
|
|
@@ -255,10 +256,9 @@ export const purchase_made_trigger_tests = async ({ sdk, sdkNonAdmin } : { sdk:
|
|
|
255
256
|
cost: { amount: 9999, currency: 'USD' },
|
|
256
257
|
processor: 'Stripe'
|
|
257
258
|
})
|
|
258
|
-
await wait(undefined, 500)
|
|
259
259
|
await async_test(
|
|
260
260
|
"Purchase Made - Multiple Partial Matches (matches 'premium')",
|
|
261
|
-
() =>
|
|
261
|
+
() => enduser_with_tags(enduser8.id, ['Purchase-Multiple-Partial']),
|
|
262
262
|
{ onResult: (e: Enduser) => !!e.tags?.includes('Purchase-Multiple-Partial') }
|
|
263
263
|
)
|
|
264
264
|
|
|
@@ -270,10 +270,9 @@ export const purchase_made_trigger_tests = async ({ sdk, sdkNonAdmin } : { sdk:
|
|
|
270
270
|
cost: { amount: 14999, currency: 'USD' },
|
|
271
271
|
processor: 'Stripe'
|
|
272
272
|
})
|
|
273
|
-
await wait(undefined, 500)
|
|
274
273
|
await async_test(
|
|
275
274
|
"Purchase Made - Multiple Partial Matches (matches 'advanced')",
|
|
276
|
-
() =>
|
|
275
|
+
() => enduser_with_tags(enduser9.id, ['Purchase-Multiple-Partial']),
|
|
277
276
|
{ onResult: (e: Enduser) => !!e.tags?.includes('Purchase-Multiple-Partial') }
|
|
278
277
|
)
|
|
279
278
|
|
|
@@ -285,10 +284,9 @@ export const purchase_made_trigger_tests = async ({ sdk, sdkNonAdmin } : { sdk:
|
|
|
285
284
|
cost: { amount: 9999, currency: 'USD' },
|
|
286
285
|
processor: 'Stripe'
|
|
287
286
|
})
|
|
288
|
-
await wait(undefined, 500)
|
|
289
287
|
await async_test(
|
|
290
288
|
"Purchase Made - Case Insensitive (lowercase filter 'mixed' matches 'MIXED')",
|
|
291
|
-
() =>
|
|
289
|
+
() => enduser_with_tags(enduser10.id, ['Purchase-Case-Test']),
|
|
292
290
|
{ onResult: (e: Enduser) => !!e.tags?.includes('Purchase-Case-Test') }
|
|
293
291
|
)
|
|
294
292
|
|
|
@@ -300,10 +298,9 @@ export const purchase_made_trigger_tests = async ({ sdk, sdkNonAdmin } : { sdk:
|
|
|
300
298
|
cost: { amount: 4999, currency: 'USD' },
|
|
301
299
|
processor: 'Stripe'
|
|
302
300
|
})
|
|
303
|
-
await wait(undefined, 500)
|
|
304
301
|
await async_test(
|
|
305
302
|
"Purchase Made - Case Insensitive (uppercase filter 'UPPER' matches 'upper')",
|
|
306
|
-
() =>
|
|
303
|
+
() => enduser_with_tags(enduser11.id, ['Purchase-Case-Test']),
|
|
307
304
|
{ onResult: (e: Enduser) => !!e.tags?.includes('Purchase-Case-Test') }
|
|
308
305
|
)
|
|
309
306
|
|
|
@@ -315,10 +312,9 @@ export const purchase_made_trigger_tests = async ({ sdk, sdkNonAdmin } : { sdk:
|
|
|
315
312
|
cost: { amount: 14999, currency: 'USD' },
|
|
316
313
|
processor: 'Stripe'
|
|
317
314
|
})
|
|
318
|
-
await wait(undefined, 500)
|
|
319
315
|
await async_test(
|
|
320
316
|
"Purchase Made - Case Insensitive (mixed case filter 'MiXeD' matches 'MiXeD')",
|
|
321
|
-
() =>
|
|
317
|
+
() => enduser_with_tags(enduser12.id, ['Purchase-Case-Test']),
|
|
322
318
|
{ onResult: (e: Enduser) => !!e.tags?.includes('Purchase-Case-Test') }
|
|
323
319
|
)
|
|
324
320
|
|
|
@@ -330,10 +326,9 @@ export const purchase_made_trigger_tests = async ({ sdk, sdkNonAdmin } : { sdk:
|
|
|
330
326
|
cost: { amount: 9999, currency: 'USD' },
|
|
331
327
|
processor: 'Stripe'
|
|
332
328
|
})
|
|
333
|
-
await wait(undefined, 500)
|
|
334
329
|
await async_test(
|
|
335
330
|
"Purchase Made - Empty titlePartialMatches Array (should trigger like any purchase)",
|
|
336
|
-
() =>
|
|
331
|
+
() => enduser_with_tags(enduser13.id, ['Purchase-Empty-Array', 'Purchase-Any']),
|
|
337
332
|
{ onResult: (e: Enduser) => !!e.tags?.includes('Purchase-Empty-Array') && !!e.tags?.includes('Purchase-Any') }
|
|
338
333
|
)
|
|
339
334
|
|
|
@@ -345,10 +340,9 @@ export const purchase_made_trigger_tests = async ({ sdk, sdkNonAdmin } : { sdk:
|
|
|
345
340
|
cost: { amount: 4999, currency: 'USD' },
|
|
346
341
|
processor: 'Stripe'
|
|
347
342
|
})
|
|
348
|
-
await wait(undefined, 500)
|
|
349
343
|
await async_test(
|
|
350
344
|
"Purchase Made - Empty Title (should not trigger partial match filters)",
|
|
351
|
-
() =>
|
|
345
|
+
() => enduser_with_tags(enduser14.id, ['Purchase-Any']),
|
|
352
346
|
{ onResult: (e: Enduser) => !!e.tags?.includes('Purchase-Any') && !e.tags?.includes('Purchase-No-Title-Test') }
|
|
353
347
|
)
|
|
354
348
|
|
|
@@ -360,10 +354,9 @@ export const purchase_made_trigger_tests = async ({ sdk, sdkNonAdmin } : { sdk:
|
|
|
360
354
|
processor: 'Stripe',
|
|
361
355
|
couponCodes: ['SUMMER20'],
|
|
362
356
|
})
|
|
363
|
-
await wait(undefined, 500)
|
|
364
357
|
await async_test(
|
|
365
358
|
"Purchase Made - Coupon Code Match (exact)",
|
|
366
|
-
() =>
|
|
359
|
+
() => enduser_with_tags(enduser15.id, ['Purchase-Coupon-Summer20', 'Purchase-Coupon-Empty']),
|
|
367
360
|
{ onResult: (e: Enduser) => !!e.tags?.includes('Purchase-Coupon-Summer20') && !!e.tags?.includes('Purchase-Coupon-Empty') }
|
|
368
361
|
)
|
|
369
362
|
|
|
@@ -376,10 +369,9 @@ export const purchase_made_trigger_tests = async ({ sdk, sdkNonAdmin } : { sdk:
|
|
|
376
369
|
processor: 'Stripe',
|
|
377
370
|
couponCodes: ['summer20'],
|
|
378
371
|
})
|
|
379
|
-
await wait(undefined, 500)
|
|
380
372
|
await async_test(
|
|
381
373
|
"Purchase Made - Coupon Code Case Mismatch (case sensitive, 'summer20' vs 'SUMMER20')",
|
|
382
|
-
() =>
|
|
374
|
+
() => enduser_with_tags(enduser16.id, ['Purchase-Any']),
|
|
383
375
|
{ onResult: (e: Enduser) => !!e.tags?.includes('Purchase-Any') && !e.tags?.includes('Purchase-Coupon-Summer20') }
|
|
384
376
|
)
|
|
385
377
|
|
|
@@ -391,10 +383,9 @@ export const purchase_made_trigger_tests = async ({ sdk, sdkNonAdmin } : { sdk:
|
|
|
391
383
|
processor: 'Stripe',
|
|
392
384
|
couponCodes: ['WINTER10'],
|
|
393
385
|
})
|
|
394
|
-
await wait(undefined, 500)
|
|
395
386
|
await async_test(
|
|
396
387
|
"Purchase Made - Non-matching Coupon Code",
|
|
397
|
-
() =>
|
|
388
|
+
() => enduser_with_tags(enduser17.id, ['Purchase-Any']),
|
|
398
389
|
{ onResult: (e: Enduser) => !!e.tags?.includes('Purchase-Any') && !e.tags?.includes('Purchase-Coupon-Summer20') }
|
|
399
390
|
)
|
|
400
391
|
|
|
@@ -406,10 +397,9 @@ export const purchase_made_trigger_tests = async ({ sdk, sdkNonAdmin } : { sdk:
|
|
|
406
397
|
cost: { amount: 9999, currency: 'USD' },
|
|
407
398
|
processor: 'Stripe',
|
|
408
399
|
})
|
|
409
|
-
await wait(undefined, 500)
|
|
410
400
|
await async_test(
|
|
411
401
|
"Purchase Made - No Coupon Data (backward compat)",
|
|
412
|
-
() =>
|
|
402
|
+
() => enduser_with_tags(enduser18.id, ['Purchase-Any', 'Purchase-Coupon-Empty']),
|
|
413
403
|
{ onResult: (e: Enduser) => !!e.tags?.includes('Purchase-Any') && !!e.tags?.includes('Purchase-Coupon-Empty') && !e.tags?.includes('Purchase-Coupon-Summer20') }
|
|
414
404
|
)
|
|
415
405
|
|
|
@@ -421,10 +411,9 @@ export const purchase_made_trigger_tests = async ({ sdk, sdkNonAdmin } : { sdk:
|
|
|
421
411
|
processor: 'Stripe',
|
|
422
412
|
couponCodes: ['SUMMER20'],
|
|
423
413
|
})
|
|
424
|
-
await wait(undefined, 500)
|
|
425
414
|
await async_test(
|
|
426
415
|
"Purchase Made - Title AND Coupon Match",
|
|
427
|
-
() =>
|
|
416
|
+
() => enduser_with_tags(enduser19.id, ['Purchase-Title-And-Coupon']),
|
|
428
417
|
{ onResult: (e: Enduser) => !!e.tags?.includes('Purchase-Title-And-Coupon') }
|
|
429
418
|
)
|
|
430
419
|
|
|
@@ -435,10 +424,9 @@ export const purchase_made_trigger_tests = async ({ sdk, sdkNonAdmin } : { sdk:
|
|
|
435
424
|
cost: { amount: 9999, currency: 'USD' },
|
|
436
425
|
processor: 'Stripe',
|
|
437
426
|
})
|
|
438
|
-
await wait(undefined, 500)
|
|
439
427
|
await async_test(
|
|
440
428
|
"Purchase Made - Title Matches But Coupon Missing (AND semantics)",
|
|
441
|
-
() =>
|
|
429
|
+
() => enduser_with_tags(enduser20.id, ['Purchase-Exact-Title']),
|
|
442
430
|
{ onResult: (e: Enduser) => !!e.tags?.includes('Purchase-Exact-Title') && !e.tags?.includes('Purchase-Title-And-Coupon') }
|
|
443
431
|
)
|
|
444
432
|
|
|
@@ -14,8 +14,7 @@ const RAND = () => Math.random().toString(36).slice(2, 10)
|
|
|
14
14
|
const FUTURE_START = () => new Date(Date.now() + 60 * 60 * 1000)
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
|
-
* Regression test
|
|
18
|
-
* (security-audit/findings/F-0196-add-to-journey-plants-foreign-enduserid.md).
|
|
17
|
+
* Regression test: `endusers.add_to_journey` must not enroll another tenant's enduser.
|
|
19
18
|
*
|
|
20
19
|
* `endusers.add_to_journey` inserted an `automated_actions` row for EACH caller-supplied `enduserId`
|
|
21
20
|
* with only mongoId-shape validation and no tenant-membership check. The preceding
|
|
@@ -25,10 +24,10 @@ const FUTURE_START = () => new Date(Date.now() + 60 * 60 * 1000)
|
|
|
25
24
|
* `businessId: <caller's tenant>` while carrying `enduserId: <a victim in another tenant>`.
|
|
26
25
|
*
|
|
27
26
|
* The worker then dereferences that enduser with the raw driver and no `businessId`
|
|
28
|
-
* (worker/modules/automations.ts, the
|
|
27
|
+
* (worker/modules/automations.ts, the worker's unscoped raw-driver lookup family), so the victim's record loads
|
|
29
28
|
* under the attacker's automation: `pushFormsToPortal` copies the victim's PHI into the attacker's
|
|
30
29
|
* `form_responses` (readable by their staff) and `iterableCustomEvent` writes an attacker-authored
|
|
31
|
-
* note into the victim's chart.
|
|
30
|
+
* note into the victim's chart. This plant is the reachability that made those three exploitable.
|
|
32
31
|
*
|
|
33
32
|
* There are TWO independent plant sites and a fix to only one is a half fix:
|
|
34
33
|
* - inline branch, taken when `automationStepId` is supplied (api.ts add_to_journey handler)
|
|
@@ -190,7 +189,7 @@ export const add_to_journey_foreign_enduserid_checks = async (): Promise<Check[]
|
|
|
190
189
|
|
|
191
190
|
/** Asserting wrapper, for standalone runs and for sequential use in the suite. */
|
|
192
191
|
export const add_to_journey_foreign_enduserid_tests = async () => {
|
|
193
|
-
assert_checks('
|
|
192
|
+
assert_checks('add_to_journey foreign enduserId', await add_to_journey_foreign_enduserid_checks())
|
|
194
193
|
}
|
|
195
194
|
|
|
196
195
|
// Allow running this test file independently
|
|
@@ -198,11 +197,11 @@ if (require.main === module) {
|
|
|
198
197
|
console.log(`🌐 Using API URL: ${host}`)
|
|
199
198
|
add_to_journey_foreign_enduserid_tests()
|
|
200
199
|
.then(() => {
|
|
201
|
-
console.log("✅
|
|
200
|
+
console.log("✅ add_to_journey foreign enduserId test suite completed successfully")
|
|
202
201
|
process.exit(0)
|
|
203
202
|
})
|
|
204
203
|
.catch((error) => {
|
|
205
|
-
console.error("❌
|
|
204
|
+
console.error("❌ add_to_journey foreign enduserId test suite failed:", error)
|
|
206
205
|
process.exit(1)
|
|
207
206
|
})
|
|
208
207
|
}
|
|
@@ -14,7 +14,7 @@ const host = process.env.API_URL || 'http://localhost:8080' as const
|
|
|
14
14
|
const [nonAdminEmail, nonAdminPassword] = [process.env.NON_ADMIN_EMAIL, process.env.NON_ADMIN_PASSWORD]
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
|
-
* Regression test
|
|
17
|
+
* Regression test: `ai_conversations` RBAC.
|
|
18
18
|
*
|
|
19
19
|
* Both `ai_conversations.send_message` and `ai_conversations.generate_ai_decision` are
|
|
20
20
|
* registered with `noAccessPermissions: true` ([api.ts:22699, 22721](packages/private/api/api/v1/api.ts)).
|
|
@@ -46,7 +46,7 @@ const [nonAdminEmail, nonAdminPassword] = [process.env.NON_ADMIN_EMAIL, process.
|
|
|
46
46
|
* Post-fix: both endpoints throw 403 before any work happens. Test passes.
|
|
47
47
|
*/
|
|
48
48
|
export const ai_conversations_rbac_tests = async ({ sdk, sdkNonAdmin } : { sdk: Session, sdkNonAdmin: Session }) => {
|
|
49
|
-
log_header("
|
|
49
|
+
log_header("ai_conversations RBAC bypass regression")
|
|
50
50
|
|
|
51
51
|
const roleName = `f0005-ai-conversations-no-access-${Date.now()}`
|
|
52
52
|
const grantRoleName = `f0005-ai-conversations-create-granted-${Date.now()}`
|
|
@@ -83,9 +83,9 @@ export const ai_conversations_rbac_tests = async ({ sdk, sdkNonAdmin } : { sdk:
|
|
|
83
83
|
// 3a. send_message must throw 403 (or equivalent access error). Pre-fix: succeeds (or
|
|
84
84
|
// fails downstream in Bedrock without 403). Post-fix: throws before any work.
|
|
85
85
|
await async_test(
|
|
86
|
-
"
|
|
86
|
+
"ai_conversations.send_message must throw 403 when role denies ai_conversations",
|
|
87
87
|
() => sdkNonAdmin.api.ai_conversations.send_message({
|
|
88
|
-
message: '
|
|
88
|
+
message: 'regression test',
|
|
89
89
|
type: 'Test',
|
|
90
90
|
} as any),
|
|
91
91
|
{
|
|
@@ -105,12 +105,12 @@ export const ai_conversations_rbac_tests = async ({ sdk, sdkNonAdmin } : { sdk:
|
|
|
105
105
|
// Pre-fix: handler responds 200 with {} immediately and processes in background.
|
|
106
106
|
// Post-fix: handler throws 403 before res.json({}).
|
|
107
107
|
await async_test(
|
|
108
|
-
"
|
|
108
|
+
"ai_conversations.generate_ai_decision must throw 403 when role denies endusers/ai_conversations",
|
|
109
109
|
() => sdkNonAdmin.api.ai_conversations.generate_ai_decision({
|
|
110
110
|
enduserId: new ObjectId().toHexString(), // fake id — access check should fire first
|
|
111
111
|
automationStepId: new ObjectId().toHexString(), // fake id — access check should fire first
|
|
112
112
|
outcomes: ['yes', 'no'],
|
|
113
|
-
prompt: '
|
|
113
|
+
prompt: 'regression test',
|
|
114
114
|
sources: [{ type: 'SMS', limit: 1 }], // non-empty so the validator passes; access check then fires
|
|
115
115
|
} as any),
|
|
116
116
|
{
|
|
@@ -145,9 +145,9 @@ export const ai_conversations_rbac_tests = async ({ sdk, sdkNonAdmin } : { sdk:
|
|
|
145
145
|
await sdkNonAdmin.authenticate(nonAdminEmail!, nonAdminPassword!)
|
|
146
146
|
|
|
147
147
|
await async_test(
|
|
148
|
-
"
|
|
148
|
+
"ai_conversations.send_message must NOT be access-denied when role grants create",
|
|
149
149
|
() => sdkNonAdmin.api.ai_conversations.send_message({
|
|
150
|
-
message: '
|
|
150
|
+
message: 'positive-case test',
|
|
151
151
|
type: 'Test',
|
|
152
152
|
maxTokens: 1,
|
|
153
153
|
} as any)
|
|
@@ -168,9 +168,9 @@ export const ai_conversations_rbac_tests = async ({ sdk, sdkNonAdmin } : { sdk:
|
|
|
168
168
|
// existing conversation — send_message with conversationId returns the full stored history
|
|
169
169
|
// and appends to it. Fake id is fine: the access check must fire before any lookup.
|
|
170
170
|
await async_test(
|
|
171
|
-
"
|
|
171
|
+
"ai_conversations.send_message with conversationId must 403 when role denies read/update",
|
|
172
172
|
() => sdkNonAdmin.api.ai_conversations.send_message({
|
|
173
|
-
message: '
|
|
173
|
+
message: 'conversationId bypass test',
|
|
174
174
|
type: 'Test',
|
|
175
175
|
maxTokens: 1,
|
|
176
176
|
conversationId: new ObjectId().toHexString(),
|
|
@@ -205,9 +205,9 @@ export const ai_conversations_rbac_tests = async ({ sdk, sdkNonAdmin } : { sdk:
|
|
|
205
205
|
await sdkNonAdmin.authenticate(nonAdminEmail!, nonAdminPassword!)
|
|
206
206
|
|
|
207
207
|
await async_test(
|
|
208
|
-
"
|
|
208
|
+
"ai_conversations.send_message must not 500 for Assigned-access (default provider) role",
|
|
209
209
|
() => sdkNonAdmin.api.ai_conversations.send_message({
|
|
210
|
-
message: '
|
|
210
|
+
message: 'assigned-access regression test',
|
|
211
211
|
type: 'Test',
|
|
212
212
|
maxTokens: 1,
|
|
213
213
|
} as any)
|
|
@@ -267,11 +267,11 @@ if (require.main === module) {
|
|
|
267
267
|
|
|
268
268
|
runTests()
|
|
269
269
|
.then(() => {
|
|
270
|
-
console.log("✅
|
|
270
|
+
console.log("✅ ai_conversations RBAC test suite completed successfully")
|
|
271
271
|
process.exit(0)
|
|
272
272
|
})
|
|
273
273
|
.catch((error) => {
|
|
274
|
-
console.error("❌
|
|
274
|
+
console.error("❌ ai_conversations RBAC test suite failed:", error)
|
|
275
275
|
process.exit(1)
|
|
276
276
|
})
|
|
277
277
|
}
|
|
@@ -12,7 +12,7 @@ import { setup_tests } from "../../setup"
|
|
|
12
12
|
const host = process.env.API_URL || 'http://localhost:8080' as const
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
|
-
* Regression test
|
|
15
|
+
* Regression test — allowedPaths wildcard disables path confinement entirely.
|
|
16
16
|
*
|
|
17
17
|
* Several public, unauthenticated endpoints mint a JWT confined to a small set of API paths via an
|
|
18
18
|
* `allowedPaths` claim. The enforcement predicate (api/modules/authentication.ts checkAccess)
|
|
@@ -69,7 +69,7 @@ type Probe = {
|
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
export const allowed_paths_confinement_tests = async ({ sdk } : { sdk: Session, sdkNonAdmin: Session }) => {
|
|
72
|
-
log_header("
|
|
72
|
+
log_header("allowedPaths wildcard bypasses session path confinement")
|
|
73
73
|
|
|
74
74
|
const probes: Probe[] = []
|
|
75
75
|
|
|
@@ -157,7 +157,7 @@ export const allowed_paths_confinement_tests = async ({ sdk } : { sdk: Session,
|
|
|
157
157
|
|
|
158
158
|
// -- public form (no wildcard in its allowedPaths)
|
|
159
159
|
const form = await sdk.api.forms.createOne({
|
|
160
|
-
title: `
|
|
160
|
+
title: `path confinement ${RAND()}`,
|
|
161
161
|
allowPublicURL: true,
|
|
162
162
|
})
|
|
163
163
|
formId = form.id
|
|
@@ -179,7 +179,7 @@ export const allowed_paths_confinement_tests = async ({ sdk } : { sdk: Session,
|
|
|
179
179
|
})
|
|
180
180
|
|
|
181
181
|
const product = await sdk.api.products.createOne({
|
|
182
|
-
title: `
|
|
182
|
+
title: `product ${RAND()}`,
|
|
183
183
|
cost: { amount: 500, currency: 'USD' },
|
|
184
184
|
processor: 'Stripe',
|
|
185
185
|
} as any)
|
|
@@ -193,13 +193,13 @@ export const allowed_paths_confinement_tests = async ({ sdk } : { sdk: Session,
|
|
|
193
193
|
|
|
194
194
|
const joinLinkToken = `f0166-join-${RAND()}${RAND()}`
|
|
195
195
|
const joinEvent = await sdk.api.calendar_events.createOne({
|
|
196
|
-
title: '
|
|
196
|
+
title: 'join', durationInMinutes: 30, startTimeInMS: Date.now() + 3600_000,
|
|
197
197
|
attendees: [{ type: 'enduser', id: joinEnduser.id, joinLinkToken }],
|
|
198
198
|
} as any)
|
|
199
199
|
eventIds.push(joinEvent.id)
|
|
200
200
|
|
|
201
201
|
const unrelatedEvent = await sdk.api.calendar_events.createOne({
|
|
202
|
-
title: '
|
|
202
|
+
title: 'unrelated', durationInMinutes: 30, startTimeInMS: Date.now() + 3600_000,
|
|
203
203
|
attendees: [{ type: 'enduser', id: joinEnduser.id }],
|
|
204
204
|
} as any)
|
|
205
205
|
eventIds.push(unrelatedEvent.id)
|
|
@@ -219,7 +219,7 @@ export const allowed_paths_confinement_tests = async ({ sdk } : { sdk: Session,
|
|
|
219
219
|
|
|
220
220
|
const startLinkToken = `f0166-start-${RAND()}${RAND()}`
|
|
221
221
|
const startEvent = await sdk.api.calendar_events.createOne({
|
|
222
|
-
title: '
|
|
222
|
+
title: 'start', durationInMinutes: 30, startTimeInMS: Date.now() + 3600_000,
|
|
223
223
|
attendees: [{ type: 'user', id: hostUser.id }, { type: 'enduser', id: joinEnduser.id }],
|
|
224
224
|
startLinkToken,
|
|
225
225
|
} as any)
|
|
@@ -553,7 +553,7 @@ export const allowed_paths_confinement_tests = async ({ sdk } : { sdk: Session,
|
|
|
553
553
|
const S7 = 'S7 appointment-booking'
|
|
554
554
|
|
|
555
555
|
const bookingTemplate = await sdk.api.calendar_event_templates.createOne({
|
|
556
|
-
title: `
|
|
556
|
+
title: `booking ${RAND()}`, durationInMinutes: 30,
|
|
557
557
|
})
|
|
558
558
|
templateId = bookingTemplate.id
|
|
559
559
|
|
|
@@ -656,7 +656,7 @@ export const allowed_paths_confinement_tests = async ({ sdk } : { sdk: Session,
|
|
|
656
656
|
const failures = probes.filter(p => !p.pass)
|
|
657
657
|
|
|
658
658
|
console.log('')
|
|
659
|
-
console.log('
|
|
659
|
+
console.log(' full probe table')
|
|
660
660
|
console.log(' ' + '-'.repeat(112))
|
|
661
661
|
const scenarios = probes.map(p => p.scenario).filter((s, i, all) => all.indexOf(s) === i)
|
|
662
662
|
for (const scenario of scenarios) {
|
|
@@ -711,11 +711,11 @@ if (require.main === module) {
|
|
|
711
711
|
|
|
712
712
|
runTests()
|
|
713
713
|
.then(() => {
|
|
714
|
-
console.log("✅
|
|
714
|
+
console.log("✅ allowedPaths confinement test suite completed successfully")
|
|
715
715
|
process.exit(0)
|
|
716
716
|
})
|
|
717
717
|
.catch((error) => {
|
|
718
|
-
console.error("❌
|
|
718
|
+
console.error("❌ allowedPaths confinement test suite failed:", error)
|
|
719
719
|
process.exit(1)
|
|
720
720
|
})
|
|
721
721
|
}
|
|
@@ -29,8 +29,7 @@ type Check = {
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
/**
|
|
32
|
-
* Regression test
|
|
33
|
-
* (security-audit/findings/F-0192-automated-actions-process-fire-replay.md).
|
|
32
|
+
* Regression test: `automated_actions.process` must be admin-gated, single-fire and audited.
|
|
34
33
|
*
|
|
35
34
|
* `automated_actions.process` (api.ts:3902) is the WORKER's action runner — its schema description
|
|
36
35
|
* reads "Used by worker for new action types". It was registered with only
|
|
@@ -46,7 +45,7 @@ type Check = {
|
|
|
46
45
|
*
|
|
47
46
|
* The fix has three parts:
|
|
48
47
|
* 1. `adminOnly: true` on the api.ts registration (routing.ts:944 reads the flag from that
|
|
49
|
-
* options object — a schema-only flag is inert, which is
|
|
48
|
+
* options object — a schema-only flag is inert, which is a separate issue).
|
|
50
49
|
* 2. A single-fire claim for human callers: an atomic findOneAndUpdate with `status: 'active'` in
|
|
51
50
|
* the filter, stamping `finished` + `processedAt` before the vendor dispatch. The worker
|
|
52
51
|
* (`wasAutomated`) is exempt because its own claim in
|
|
@@ -66,7 +65,7 @@ type Check = {
|
|
|
66
65
|
* GREEN (post-fix): all five checks pass.
|
|
67
66
|
*/
|
|
68
67
|
export const automated_actions_process_gate_tests = async ({ sdk } : { sdk: Session, sdkNonAdmin: Session }) => {
|
|
69
|
-
log_header("
|
|
68
|
+
log_header("automated_actions.process must be admin-only and single-fire")
|
|
70
69
|
|
|
71
70
|
const checks: Check[] = []
|
|
72
71
|
const record = (label: string, pass: boolean, detail: string) => checks.push({ label, pass, detail })
|
|
@@ -196,7 +195,7 @@ export const automated_actions_process_gate_tests = async ({ sdk } : { sdk: Sess
|
|
|
196
195
|
)
|
|
197
196
|
|
|
198
197
|
/* ===== report: print full table first, then assert (harness exits on first failure) ===== */
|
|
199
|
-
console.log('\n
|
|
198
|
+
console.log('\n check summary:')
|
|
200
199
|
for (const c of checks) {
|
|
201
200
|
console.log(` ${c.pass ? 'PASS' : 'FAIL'} ${c.label} — ${c.detail}`)
|
|
202
201
|
}
|
|
@@ -228,11 +227,11 @@ if (require.main === module) {
|
|
|
228
227
|
|
|
229
228
|
runTests()
|
|
230
229
|
.then(() => {
|
|
231
|
-
console.log("✅
|
|
230
|
+
console.log("✅ automated_actions.process gate test suite completed successfully")
|
|
232
231
|
process.exit(0)
|
|
233
232
|
})
|
|
234
233
|
.catch((error) => {
|
|
235
|
-
console.error("❌
|
|
234
|
+
console.error("❌ automated_actions.process gate test suite failed:", error)
|
|
236
235
|
process.exit(1)
|
|
237
236
|
})
|
|
238
237
|
}
|
|
@@ -22,8 +22,7 @@ type Check = {
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
/**
|
|
25
|
-
* Regression test for
|
|
26
|
-
* (security-audit/findings/F-0179-booking-info-idor-token-mint.md).
|
|
25
|
+
* Regression test: `form_fields.booking_info` must not mint a booking token for another patient.
|
|
27
26
|
*
|
|
28
27
|
* `form_fields.booking_info` resolved its target patient as
|
|
29
28
|
* `DB.endusers.findById(enduserId || req.session.id)` with no ownership check for enduser
|
|
@@ -46,7 +45,7 @@ type Check = {
|
|
|
46
45
|
* before `finally` cleanup.
|
|
47
46
|
*/
|
|
48
47
|
export const booking_info_idor_tests = async ({ sdk } : { sdk: Session, sdkNonAdmin: Session }) => {
|
|
49
|
-
log_header("
|
|
48
|
+
log_header("booking_info must not mint an appointment-booking token for another enduser")
|
|
50
49
|
|
|
51
50
|
const checks: Check[] = []
|
|
52
51
|
const record = (label: string, pass: boolean, detail: string) => checks.push({ label, pass, detail })
|
|
@@ -186,7 +185,7 @@ export const booking_info_idor_tests = async ({ sdk } : { sdk: Session, sdkNonAd
|
|
|
186
185
|
record('C2: staff test-contact preview branch still works', c2Pass, c2Detail)
|
|
187
186
|
|
|
188
187
|
/* ===== report: print full table first, then assert (harness exits on first failure) ===== */
|
|
189
|
-
console.log('\n
|
|
188
|
+
console.log('\n check summary:')
|
|
190
189
|
for (const c of checks) {
|
|
191
190
|
console.log(` ${c.pass ? 'PASS' : 'FAIL'} ${c.label} — ${c.detail}`)
|
|
192
191
|
}
|
|
@@ -215,11 +214,11 @@ if (require.main === module) {
|
|
|
215
214
|
|
|
216
215
|
runTests()
|
|
217
216
|
.then(() => {
|
|
218
|
-
console.log("✅
|
|
217
|
+
console.log("✅ booking_info IDOR test suite completed successfully")
|
|
219
218
|
process.exit(0)
|
|
220
219
|
})
|
|
221
220
|
.catch((error) => {
|
|
222
|
-
console.error("❌
|
|
221
|
+
console.error("❌ booking_info IDOR test suite failed:", error)
|
|
223
222
|
process.exit(1)
|
|
224
223
|
})
|
|
225
224
|
}
|