@tellescope/sdk 2.0.0-beta.0 → 2.0.0-beta.2
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/CLAUDE.md +24 -0
- package/env.example +6 -0
- package/lib/cjs/sdk.d.ts +376 -3
- package/lib/cjs/sdk.d.ts.map +1 -1
- package/lib/cjs/sdk.js +1 -0
- package/lib/cjs/sdk.js.map +1 -1
- package/lib/cjs/tests/api_tests/booking_prevent_upcoming_duplicate.test.d.ts +22 -0
- package/lib/cjs/tests/api_tests/booking_prevent_upcoming_duplicate.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/booking_prevent_upcoming_duplicate.test.js +506 -0
- package/lib/cjs/tests/api_tests/booking_prevent_upcoming_duplicate.test.js.map +1 -0
- package/lib/cjs/tests/api_tests/enduser_fields_sync.test.d.ts +3 -1
- package/lib/cjs/tests/api_tests/enduser_fields_sync.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/enduser_fields_sync.test.js +3 -1
- package/lib/cjs/tests/api_tests/enduser_fields_sync.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/enduser_observations_auto_review.test.d.ts +3 -1
- package/lib/cjs/tests/api_tests/enduser_observations_auto_review.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/enduser_observations_auto_review.test.js +3 -1
- package/lib/cjs/tests/api_tests/enduser_observations_auto_review.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/form_vital_reading.test.d.ts +7 -0
- package/lib/cjs/tests/api_tests/form_vital_reading.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/form_vital_reading.test.js +461 -0
- package/lib/cjs/tests/api_tests/form_vital_reading.test.js.map +1 -0
- package/lib/cjs/tests/api_tests/journey_statistics_cache.test.d.ts +26 -0
- package/lib/cjs/tests/api_tests/journey_statistics_cache.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/journey_statistics_cache.test.js +232 -0
- package/lib/cjs/tests/api_tests/journey_statistics_cache.test.js.map +1 -0
- package/lib/cjs/tests/api_tests/journey_step_manual_count.test.d.ts +34 -0
- package/lib/cjs/tests/api_tests/journey_step_manual_count.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/journey_step_manual_count.test.js +243 -0
- package/lib/cjs/tests/api_tests/journey_step_manual_count.test.js.map +1 -0
- package/lib/cjs/tests/api_tests/load_threads_care_team.test.d.ts +3 -1
- package/lib/cjs/tests/api_tests/load_threads_care_team.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/load_threads_care_team.test.js +3 -1
- package/lib/cjs/tests/api_tests/load_threads_care_team.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/mdi_case_offerings.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/mdi_case_offerings.test.js +139 -9
- package/lib/cjs/tests/api_tests/mdi_case_offerings.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/organization_signup.test.d.ts +3 -1
- package/lib/cjs/tests/api_tests/organization_signup.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/organization_signup.test.js +3 -1
- package/lib/cjs/tests/api_tests/organization_signup.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/phone_embed_leave_message.test.d.ts +7 -0
- package/lib/cjs/tests/api_tests/phone_embed_leave_message.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/phone_embed_leave_message.test.js +571 -0
- package/lib/cjs/tests/api_tests/phone_embed_leave_message.test.js.map +1 -0
- package/lib/cjs/tests/api_tests/programs.test.d.ts +3 -1
- package/lib/cjs/tests/api_tests/programs.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/programs.test.js +73 -17
- package/lib/cjs/tests/api_tests/programs.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/public_form_case_insensitive_match.test.d.ts +7 -0
- package/lib/cjs/tests/api_tests/public_form_case_insensitive_match.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/public_form_case_insensitive_match.test.js +733 -0
- package/lib/cjs/tests/api_tests/public_form_case_insensitive_match.test.js.map +1 -0
- package/lib/cjs/tests/api_tests/security/add-to-journey-foreign-enduserid.test.d.ts +3 -1
- package/lib/cjs/tests/api_tests/security/add-to-journey-foreign-enduserid.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/security/add-to-journey-foreign-enduserid.test.js +58 -48
- package/lib/cjs/tests/api_tests/security/add-to-journey-foreign-enduserid.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/security/appointment-reschedule-ownership.test.d.ts +3 -1
- package/lib/cjs/tests/api_tests/security/appointment-reschedule-ownership.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/security/appointment-reschedule-ownership.test.js +3 -1
- package/lib/cjs/tests/api_tests/security/appointment-reschedule-ownership.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/security/file-link-session-confinement.test.d.ts +3 -1
- package/lib/cjs/tests/api_tests/security/file-link-session-confinement.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/security/file-link-session-confinement.test.js +3 -1
- package/lib/cjs/tests/api_tests/security/file-link-session-confinement.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/security/form-logic-js-execution.test.d.ts +3 -1
- package/lib/cjs/tests/api_tests/security/form-logic-js-execution.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/security/form-logic-js-execution.test.js +3 -1
- package/lib/cjs/tests/api_tests/security/form-logic-js-execution.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/security/formsort_webhook_auth_field_lock.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/security/formsort_webhook_auth_field_lock.test.js +424 -39
- package/lib/cjs/tests/api_tests/security/formsort_webhook_auth_field_lock.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/security/register_business_id_injection.test.js +2 -2
- package/lib/cjs/tests/api_tests/security/register_business_id_injection.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/security/rich-text-answer-sanitized-on-write.test.d.ts +3 -1
- package/lib/cjs/tests/api_tests/security/rich-text-answer-sanitized-on-write.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/security/rich-text-answer-sanitized-on-write.test.js +3 -1
- package/lib/cjs/tests/api_tests/security/rich-text-answer-sanitized-on-write.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/session_for_join_link.test.d.ts +10 -0
- package/lib/cjs/tests/api_tests/session_for_join_link.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/session_for_join_link.test.js +147 -0
- package/lib/cjs/tests/api_tests/session_for_join_link.test.js.map +1 -0
- package/lib/cjs/tests/api_tests/set_fields_order_templates.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/set_fields_order_templates.test.js +191 -88
- package/lib/cjs/tests/api_tests/set_fields_order_templates.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/stripe_checkout_items.test.d.ts +17 -0
- package/lib/cjs/tests/api_tests/stripe_checkout_items.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/stripe_checkout_items.test.js +219 -0
- package/lib/cjs/tests/api_tests/stripe_checkout_items.test.js.map +1 -0
- package/lib/cjs/tests/api_tests/stripe_multiple_customer_ids.test.d.ts +5 -0
- package/lib/cjs/tests/api_tests/stripe_multiple_customer_ids.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/stripe_multiple_customer_ids.test.js +396 -0
- package/lib/cjs/tests/api_tests/stripe_multiple_customer_ids.test.js.map +1 -0
- package/lib/cjs/tests/api_tests/tickets_bulk_assign_from_queue.test.d.ts +3 -1
- package/lib/cjs/tests/api_tests/tickets_bulk_assign_from_queue.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/tickets_bulk_assign_from_queue.test.js +3 -1
- package/lib/cjs/tests/api_tests/tickets_bulk_assign_from_queue.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/totp_mfa.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/totp_mfa.test.js +37 -31
- package/lib/cjs/tests/api_tests/totp_mfa.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/trigger_contains_matching.test.d.ts +3 -1
- package/lib/cjs/tests/api_tests/trigger_contains_matching.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/trigger_contains_matching.test.js +3 -1
- package/lib/cjs/tests/api_tests/trigger_contains_matching.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/user_logs_restore_deleted.test.d.ts +3 -1
- package/lib/cjs/tests/api_tests/user_logs_restore_deleted.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/user_logs_restore_deleted.test.js +3 -1
- package/lib/cjs/tests/api_tests/user_logs_restore_deleted.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/vital_review_trigger_action.test.d.ts +3 -1
- package/lib/cjs/tests/api_tests/vital_review_trigger_action.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/vital_review_trigger_action.test.js +3 -1
- package/lib/cjs/tests/api_tests/vital_review_trigger_action.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/vitl_push.test.d.ts +7 -0
- package/lib/cjs/tests/api_tests/vitl_push.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/vitl_push.test.js +341 -0
- package/lib/cjs/tests/api_tests/vitl_push.test.js.map +1 -0
- package/lib/cjs/tests/setup_isolated.d.ts +48 -0
- package/lib/cjs/tests/setup_isolated.d.ts.map +1 -1
- package/lib/cjs/tests/setup_isolated.js +119 -1
- package/lib/cjs/tests/setup_isolated.js.map +1 -1
- package/lib/cjs/tests/tests.d.ts.map +1 -1
- package/lib/cjs/tests/tests.js +378 -282
- package/lib/cjs/tests/tests.js.map +1 -1
- package/lib/cjs/tests/unit_tests/isolated_suite_discovery.test.d.ts +2 -0
- package/lib/cjs/tests/unit_tests/isolated_suite_discovery.test.d.ts.map +1 -0
- package/lib/cjs/tests/unit_tests/isolated_suite_discovery.test.js +201 -0
- package/lib/cjs/tests/unit_tests/isolated_suite_discovery.test.js.map +1 -0
- package/lib/cjs/tests/unit_tests/programs_conditional_logic.test.d.ts +3 -0
- package/lib/cjs/tests/unit_tests/programs_conditional_logic.test.d.ts.map +1 -0
- package/lib/cjs/tests/unit_tests/programs_conditional_logic.test.js +120 -0
- package/lib/cjs/tests/unit_tests/programs_conditional_logic.test.js.map +1 -0
- package/lib/cjs/tests/webhooks_tests.js +44 -34
- package/lib/cjs/tests/webhooks_tests.js.map +1 -1
- package/lib/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/lib/esm/sdk.d.ts +376 -3
- package/lib/esm/sdk.d.ts.map +1 -1
- package/lib/esm/sdk.js +1 -0
- package/lib/esm/sdk.js.map +1 -1
- package/lib/esm/tests/api_tests/booking_prevent_upcoming_duplicate.test.d.ts +22 -0
- package/lib/esm/tests/api_tests/booking_prevent_upcoming_duplicate.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/booking_prevent_upcoming_duplicate.test.js +501 -0
- package/lib/esm/tests/api_tests/booking_prevent_upcoming_duplicate.test.js.map +1 -0
- package/lib/esm/tests/api_tests/enduser_fields_sync.test.d.ts +3 -1
- package/lib/esm/tests/api_tests/enduser_fields_sync.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/enduser_fields_sync.test.js +2 -0
- package/lib/esm/tests/api_tests/enduser_fields_sync.test.js.map +1 -1
- package/lib/esm/tests/api_tests/enduser_observations_auto_review.test.d.ts +3 -1
- package/lib/esm/tests/api_tests/enduser_observations_auto_review.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/enduser_observations_auto_review.test.js +2 -0
- package/lib/esm/tests/api_tests/enduser_observations_auto_review.test.js.map +1 -1
- package/lib/esm/tests/api_tests/form_vital_reading.test.d.ts +7 -0
- package/lib/esm/tests/api_tests/form_vital_reading.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/form_vital_reading.test.js +456 -0
- package/lib/esm/tests/api_tests/form_vital_reading.test.js.map +1 -0
- package/lib/esm/tests/api_tests/journey_statistics_cache.test.d.ts +26 -0
- package/lib/esm/tests/api_tests/journey_statistics_cache.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/journey_statistics_cache.test.js +227 -0
- package/lib/esm/tests/api_tests/journey_statistics_cache.test.js.map +1 -0
- package/lib/esm/tests/api_tests/journey_step_manual_count.test.d.ts +34 -0
- package/lib/esm/tests/api_tests/journey_step_manual_count.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/journey_step_manual_count.test.js +238 -0
- package/lib/esm/tests/api_tests/journey_step_manual_count.test.js.map +1 -0
- package/lib/esm/tests/api_tests/load_threads_care_team.test.d.ts +3 -1
- package/lib/esm/tests/api_tests/load_threads_care_team.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/load_threads_care_team.test.js +2 -0
- package/lib/esm/tests/api_tests/load_threads_care_team.test.js.map +1 -1
- package/lib/esm/tests/api_tests/mdi_case_offerings.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/mdi_case_offerings.test.js +139 -9
- package/lib/esm/tests/api_tests/mdi_case_offerings.test.js.map +1 -1
- package/lib/esm/tests/api_tests/organization_signup.test.d.ts +3 -1
- package/lib/esm/tests/api_tests/organization_signup.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/organization_signup.test.js +2 -0
- package/lib/esm/tests/api_tests/organization_signup.test.js.map +1 -1
- package/lib/esm/tests/api_tests/phone_embed_leave_message.test.d.ts +7 -0
- package/lib/esm/tests/api_tests/phone_embed_leave_message.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/phone_embed_leave_message.test.js +566 -0
- package/lib/esm/tests/api_tests/phone_embed_leave_message.test.js.map +1 -0
- package/lib/esm/tests/api_tests/programs.test.d.ts +3 -1
- package/lib/esm/tests/api_tests/programs.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/programs.test.js +72 -16
- package/lib/esm/tests/api_tests/programs.test.js.map +1 -1
- package/lib/esm/tests/api_tests/public_form_case_insensitive_match.test.d.ts +7 -0
- package/lib/esm/tests/api_tests/public_form_case_insensitive_match.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/public_form_case_insensitive_match.test.js +728 -0
- package/lib/esm/tests/api_tests/public_form_case_insensitive_match.test.js.map +1 -0
- package/lib/esm/tests/api_tests/security/add-to-journey-foreign-enduserid.test.d.ts +3 -1
- package/lib/esm/tests/api_tests/security/add-to-journey-foreign-enduserid.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/security/add-to-journey-foreign-enduserid.test.js +57 -47
- package/lib/esm/tests/api_tests/security/add-to-journey-foreign-enduserid.test.js.map +1 -1
- package/lib/esm/tests/api_tests/security/appointment-reschedule-ownership.test.d.ts +3 -1
- package/lib/esm/tests/api_tests/security/appointment-reschedule-ownership.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/security/appointment-reschedule-ownership.test.js +2 -0
- package/lib/esm/tests/api_tests/security/appointment-reschedule-ownership.test.js.map +1 -1
- package/lib/esm/tests/api_tests/security/file-link-session-confinement.test.d.ts +3 -1
- package/lib/esm/tests/api_tests/security/file-link-session-confinement.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/security/file-link-session-confinement.test.js +2 -0
- package/lib/esm/tests/api_tests/security/file-link-session-confinement.test.js.map +1 -1
- package/lib/esm/tests/api_tests/security/form-logic-js-execution.test.d.ts +3 -1
- package/lib/esm/tests/api_tests/security/form-logic-js-execution.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/security/form-logic-js-execution.test.js +2 -0
- package/lib/esm/tests/api_tests/security/form-logic-js-execution.test.js.map +1 -1
- package/lib/esm/tests/api_tests/security/formsort_webhook_auth_field_lock.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/security/formsort_webhook_auth_field_lock.test.js +424 -39
- package/lib/esm/tests/api_tests/security/formsort_webhook_auth_field_lock.test.js.map +1 -1
- package/lib/esm/tests/api_tests/security/register_business_id_injection.test.js +2 -2
- package/lib/esm/tests/api_tests/security/register_business_id_injection.test.js.map +1 -1
- package/lib/esm/tests/api_tests/security/rich-text-answer-sanitized-on-write.test.d.ts +3 -1
- package/lib/esm/tests/api_tests/security/rich-text-answer-sanitized-on-write.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/security/rich-text-answer-sanitized-on-write.test.js +2 -0
- package/lib/esm/tests/api_tests/security/rich-text-answer-sanitized-on-write.test.js.map +1 -1
- package/lib/esm/tests/api_tests/session_for_join_link.test.d.ts +10 -0
- package/lib/esm/tests/api_tests/session_for_join_link.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/session_for_join_link.test.js +142 -0
- package/lib/esm/tests/api_tests/session_for_join_link.test.js.map +1 -0
- package/lib/esm/tests/api_tests/set_fields_order_templates.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/set_fields_order_templates.test.js +191 -88
- package/lib/esm/tests/api_tests/set_fields_order_templates.test.js.map +1 -1
- package/lib/esm/tests/api_tests/stripe_checkout_items.test.d.ts +17 -0
- package/lib/esm/tests/api_tests/stripe_checkout_items.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/stripe_checkout_items.test.js +214 -0
- package/lib/esm/tests/api_tests/stripe_checkout_items.test.js.map +1 -0
- package/lib/esm/tests/api_tests/stripe_multiple_customer_ids.test.d.ts +5 -0
- package/lib/esm/tests/api_tests/stripe_multiple_customer_ids.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/stripe_multiple_customer_ids.test.js +388 -0
- package/lib/esm/tests/api_tests/stripe_multiple_customer_ids.test.js.map +1 -0
- package/lib/esm/tests/api_tests/tickets_bulk_assign_from_queue.test.d.ts +3 -1
- package/lib/esm/tests/api_tests/tickets_bulk_assign_from_queue.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/tickets_bulk_assign_from_queue.test.js +2 -0
- package/lib/esm/tests/api_tests/tickets_bulk_assign_from_queue.test.js.map +1 -1
- package/lib/esm/tests/api_tests/totp_mfa.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/totp_mfa.test.js +37 -31
- package/lib/esm/tests/api_tests/totp_mfa.test.js.map +1 -1
- package/lib/esm/tests/api_tests/trigger_contains_matching.test.d.ts +3 -1
- package/lib/esm/tests/api_tests/trigger_contains_matching.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/trigger_contains_matching.test.js +2 -0
- package/lib/esm/tests/api_tests/trigger_contains_matching.test.js.map +1 -1
- package/lib/esm/tests/api_tests/user_logs_restore_deleted.test.d.ts +3 -1
- package/lib/esm/tests/api_tests/user_logs_restore_deleted.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/user_logs_restore_deleted.test.js +2 -0
- package/lib/esm/tests/api_tests/user_logs_restore_deleted.test.js.map +1 -1
- package/lib/esm/tests/api_tests/vital_review_trigger_action.test.d.ts +3 -1
- package/lib/esm/tests/api_tests/vital_review_trigger_action.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/vital_review_trigger_action.test.js +2 -0
- package/lib/esm/tests/api_tests/vital_review_trigger_action.test.js.map +1 -1
- package/lib/esm/tests/api_tests/vitl_push.test.d.ts +7 -0
- package/lib/esm/tests/api_tests/vitl_push.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/vitl_push.test.js +333 -0
- package/lib/esm/tests/api_tests/vitl_push.test.js.map +1 -0
- package/lib/esm/tests/setup_isolated.d.ts +48 -0
- package/lib/esm/tests/setup_isolated.d.ts.map +1 -1
- package/lib/esm/tests/setup_isolated.js +114 -0
- package/lib/esm/tests/setup_isolated.js.map +1 -1
- package/lib/esm/tests/tests.d.ts.map +1 -1
- package/lib/esm/tests/tests.js +379 -283
- package/lib/esm/tests/tests.js.map +1 -1
- package/lib/esm/tests/unit_tests/isolated_suite_discovery.test.d.ts +2 -0
- package/lib/esm/tests/unit_tests/isolated_suite_discovery.test.d.ts.map +1 -0
- package/lib/esm/tests/unit_tests/isolated_suite_discovery.test.js +174 -0
- package/lib/esm/tests/unit_tests/isolated_suite_discovery.test.js.map +1 -0
- package/lib/esm/tests/unit_tests/programs_conditional_logic.test.d.ts +3 -0
- package/lib/esm/tests/unit_tests/programs_conditional_logic.test.d.ts.map +1 -0
- package/lib/esm/tests/unit_tests/programs_conditional_logic.test.js +117 -0
- package/lib/esm/tests/unit_tests/programs_conditional_logic.test.js.map +1 -0
- package/lib/esm/tests/webhooks_tests.js +44 -34
- package/lib/esm/tests/webhooks_tests.js.map +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +12 -11
- package/src/sdk.ts +9 -2
- package/src/tests/api_tests/booking_prevent_upcoming_duplicate.test.ts +541 -0
- package/src/tests/api_tests/enduser_fields_sync.test.ts +154 -0
- package/src/tests/api_tests/enduser_observations_auto_review.test.ts +4 -0
- package/src/tests/api_tests/form_vital_reading.test.ts +393 -0
- package/src/tests/api_tests/journey_statistics_cache.test.ts +237 -0
- package/src/tests/api_tests/journey_step_manual_count.test.ts +220 -0
- package/src/tests/api_tests/load_threads_care_team.test.ts +214 -0
- package/src/tests/api_tests/mdi_case_offerings.test.ts +138 -0
- package/src/tests/api_tests/organization_signup.test.ts +4 -0
- package/src/tests/api_tests/phone_embed_leave_message.test.ts +541 -0
- package/src/tests/api_tests/programs.test.ts +351 -0
- package/src/tests/api_tests/public_form_case_insensitive_match.test.ts +632 -0
- package/src/tests/api_tests/security/add-to-journey-foreign-enduserid.test.ts +37 -26
- package/src/tests/api_tests/security/appointment-reschedule-ownership.test.ts +436 -0
- package/src/tests/api_tests/security/file-link-session-confinement.test.ts +4 -0
- package/src/tests/api_tests/security/form-logic-js-execution.test.ts +4 -0
- package/src/tests/api_tests/security/formsort_webhook_auth_field_lock.test.ts +225 -0
- package/src/tests/api_tests/security/register_business_id_injection.test.ts +2 -2
- package/src/tests/api_tests/security/rich-text-answer-sanitized-on-write.test.ts +4 -0
- package/src/tests/api_tests/session_for_join_link.test.ts +99 -0
- package/src/tests/api_tests/set_fields_order_templates.test.ts +94 -9
- package/src/tests/api_tests/stripe_checkout_items.test.ts +186 -0
- package/src/tests/api_tests/tickets_bulk_assign_from_queue.test.ts +4 -0
- package/src/tests/api_tests/totp_mfa.test.ts +10 -5
- package/src/tests/api_tests/trigger_contains_matching.test.ts +349 -0
- package/src/tests/api_tests/user_logs_restore_deleted.test.ts +419 -0
- package/src/tests/api_tests/vital_review_trigger_action.test.ts +455 -0
- package/src/tests/api_tests/vitl_push.test.ts +323 -0
- package/src/tests/setup_isolated.ts +140 -0
- package/src/tests/tests.ts +126 -20
- package/src/tests/unit_tests/isolated_suite_discovery.test.ts +178 -0
- package/src/tests/unit_tests/programs_conditional_logic.test.ts +189 -0
- package/src/tests/unit_tests/trigger_title_partials.test.ts +174 -0
- package/src/tests/webhooks_tests.ts +6 -1
- package/test_generated.pdf +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"form-logic-js-execution.test.js","sourceRoot":"","sources":["../../../../../src/tests/api_tests/security/form-logic-js-execution.test.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,OAAO,CAAC,oBAAoB,CAAC,CAAC,OAAO,EAAE,CAAC;AAExC,
|
|
1
|
+
{"version":3,"file":"form-logic-js-execution.test.js","sourceRoot":"","sources":["../../../../../src/tests/api_tests/security/form-logic-js-execution.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"formsort_webhook_auth_field_lock.test.d.ts","sourceRoot":"","sources":["../../../../../src/tests/api_tests/security/formsort_webhook_auth_field_lock.test.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;
|
|
1
|
+
{"version":3,"file":"formsort_webhook_auth_field_lock.test.d.ts","sourceRoot":"","sources":["../../../../../src/tests/api_tests/security/formsort_webhook_auth_field_lock.test.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAsGtC,eAAO,MAAM,sCAAsC;SACpB,OAAO;iBAAe,OAAO;mBAi1B3D,CAAA"}
|
|
@@ -111,6 +111,19 @@ var host = process.env.API_URL || 'http://localhost:8080';
|
|
|
111
111
|
* R14 both grace markers are load-bearing: neither source nor stripeCustomerId alone opens it
|
|
112
112
|
* R15 the grace is per-request — it does not clear the stored flag
|
|
113
113
|
*
|
|
114
|
+
* ?alwaysSetPhone=true (CU-86e3k4ptv) is a second per-request override, narrower than ?enduserId=:
|
|
115
|
+
* it allows PHONE ONLY through the lock, on every finalized webhook, overwriting an existing and
|
|
116
|
+
* different number. Email — the password-reset channel this lock exists to protect — stays blocked.
|
|
117
|
+
* G16 (GREEN) the flag overwrites an existing, different phone on a guessed match
|
|
118
|
+
* G17 (GREEN) ...and in that same request the submitted email is still dropped
|
|
119
|
+
* R16 (RED) the identical request WITHOUT the flag leaves both phone and email blocked
|
|
120
|
+
* R17 (RED) the flag does not open email on a phone match either
|
|
121
|
+
* R18 (RED) only the literal string 'true' enables it — ?alwaysSetPhone=1 keeps the lock
|
|
122
|
+
* G18 (GREEN) a flagged webhook still stamps authFieldIntakeDisabled on the response, so later
|
|
123
|
+
* writes through save_enduser_updates_for_form_response stay blocked
|
|
124
|
+
* R19 (RED) it is request-scoped: a flag passed on an earlier webhook for the same
|
|
125
|
+
* responder_uuid does not unlock a later one that omits it
|
|
126
|
+
*
|
|
114
127
|
* The Stripe grace is deliberately confined to THIS endpoint, which is API-key authenticated. The
|
|
115
128
|
* anonymous public-form path gets no exemption; that boundary is pinned by G28 in
|
|
116
129
|
* public_endpoint_auth_field_lock.test.ts.
|
|
@@ -198,6 +211,8 @@ var formsort_webhook_auth_field_lock_tests = function (_a) {
|
|
|
198
211
|
url.searchParams.set('enduserId', o.enduserId);
|
|
199
212
|
if (o.createNewEnduser)
|
|
200
213
|
url.searchParams.set('createNewEnduser', 'true');
|
|
214
|
+
if (o.alwaysSetPhone !== undefined)
|
|
215
|
+
url.searchParams.set('alwaysSetPhone', o.alwaysSetPhone);
|
|
201
216
|
return [4 /*yield*/, axios_1.default.post(url.toString(), { answers: o.answers, responder_uuid: uuidFor(o.label), finalized: o.finalized }, { validateStatus: function () { return true; } })
|
|
202
217
|
// In-progress webhooks always return a bare 200 (the handler returns before the returnJSON
|
|
203
218
|
// block), so `data` is only populated for finalized calls.
|
|
@@ -1070,7 +1085,10 @@ var formsort_webhook_auth_field_lock_tests = function (_a) {
|
|
|
1070
1085
|
});
|
|
1071
1086
|
}); })
|
|
1072
1087
|
// ---------------------------------------------------------------------------------------------
|
|
1073
|
-
//
|
|
1088
|
+
// G16 — ?alwaysSetPhone=true: the opt-in allows phone through the lock on a GUESSED match (the
|
|
1089
|
+
// path R2 blocks), overwriting a phone that is already stored and different. Phone is also the
|
|
1090
|
+
// only field this submission changes, which exercises the "at least one update provided" guard —
|
|
1091
|
+
// if the delete happened before that guard, nothing would be written at all.
|
|
1074
1092
|
// ---------------------------------------------------------------------------------------------
|
|
1075
1093
|
];
|
|
1076
1094
|
case 20:
|
|
@@ -1081,6 +1099,373 @@ var formsort_webhook_auth_field_lock_tests = function (_a) {
|
|
|
1081
1099
|
// after the window closes) stays protected.
|
|
1082
1100
|
// ---------------------------------------------------------------------------------------------
|
|
1083
1101
|
_h.sent();
|
|
1102
|
+
// ---------------------------------------------------------------------------------------------
|
|
1103
|
+
// G16 — ?alwaysSetPhone=true: the opt-in allows phone through the lock on a GUESSED match (the
|
|
1104
|
+
// path R2 blocks), overwriting a phone that is already stored and different. Phone is also the
|
|
1105
|
+
// only field this submission changes, which exercises the "at least one update provided" guard —
|
|
1106
|
+
// if the delete happened before that guard, nothing would be written at all.
|
|
1107
|
+
// ---------------------------------------------------------------------------------------------
|
|
1108
|
+
return [4 /*yield*/, runScenario('G16', 'alwaysSetPhone=true overwrites an existing phone on a guessed match', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
1109
|
+
var email, originalPhone, victim, intakePhone, data, enduser;
|
|
1110
|
+
return __generator(this, function (_a) {
|
|
1111
|
+
switch (_a.label) {
|
|
1112
|
+
case 0:
|
|
1113
|
+
email = emailFor('g16');
|
|
1114
|
+
originalPhone = nextPhone();
|
|
1115
|
+
return [4 /*yield*/, makeVictim('g16', { email: email, phone: originalPhone })];
|
|
1116
|
+
case 1:
|
|
1117
|
+
victim = _a.sent();
|
|
1118
|
+
intakePhone = nextPhone();
|
|
1119
|
+
return [4 /*yield*/, postWebhook({
|
|
1120
|
+
label: 'g16',
|
|
1121
|
+
finalized: true,
|
|
1122
|
+
alwaysSetPhone: 'true',
|
|
1123
|
+
answers: [{ key: 'email', value: email }, { key: 'phone', value: intakePhone }],
|
|
1124
|
+
})];
|
|
1125
|
+
case 2:
|
|
1126
|
+
data = (_a.sent()).data;
|
|
1127
|
+
if (!matched('G16', 'alwaysSetPhone=true overwrites an existing phone on a guessed match', data, victim.id))
|
|
1128
|
+
return [2 /*return*/];
|
|
1129
|
+
return [4 /*yield*/, pollEnduser(victim.id, function (e) { return e.phone === intakePhone; })];
|
|
1130
|
+
case 3:
|
|
1131
|
+
enduser = _a.sent();
|
|
1132
|
+
record('G16', 'alwaysSetPhone=true overwrites an existing phone on a guessed match', (enduser === null || enduser === void 0 ? void 0 : enduser.phone) === intakePhone, "phone=".concat((enduser === null || enduser === void 0 ? void 0 : enduser.phone) || '(unset)', " expected=").concat(intakePhone));
|
|
1133
|
+
return [2 /*return*/];
|
|
1134
|
+
}
|
|
1135
|
+
});
|
|
1136
|
+
}); })
|
|
1137
|
+
// ---------------------------------------------------------------------------------------------
|
|
1138
|
+
// G17 — the same request, with BOTH a new phone and a different email, so the two halves of the
|
|
1139
|
+
// rule are observed together: phone lands, email does not. Shaped like R3 (a draft formed by a
|
|
1140
|
+
// guess, finalized through the sticky flag) because that is the only resolution path where the
|
|
1141
|
+
// submitted email can differ from the stored one while the patient still matches.
|
|
1142
|
+
// ---------------------------------------------------------------------------------------------
|
|
1143
|
+
];
|
|
1144
|
+
case 21:
|
|
1145
|
+
// ---------------------------------------------------------------------------------------------
|
|
1146
|
+
// G16 — ?alwaysSetPhone=true: the opt-in allows phone through the lock on a GUESSED match (the
|
|
1147
|
+
// path R2 blocks), overwriting a phone that is already stored and different. Phone is also the
|
|
1148
|
+
// only field this submission changes, which exercises the "at least one update provided" guard —
|
|
1149
|
+
// if the delete happened before that guard, nothing would be written at all.
|
|
1150
|
+
// ---------------------------------------------------------------------------------------------
|
|
1151
|
+
_h.sent();
|
|
1152
|
+
// ---------------------------------------------------------------------------------------------
|
|
1153
|
+
// G17 — the same request, with BOTH a new phone and a different email, so the two halves of the
|
|
1154
|
+
// rule are observed together: phone lands, email does not. Shaped like R3 (a draft formed by a
|
|
1155
|
+
// guess, finalized through the sticky flag) because that is the only resolution path where the
|
|
1156
|
+
// submitted email can differ from the stored one while the patient still matches.
|
|
1157
|
+
// ---------------------------------------------------------------------------------------------
|
|
1158
|
+
return [4 /*yield*/, runScenario('G17', 'alwaysSetPhone=true writes phone and still drops email', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
1159
|
+
var originalEmail, originalPhone, victim, attackerEmail, intakePhone, data, enduser;
|
|
1160
|
+
return __generator(this, function (_a) {
|
|
1161
|
+
switch (_a.label) {
|
|
1162
|
+
case 0:
|
|
1163
|
+
originalEmail = emailFor('g17');
|
|
1164
|
+
originalPhone = nextPhone();
|
|
1165
|
+
return [4 /*yield*/, makeVictim('g17', { email: originalEmail, phone: originalPhone })];
|
|
1166
|
+
case 1:
|
|
1167
|
+
victim = _a.sent();
|
|
1168
|
+
attackerEmail = emailFor('g17-attacker');
|
|
1169
|
+
intakePhone = nextPhone();
|
|
1170
|
+
// draft matches the pre-existing patient by phone -> authFieldIntakeDisabled is stamped on it
|
|
1171
|
+
return [4 /*yield*/, postWebhook({ label: 'g17', finalized: false, answers: [{ key: 'phone', value: originalPhone }] })];
|
|
1172
|
+
case 2:
|
|
1173
|
+
// draft matches the pre-existing patient by phone -> authFieldIntakeDisabled is stamped on it
|
|
1174
|
+
_a.sent();
|
|
1175
|
+
return [4 /*yield*/, postWebhook({
|
|
1176
|
+
label: 'g17',
|
|
1177
|
+
finalized: true,
|
|
1178
|
+
alwaysSetPhone: 'true',
|
|
1179
|
+
answers: [{ key: 'phone', value: intakePhone }, { key: 'email', value: attackerEmail }],
|
|
1180
|
+
})];
|
|
1181
|
+
case 3:
|
|
1182
|
+
data = (_a.sent()).data;
|
|
1183
|
+
if (!matched('G17', 'alwaysSetPhone=true writes phone and still drops email', data, victim.id))
|
|
1184
|
+
return [2 /*return*/];
|
|
1185
|
+
return [4 /*yield*/, pollEnduser(victim.id, function (e) { return e.phone === intakePhone; })];
|
|
1186
|
+
case 4:
|
|
1187
|
+
enduser = _a.sent();
|
|
1188
|
+
record('G17', 'alwaysSetPhone=true writes phone through the sticky flag', (enduser === null || enduser === void 0 ? void 0 : enduser.phone) === intakePhone, "phone=".concat((enduser === null || enduser === void 0 ? void 0 : enduser.phone) || '(unset)', " expected=").concat(intakePhone));
|
|
1189
|
+
record('G17', 'alwaysSetPhone=true leaves email blocked in the same request', (enduser === null || enduser === void 0 ? void 0 : enduser.email) === originalEmail, "email=".concat((enduser === null || enduser === void 0 ? void 0 : enduser.email) || '(unset)', " expected=").concat(originalEmail));
|
|
1190
|
+
return [2 /*return*/];
|
|
1191
|
+
}
|
|
1192
|
+
});
|
|
1193
|
+
}); })
|
|
1194
|
+
// ---------------------------------------------------------------------------------------------
|
|
1195
|
+
// R16 — the control for G17: byte-identical request without the flag. Both fields stay blocked,
|
|
1196
|
+
// i.e. the default behavior is unchanged.
|
|
1197
|
+
// ---------------------------------------------------------------------------------------------
|
|
1198
|
+
];
|
|
1199
|
+
case 22:
|
|
1200
|
+
// ---------------------------------------------------------------------------------------------
|
|
1201
|
+
// G17 — the same request, with BOTH a new phone and a different email, so the two halves of the
|
|
1202
|
+
// rule are observed together: phone lands, email does not. Shaped like R3 (a draft formed by a
|
|
1203
|
+
// guess, finalized through the sticky flag) because that is the only resolution path where the
|
|
1204
|
+
// submitted email can differ from the stored one while the patient still matches.
|
|
1205
|
+
// ---------------------------------------------------------------------------------------------
|
|
1206
|
+
_h.sent();
|
|
1207
|
+
// ---------------------------------------------------------------------------------------------
|
|
1208
|
+
// R16 — the control for G17: byte-identical request without the flag. Both fields stay blocked,
|
|
1209
|
+
// i.e. the default behavior is unchanged.
|
|
1210
|
+
// ---------------------------------------------------------------------------------------------
|
|
1211
|
+
return [4 /*yield*/, runScenario('R16', 'without the flag the same request blocks phone and email', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
1212
|
+
var originalEmail, originalPhone, victim, attackerEmail, intakePhone, data, enduser;
|
|
1213
|
+
return __generator(this, function (_a) {
|
|
1214
|
+
switch (_a.label) {
|
|
1215
|
+
case 0:
|
|
1216
|
+
originalEmail = emailFor('r16');
|
|
1217
|
+
originalPhone = nextPhone();
|
|
1218
|
+
return [4 /*yield*/, makeVictim('r16', { email: originalEmail, phone: originalPhone })];
|
|
1219
|
+
case 1:
|
|
1220
|
+
victim = _a.sent();
|
|
1221
|
+
attackerEmail = emailFor('r16-attacker');
|
|
1222
|
+
intakePhone = nextPhone();
|
|
1223
|
+
return [4 /*yield*/, postWebhook({ label: 'r16', finalized: false, answers: [{ key: 'phone', value: originalPhone }] })];
|
|
1224
|
+
case 2:
|
|
1225
|
+
_a.sent();
|
|
1226
|
+
return [4 /*yield*/, postWebhook({
|
|
1227
|
+
label: 'r16',
|
|
1228
|
+
finalized: true,
|
|
1229
|
+
answers: [{ key: 'phone', value: intakePhone }, { key: 'email', value: attackerEmail }],
|
|
1230
|
+
})];
|
|
1231
|
+
case 3:
|
|
1232
|
+
data = (_a.sent()).data;
|
|
1233
|
+
if (!matched('R16', 'without the flag the same request blocks phone and email', data, victim.id))
|
|
1234
|
+
return [2 /*return*/];
|
|
1235
|
+
return [4 /*yield*/, pollEnduser(victim.id, function (e) { return e.phone === intakePhone || e.email === attackerEmail; })];
|
|
1236
|
+
case 4:
|
|
1237
|
+
enduser = _a.sent();
|
|
1238
|
+
record('R16', 'without the flag phone stays blocked', (enduser === null || enduser === void 0 ? void 0 : enduser.phone) === originalPhone, "phone=".concat((enduser === null || enduser === void 0 ? void 0 : enduser.phone) || '(unset)', " expected=").concat(originalPhone));
|
|
1239
|
+
record('R16', 'without the flag email stays blocked', (enduser === null || enduser === void 0 ? void 0 : enduser.email) === originalEmail, "email=".concat((enduser === null || enduser === void 0 ? void 0 : enduser.email) || '(unset)', " expected=").concat(originalEmail));
|
|
1240
|
+
return [2 /*return*/];
|
|
1241
|
+
}
|
|
1242
|
+
});
|
|
1243
|
+
}); })
|
|
1244
|
+
// ---------------------------------------------------------------------------------------------
|
|
1245
|
+
// R17 — the flag is phone-only in BOTH match directions: matched on phone (R1's shape), the
|
|
1246
|
+
// submitted email must still not land.
|
|
1247
|
+
// ---------------------------------------------------------------------------------------------
|
|
1248
|
+
];
|
|
1249
|
+
case 23:
|
|
1250
|
+
// ---------------------------------------------------------------------------------------------
|
|
1251
|
+
// R16 — the control for G17: byte-identical request without the flag. Both fields stay blocked,
|
|
1252
|
+
// i.e. the default behavior is unchanged.
|
|
1253
|
+
// ---------------------------------------------------------------------------------------------
|
|
1254
|
+
_h.sent();
|
|
1255
|
+
// ---------------------------------------------------------------------------------------------
|
|
1256
|
+
// R17 — the flag is phone-only in BOTH match directions: matched on phone (R1's shape), the
|
|
1257
|
+
// submitted email must still not land.
|
|
1258
|
+
// ---------------------------------------------------------------------------------------------
|
|
1259
|
+
return [4 /*yield*/, runScenario('R17', 'alwaysSetPhone=true does not repoint email on a phone match', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
1260
|
+
var originalEmail, phone, victim, attackerEmail, data, enduser;
|
|
1261
|
+
return __generator(this, function (_a) {
|
|
1262
|
+
switch (_a.label) {
|
|
1263
|
+
case 0:
|
|
1264
|
+
originalEmail = emailFor('r17');
|
|
1265
|
+
phone = nextPhone();
|
|
1266
|
+
return [4 /*yield*/, makeVictim('r17', { email: originalEmail, phone: phone })];
|
|
1267
|
+
case 1:
|
|
1268
|
+
victim = _a.sent();
|
|
1269
|
+
attackerEmail = emailFor('r17-attacker');
|
|
1270
|
+
return [4 /*yield*/, postWebhook({
|
|
1271
|
+
label: 'r17',
|
|
1272
|
+
finalized: true,
|
|
1273
|
+
alwaysSetPhone: 'true',
|
|
1274
|
+
answers: [{ key: 'phone', value: phone }, { key: 'email', value: attackerEmail }],
|
|
1275
|
+
})];
|
|
1276
|
+
case 2:
|
|
1277
|
+
data = (_a.sent()).data;
|
|
1278
|
+
if (!matched('R17', 'alwaysSetPhone=true does not repoint email on a phone match', data, victim.id))
|
|
1279
|
+
return [2 /*return*/];
|
|
1280
|
+
return [4 /*yield*/, pollEnduser(victim.id, function (e) { return e.email === attackerEmail; })];
|
|
1281
|
+
case 3:
|
|
1282
|
+
enduser = _a.sent();
|
|
1283
|
+
record('R17', 'alwaysSetPhone=true does not repoint email on a phone match', (enduser === null || enduser === void 0 ? void 0 : enduser.email) === originalEmail, "email=".concat((enduser === null || enduser === void 0 ? void 0 : enduser.email) || '(unset)', " expected=").concat(originalEmail));
|
|
1284
|
+
return [2 /*return*/];
|
|
1285
|
+
}
|
|
1286
|
+
});
|
|
1287
|
+
}); })
|
|
1288
|
+
// ---------------------------------------------------------------------------------------------
|
|
1289
|
+
// R18 — parsed as === 'true', matching createNewEnduser / matchByName. Any other value, including
|
|
1290
|
+
// a truthy-looking one, keeps today's behavior.
|
|
1291
|
+
// ---------------------------------------------------------------------------------------------
|
|
1292
|
+
];
|
|
1293
|
+
case 24:
|
|
1294
|
+
// ---------------------------------------------------------------------------------------------
|
|
1295
|
+
// R17 — the flag is phone-only in BOTH match directions: matched on phone (R1's shape), the
|
|
1296
|
+
// submitted email must still not land.
|
|
1297
|
+
// ---------------------------------------------------------------------------------------------
|
|
1298
|
+
_h.sent();
|
|
1299
|
+
// ---------------------------------------------------------------------------------------------
|
|
1300
|
+
// R18 — parsed as === 'true', matching createNewEnduser / matchByName. Any other value, including
|
|
1301
|
+
// a truthy-looking one, keeps today's behavior.
|
|
1302
|
+
// ---------------------------------------------------------------------------------------------
|
|
1303
|
+
return [4 /*yield*/, runScenario('R18', 'alwaysSetPhone=1 does not enable the opt-in', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
1304
|
+
var email, originalPhone, victim, intakePhone, data, enduser;
|
|
1305
|
+
return __generator(this, function (_a) {
|
|
1306
|
+
switch (_a.label) {
|
|
1307
|
+
case 0:
|
|
1308
|
+
email = emailFor('r18');
|
|
1309
|
+
originalPhone = nextPhone();
|
|
1310
|
+
return [4 /*yield*/, makeVictim('r18', { email: email, phone: originalPhone })];
|
|
1311
|
+
case 1:
|
|
1312
|
+
victim = _a.sent();
|
|
1313
|
+
intakePhone = nextPhone();
|
|
1314
|
+
return [4 /*yield*/, postWebhook({
|
|
1315
|
+
label: 'r18',
|
|
1316
|
+
finalized: true,
|
|
1317
|
+
alwaysSetPhone: '1',
|
|
1318
|
+
answers: [{ key: 'email', value: email }, { key: 'phone', value: intakePhone }],
|
|
1319
|
+
})];
|
|
1320
|
+
case 2:
|
|
1321
|
+
data = (_a.sent()).data;
|
|
1322
|
+
if (!matched('R18', 'alwaysSetPhone=1 does not enable the opt-in', data, victim.id))
|
|
1323
|
+
return [2 /*return*/];
|
|
1324
|
+
return [4 /*yield*/, pollEnduser(victim.id, function (e) { return e.phone === intakePhone; })];
|
|
1325
|
+
case 3:
|
|
1326
|
+
enduser = _a.sent();
|
|
1327
|
+
record('R18', 'alwaysSetPhone=1 does not enable the opt-in', (enduser === null || enduser === void 0 ? void 0 : enduser.phone) === originalPhone, "phone=".concat((enduser === null || enduser === void 0 ? void 0 : enduser.phone) || '(unset)', " expected=").concat(originalPhone));
|
|
1328
|
+
return [2 /*return*/];
|
|
1329
|
+
}
|
|
1330
|
+
});
|
|
1331
|
+
}); })
|
|
1332
|
+
// ---------------------------------------------------------------------------------------------
|
|
1333
|
+
// G18 — the opt-in is a per-REQUEST allow, exactly like G11 (?enduserId=) and R15 (the Stripe
|
|
1334
|
+
// grace): the response still records that it attached to a pre-existing patient, so the other
|
|
1335
|
+
// consumer of that flag — save_enduser_updates_for_form_response, reached by later staff edits —
|
|
1336
|
+
// stays protected.
|
|
1337
|
+
// ---------------------------------------------------------------------------------------------
|
|
1338
|
+
];
|
|
1339
|
+
case 25:
|
|
1340
|
+
// ---------------------------------------------------------------------------------------------
|
|
1341
|
+
// R18 — parsed as === 'true', matching createNewEnduser / matchByName. Any other value, including
|
|
1342
|
+
// a truthy-looking one, keeps today's behavior.
|
|
1343
|
+
// ---------------------------------------------------------------------------------------------
|
|
1344
|
+
_h.sent();
|
|
1345
|
+
// ---------------------------------------------------------------------------------------------
|
|
1346
|
+
// G18 — the opt-in is a per-REQUEST allow, exactly like G11 (?enduserId=) and R15 (the Stripe
|
|
1347
|
+
// grace): the response still records that it attached to a pre-existing patient, so the other
|
|
1348
|
+
// consumer of that flag — save_enduser_updates_for_form_response, reached by later staff edits —
|
|
1349
|
+
// stays protected.
|
|
1350
|
+
// ---------------------------------------------------------------------------------------------
|
|
1351
|
+
return [4 /*yield*/, runScenario('G18', 'alwaysSetPhone does not clear the stored flag', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
1352
|
+
var email, victim, intakePhone, data, enduser, response;
|
|
1353
|
+
return __generator(this, function (_a) {
|
|
1354
|
+
switch (_a.label) {
|
|
1355
|
+
case 0:
|
|
1356
|
+
email = emailFor('g18');
|
|
1357
|
+
return [4 /*yield*/, makeVictim('g18', { email: email, phone: nextPhone() })];
|
|
1358
|
+
case 1:
|
|
1359
|
+
victim = _a.sent();
|
|
1360
|
+
intakePhone = nextPhone();
|
|
1361
|
+
return [4 /*yield*/, postWebhook({
|
|
1362
|
+
label: 'g18',
|
|
1363
|
+
finalized: true,
|
|
1364
|
+
alwaysSetPhone: 'true',
|
|
1365
|
+
answers: [{ key: 'email', value: email }, { key: 'phone', value: intakePhone }],
|
|
1366
|
+
})];
|
|
1367
|
+
case 2:
|
|
1368
|
+
data = (_a.sent()).data;
|
|
1369
|
+
if (!matched('G18', 'alwaysSetPhone does not clear the stored flag', data, victim.id))
|
|
1370
|
+
return [2 /*return*/];
|
|
1371
|
+
return [4 /*yield*/, pollEnduser(victim.id, function (e) { return e.phone === intakePhone; })];
|
|
1372
|
+
case 3:
|
|
1373
|
+
enduser = _a.sent();
|
|
1374
|
+
record('G18', 'flagged webhook landed the phone (probe precondition)', (enduser === null || enduser === void 0 ? void 0 : enduser.phone) === intakePhone, "phone=".concat((enduser === null || enduser === void 0 ? void 0 : enduser.phone) || '(unset)', " expected=").concat(intakePhone));
|
|
1375
|
+
if (!data.formResponseId) {
|
|
1376
|
+
skip('G18', 'alwaysSetPhone does not clear the stored flag', 'webhook returned no formResponseId');
|
|
1377
|
+
return [2 /*return*/];
|
|
1378
|
+
}
|
|
1379
|
+
return [4 /*yield*/, sdk.api.form_responses.getOne(data.formResponseId).catch(function () { return null; })];
|
|
1380
|
+
case 4:
|
|
1381
|
+
response = _a.sent();
|
|
1382
|
+
if (!response) {
|
|
1383
|
+
skip('G18', 'alwaysSetPhone does not clear the stored flag', 'form response not readable');
|
|
1384
|
+
}
|
|
1385
|
+
else if (response.authFieldIntakeDisabled === undefined) {
|
|
1386
|
+
// deliberately absent from schema.ts; if reads project it away there is nothing to assert here
|
|
1387
|
+
skip('G18', 'alwaysSetPhone does not clear the stored flag', 'authFieldIntakeDisabled not exposed on read');
|
|
1388
|
+
}
|
|
1389
|
+
else {
|
|
1390
|
+
record('G18', 'alwaysSetPhone does not clear the stored flag', response.authFieldIntakeDisabled === true, "authFieldIntakeDisabled=".concat(response.authFieldIntakeDisabled, " expected=true"));
|
|
1391
|
+
}
|
|
1392
|
+
return [2 /*return*/];
|
|
1393
|
+
}
|
|
1394
|
+
});
|
|
1395
|
+
}); })
|
|
1396
|
+
// ---------------------------------------------------------------------------------------------
|
|
1397
|
+
// R19 — nothing about the opt-in is recorded on the response, so a later webhook for the same
|
|
1398
|
+
// responder_uuid that omits it is blocked as usual. The earlier webhook here must be the DRAFT:
|
|
1399
|
+
// once a response is submitted the handler returns 'Already submitted' before reaching the lock,
|
|
1400
|
+
// which would make a finalized-then-finalized pair pass no matter what the implementation did.
|
|
1401
|
+
// ---------------------------------------------------------------------------------------------
|
|
1402
|
+
];
|
|
1403
|
+
case 26:
|
|
1404
|
+
// ---------------------------------------------------------------------------------------------
|
|
1405
|
+
// G18 — the opt-in is a per-REQUEST allow, exactly like G11 (?enduserId=) and R15 (the Stripe
|
|
1406
|
+
// grace): the response still records that it attached to a pre-existing patient, so the other
|
|
1407
|
+
// consumer of that flag — save_enduser_updates_for_form_response, reached by later staff edits —
|
|
1408
|
+
// stays protected.
|
|
1409
|
+
// ---------------------------------------------------------------------------------------------
|
|
1410
|
+
_h.sent();
|
|
1411
|
+
// ---------------------------------------------------------------------------------------------
|
|
1412
|
+
// R19 — nothing about the opt-in is recorded on the response, so a later webhook for the same
|
|
1413
|
+
// responder_uuid that omits it is blocked as usual. The earlier webhook here must be the DRAFT:
|
|
1414
|
+
// once a response is submitted the handler returns 'Already submitted' before reaching the lock,
|
|
1415
|
+
// which would make a finalized-then-finalized pair pass no matter what the implementation did.
|
|
1416
|
+
// ---------------------------------------------------------------------------------------------
|
|
1417
|
+
return [4 /*yield*/, runScenario('R19', 'alwaysSetPhone on an earlier webhook does not unlock a later one', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
1418
|
+
var email, originalPhone, victim, intakePhone, draft, data, enduser;
|
|
1419
|
+
return __generator(this, function (_a) {
|
|
1420
|
+
switch (_a.label) {
|
|
1421
|
+
case 0:
|
|
1422
|
+
email = emailFor('r19');
|
|
1423
|
+
originalPhone = nextPhone();
|
|
1424
|
+
return [4 /*yield*/, makeVictim('r19', { email: email, phone: originalPhone })];
|
|
1425
|
+
case 1:
|
|
1426
|
+
victim = _a.sent();
|
|
1427
|
+
intakePhone = nextPhone();
|
|
1428
|
+
return [4 /*yield*/, postWebhook({
|
|
1429
|
+
label: 'r19',
|
|
1430
|
+
finalized: false,
|
|
1431
|
+
alwaysSetPhone: 'true',
|
|
1432
|
+
answers: [{ key: 'email', value: email }],
|
|
1433
|
+
})];
|
|
1434
|
+
case 2:
|
|
1435
|
+
draft = _a.sent();
|
|
1436
|
+
if (draft.status !== 200) {
|
|
1437
|
+
record('R19', 'alwaysSetPhone on an earlier webhook does not unlock a later one', false, "draft webhook returned ".concat(draft.status));
|
|
1438
|
+
return [2 /*return*/];
|
|
1439
|
+
}
|
|
1440
|
+
return [4 /*yield*/, postWebhook({
|
|
1441
|
+
label: 'r19',
|
|
1442
|
+
finalized: true,
|
|
1443
|
+
answers: [{ key: 'email', value: email }, { key: 'phone', value: intakePhone }],
|
|
1444
|
+
})];
|
|
1445
|
+
case 3:
|
|
1446
|
+
data = (_a.sent()).data;
|
|
1447
|
+
if (!matched('R19', 'alwaysSetPhone on an earlier webhook does not unlock a later one', data, victim.id))
|
|
1448
|
+
return [2 /*return*/];
|
|
1449
|
+
return [4 /*yield*/, pollEnduser(victim.id, function (e) { return e.phone === intakePhone; })];
|
|
1450
|
+
case 4:
|
|
1451
|
+
enduser = _a.sent();
|
|
1452
|
+
record('R19', 'alwaysSetPhone on an earlier webhook does not unlock a later one', (enduser === null || enduser === void 0 ? void 0 : enduser.phone) === originalPhone, "phone=".concat((enduser === null || enduser === void 0 ? void 0 : enduser.phone) || '(unset)', " expected=").concat(originalPhone));
|
|
1453
|
+
return [2 /*return*/];
|
|
1454
|
+
}
|
|
1455
|
+
});
|
|
1456
|
+
}); })
|
|
1457
|
+
// ---------------------------------------------------------------------------------------------
|
|
1458
|
+
// Report
|
|
1459
|
+
// ---------------------------------------------------------------------------------------------
|
|
1460
|
+
];
|
|
1461
|
+
case 27:
|
|
1462
|
+
// ---------------------------------------------------------------------------------------------
|
|
1463
|
+
// R19 — nothing about the opt-in is recorded on the response, so a later webhook for the same
|
|
1464
|
+
// responder_uuid that omits it is blocked as usual. The earlier webhook here must be the DRAFT:
|
|
1465
|
+
// once a response is submitted the handler returns 'Already submitted' before reaching the lock,
|
|
1466
|
+
// which would make a finalized-then-finalized pair pass no matter what the implementation did.
|
|
1467
|
+
// ---------------------------------------------------------------------------------------------
|
|
1468
|
+
_h.sent();
|
|
1084
1469
|
failures = results.filter(function (r) { return !r.ok; });
|
|
1085
1470
|
skipped = results.filter(function (r) { return !!r.skipped; });
|
|
1086
1471
|
console.log('');
|
|
@@ -1093,69 +1478,69 @@ var formsort_webhook_auth_field_lock_tests = function (_a) {
|
|
|
1093
1478
|
console.log(" \u2514\u2500 ".concat(results.length - failures.length, "/").concat(results.length, " passed, ").concat(skipped.length, " skipped, ").concat(failures.length, " failed"));
|
|
1094
1479
|
console.log('');
|
|
1095
1480
|
_b = 0, createdFormIds_1 = createdFormIds;
|
|
1096
|
-
_h.label =
|
|
1097
|
-
case
|
|
1098
|
-
if (!(_b < createdFormIds_1.length)) return [3 /*break*/,
|
|
1481
|
+
_h.label = 28;
|
|
1482
|
+
case 28:
|
|
1483
|
+
if (!(_b < createdFormIds_1.length)) return [3 /*break*/, 34];
|
|
1099
1484
|
formId = createdFormIds_1[_b];
|
|
1100
1485
|
return [4 /*yield*/, sdk.api.form_responses.getSome({ filter: { formId: formId } }).catch(function () { return []; })];
|
|
1101
|
-
case
|
|
1486
|
+
case 29:
|
|
1102
1487
|
responses = _h.sent();
|
|
1103
1488
|
_c = 0, responses_1 = responses;
|
|
1104
|
-
_h.label =
|
|
1105
|
-
case
|
|
1106
|
-
if (!(_c < responses_1.length)) return [3 /*break*/,
|
|
1489
|
+
_h.label = 30;
|
|
1490
|
+
case 30:
|
|
1491
|
+
if (!(_c < responses_1.length)) return [3 /*break*/, 33];
|
|
1107
1492
|
response = responses_1[_c];
|
|
1108
1493
|
return [4 /*yield*/, sdk.api.form_responses.deleteOne(response.id).catch(function () { return null; })];
|
|
1109
|
-
case
|
|
1494
|
+
case 31:
|
|
1110
1495
|
_h.sent();
|
|
1111
|
-
_h.label =
|
|
1112
|
-
case
|
|
1496
|
+
_h.label = 32;
|
|
1497
|
+
case 32:
|
|
1113
1498
|
_c++;
|
|
1114
|
-
return [3 /*break*/,
|
|
1115
|
-
case
|
|
1499
|
+
return [3 /*break*/, 30];
|
|
1500
|
+
case 33:
|
|
1116
1501
|
_b++;
|
|
1117
|
-
return [3 /*break*/,
|
|
1118
|
-
case
|
|
1502
|
+
return [3 /*break*/, 28];
|
|
1503
|
+
case 34:
|
|
1119
1504
|
_d = 0, createdFormIds_2 = createdFormIds;
|
|
1120
|
-
_h.label =
|
|
1121
|
-
case
|
|
1122
|
-
if (!(_d < createdFormIds_2.length)) return [3 /*break*/,
|
|
1505
|
+
_h.label = 35;
|
|
1506
|
+
case 35:
|
|
1507
|
+
if (!(_d < createdFormIds_2.length)) return [3 /*break*/, 38];
|
|
1123
1508
|
id = createdFormIds_2[_d];
|
|
1124
1509
|
return [4 /*yield*/, sdk.api.forms.deleteOne(id).catch(function () { return null; })];
|
|
1125
|
-
case
|
|
1510
|
+
case 36:
|
|
1126
1511
|
_h.sent();
|
|
1127
|
-
_h.label =
|
|
1128
|
-
case
|
|
1512
|
+
_h.label = 37;
|
|
1513
|
+
case 37:
|
|
1129
1514
|
_d++;
|
|
1130
|
-
return [3 /*break*/,
|
|
1131
|
-
case
|
|
1515
|
+
return [3 /*break*/, 35];
|
|
1516
|
+
case 38:
|
|
1132
1517
|
uniqueEnduserIds = createdEnduserIds.filter(function (id, i) { return !!id && createdEnduserIds.indexOf(id) === i; });
|
|
1133
1518
|
_e = 0, uniqueEnduserIds_1 = uniqueEnduserIds;
|
|
1134
|
-
_h.label =
|
|
1135
|
-
case
|
|
1136
|
-
if (!(_e < uniqueEnduserIds_1.length)) return [3 /*break*/,
|
|
1519
|
+
_h.label = 39;
|
|
1520
|
+
case 39:
|
|
1521
|
+
if (!(_e < uniqueEnduserIds_1.length)) return [3 /*break*/, 42];
|
|
1137
1522
|
id = uniqueEnduserIds_1[_e];
|
|
1138
1523
|
return [4 /*yield*/, sdk.api.endusers.deleteOne(id).catch(function () { return null; })];
|
|
1139
|
-
case
|
|
1524
|
+
case 40:
|
|
1140
1525
|
_h.sent();
|
|
1141
|
-
_h.label =
|
|
1142
|
-
case
|
|
1526
|
+
_h.label = 41;
|
|
1527
|
+
case 41:
|
|
1143
1528
|
_e++;
|
|
1144
|
-
return [3 /*break*/,
|
|
1145
|
-
case
|
|
1529
|
+
return [3 /*break*/, 39];
|
|
1530
|
+
case 42:
|
|
1146
1531
|
_f = 0, createdApiKeyIds_1 = createdApiKeyIds;
|
|
1147
|
-
_h.label =
|
|
1148
|
-
case
|
|
1149
|
-
if (!(_f < createdApiKeyIds_1.length)) return [3 /*break*/,
|
|
1532
|
+
_h.label = 43;
|
|
1533
|
+
case 43:
|
|
1534
|
+
if (!(_f < createdApiKeyIds_1.length)) return [3 /*break*/, 46];
|
|
1150
1535
|
id = createdApiKeyIds_1[_f];
|
|
1151
1536
|
return [4 /*yield*/, sdk.api.api_keys.deleteOne(id).catch(function () { return null; })];
|
|
1152
|
-
case
|
|
1537
|
+
case 44:
|
|
1153
1538
|
_h.sent();
|
|
1154
|
-
_h.label =
|
|
1155
|
-
case
|
|
1539
|
+
_h.label = 45;
|
|
1540
|
+
case 45:
|
|
1156
1541
|
_f++;
|
|
1157
|
-
return [3 /*break*/,
|
|
1158
|
-
case
|
|
1542
|
+
return [3 /*break*/, 43];
|
|
1543
|
+
case 46:
|
|
1159
1544
|
// ---------------------------------------------------------------------------------------------
|
|
1160
1545
|
// Assert — single pass, last, so the full table above is always printed first.
|
|
1161
1546
|
// ---------------------------------------------------------------------------------------------
|