@tellescope/sdk 2.0.0-beta.2 → 2.0.0-beta.3
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/sdk.d.ts +6 -5
- package/lib/cjs/sdk.d.ts.map +1 -1
- package/lib/cjs/sdk.js +5 -0
- package/lib/cjs/sdk.js.map +1 -1
- package/lib/cjs/tests/api_tests/ai_conversations.test.d.ts +14 -5
- package/lib/cjs/tests/api_tests/ai_conversations.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/ai_conversations.test.js +163 -149
- package/lib/cjs/tests/api_tests/ai_conversations.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/ai_conversations_agent_message.test.d.ts +22 -0
- package/lib/cjs/tests/api_tests/ai_conversations_agent_message.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/ai_conversations_agent_message.test.js +518 -0
- package/lib/cjs/tests/api_tests/ai_conversations_agent_message.test.js.map +1 -0
- package/lib/cjs/tests/api_tests/appointment_link_expiration.test.d.ts +6 -5
- package/lib/cjs/tests/api_tests/appointment_link_expiration.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/appointment_link_expiration.test.js +135 -73
- package/lib/cjs/tests/api_tests/appointment_link_expiration.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/appointment_no_showed_trigger.test.d.ts +6 -5
- package/lib/cjs/tests/api_tests/appointment_no_showed_trigger.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/appointment_no_showed_trigger.test.js +240 -174
- package/lib/cjs/tests/api_tests/appointment_no_showed_trigger.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/availability_block_buffer.test.d.ts +22 -0
- package/lib/cjs/tests/api_tests/availability_block_buffer.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/availability_block_buffer.test.js +311 -0
- package/lib/cjs/tests/api_tests/availability_block_buffer.test.js.map +1 -0
- package/lib/cjs/tests/api_tests/beluga_manual_sync.test.d.ts +6 -5
- package/lib/cjs/tests/api_tests/beluga_manual_sync.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/beluga_manual_sync.test.js +235 -192
- package/lib/cjs/tests/api_tests/beluga_manual_sync.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/beluga_trigger_refill.test.d.ts +6 -5
- package/lib/cjs/tests/api_tests/beluga_trigger_refill.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/beluga_trigger_refill.test.js +351 -264
- package/lib/cjs/tests/api_tests/beluga_trigger_refill.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/bulk_assignment.test.d.ts +16 -5
- package/lib/cjs/tests/api_tests/bulk_assignment.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/bulk_assignment.test.js +336 -243
- package/lib/cjs/tests/api_tests/bulk_assignment.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/calendar_event_references_update.test.d.ts +13 -5
- package/lib/cjs/tests/api_tests/calendar_event_references_update.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/calendar_event_references_update.test.js +131 -108
- package/lib/cjs/tests/api_tests/calendar_event_references_update.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/calendar_event_webhook_template.test.d.ts +15 -5
- package/lib/cjs/tests/api_tests/calendar_event_webhook_template.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/calendar_event_webhook_template.test.js +240 -252
- package/lib/cjs/tests/api_tests/calendar_event_webhook_template.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/chats_analytics.test.d.ts +14 -5
- package/lib/cjs/tests/api_tests/chats_analytics.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/chats_analytics.test.js +190 -189
- package/lib/cjs/tests/api_tests/chats_analytics.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/concurrent_build_threads.test.d.ts +23 -5
- package/lib/cjs/tests/api_tests/concurrent_build_threads.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/concurrent_build_threads.test.js +121 -118
- package/lib/cjs/tests/api_tests/concurrent_build_threads.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/configurations_public_read.test.d.ts +21 -5
- package/lib/cjs/tests/api_tests/configurations_public_read.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/configurations_public_read.test.js +235 -119
- package/lib/cjs/tests/api_tests/configurations_public_read.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/copied_form_response_no_enduser_sync.test.d.ts +7 -0
- package/lib/cjs/tests/api_tests/copied_form_response_no_enduser_sync.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/copied_form_response_no_enduser_sync.test.js +356 -0
- package/lib/cjs/tests/api_tests/copied_form_response_no_enduser_sync.test.js.map +1 -0
- package/lib/cjs/tests/api_tests/create_note_action.test.d.ts +18 -5
- package/lib/cjs/tests/api_tests/create_note_action.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/create_note_action.test.js +218 -173
- package/lib/cjs/tests/api_tests/create_note_action.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/create_user_notifications_trigger.test.d.ts +17 -4
- package/lib/cjs/tests/api_tests/create_user_notifications_trigger.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/create_user_notifications_trigger.test.js +144 -205
- package/lib/cjs/tests/api_tests/create_user_notifications_trigger.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/custom_aggregation.test.d.ts +15 -5
- package/lib/cjs/tests/api_tests/custom_aggregation.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/custom_aggregation.test.js +284 -223
- package/lib/cjs/tests/api_tests/custom_aggregation.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/database_cascade_delete.test.d.ts +13 -5
- package/lib/cjs/tests/api_tests/database_cascade_delete.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/database_cascade_delete.test.js +218 -242
- package/lib/cjs/tests/api_tests/database_cascade_delete.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/dont_sync_to_elation_form_submission.test.d.ts +21 -5
- package/lib/cjs/tests/api_tests/dont_sync_to_elation_form_submission.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/dont_sync_to_elation_form_submission.test.js +168 -112
- package/lib/cjs/tests/api_tests/dont_sync_to_elation_form_submission.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/elation_user_id.test.d.ts +17 -5
- package/lib/cjs/tests/api_tests/elation_user_id.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/elation_user_id.test.js +121 -54
- package/lib/cjs/tests/api_tests/elation_user_id.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/file_download_unicode_names.test.d.ts +6 -5
- package/lib/cjs/tests/api_tests/file_download_unicode_names.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/file_download_unicode_names.test.js +193 -143
- package/lib/cjs/tests/api_tests/file_download_unicode_names.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/form_intake_email_normalization.test.d.ts +7 -0
- package/lib/cjs/tests/api_tests/form_intake_email_normalization.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/form_intake_email_normalization.test.js +532 -0
- package/lib/cjs/tests/api_tests/form_intake_email_normalization.test.js.map +1 -0
- package/lib/cjs/tests/api_tests/form_submitted_trigger.test.d.ts +25 -5
- package/lib/cjs/tests/api_tests/form_submitted_trigger.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/form_submitted_trigger.test.js +395 -366
- package/lib/cjs/tests/api_tests/form_submitted_trigger.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/form_translations.test.d.ts +6 -5
- package/lib/cjs/tests/api_tests/form_translations.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/form_translations.test.js +269 -189
- package/lib/cjs/tests/api_tests/form_translations.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/formsort_header_auth.test.d.ts +29 -5
- package/lib/cjs/tests/api_tests/formsort_header_auth.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/formsort_header_auth.test.js +179 -162
- package/lib/cjs/tests/api_tests/formsort_header_auth.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/gcal_sync_retry.test.d.ts +12 -6
- package/lib/cjs/tests/api_tests/gcal_sync_retry.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/gcal_sync_retry.test.js +98 -84
- package/lib/cjs/tests/api_tests/gcal_sync_retry.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/get_some_projection.test.d.ts +20 -5
- package/lib/cjs/tests/api_tests/get_some_projection.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/get_some_projection.test.js +342 -298
- package/lib/cjs/tests/api_tests/get_some_projection.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/group_event_attendee_self_update.test.d.ts +6 -5
- package/lib/cjs/tests/api_tests/group_event_attendee_self_update.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/group_event_attendee_self_update.test.js +294 -223
- package/lib/cjs/tests/api_tests/group_event_attendee_self_update.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/integrations_redacted.test.d.ts +6 -5
- package/lib/cjs/tests/api_tests/integrations_redacted.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/integrations_redacted.test.js +307 -213
- package/lib/cjs/tests/api_tests/integrations_redacted.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/journey_delete_cancels_actions.test.d.ts +6 -5
- package/lib/cjs/tests/api_tests/journey_delete_cancels_actions.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/journey_delete_cancels_actions.test.js +179 -178
- package/lib/cjs/tests/api_tests/journey_delete_cancels_actions.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/load_team_chat.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/load_team_chat.test.js +181 -124
- package/lib/cjs/tests/api_tests/load_team_chat.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/load_threads_autobuild.test.d.ts +24 -5
- package/lib/cjs/tests/api_tests/load_threads_autobuild.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/load_threads_autobuild.test.js +261 -227
- package/lib/cjs/tests/api_tests/load_threads_autobuild.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/load_threads_care_team.test.d.ts +6 -0
- 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 +115 -31
- package/lib/cjs/tests/api_tests/load_threads_care_team.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/managed_content_file_access.test.d.ts +15 -5
- package/lib/cjs/tests/api_tests/managed_content_file_access.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/managed_content_file_access.test.js +285 -311
- package/lib/cjs/tests/api_tests/managed_content_file_access.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/mdb_sort.test.d.ts +20 -5
- package/lib/cjs/tests/api_tests/mdb_sort.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/mdb_sort.test.js +361 -305
- package/lib/cjs/tests/api_tests/mdb_sort.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/mdi_manual_sync.test.d.ts +27 -0
- package/lib/cjs/tests/api_tests/mdi_manual_sync.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/mdi_manual_sync.test.js +395 -0
- package/lib/cjs/tests/api_tests/mdi_manual_sync.test.js.map +1 -0
- package/lib/cjs/tests/api_tests/mdi_trigger_refill.test.d.ts +6 -5
- package/lib/cjs/tests/api_tests/mdi_trigger_refill.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/mdi_trigger_refill.test.js +259 -209
- package/lib/cjs/tests/api_tests/mdi_trigger_refill.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/mdi_webhooks.test.d.ts +12 -5
- package/lib/cjs/tests/api_tests/mdi_webhooks.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/mdi_webhooks.test.js +67 -61
- package/lib/cjs/tests/api_tests/mdi_webhooks.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/message_assignment_trigger.test.d.ts +23 -14
- package/lib/cjs/tests/api_tests/message_assignment_trigger.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/message_assignment_trigger.test.js +258 -306
- package/lib/cjs/tests/api_tests/message_assignment_trigger.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/metriport_push_form_response.test.d.ts +6 -5
- package/lib/cjs/tests/api_tests/metriport_push_form_response.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/metriport_push_form_response.test.js +301 -238
- package/lib/cjs/tests/api_tests/metriport_push_form_response.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/organization_api_keys.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/organization_api_keys.test.js +226 -59
- package/lib/cjs/tests/api_tests/organization_api_keys.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/organization_settings_duplicates.test.d.ts +19 -5
- package/lib/cjs/tests/api_tests/organization_settings_duplicates.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/organization_settings_duplicates.test.js +335 -222
- package/lib/cjs/tests/api_tests/organization_settings_duplicates.test.js.map +1 -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 +218 -51
- package/lib/cjs/tests/api_tests/organization_signup.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/out_of_office_endpoint.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/out_of_office_endpoint.test.js +109 -1
- package/lib/cjs/tests/api_tests/out_of_office_endpoint.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/outbound_chat_sent_trigger.test.d.ts +6 -6
- package/lib/cjs/tests/api_tests/outbound_chat_sent_trigger.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/outbound_chat_sent_trigger.test.js +309 -361
- package/lib/cjs/tests/api_tests/outbound_chat_sent_trigger.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/phone_calls_cold_transfer.test.d.ts +6 -5
- package/lib/cjs/tests/api_tests/phone_calls_cold_transfer.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/phone_calls_cold_transfer.test.js +246 -165
- package/lib/cjs/tests/api_tests/phone_calls_cold_transfer.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/phone_calls_conference_hold.test.d.ts +15 -5
- package/lib/cjs/tests/api_tests/phone_calls_conference_hold.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/phone_calls_conference_hold.test.js +130 -47
- package/lib/cjs/tests/api_tests/phone_calls_conference_hold.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/phone_tree_enduser_condition.test.d.ts +6 -5
- package/lib/cjs/tests/api_tests/phone_tree_enduser_condition.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/phone_tree_enduser_condition.test.js +180 -132
- package/lib/cjs/tests/api_tests/phone_tree_enduser_condition.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/programs.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/programs.test.js +417 -50
- package/lib/cjs/tests/api_tests/programs.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/security/ai-conversations-rbac.test.d.ts +10 -5
- package/lib/cjs/tests/api_tests/security/ai-conversations-rbac.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/security/ai-conversations-rbac.test.js +401 -282
- package/lib/cjs/tests/api_tests/security/ai-conversations-rbac.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/security/automated-actions-process-gate.test.d.ts +9 -5
- package/lib/cjs/tests/api_tests/security/automated-actions-process-gate.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/security/automated-actions-process-gate.test.js +228 -211
- package/lib/cjs/tests/api_tests/security/automated-actions-process-gate.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/security/booking-info-idor-token-mint.test.d.ts +13 -8
- package/lib/cjs/tests/api_tests/security/booking-info-idor-token-mint.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/security/booking-info-idor-token-mint.test.js +270 -254
- package/lib/cjs/tests/api_tests/security/booking-info-idor-token-mint.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/security/cascade-role-rename-cross-tenant.test.d.ts +16 -6
- package/lib/cjs/tests/api_tests/security/cascade-role-rename-cross-tenant.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/security/cascade-role-rename-cross-tenant.test.js +167 -142
- package/lib/cjs/tests/api_tests/security/cascade-role-rename-cross-tenant.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/security/data-sync-redaction-bypass.test.d.ts +10 -5
- package/lib/cjs/tests/api_tests/security/data-sync-redaction-bypass.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/security/data-sync-redaction-bypass.test.js +296 -221
- package/lib/cjs/tests/api_tests/security/data-sync-redaction-bypass.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/security/develop-health-benefit-verification-rbac.test.d.ts +12 -5
- package/lib/cjs/tests/api_tests/security/develop-health-benefit-verification-rbac.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/security/develop-health-benefit-verification-rbac.test.js +221 -216
- package/lib/cjs/tests/api_tests/security/develop-health-benefit-verification-rbac.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/security/enduser-ai-summary-trust-gate.test.d.ts +11 -5
- package/lib/cjs/tests/api_tests/security/enduser-ai-summary-trust-gate.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/security/enduser-ai-summary-trust-gate.test.js +300 -203
- package/lib/cjs/tests/api_tests/security/enduser-ai-summary-trust-gate.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/security/enduser-cross-create.test.d.ts +11 -5
- package/lib/cjs/tests/api_tests/security/enduser-cross-create.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/security/enduser-cross-create.test.js +415 -275
- package/lib/cjs/tests/api_tests/security/enduser-cross-create.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/security/enduser-write-restrictions.test.d.ts +11 -5
- package/lib/cjs/tests/api_tests/security/enduser-write-restrictions.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/security/enduser-write-restrictions.test.js +347 -228
- package/lib/cjs/tests/api_tests/security/enduser-write-restrictions.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/security/globalunique-conflict-redaction.test.d.ts +18 -7
- package/lib/cjs/tests/api_tests/security/globalunique-conflict-redaction.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/security/globalunique-conflict-redaction.test.js +164 -75
- package/lib/cjs/tests/api_tests/security/globalunique-conflict-redaction.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/security/handle-incoming-communication-cross-tenant.test.d.ts +15 -9
- package/lib/cjs/tests/api_tests/security/handle-incoming-communication-cross-tenant.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/security/handle-incoming-communication-cross-tenant.test.js +99 -102
- package/lib/cjs/tests/api_tests/security/handle-incoming-communication-cross-tenant.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/security/load-inbox-redaction.test.d.ts +11 -5
- package/lib/cjs/tests/api_tests/security/load-inbox-redaction.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/security/load-inbox-redaction.test.js +132 -89
- package/lib/cjs/tests/api_tests/security/load-inbox-redaction.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/security/proxy-image-unauth-ssrf.test.d.ts +12 -5
- package/lib/cjs/tests/api_tests/security/proxy-image-unauth-ssrf.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/security/proxy-image-unauth-ssrf.test.js +190 -138
- package/lib/cjs/tests/api_tests/security/proxy-image-unauth-ssrf.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/security/register_business_id_injection.test.d.ts +18 -16
- package/lib/cjs/tests/api_tests/security/register_business_id_injection.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/security/register_business_id_injection.test.js +164 -124
- package/lib/cjs/tests/api_tests/security/register_business_id_injection.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/security/sanitize-user-html-with-iframes.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/security/sanitize-user-html-with-iframes.test.js +122 -2
- package/lib/cjs/tests/api_tests/security/sanitize-user-html-with-iframes.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/security/schema-adminonly-enforcement.test.d.ts +11 -5
- package/lib/cjs/tests/api_tests/security/schema-adminonly-enforcement.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/security/schema-adminonly-enforcement.test.js +288 -274
- package/lib/cjs/tests/api_tests/security/schema-adminonly-enforcement.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/security/self-admin-role-assignment.test.d.ts +17 -10
- package/lib/cjs/tests/api_tests/security/self-admin-role-assignment.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/security/self-admin-role-assignment.test.js +173 -138
- package/lib/cjs/tests/api_tests/security/self-admin-role-assignment.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/security/startlinktoken-enduser-staff-escalation.test.d.ts +6 -5
- package/lib/cjs/tests/api_tests/security/startlinktoken-enduser-staff-escalation.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/security/startlinktoken-enduser-staff-escalation.test.js +310 -265
- package/lib/cjs/tests/api_tests/security/startlinktoken-enduser-staff-escalation.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/security/webhook-timeout.test.d.ts +9 -5
- package/lib/cjs/tests/api_tests/security/webhook-timeout.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/security/webhook-timeout.test.js +108 -83
- package/lib/cjs/tests/api_tests/security/webhook-timeout.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/stedi_approval.test.d.ts +6 -5
- package/lib/cjs/tests/api_tests/stedi_approval.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/stedi_approval.test.js +206 -137
- package/lib/cjs/tests/api_tests/stedi_approval.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/ticket_stage_archive.test.d.ts +7 -0
- package/lib/cjs/tests/api_tests/ticket_stage_archive.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/ticket_stage_archive.test.js +344 -0
- package/lib/cjs/tests/api_tests/ticket_stage_archive.test.js.map +1 -0
- package/lib/cjs/tests/api_tests/tickets_bulk_assign_care_team.test.d.ts +6 -5
- package/lib/cjs/tests/api_tests/tickets_bulk_assign_care_team.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/tickets_bulk_assign_care_team.test.js +165 -149
- package/lib/cjs/tests/api_tests/tickets_bulk_assign_care_team.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/translations.test.d.ts +6 -5
- package/lib/cjs/tests/api_tests/translations.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/translations.test.js +104 -75
- package/lib/cjs/tests/api_tests/translations.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/trigger_set_fields_date_difference.test.d.ts +21 -4
- package/lib/cjs/tests/api_tests/trigger_set_fields_date_difference.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/trigger_set_fields_date_difference.test.js +238 -370
- package/lib/cjs/tests/api_tests/trigger_set_fields_date_difference.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/user_preferences.test.d.ts +30 -0
- package/lib/cjs/tests/api_tests/user_preferences.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/user_preferences.test.js +279 -0
- package/lib/cjs/tests/api_tests/user_preferences.test.js.map +1 -0
- package/lib/cjs/tests/api_tests/webhook_error_handling.test.d.ts +17 -5
- package/lib/cjs/tests/api_tests/webhook_error_handling.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/webhook_error_handling.test.js +204 -195
- package/lib/cjs/tests/api_tests/webhook_error_handling.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/webhook_raw_json_number.test.d.ts +15 -5
- package/lib/cjs/tests/api_tests/webhook_raw_json_number.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/webhook_raw_json_number.test.js +154 -179
- package/lib/cjs/tests/api_tests/webhook_raw_json_number.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/welle_partner_token.test.d.ts +6 -5
- package/lib/cjs/tests/api_tests/welle_partner_token.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/welle_partner_token.test.js +393 -251
- package/lib/cjs/tests/api_tests/welle_partner_token.test.js.map +1 -1
- package/lib/cjs/tests/setup_isolated.d.ts +7 -0
- package/lib/cjs/tests/setup_isolated.d.ts.map +1 -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 +229 -461
- package/lib/cjs/tests/tests.js.map +1 -1
- package/lib/cjs/tests/unit_tests/date_string_validation.test.d.ts +2 -0
- package/lib/cjs/tests/unit_tests/date_string_validation.test.d.ts.map +1 -0
- package/lib/cjs/tests/unit_tests/date_string_validation.test.js +112 -0
- package/lib/cjs/tests/unit_tests/date_string_validation.test.js.map +1 -0
- package/lib/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/lib/esm/sdk.d.ts +6 -5
- package/lib/esm/sdk.d.ts.map +1 -1
- package/lib/esm/sdk.js +5 -0
- package/lib/esm/sdk.js.map +1 -1
- package/lib/esm/tests/api_tests/ai_conversations.test.d.ts +14 -5
- package/lib/esm/tests/api_tests/ai_conversations.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/ai_conversations.test.js +161 -148
- package/lib/esm/tests/api_tests/ai_conversations.test.js.map +1 -1
- package/lib/esm/tests/api_tests/ai_conversations_agent_message.test.d.ts +22 -0
- package/lib/esm/tests/api_tests/ai_conversations_agent_message.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/ai_conversations_agent_message.test.js +510 -0
- package/lib/esm/tests/api_tests/ai_conversations_agent_message.test.js.map +1 -0
- package/lib/esm/tests/api_tests/appointment_link_expiration.test.d.ts +6 -5
- package/lib/esm/tests/api_tests/appointment_link_expiration.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/appointment_link_expiration.test.js +132 -71
- package/lib/esm/tests/api_tests/appointment_link_expiration.test.js.map +1 -1
- package/lib/esm/tests/api_tests/appointment_no_showed_trigger.test.d.ts +6 -5
- package/lib/esm/tests/api_tests/appointment_no_showed_trigger.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/appointment_no_showed_trigger.test.js +238 -173
- package/lib/esm/tests/api_tests/appointment_no_showed_trigger.test.js.map +1 -1
- package/lib/esm/tests/api_tests/availability_block_buffer.test.d.ts +22 -0
- package/lib/esm/tests/api_tests/availability_block_buffer.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/availability_block_buffer.test.js +306 -0
- package/lib/esm/tests/api_tests/availability_block_buffer.test.js.map +1 -0
- package/lib/esm/tests/api_tests/beluga_manual_sync.test.d.ts +6 -5
- package/lib/esm/tests/api_tests/beluga_manual_sync.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/beluga_manual_sync.test.js +232 -190
- package/lib/esm/tests/api_tests/beluga_manual_sync.test.js.map +1 -1
- package/lib/esm/tests/api_tests/beluga_trigger_refill.test.d.ts +6 -5
- package/lib/esm/tests/api_tests/beluga_trigger_refill.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/beluga_trigger_refill.test.js +348 -262
- package/lib/esm/tests/api_tests/beluga_trigger_refill.test.js.map +1 -1
- package/lib/esm/tests/api_tests/bulk_assignment.test.d.ts +16 -5
- package/lib/esm/tests/api_tests/bulk_assignment.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/bulk_assignment.test.js +333 -241
- package/lib/esm/tests/api_tests/bulk_assignment.test.js.map +1 -1
- package/lib/esm/tests/api_tests/calendar_event_references_update.test.d.ts +13 -5
- package/lib/esm/tests/api_tests/calendar_event_references_update.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/calendar_event_references_update.test.js +129 -107
- package/lib/esm/tests/api_tests/calendar_event_references_update.test.js.map +1 -1
- package/lib/esm/tests/api_tests/calendar_event_webhook_template.test.d.ts +15 -5
- package/lib/esm/tests/api_tests/calendar_event_webhook_template.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/calendar_event_webhook_template.test.js +238 -251
- package/lib/esm/tests/api_tests/calendar_event_webhook_template.test.js.map +1 -1
- package/lib/esm/tests/api_tests/chats_analytics.test.d.ts +14 -5
- package/lib/esm/tests/api_tests/chats_analytics.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/chats_analytics.test.js +188 -188
- package/lib/esm/tests/api_tests/chats_analytics.test.js.map +1 -1
- package/lib/esm/tests/api_tests/concurrent_build_threads.test.d.ts +23 -5
- package/lib/esm/tests/api_tests/concurrent_build_threads.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/concurrent_build_threads.test.js +119 -117
- package/lib/esm/tests/api_tests/concurrent_build_threads.test.js.map +1 -1
- package/lib/esm/tests/api_tests/configurations_public_read.test.d.ts +21 -5
- package/lib/esm/tests/api_tests/configurations_public_read.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/configurations_public_read.test.js +233 -118
- package/lib/esm/tests/api_tests/configurations_public_read.test.js.map +1 -1
- package/lib/esm/tests/api_tests/copied_form_response_no_enduser_sync.test.d.ts +7 -0
- package/lib/esm/tests/api_tests/copied_form_response_no_enduser_sync.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/copied_form_response_no_enduser_sync.test.js +351 -0
- package/lib/esm/tests/api_tests/copied_form_response_no_enduser_sync.test.js.map +1 -0
- package/lib/esm/tests/api_tests/create_note_action.test.d.ts +18 -5
- package/lib/esm/tests/api_tests/create_note_action.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/create_note_action.test.js +216 -172
- package/lib/esm/tests/api_tests/create_note_action.test.js.map +1 -1
- package/lib/esm/tests/api_tests/create_user_notifications_trigger.test.d.ts +17 -4
- package/lib/esm/tests/api_tests/create_user_notifications_trigger.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/create_user_notifications_trigger.test.js +141 -203
- package/lib/esm/tests/api_tests/create_user_notifications_trigger.test.js.map +1 -1
- package/lib/esm/tests/api_tests/custom_aggregation.test.d.ts +15 -5
- package/lib/esm/tests/api_tests/custom_aggregation.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/custom_aggregation.test.js +282 -222
- package/lib/esm/tests/api_tests/custom_aggregation.test.js.map +1 -1
- package/lib/esm/tests/api_tests/database_cascade_delete.test.d.ts +13 -5
- package/lib/esm/tests/api_tests/database_cascade_delete.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/database_cascade_delete.test.js +216 -241
- package/lib/esm/tests/api_tests/database_cascade_delete.test.js.map +1 -1
- package/lib/esm/tests/api_tests/dont_sync_to_elation_form_submission.test.d.ts +21 -5
- package/lib/esm/tests/api_tests/dont_sync_to_elation_form_submission.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/dont_sync_to_elation_form_submission.test.js +165 -110
- package/lib/esm/tests/api_tests/dont_sync_to_elation_form_submission.test.js.map +1 -1
- package/lib/esm/tests/api_tests/elation_user_id.test.d.ts +17 -5
- package/lib/esm/tests/api_tests/elation_user_id.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/elation_user_id.test.js +119 -53
- package/lib/esm/tests/api_tests/elation_user_id.test.js.map +1 -1
- package/lib/esm/tests/api_tests/file_download_unicode_names.test.d.ts +6 -5
- package/lib/esm/tests/api_tests/file_download_unicode_names.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/file_download_unicode_names.test.js +190 -141
- package/lib/esm/tests/api_tests/file_download_unicode_names.test.js.map +1 -1
- package/lib/esm/tests/api_tests/form_intake_email_normalization.test.d.ts +7 -0
- package/lib/esm/tests/api_tests/form_intake_email_normalization.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/form_intake_email_normalization.test.js +527 -0
- package/lib/esm/tests/api_tests/form_intake_email_normalization.test.js.map +1 -0
- package/lib/esm/tests/api_tests/form_submitted_trigger.test.d.ts +25 -5
- package/lib/esm/tests/api_tests/form_submitted_trigger.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/form_submitted_trigger.test.js +393 -365
- package/lib/esm/tests/api_tests/form_submitted_trigger.test.js.map +1 -1
- package/lib/esm/tests/api_tests/form_translations.test.d.ts +6 -5
- package/lib/esm/tests/api_tests/form_translations.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/form_translations.test.js +268 -189
- package/lib/esm/tests/api_tests/form_translations.test.js.map +1 -1
- package/lib/esm/tests/api_tests/formsort_header_auth.test.d.ts +29 -5
- package/lib/esm/tests/api_tests/formsort_header_auth.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/formsort_header_auth.test.js +177 -161
- package/lib/esm/tests/api_tests/formsort_header_auth.test.js.map +1 -1
- package/lib/esm/tests/api_tests/gcal_sync_retry.test.d.ts +12 -6
- package/lib/esm/tests/api_tests/gcal_sync_retry.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/gcal_sync_retry.test.js +96 -83
- package/lib/esm/tests/api_tests/gcal_sync_retry.test.js.map +1 -1
- package/lib/esm/tests/api_tests/get_some_projection.test.d.ts +20 -5
- package/lib/esm/tests/api_tests/get_some_projection.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/get_some_projection.test.js +339 -296
- package/lib/esm/tests/api_tests/get_some_projection.test.js.map +1 -1
- package/lib/esm/tests/api_tests/group_event_attendee_self_update.test.d.ts +6 -5
- package/lib/esm/tests/api_tests/group_event_attendee_self_update.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/group_event_attendee_self_update.test.js +292 -222
- package/lib/esm/tests/api_tests/group_event_attendee_self_update.test.js.map +1 -1
- package/lib/esm/tests/api_tests/integrations_redacted.test.d.ts +6 -5
- package/lib/esm/tests/api_tests/integrations_redacted.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/integrations_redacted.test.js +304 -211
- package/lib/esm/tests/api_tests/integrations_redacted.test.js.map +1 -1
- package/lib/esm/tests/api_tests/journey_delete_cancels_actions.test.d.ts +6 -5
- package/lib/esm/tests/api_tests/journey_delete_cancels_actions.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/journey_delete_cancels_actions.test.js +177 -154
- package/lib/esm/tests/api_tests/journey_delete_cancels_actions.test.js.map +1 -1
- package/lib/esm/tests/api_tests/load_team_chat.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/load_team_chat.test.js +181 -124
- package/lib/esm/tests/api_tests/load_team_chat.test.js.map +1 -1
- package/lib/esm/tests/api_tests/load_threads_autobuild.test.d.ts +24 -5
- package/lib/esm/tests/api_tests/load_threads_autobuild.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/load_threads_autobuild.test.js +259 -226
- package/lib/esm/tests/api_tests/load_threads_autobuild.test.js.map +1 -1
- package/lib/esm/tests/api_tests/load_threads_care_team.test.d.ts +6 -0
- 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 +115 -31
- package/lib/esm/tests/api_tests/load_threads_care_team.test.js.map +1 -1
- package/lib/esm/tests/api_tests/managed_content_file_access.test.d.ts +15 -5
- package/lib/esm/tests/api_tests/managed_content_file_access.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/managed_content_file_access.test.js +283 -287
- package/lib/esm/tests/api_tests/managed_content_file_access.test.js.map +1 -1
- package/lib/esm/tests/api_tests/mdb_sort.test.d.ts +20 -5
- package/lib/esm/tests/api_tests/mdb_sort.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/mdb_sort.test.js +358 -303
- package/lib/esm/tests/api_tests/mdb_sort.test.js.map +1 -1
- package/lib/esm/tests/api_tests/mdi_manual_sync.test.d.ts +27 -0
- package/lib/esm/tests/api_tests/mdi_manual_sync.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/mdi_manual_sync.test.js +390 -0
- package/lib/esm/tests/api_tests/mdi_manual_sync.test.js.map +1 -0
- package/lib/esm/tests/api_tests/mdi_trigger_refill.test.d.ts +6 -5
- package/lib/esm/tests/api_tests/mdi_trigger_refill.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/mdi_trigger_refill.test.js +257 -208
- package/lib/esm/tests/api_tests/mdi_trigger_refill.test.js.map +1 -1
- package/lib/esm/tests/api_tests/mdi_webhooks.test.d.ts +12 -5
- package/lib/esm/tests/api_tests/mdi_webhooks.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/mdi_webhooks.test.js +65 -60
- package/lib/esm/tests/api_tests/mdi_webhooks.test.js.map +1 -1
- package/lib/esm/tests/api_tests/message_assignment_trigger.test.d.ts +23 -14
- package/lib/esm/tests/api_tests/message_assignment_trigger.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/message_assignment_trigger.test.js +256 -305
- package/lib/esm/tests/api_tests/message_assignment_trigger.test.js.map +1 -1
- package/lib/esm/tests/api_tests/metriport_push_form_response.test.d.ts +6 -5
- package/lib/esm/tests/api_tests/metriport_push_form_response.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/metriport_push_form_response.test.js +298 -236
- package/lib/esm/tests/api_tests/metriport_push_form_response.test.js.map +1 -1
- package/lib/esm/tests/api_tests/organization_api_keys.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/organization_api_keys.test.js +226 -59
- package/lib/esm/tests/api_tests/organization_api_keys.test.js.map +1 -1
- package/lib/esm/tests/api_tests/organization_settings_duplicates.test.d.ts +19 -5
- package/lib/esm/tests/api_tests/organization_settings_duplicates.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/organization_settings_duplicates.test.js +332 -220
- package/lib/esm/tests/api_tests/organization_settings_duplicates.test.js.map +1 -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 +218 -51
- package/lib/esm/tests/api_tests/organization_signup.test.js.map +1 -1
- package/lib/esm/tests/api_tests/out_of_office_endpoint.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/out_of_office_endpoint.test.js +109 -1
- package/lib/esm/tests/api_tests/out_of_office_endpoint.test.js.map +1 -1
- package/lib/esm/tests/api_tests/outbound_chat_sent_trigger.test.d.ts +6 -6
- package/lib/esm/tests/api_tests/outbound_chat_sent_trigger.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/outbound_chat_sent_trigger.test.js +308 -361
- package/lib/esm/tests/api_tests/outbound_chat_sent_trigger.test.js.map +1 -1
- package/lib/esm/tests/api_tests/phone_calls_cold_transfer.test.d.ts +6 -5
- package/lib/esm/tests/api_tests/phone_calls_cold_transfer.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/phone_calls_cold_transfer.test.js +243 -163
- package/lib/esm/tests/api_tests/phone_calls_cold_transfer.test.js.map +1 -1
- package/lib/esm/tests/api_tests/phone_calls_conference_hold.test.d.ts +15 -5
- package/lib/esm/tests/api_tests/phone_calls_conference_hold.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/phone_calls_conference_hold.test.js +127 -45
- package/lib/esm/tests/api_tests/phone_calls_conference_hold.test.js.map +1 -1
- package/lib/esm/tests/api_tests/phone_tree_enduser_condition.test.d.ts +6 -5
- package/lib/esm/tests/api_tests/phone_tree_enduser_condition.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/phone_tree_enduser_condition.test.js +177 -130
- package/lib/esm/tests/api_tests/phone_tree_enduser_condition.test.js.map +1 -1
- package/lib/esm/tests/api_tests/programs.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/programs.test.js +417 -50
- package/lib/esm/tests/api_tests/programs.test.js.map +1 -1
- package/lib/esm/tests/api_tests/security/ai-conversations-rbac.test.d.ts +10 -5
- package/lib/esm/tests/api_tests/security/ai-conversations-rbac.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/security/ai-conversations-rbac.test.js +399 -281
- package/lib/esm/tests/api_tests/security/ai-conversations-rbac.test.js.map +1 -1
- package/lib/esm/tests/api_tests/security/automated-actions-process-gate.test.d.ts +9 -5
- package/lib/esm/tests/api_tests/security/automated-actions-process-gate.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/security/automated-actions-process-gate.test.js +225 -209
- package/lib/esm/tests/api_tests/security/automated-actions-process-gate.test.js.map +1 -1
- package/lib/esm/tests/api_tests/security/booking-info-idor-token-mint.test.d.ts +13 -8
- package/lib/esm/tests/api_tests/security/booking-info-idor-token-mint.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/security/booking-info-idor-token-mint.test.js +268 -253
- package/lib/esm/tests/api_tests/security/booking-info-idor-token-mint.test.js.map +1 -1
- package/lib/esm/tests/api_tests/security/cascade-role-rename-cross-tenant.test.d.ts +16 -6
- package/lib/esm/tests/api_tests/security/cascade-role-rename-cross-tenant.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/security/cascade-role-rename-cross-tenant.test.js +165 -141
- package/lib/esm/tests/api_tests/security/cascade-role-rename-cross-tenant.test.js.map +1 -1
- package/lib/esm/tests/api_tests/security/data-sync-redaction-bypass.test.d.ts +10 -5
- package/lib/esm/tests/api_tests/security/data-sync-redaction-bypass.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/security/data-sync-redaction-bypass.test.js +294 -220
- package/lib/esm/tests/api_tests/security/data-sync-redaction-bypass.test.js.map +1 -1
- package/lib/esm/tests/api_tests/security/develop-health-benefit-verification-rbac.test.d.ts +12 -5
- package/lib/esm/tests/api_tests/security/develop-health-benefit-verification-rbac.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/security/develop-health-benefit-verification-rbac.test.js +219 -215
- package/lib/esm/tests/api_tests/security/develop-health-benefit-verification-rbac.test.js.map +1 -1
- package/lib/esm/tests/api_tests/security/enduser-ai-summary-trust-gate.test.d.ts +11 -5
- package/lib/esm/tests/api_tests/security/enduser-ai-summary-trust-gate.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/security/enduser-ai-summary-trust-gate.test.js +298 -202
- package/lib/esm/tests/api_tests/security/enduser-ai-summary-trust-gate.test.js.map +1 -1
- package/lib/esm/tests/api_tests/security/enduser-cross-create.test.d.ts +11 -5
- package/lib/esm/tests/api_tests/security/enduser-cross-create.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/security/enduser-cross-create.test.js +413 -274
- package/lib/esm/tests/api_tests/security/enduser-cross-create.test.js.map +1 -1
- package/lib/esm/tests/api_tests/security/enduser-write-restrictions.test.d.ts +11 -5
- package/lib/esm/tests/api_tests/security/enduser-write-restrictions.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/security/enduser-write-restrictions.test.js +345 -227
- package/lib/esm/tests/api_tests/security/enduser-write-restrictions.test.js.map +1 -1
- package/lib/esm/tests/api_tests/security/globalunique-conflict-redaction.test.d.ts +18 -7
- package/lib/esm/tests/api_tests/security/globalunique-conflict-redaction.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/security/globalunique-conflict-redaction.test.js +162 -74
- package/lib/esm/tests/api_tests/security/globalunique-conflict-redaction.test.js.map +1 -1
- package/lib/esm/tests/api_tests/security/handle-incoming-communication-cross-tenant.test.d.ts +15 -9
- package/lib/esm/tests/api_tests/security/handle-incoming-communication-cross-tenant.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/security/handle-incoming-communication-cross-tenant.test.js +96 -100
- package/lib/esm/tests/api_tests/security/handle-incoming-communication-cross-tenant.test.js.map +1 -1
- package/lib/esm/tests/api_tests/security/load-inbox-redaction.test.d.ts +11 -5
- package/lib/esm/tests/api_tests/security/load-inbox-redaction.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/security/load-inbox-redaction.test.js +129 -87
- package/lib/esm/tests/api_tests/security/load-inbox-redaction.test.js.map +1 -1
- package/lib/esm/tests/api_tests/security/proxy-image-unauth-ssrf.test.d.ts +12 -5
- package/lib/esm/tests/api_tests/security/proxy-image-unauth-ssrf.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/security/proxy-image-unauth-ssrf.test.js +187 -136
- package/lib/esm/tests/api_tests/security/proxy-image-unauth-ssrf.test.js.map +1 -1
- package/lib/esm/tests/api_tests/security/register_business_id_injection.test.d.ts +18 -16
- package/lib/esm/tests/api_tests/security/register_business_id_injection.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/security/register_business_id_injection.test.js +162 -123
- package/lib/esm/tests/api_tests/security/register_business_id_injection.test.js.map +1 -1
- package/lib/esm/tests/api_tests/security/sanitize-user-html-with-iframes.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/security/sanitize-user-html-with-iframes.test.js +122 -2
- package/lib/esm/tests/api_tests/security/sanitize-user-html-with-iframes.test.js.map +1 -1
- package/lib/esm/tests/api_tests/security/schema-adminonly-enforcement.test.d.ts +11 -5
- package/lib/esm/tests/api_tests/security/schema-adminonly-enforcement.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/security/schema-adminonly-enforcement.test.js +285 -272
- package/lib/esm/tests/api_tests/security/schema-adminonly-enforcement.test.js.map +1 -1
- package/lib/esm/tests/api_tests/security/self-admin-role-assignment.test.d.ts +17 -10
- package/lib/esm/tests/api_tests/security/self-admin-role-assignment.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/security/self-admin-role-assignment.test.js +171 -137
- package/lib/esm/tests/api_tests/security/self-admin-role-assignment.test.js.map +1 -1
- package/lib/esm/tests/api_tests/security/startlinktoken-enduser-staff-escalation.test.d.ts +6 -5
- package/lib/esm/tests/api_tests/security/startlinktoken-enduser-staff-escalation.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/security/startlinktoken-enduser-staff-escalation.test.js +307 -263
- package/lib/esm/tests/api_tests/security/startlinktoken-enduser-staff-escalation.test.js.map +1 -1
- package/lib/esm/tests/api_tests/security/webhook-timeout.test.d.ts +9 -5
- package/lib/esm/tests/api_tests/security/webhook-timeout.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/security/webhook-timeout.test.js +105 -81
- package/lib/esm/tests/api_tests/security/webhook-timeout.test.js.map +1 -1
- package/lib/esm/tests/api_tests/stedi_approval.test.d.ts +6 -5
- package/lib/esm/tests/api_tests/stedi_approval.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/stedi_approval.test.js +204 -136
- package/lib/esm/tests/api_tests/stedi_approval.test.js.map +1 -1
- package/lib/esm/tests/api_tests/ticket_stage_archive.test.d.ts +7 -0
- package/lib/esm/tests/api_tests/ticket_stage_archive.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/ticket_stage_archive.test.js +339 -0
- package/lib/esm/tests/api_tests/ticket_stage_archive.test.js.map +1 -0
- package/lib/esm/tests/api_tests/tickets_bulk_assign_care_team.test.d.ts +6 -5
- package/lib/esm/tests/api_tests/tickets_bulk_assign_care_team.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/tickets_bulk_assign_care_team.test.js +162 -147
- package/lib/esm/tests/api_tests/tickets_bulk_assign_care_team.test.js.map +1 -1
- package/lib/esm/tests/api_tests/translations.test.d.ts +6 -5
- package/lib/esm/tests/api_tests/translations.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/translations.test.js +102 -74
- package/lib/esm/tests/api_tests/translations.test.js.map +1 -1
- package/lib/esm/tests/api_tests/trigger_set_fields_date_difference.test.d.ts +21 -4
- package/lib/esm/tests/api_tests/trigger_set_fields_date_difference.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/trigger_set_fields_date_difference.test.js +236 -369
- package/lib/esm/tests/api_tests/trigger_set_fields_date_difference.test.js.map +1 -1
- package/lib/esm/tests/api_tests/user_preferences.test.d.ts +30 -0
- package/lib/esm/tests/api_tests/user_preferences.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/user_preferences.test.js +274 -0
- package/lib/esm/tests/api_tests/user_preferences.test.js.map +1 -0
- package/lib/esm/tests/api_tests/webhook_error_handling.test.d.ts +17 -5
- package/lib/esm/tests/api_tests/webhook_error_handling.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/webhook_error_handling.test.js +202 -194
- package/lib/esm/tests/api_tests/webhook_error_handling.test.js.map +1 -1
- package/lib/esm/tests/api_tests/webhook_raw_json_number.test.d.ts +15 -5
- package/lib/esm/tests/api_tests/webhook_raw_json_number.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/webhook_raw_json_number.test.js +152 -178
- package/lib/esm/tests/api_tests/webhook_raw_json_number.test.js.map +1 -1
- package/lib/esm/tests/api_tests/welle_partner_token.test.d.ts +6 -5
- package/lib/esm/tests/api_tests/welle_partner_token.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/welle_partner_token.test.js +391 -250
- package/lib/esm/tests/api_tests/welle_partner_token.test.js.map +1 -1
- package/lib/esm/tests/setup_isolated.d.ts +7 -0
- package/lib/esm/tests/setup_isolated.d.ts.map +1 -1
- 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 +229 -461
- package/lib/esm/tests/tests.js.map +1 -1
- package/lib/esm/tests/unit_tests/date_string_validation.test.d.ts +2 -0
- package/lib/esm/tests/unit_tests/date_string_validation.test.d.ts.map +1 -0
- package/lib/esm/tests/unit_tests/date_string_validation.test.js +108 -0
- package/lib/esm/tests/unit_tests/date_string_validation.test.js.map +1 -0
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +10 -10
- package/src/sdk.ts +14 -3
- package/src/tests/api_tests/ai_conversations.test.ts +170 -138
- package/src/tests/api_tests/ai_conversations_agent_message.test.ts +491 -0
- package/src/tests/api_tests/appointment_link_expiration.test.ts +94 -35
- package/src/tests/api_tests/appointment_no_showed_trigger.test.ts +181 -128
- package/src/tests/api_tests/availability_block_buffer.test.ts +286 -0
- package/src/tests/api_tests/beluga_manual_sync.test.ts +103 -53
- package/src/tests/api_tests/beluga_trigger_refill.test.ts +131 -46
- package/src/tests/api_tests/bulk_assignment.test.ts +307 -220
- package/src/tests/api_tests/calendar_event_references_update.test.ts +97 -54
- package/src/tests/api_tests/calendar_event_webhook_template.test.ts +198 -158
- package/src/tests/api_tests/chats_analytics.test.ts +161 -123
- package/src/tests/api_tests/concurrent_build_threads.test.ts +80 -69
- package/src/tests/api_tests/configurations_public_read.test.ts +154 -67
- package/src/tests/api_tests/copied_form_response_no_enduser_sync.test.ts +307 -0
- package/src/tests/api_tests/create_note_action.test.ts +149 -70
- package/src/tests/api_tests/create_user_notifications_trigger.test.ts +116 -144
- package/src/tests/api_tests/custom_aggregation.test.ts +163 -92
- package/src/tests/api_tests/database_cascade_delete.test.ts +101 -87
- package/src/tests/api_tests/dont_sync_to_elation_form_submission.test.ts +122 -51
- package/src/tests/api_tests/elation_user_id.test.ts +105 -42
- package/src/tests/api_tests/file_download_unicode_names.test.ts +171 -122
- package/src/tests/api_tests/form_intake_email_normalization.test.ts +489 -0
- package/src/tests/api_tests/form_submitted_trigger.test.ts +152 -86
- package/src/tests/api_tests/form_translations.test.ts +117 -48
- package/src/tests/api_tests/formsort_header_auth.test.ts +147 -97
- package/src/tests/api_tests/gcal_sync_retry.test.ts +71 -49
- package/src/tests/api_tests/get_some_projection.test.ts +333 -169
- package/src/tests/api_tests/group_event_attendee_self_update.test.ts +103 -52
- package/src/tests/api_tests/integrations_redacted.test.ts +161 -84
- package/src/tests/api_tests/journey_delete_cancels_actions.test.ts +93 -64
- package/src/tests/api_tests/load_team_chat.test.ts +62 -6
- package/src/tests/api_tests/load_threads_autobuild.test.ts +163 -67
- package/src/tests/api_tests/load_threads_care_team.test.ts +103 -0
- package/src/tests/api_tests/managed_content_file_access.test.ts +132 -108
- package/src/tests/api_tests/mdb_sort.test.ts +247 -161
- package/src/tests/api_tests/mdi_manual_sync.test.ts +277 -0
- package/src/tests/api_tests/mdi_trigger_refill.test.ts +132 -78
- package/src/tests/api_tests/mdi_webhooks.test.ts +52 -22
- package/src/tests/api_tests/message_assignment_trigger.test.ts +129 -155
- package/src/tests/api_tests/metriport_push_form_response.test.ts +109 -49
- package/src/tests/api_tests/organization_api_keys.test.ts +170 -2
- package/src/tests/api_tests/organization_settings_duplicates.test.ts +291 -181
- package/src/tests/api_tests/organization_signup.test.ts +170 -5
- package/src/tests/api_tests/out_of_office_endpoint.test.ts +98 -0
- package/src/tests/api_tests/outbound_chat_sent_trigger.test.ts +163 -175
- package/src/tests/api_tests/phone_calls_cold_transfer.test.ts +195 -133
- package/src/tests/api_tests/phone_calls_conference_hold.test.ts +112 -42
- package/src/tests/api_tests/phone_tree_enduser_condition.test.ts +81 -32
- package/src/tests/api_tests/programs.test.ts +350 -0
- package/src/tests/api_tests/security/ai-conversations-rbac.test.ts +248 -128
- package/src/tests/api_tests/security/automated-actions-process-gate.test.ts +47 -42
- package/src/tests/api_tests/security/booking-info-idor-token-mint.test.ts +53 -45
- package/src/tests/api_tests/security/cascade-role-rename-cross-tenant.test.ts +100 -73
- package/src/tests/api_tests/security/data-sync-redaction-bypass.test.ts +125 -59
- package/src/tests/api_tests/security/develop-health-benefit-verification-rbac.test.ts +131 -103
- package/src/tests/api_tests/security/enduser-ai-summary-trust-gate.test.ts +161 -68
- package/src/tests/api_tests/security/enduser-cross-create.test.ts +200 -61
- package/src/tests/api_tests/security/enduser-write-restrictions.test.ts +179 -61
- package/src/tests/api_tests/security/globalunique-conflict-redaction.test.ts +163 -44
- package/src/tests/api_tests/security/handle-incoming-communication-cross-tenant.test.ts +78 -70
- package/src/tests/api_tests/security/load-inbox-redaction.test.ts +79 -44
- package/src/tests/api_tests/security/proxy-image-unauth-ssrf.test.ts +95 -52
- package/src/tests/api_tests/security/register_business_id_injection.test.ts +132 -93
- package/src/tests/api_tests/security/sanitize-user-html-with-iframes.test.ts +127 -0
- package/src/tests/api_tests/security/schema-adminonly-enforcement.test.ts +42 -37
- package/src/tests/api_tests/security/self-admin-role-assignment.test.ts +92 -54
- package/src/tests/api_tests/security/startlinktoken-enduser-staff-escalation.test.ts +76 -34
- package/src/tests/api_tests/security/webhook-timeout.test.ts +67 -36
- package/src/tests/api_tests/stedi_approval.test.ts +156 -90
- package/src/tests/api_tests/ticket_stage_archive.test.ts +314 -0
- package/src/tests/api_tests/tickets_bulk_assign_care_team.test.ts +138 -103
- package/src/tests/api_tests/translations.test.ts +69 -46
- package/src/tests/api_tests/trigger_set_fields_date_difference.test.ts +198 -256
- package/src/tests/api_tests/user_preferences.test.ts +227 -0
- package/src/tests/api_tests/webhook_error_handling.test.ts +121 -60
- package/src/tests/api_tests/webhook_raw_json_number.test.ts +127 -109
- package/src/tests/api_tests/welle_partner_token.test.ts +217 -90
- package/src/tests/setup_isolated.ts +7 -0
- package/src/tests/tests.ts +41 -147
- package/src/tests/{api_tests → unit_tests}/date_string_validation.test.ts +2 -23
- package/test_generated.pdf +0 -0
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
require('source-map-support').install();
|
|
2
2
|
|
|
3
3
|
import { Session } from "../../../sdk"
|
|
4
|
+
import { wait } from "@tellescope/testing"
|
|
4
5
|
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
assert_checks,
|
|
7
|
+
Check,
|
|
8
|
+
IsolatedSuite,
|
|
9
|
+
setup_isolated_tenant,
|
|
10
|
+
} from "../../setup_isolated"
|
|
10
11
|
|
|
11
12
|
const host = process.env.API_URL || 'http://localhost:8080' as const
|
|
12
13
|
|
|
14
|
+
const RAND = () => Math.random().toString(36).slice(2, 10)
|
|
15
|
+
|
|
13
16
|
/**
|
|
14
17
|
* Self-role privilege-escalation guard (relates to a prior internal review, which was
|
|
15
18
|
* investigated and closed as a FALSE POSITIVE — see that file for the full code trace).
|
|
@@ -29,43 +32,68 @@ const host = process.env.API_URL || 'http://localhost:8080' as const
|
|
|
29
32
|
* The self-promotion is blocked.
|
|
30
33
|
*
|
|
31
34
|
* This test locks that boundary in place so a future refactor of the role constraints can't
|
|
32
|
-
* silently reintroduce the escalation.
|
|
33
|
-
* "attacker"
|
|
35
|
+
* silently reintroduce the escalation. It runs on its own provisioned tenant, whose single user is
|
|
36
|
+
* the admin; the "attacker" is a throwaway user this suite creates:
|
|
34
37
|
* 1. Admin creates a throwaway user and assigns it a non-admin role (`['Provider']`).
|
|
35
38
|
* 2. Authenticate AS that user via a freshly-minted auth token.
|
|
36
39
|
* 3. As the attacker, attempt four self-role mutations — ['Admin'], ['Provider','Admin'],
|
|
37
|
-
* an arbitrary role, and [] — and
|
|
40
|
+
* an arbitrary role, and [] — and check EACH is blocked. <-- the security checks
|
|
38
41
|
* 4. Confirm (as admin) the attacker's roles are still ['Provider'] — nothing slipped through.
|
|
39
42
|
* 5. Positive control: admin CAN update the throwaway user's roles. <-- guards against an
|
|
40
43
|
* over-restrictive regression that would block legitimate admin role management.
|
|
41
44
|
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
45
|
+
* The tenant provisions `roles: [{ role: 'Provider' }]` so the attacker's permissions come from a
|
|
46
|
+
* real role record (users.update: 'Default'), rather than from get_access_permissions_by_roles'
|
|
47
|
+
* unknown-role fallback — the escalation checks must only be able to pass via the role constraint.
|
|
48
|
+
* That `roles:` spec replaces the provisioner's default `[Non-Admin, Test]` entirely, which is safe
|
|
49
|
+
* here only because this tenant provisions no non-admin user.
|
|
50
|
+
*
|
|
51
|
+
* Expected on current (correct) code: all checks pass. A regression that made the self-update
|
|
52
|
+
* path role-writable by non-admins would flip the step-3/step-4 checks to red.
|
|
44
53
|
*/
|
|
45
|
-
export const
|
|
46
|
-
|
|
54
|
+
export const self_admin_role_assignment_checks = async (): Promise<Check[]> => {
|
|
55
|
+
const checks: Check[] = []
|
|
56
|
+
const record = (label: string, pass: boolean, detail: string) => checks.push({ label, pass, detail })
|
|
47
57
|
|
|
48
58
|
const stamp = Date.now()
|
|
49
59
|
const NON_ADMIN_ROLE = 'Provider'
|
|
50
60
|
|
|
51
|
-
|
|
52
|
-
const expect_blocked = async (fn: () => Promise<any>, description: string) => {
|
|
53
|
-
try {
|
|
54
|
-
await fn()
|
|
55
|
-
assert(false, `${description} - SELF-ROLE ESCALATION SUCCEEDED (expected it to be blocked)`)
|
|
56
|
-
} catch (e: any) {
|
|
57
|
-
// CRUD relationship-constraint failures surface as 400 { message, info } via SDK parseError.
|
|
58
|
-
assert(
|
|
59
|
-
e?.code === 400 || e?.statusCode === 400 || typeof e?.message === 'string',
|
|
60
|
-
`${description} - expected a block error, got: ${JSON.stringify(e)}`,
|
|
61
|
-
description,
|
|
62
|
-
)
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
61
|
+
let tenant: Awaited<ReturnType<typeof setup_isolated_tenant>> | undefined
|
|
66
62
|
let attackerId: string | undefined
|
|
67
63
|
|
|
68
64
|
try {
|
|
65
|
+
tenant = await setup_isolated_tenant({
|
|
66
|
+
name: `SelfAdminRoleAssignment ${RAND()}`,
|
|
67
|
+
users: [{ isAdmin: true }],
|
|
68
|
+
roles: [{ role: NON_ADMIN_ROLE }],
|
|
69
|
+
apiKeys: 0,
|
|
70
|
+
})
|
|
71
|
+
const { sdk } = tenant
|
|
72
|
+
|
|
73
|
+
// Record whether a self-role-update attempt is rejected by the relationship constraints.
|
|
74
|
+
const expect_blocked = async (fn: () => Promise<any>, description: string) => {
|
|
75
|
+
try {
|
|
76
|
+
const unexpected = await fn()
|
|
77
|
+
record(
|
|
78
|
+
description,
|
|
79
|
+
false,
|
|
80
|
+
`SELF-ROLE ESCALATION SUCCEEDED (expected it to be blocked); result=`
|
|
81
|
+
+ `${unexpected === undefined ? '(none)' : JSON.stringify(unexpected)}`,
|
|
82
|
+
)
|
|
83
|
+
} catch (e: any) {
|
|
84
|
+
// CRUD relationship-constraint failures surface as 400 { message, info } via SDK parseError.
|
|
85
|
+
record(
|
|
86
|
+
description,
|
|
87
|
+
e?.code === 400 || e?.statusCode === 400 || typeof e?.message === 'string',
|
|
88
|
+
`blocked with ${
|
|
89
|
+
typeof e?.message === 'string' && e.message !== ''
|
|
90
|
+
? e.message
|
|
91
|
+
: (e === undefined || e === null ? String(e) : JSON.stringify(e))
|
|
92
|
+
}`,
|
|
93
|
+
)
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
69
97
|
// 1. Admin creates a throwaway non-admin user (notification emails off, timestamped email).
|
|
70
98
|
// verifiedEmail is set at creation (admin-only, updatesDisabled after) so the attacker can
|
|
71
99
|
// drive an authenticated session — otherwise actions are blocked on email-verification, not
|
|
@@ -81,10 +109,10 @@ export const self_admin_role_assignment_tests = async ({ sdk } : { sdk: Session,
|
|
|
81
109
|
|
|
82
110
|
// Setup sanity: the attacker holds exactly the non-admin role and is NOT an admin.
|
|
83
111
|
const attackerBefore = await sdk.api.users.getOne(attackerId)
|
|
84
|
-
|
|
85
|
-
JSON.stringify(attackerBefore.roles) === JSON.stringify([NON_ADMIN_ROLE]),
|
|
86
|
-
`Setup failed: expected attacker to hold [${NON_ADMIN_ROLE}], got ${JSON.stringify(attackerBefore.roles)}`,
|
|
112
|
+
record(
|
|
87
113
|
'setup: attacker holds a non-admin role',
|
|
114
|
+
JSON.stringify(attackerBefore.roles) === JSON.stringify([NON_ADMIN_ROLE]),
|
|
115
|
+
`roles=${JSON.stringify(attackerBefore.roles ?? null)} (want [${NON_ADMIN_ROLE}])`,
|
|
88
116
|
)
|
|
89
117
|
|
|
90
118
|
// 2. Authenticate AS the attacker (no password needed — admin mints an auth token).
|
|
@@ -93,13 +121,14 @@ export const self_admin_role_assignment_tests = async ({ sdk } : { sdk: Session,
|
|
|
93
121
|
authToken: (await sdk.api.users.generate_auth_token({ id: attackerId })).authToken,
|
|
94
122
|
})
|
|
95
123
|
await sdkAttacker.refresh_session() // populate userInfo from the freshly-minted token
|
|
96
|
-
|
|
97
|
-
sdkAttacker.userInfo.id === attackerId && !(sdkAttacker.userInfo.roles ?? []).includes('Admin'),
|
|
98
|
-
`Setup failed: attacker session is not the expected non-admin user`,
|
|
124
|
+
record(
|
|
99
125
|
'setup: authenticated as the non-admin attacker',
|
|
126
|
+
sdkAttacker.userInfo.id === attackerId && !(sdkAttacker.userInfo.roles ?? []).includes('Admin'),
|
|
127
|
+
`session id=${JSON.stringify(sdkAttacker.userInfo.id ?? null)} roles=`
|
|
128
|
+
+ `${JSON.stringify(sdkAttacker.userInfo.roles ?? null)} (want id=${attackerId}, no Admin)`,
|
|
100
129
|
)
|
|
101
130
|
|
|
102
|
-
// 3. SECURITY
|
|
131
|
+
// 3. SECURITY CHECKS — every self-role mutation by the non-admin must be blocked.
|
|
103
132
|
await expect_blocked(
|
|
104
133
|
() => sdkAttacker.api.users.updateOne(attackerId!, { roles: ['Admin'] }, { replaceObjectFields: true }),
|
|
105
134
|
'non-admin self-update to [Admin] is blocked',
|
|
@@ -117,43 +146,52 @@ export const self_admin_role_assignment_tests = async ({ sdk } : { sdk: Session,
|
|
|
117
146
|
'non-admin self-update to [] (would grant defaults) is blocked',
|
|
118
147
|
)
|
|
119
148
|
|
|
120
|
-
// 4. STATE
|
|
149
|
+
// 4. STATE CHECK — nothing slipped through; roles are still the original non-admin role.
|
|
121
150
|
const attackerAfter = await sdk.api.users.getOne(attackerId)
|
|
122
|
-
|
|
123
|
-
JSON.stringify(attackerAfter.roles) === JSON.stringify([NON_ADMIN_ROLE]),
|
|
124
|
-
`ESCALATION LEAK: attacker roles changed to ${JSON.stringify(attackerAfter.roles)} `
|
|
125
|
-
+ `after self-update attempts. Expected [${NON_ADMIN_ROLE}].`,
|
|
151
|
+
record(
|
|
126
152
|
'attacker roles unchanged after all self-escalation attempts',
|
|
153
|
+
JSON.stringify(attackerAfter.roles) === JSON.stringify([NON_ADMIN_ROLE]),
|
|
154
|
+
`roles=${JSON.stringify(attackerAfter.roles ?? null)} after self-update attempts`
|
|
155
|
+
+ ` (want [${NON_ADMIN_ROLE}]; anything else is an ESCALATION LEAK)`,
|
|
127
156
|
)
|
|
128
157
|
|
|
129
158
|
// 5. POSITIVE CONTROL — an Admin CAN update the user's roles (mechanism is not over-restricted).
|
|
130
159
|
await sdk.api.users.updateOne(attackerId, { roles: [NON_ADMIN_ROLE] }, { replaceObjectFields: true })
|
|
131
160
|
const afterAdminUpdate = await sdk.api.users.getOne(attackerId)
|
|
132
|
-
|
|
133
|
-
JSON.stringify(afterAdminUpdate.roles) === JSON.stringify([NON_ADMIN_ROLE]),
|
|
134
|
-
`Admin role update failed: roles are ${JSON.stringify(afterAdminUpdate.roles)}, expected [${NON_ADMIN_ROLE}]`,
|
|
161
|
+
record(
|
|
135
162
|
'admin can manage user roles (positive control)',
|
|
163
|
+
JSON.stringify(afterAdminUpdate.roles) === JSON.stringify([NON_ADMIN_ROLE]),
|
|
164
|
+
`roles=${JSON.stringify(afterAdminUpdate.roles ?? null)} (want [${NON_ADMIN_ROLE}])`,
|
|
136
165
|
)
|
|
137
166
|
} finally {
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
167
|
+
if (tenant) {
|
|
168
|
+
// Cleanup: delete the throwaway attacker. Never touches pre-existing users.
|
|
169
|
+
if (attackerId) {
|
|
170
|
+
try { await tenant.sdk.api.users.deleteOne(attackerId) } catch {}
|
|
171
|
+
}
|
|
172
|
+
// Teardown BEFORE anything asserts — assert calls process.exit, which would strand this tenant.
|
|
173
|
+
try { await tenant.teardown() } catch (e) { console.error('teardown failed', e) }
|
|
141
174
|
}
|
|
142
175
|
}
|
|
176
|
+
|
|
177
|
+
return checks
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/** Asserting wrapper, for standalone runs. */
|
|
181
|
+
export const self_admin_role_assignment_tests = async () => {
|
|
182
|
+
assert_checks('Self-admin role assignment', await self_admin_role_assignment_checks())
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/** Enrolls this suite in the auto-discovered parallel pool — see run_discovered_isolated_suites. */
|
|
186
|
+
export const ISOLATED_SUITE: IsolatedSuite = {
|
|
187
|
+
name: 'Self-admin role assignment',
|
|
188
|
+
run: self_admin_role_assignment_checks,
|
|
143
189
|
}
|
|
144
190
|
|
|
145
191
|
// Allow running this test file independently
|
|
146
192
|
if (require.main === module) {
|
|
147
193
|
console.log(`🌐 Using API URL: ${host}`)
|
|
148
|
-
|
|
149
|
-
const sdkNonAdmin = new Session({ host })
|
|
150
|
-
|
|
151
|
-
const runTests = async () => {
|
|
152
|
-
await setup_tests(sdk, sdkNonAdmin)
|
|
153
|
-
await self_admin_role_assignment_tests({ sdk, sdkNonAdmin })
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
runTests()
|
|
194
|
+
self_admin_role_assignment_tests()
|
|
157
195
|
.then(() => {
|
|
158
196
|
console.log("✅ self-admin role assignment test suite completed successfully")
|
|
159
197
|
process.exit(0)
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
require('source-map-support').install();
|
|
2
2
|
|
|
3
3
|
import { Session, EnduserSession } from "../../../sdk"
|
|
4
|
-
import { assert, log_header } from "@tellescope/testing"
|
|
5
|
-
import { setup_tests, authenticate_enduser_via_token } from "../../setup"
|
|
6
4
|
import { PROVIDER_PERMISSIONS } from "@tellescope/constants"
|
|
5
|
+
import {
|
|
6
|
+
assert_checks,
|
|
7
|
+
Check,
|
|
8
|
+
IsolatedSuite,
|
|
9
|
+
setup_isolated_tenant,
|
|
10
|
+
} from "../../setup_isolated"
|
|
7
11
|
|
|
8
12
|
const host = process.env.API_URL || 'http://localhost:8080' as const
|
|
9
13
|
|
|
@@ -28,30 +32,38 @@ const host = process.env.API_URL || 'http://localhost:8080' as const
|
|
|
28
32
|
* redactions: ['all'] (closes READ for endusers AND non-admin users; safe — nothing reads
|
|
29
33
|
* the value back). NOT `readonly` (would break the staff write — A2).
|
|
30
34
|
*
|
|
31
|
-
* Checks (collected,
|
|
35
|
+
* Checks (collected, never asserted here, so a RED run shows every failing vector):
|
|
32
36
|
* A1 enduser attendee PATCH of startLinkToken is REJECTED (WRITE gate)
|
|
33
37
|
* A2 a staff-set token still redeems for the host's session (feature preserved)
|
|
34
38
|
* A3 an enduser-set token (if the write lands) does NOT redeem (defence-in-depth)
|
|
35
39
|
* A4 an enduser attendee does NOT receive startLinkToken on read (READ gate, endusers)
|
|
36
40
|
* A5 a non-admin staff user does NOT receive startLinkToken on read (READ gate, users)
|
|
37
41
|
*
|
|
38
|
-
* No vendor, no Bedrock; the "host" is a throwaway user.
|
|
42
|
+
* No vendor, no Bedrock; the "host" is a throwaway user. Runs on its own provisioned tenant and
|
|
43
|
+
* cleans up every created record before tearing it down. The patient session is minted inline from
|
|
44
|
+
* endusers.generate_auth_token — this file imports nothing from the shared setup.ts fixture.
|
|
39
45
|
*/
|
|
40
46
|
const RAND = () => Math.random().toString(36).slice(2, 10)
|
|
41
47
|
|
|
42
|
-
export const
|
|
43
|
-
|
|
48
|
+
export const startlinktoken_escalation_checks = async (): Promise<Check[]> => {
|
|
49
|
+
const checks: Check[] = []
|
|
50
|
+
const record = (label: string, pass: boolean, detail: string) => checks.push({ label, pass, detail })
|
|
44
51
|
|
|
45
|
-
|
|
52
|
+
let tenant: Awaited<ReturnType<typeof setup_isolated_tenant>> | undefined
|
|
46
53
|
const userIds: string[] = []
|
|
47
54
|
const enduserIds: string[] = []
|
|
48
55
|
const eventIds: string[] = []
|
|
49
56
|
const roleIds: string[] = []
|
|
50
57
|
|
|
51
|
-
const checks: { label: string, pass: boolean, detail: string }[] = []
|
|
52
|
-
const record = (label: string, pass: boolean, detail: string) => checks.push({ label, pass, detail })
|
|
53
|
-
|
|
54
58
|
try {
|
|
59
|
+
tenant = await setup_isolated_tenant({
|
|
60
|
+
name: `startLinkToken escalation ${RAND()}`,
|
|
61
|
+
users: [{ isAdmin: true }],
|
|
62
|
+
apiKeys: 0,
|
|
63
|
+
})
|
|
64
|
+
const { sdk } = tenant
|
|
65
|
+
const businessId = tenant.businessId
|
|
66
|
+
|
|
55
67
|
// Throwaway host staff user — the account an attacker would escalate INTO.
|
|
56
68
|
const host_user = await sdk.api.users.createOne({
|
|
57
69
|
email: `f0185-host-${RAND()}@tellescope.example`, fname: 'F0185', lname: 'Host',
|
|
@@ -71,8 +83,12 @@ export const startlinktoken_escalation_tests = async ({ sdk } : { sdk: Session,
|
|
|
71
83
|
} as any)
|
|
72
84
|
eventIds.push(event.id)
|
|
73
85
|
|
|
74
|
-
const
|
|
75
|
-
|
|
86
|
+
const { authToken: patientAuthToken, enduser: patientInfo } = (
|
|
87
|
+
await sdk.api.endusers.generate_auth_token({ id: patient.id })
|
|
88
|
+
)
|
|
89
|
+
const patientSDK = new EnduserSession({
|
|
90
|
+
host, authToken: patientAuthToken, enduser: patientInfo, businessId,
|
|
91
|
+
})
|
|
76
92
|
|
|
77
93
|
// ---- A1: WRITE gate — enduser attendee cannot PATCH startLinkToken ----
|
|
78
94
|
const attackerToken = `f0185-attacker-${RAND()}${RAND()}`
|
|
@@ -93,6 +109,8 @@ export const startlinktoken_escalation_tests = async ({ sdk } : { sdk: Session,
|
|
|
93
109
|
record('A3: enduser-set token does not mint a staff session', !redeemed?.authToken,
|
|
94
110
|
redeemed?.authToken ? `minted a STAFF authToken for host ${host_user.id}` : 'not redeemable')
|
|
95
111
|
} else {
|
|
112
|
+
// A genuine conditional vector, not a skip: the value never landed because A1 blocked the
|
|
113
|
+
// write, which is exactly the fixed behaviour this check is defence-in-depth for.
|
|
96
114
|
record('A3: enduser-set token does not mint a staff session', true, '(n/a — write blocked, value never landed)')
|
|
97
115
|
}
|
|
98
116
|
|
|
@@ -108,19 +126,24 @@ export const startlinktoken_escalation_tests = async ({ sdk } : { sdk: Session,
|
|
|
108
126
|
`staffWrite=${staffWriteErr ? 'REJECTED(' + staffWriteErr + ')' : 'ok'} authToken=${!!legit?.authToken} eventId=${legit?.eventId} ${legit?.error ? '(' + legit.error + ')' : ''}`)
|
|
109
127
|
|
|
110
128
|
// ---- A4: READ gate (endusers) — patient attendee must not receive the token ----
|
|
111
|
-
let enduserRead: any = null
|
|
112
|
-
try { enduserRead = await patientSDK.api.calendar_events.getOne(event.id) } catch {}
|
|
129
|
+
let enduserRead: any = null, enduserReadErr = ''
|
|
130
|
+
try { enduserRead = await patientSDK.api.calendar_events.getOne(event.id) } catch (e: any) { enduserReadErr = e?.message ?? String(e) }
|
|
113
131
|
record('A4: startLinkToken redacted from enduser reads',
|
|
114
132
|
!enduserRead || (enduserRead as any).startLinkToken === undefined,
|
|
115
|
-
|
|
133
|
+
// The detail distinguishes "read succeeded, token absent" from "read failed", which both
|
|
134
|
+
// satisfy the predicate: a blocked read proves nothing about redaction.
|
|
135
|
+
`enduser read startLinkToken=${(enduserRead as any)?.startLinkToken ?? '(absent)'}`
|
|
136
|
+
+ `${enduserRead ? '' : ` — READ FAILED (${enduserReadErr !== '' ? enduserReadErr : 'no error message'}), so the READ gate was not probed`}`
|
|
137
|
+
+ ` — could redeem a staff-set token`)
|
|
116
138
|
|
|
117
139
|
// ---- A5: READ gate (non-admin users) — low-priv staff must not receive the token ----
|
|
140
|
+
let roleCreateErr = ''
|
|
118
141
|
const rbap = await sdk.api.role_based_access_permissions.createOne({
|
|
119
142
|
role: `F0185NonAdmin-${RAND()}`,
|
|
120
143
|
// Non-admin (non-Admin-role) staff with tenant-wide calendar READ — enough to load the event,
|
|
121
144
|
// so the assertion isolates redaction (not access). Spread a valid full permissions shape.
|
|
122
145
|
permissions: { ...PROVIDER_PERMISSIONS, calendar_events: { ...(PROVIDER_PERMISSIONS as any).calendar_events, read: 'All', readMany: 'All' } },
|
|
123
|
-
} as any).catch((e: any) => {
|
|
146
|
+
} as any).catch((e: any) => { roleCreateErr = e?.message ?? String(e); return null })
|
|
124
147
|
if (rbap) {
|
|
125
148
|
roleIds.push(rbap.id)
|
|
126
149
|
const nonAdmin = await sdk.api.users.createOne({
|
|
@@ -130,33 +153,52 @@ export const startlinktoken_escalation_tests = async ({ sdk } : { sdk: Session,
|
|
|
130
153
|
userIds.push(nonAdmin.id)
|
|
131
154
|
const { authToken } = await sdk.api.users.generate_auth_token({ id: nonAdmin.id })
|
|
132
155
|
const nonAdminSDK = new Session({ host, authToken })
|
|
133
|
-
let staffRead: any = null
|
|
134
|
-
try { staffRead = await nonAdminSDK.api.calendar_events.getOne(event.id) } catch {}
|
|
156
|
+
let staffRead: any = null, staffReadErr = ''
|
|
157
|
+
try { staffRead = await nonAdminSDK.api.calendar_events.getOne(event.id) } catch (e: any) { staffReadErr = e?.message ?? String(e) }
|
|
135
158
|
record('A5: startLinkToken redacted from non-admin user reads',
|
|
136
159
|
!staffRead || (staffRead as any).startLinkToken === undefined,
|
|
137
|
-
|
|
160
|
+
// Same as A4: a read this low-privilege user could not perform at all also satisfies the
|
|
161
|
+
// predicate, so the detail says which of the two happened.
|
|
162
|
+
`non-admin user read startLinkToken=${(staffRead as any)?.startLinkToken ?? '(absent)'}`
|
|
163
|
+
+ `${staffRead ? '' : ` — READ FAILED (${staffReadErr !== '' ? staffReadErr : 'no error message'}), so the READ gate was not probed`}`
|
|
164
|
+
+ ` — staff→host escalation via read`)
|
|
138
165
|
} else {
|
|
139
|
-
|
|
166
|
+
// Previously a PASSING "(n/a)" check, which reported green without probing the READ gate at
|
|
167
|
+
// all. On a tenant this suite provisioned, the admin can always create a role — a failure here
|
|
168
|
+
// is a real defect, so it fails and carries the error.
|
|
169
|
+
record('A5: startLinkToken redacted from non-admin user reads', false,
|
|
170
|
+
`could not create a non-admin role on this freshly provisioned tenant, so the staff READ gate `
|
|
171
|
+
+ `was never probed: ${roleCreateErr !== '' ? roleCreateErr : '(no error message)'}`)
|
|
140
172
|
}
|
|
141
|
-
|
|
142
|
-
// Report the full table before asserting (the harness exits on the first failed assert).
|
|
143
|
-
console.log('\n check summary:')
|
|
144
|
-
for (const c of checks) console.log(` ${c.pass ? 'PASS' : 'FAIL'} ${c.label} — ${c.detail}`)
|
|
145
|
-
console.log('')
|
|
146
|
-
for (const c of checks) assert(c.pass, `${c.label} — ${c.detail}`, c.label)
|
|
147
173
|
} finally {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
174
|
+
if (tenant) {
|
|
175
|
+
const { sdk } = tenant
|
|
176
|
+
for (const id of eventIds) { try { await sdk.api.calendar_events.deleteOne(id) } catch {} }
|
|
177
|
+
for (const id of enduserIds) { try { await sdk.api.endusers.deleteOne(id) } catch {} }
|
|
178
|
+
for (const id of userIds) { try { await sdk.api.users.deleteOne(id) } catch {} }
|
|
179
|
+
for (const id of roleIds) { try { await sdk.api.role_based_access_permissions.deleteOne(id) } catch {} }
|
|
180
|
+
// Teardown BEFORE anything asserts — assert calls process.exit, which would strand this tenant.
|
|
181
|
+
try { await tenant.teardown() } catch (e) { console.error('teardown failed', e) }
|
|
182
|
+
}
|
|
152
183
|
}
|
|
184
|
+
|
|
185
|
+
return checks
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/** Asserting wrapper, for standalone runs. */
|
|
189
|
+
export const startlinktoken_escalation_tests = async () => {
|
|
190
|
+
assert_checks('startLinkToken escalation', await startlinktoken_escalation_checks())
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/** Enrolls this suite in the auto-discovered parallel pool — see run_discovered_isolated_suites. */
|
|
194
|
+
export const ISOLATED_SUITE: IsolatedSuite = {
|
|
195
|
+
name: 'startLinkToken escalation',
|
|
196
|
+
run: startlinktoken_escalation_checks,
|
|
153
197
|
}
|
|
154
198
|
|
|
155
199
|
if (require.main === module) {
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
setup_tests(sdk, sdkNonAdmin)
|
|
159
|
-
.then(() => startlinktoken_escalation_tests({ sdk, sdkNonAdmin }))
|
|
200
|
+
console.log(`🌐 Using API URL: ${host}`)
|
|
201
|
+
startlinktoken_escalation_tests()
|
|
160
202
|
.then(() => { console.log("✅ startLinkToken escalation test suite completed successfully"); process.exit(0) })
|
|
161
203
|
.catch((error) => { console.error("❌ startLinkToken escalation test suite failed:", error); process.exit(1) })
|
|
162
204
|
}
|
|
@@ -1,18 +1,21 @@
|
|
|
1
1
|
require('source-map-support').install();
|
|
2
2
|
|
|
3
3
|
import http from "http"
|
|
4
|
-
|
|
4
|
+
|
|
5
5
|
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
assert_checks,
|
|
7
|
+
Check,
|
|
8
|
+
IsolatedSuite,
|
|
9
|
+
setup_isolated_tenant,
|
|
10
|
+
} from "../../setup_isolated"
|
|
10
11
|
|
|
11
12
|
const host = process.env.API_URL || 'http://localhost:8080' as const
|
|
12
13
|
|
|
13
14
|
// The server-side axios timeout is 15s (the fix under test). We bound our own wait above that.
|
|
14
15
|
const CLIENT_WAIT_MS = 20_000
|
|
15
16
|
|
|
17
|
+
const RAND = () => Math.random().toString(36).slice(2, 10)
|
|
18
|
+
|
|
16
19
|
/**
|
|
17
20
|
* Regression test: outbound webhook delivery must time out rather than hang.
|
|
18
21
|
*
|
|
@@ -25,54 +28,82 @@ const CLIENT_WAIT_MS = 20_000
|
|
|
25
28
|
* client timer.
|
|
26
29
|
* - green (fixed): server times out at ~15s → handler returns 400 → SDK call rejects < 20s
|
|
27
30
|
* - red (unfixed): the call is still pending at 20s → client timer wins
|
|
31
|
+
*
|
|
32
|
+
* The loopback receiver only clears assertPublicHttpUrl off PROD/STAGING, so this suite stays
|
|
33
|
+
* local-only, exactly as it was before it moved onto an isolated tenant.
|
|
28
34
|
*/
|
|
29
|
-
export const
|
|
30
|
-
|
|
35
|
+
export const webhook_timeout_checks = async (): Promise<Check[]> => {
|
|
36
|
+
const checks: Check[] = []
|
|
37
|
+
const record = (label: string, pass: boolean, detail: string) => checks.push({ label, pass, detail })
|
|
31
38
|
|
|
32
|
-
let
|
|
39
|
+
let tenant: Awaited<ReturnType<typeof setup_isolated_tenant>> | undefined
|
|
33
40
|
const slowServer = http.createServer(() => { /* accept connection, never respond */ })
|
|
34
41
|
|
|
35
42
|
try {
|
|
43
|
+
tenant = await setup_isolated_tenant({
|
|
44
|
+
name: `WebhookTimeout ${RAND()}`,
|
|
45
|
+
users: [{ isAdmin: true }],
|
|
46
|
+
apiKeys: 0,
|
|
47
|
+
})
|
|
48
|
+
const { sdk } = tenant
|
|
49
|
+
|
|
36
50
|
await new Promise<void>(resolve => slowServer.listen(0, '127.0.0.1', () => resolve()))
|
|
37
51
|
const port = (slowServer.address() as any).port
|
|
38
52
|
const blackholeUrl = `http://127.0.0.1:${port}/hook`
|
|
39
53
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
}
|
|
54
|
+
let enduserId: string | undefined
|
|
55
|
+
try {
|
|
56
|
+
const enduser = await sdk.api.endusers.createOne({ email: `f0155-${RAND()}@example.com`, fname: 'F0155', lname: 'Webhook' })
|
|
57
|
+
enduserId = enduser.id
|
|
58
|
+
|
|
59
|
+
// the loser of the race is cleared rather than left pending: an uncleared 20s timer would hold
|
|
60
|
+
// the event loop open for the rest of the window after this suite is done
|
|
61
|
+
let clientTimer: ReturnType<typeof setTimeout> | undefined
|
|
62
|
+
const start = Date.now()
|
|
63
|
+
const outcome = await Promise.race([
|
|
64
|
+
sdk.api.webhooks.send_automation_webhook({
|
|
65
|
+
enduserId: enduser.id,
|
|
66
|
+
action: { info: { url: blackholeUrl } },
|
|
67
|
+
} as any).then(() => 'completed').catch(() => 'errored'),
|
|
68
|
+
new Promise<string>(r => { clientTimer = setTimeout(() => r('client-timeout'), CLIENT_WAIT_MS) }),
|
|
69
|
+
]).finally(() => { if (clientTimer) clearTimeout(clientTimer) })
|
|
70
|
+
const elapsed = Date.now() - start
|
|
71
|
+
|
|
56
72
|
// green: the server-side axios timeout fired (call settled) before our 20s client wait
|
|
57
|
-
|
|
58
|
-
|
|
73
|
+
record(
|
|
74
|
+
'outbound webhook to a non-responding receiver times out server-side (does not hang)',
|
|
75
|
+
outcome !== 'client-timeout' && elapsed < CLIENT_WAIT_MS,
|
|
76
|
+
`outcome=${outcome} elapsed=${elapsed}ms (want it settled in under ${CLIENT_WAIT_MS}ms;`
|
|
77
|
+
+ ` "client-timeout" means the server-side timeout never fired)`,
|
|
78
|
+
)
|
|
79
|
+
} finally {
|
|
80
|
+
// per-record cleanup is kept even though teardown subsumes it, so the body stays runnable
|
|
81
|
+
// against any tenant
|
|
82
|
+
if (enduserId) { try { await sdk.api.endusers.deleteOne(enduserId) } catch {} }
|
|
83
|
+
}
|
|
59
84
|
} finally {
|
|
60
85
|
slowServer.close()
|
|
61
|
-
|
|
86
|
+
// Teardown BEFORE anything asserts — assert calls process.exit, which would strand this tenant.
|
|
87
|
+
if (tenant) { try { await tenant.teardown() } catch (e) { console.error('teardown failed', e) } }
|
|
62
88
|
}
|
|
89
|
+
|
|
90
|
+
return checks
|
|
63
91
|
}
|
|
64
92
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
93
|
+
/** Asserting wrapper, for standalone runs. */
|
|
94
|
+
export const webhook_timeout_tests = async () => {
|
|
95
|
+
assert_checks('Webhook timeout', await webhook_timeout_checks())
|
|
96
|
+
}
|
|
69
97
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
98
|
+
/** Enrolls this suite in the auto-discovered parallel pool — see run_discovered_isolated_suites. */
|
|
99
|
+
export const ISOLATED_SUITE: IsolatedSuite = {
|
|
100
|
+
name: 'Webhook timeout',
|
|
101
|
+
run: webhook_timeout_checks,
|
|
102
|
+
}
|
|
74
103
|
|
|
75
|
-
|
|
104
|
+
if (require.main === module) {
|
|
105
|
+
console.log(`🌐 Using API URL: ${host}`)
|
|
106
|
+
webhook_timeout_tests()
|
|
76
107
|
.then(() => {
|
|
77
108
|
console.log("✅ webhook timeout test suite completed successfully")
|
|
78
109
|
process.exit(0)
|