@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,26 +1,39 @@
|
|
|
1
1
|
require('source-map-support').install();
|
|
2
2
|
|
|
3
3
|
import axios from "axios"
|
|
4
|
-
import {
|
|
4
|
+
import { wait } from "@tellescope/testing"
|
|
5
5
|
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
assert_checks,
|
|
7
|
+
Check,
|
|
8
|
+
IsolatedSuite,
|
|
9
|
+
setup_isolated_tenant,
|
|
10
|
+
} from "../../setup_isolated"
|
|
11
11
|
|
|
12
12
|
const host = process.env.API_URL || 'http://localhost:8080' as const
|
|
13
13
|
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
14
|
+
const RAND = () => Math.random().toString(36).slice(2, 10)
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* POST /v1/users/register, retrying a 429.
|
|
18
|
+
*
|
|
19
|
+
* The endpoint is throttled at roughly 1/sec on a `user-register-<ip>` namespace that no tenant
|
|
20
|
+
* teardown clears and that every concurrently running suite shares, so a 429 here is contention
|
|
21
|
+
* between suites, not a result. (Deliberately a local copy of organization_signup.test.ts's helper
|
|
22
|
+
* rather than a shared export: the two suites stay uncoupled.)
|
|
23
|
+
*/
|
|
24
|
+
const register_request = async (data: Record<string, any>) => {
|
|
25
|
+
const send = () => axios.request({
|
|
26
|
+
method: 'post', url: `${host}/v1/users/register`,
|
|
27
|
+
data,
|
|
28
|
+
validateStatus: () => true,
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
let result = await send()
|
|
32
|
+
for (let attempt = 0; attempt < 5 && result.status === 429; attempt++) {
|
|
33
|
+
await wait(undefined, 1200)
|
|
34
|
+
result = await send()
|
|
23
35
|
}
|
|
36
|
+
return result
|
|
24
37
|
}
|
|
25
38
|
|
|
26
39
|
/**
|
|
@@ -36,99 +49,125 @@ const post = async (path: string, body: any, headers: Record<string, string> = {
|
|
|
36
49
|
* caller-supplied businessId onto a new `accountType: 'Business'` user — bypassing the
|
|
37
50
|
* globalUnique: ['email'] enforcement that only runs in the generic create route.
|
|
38
51
|
*
|
|
39
|
-
* The "victim org"
|
|
40
|
-
* anonymous caller was never invited to.
|
|
41
|
-
*
|
|
42
|
-
*
|
|
52
|
+
* The "victim org" is this suite's OWN provisioned tenant (tenant.businessId): an org the
|
|
53
|
+
* anonymous caller was never invited to. Its admin is used purely to OBSERVE whether an uninvited
|
|
54
|
+
* user record materialized inside the org (getOne({ email }) is org-scoped and throws when the
|
|
55
|
+
* email is absent from the caller's tenant). Running on a throwaway tenant rather than the shared
|
|
56
|
+
* fixture means a failing (vulnerable) run plants its user in an org that is then torn down.
|
|
43
57
|
*
|
|
44
58
|
* Expected results:
|
|
45
|
-
* - VULNERABLE code: the
|
|
46
|
-
* proving the exploit ("EXPLOIT CONFIRMED" in the failure
|
|
59
|
+
* - VULNERABLE code: the checks FAIL — the planted user appears inside the victim org,
|
|
60
|
+
* proving the exploit ("EXPLOIT CONFIRMED" in the failure detail).
|
|
47
61
|
* - FIXED code: register ignores the caller-supplied businessId (self-signups are created
|
|
48
62
|
* org-less and duplicates are rejected globally), so nothing appears in the victim org and
|
|
49
|
-
* the
|
|
63
|
+
* the checks PASS.
|
|
50
64
|
*
|
|
51
|
-
* Uses unique emails per run
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
* legitimate "root register, no org" signup
|
|
65
|
+
* Uses unique emails per run so re-runs never collide on the platform-wide unique email
|
|
66
|
+
* constraint. NOTE: on the FIXED path these registrations create org-less user records that
|
|
67
|
+
* neither an org-scoped admin nor the tenant teardown (which deletes by businessId) can remove —
|
|
68
|
+
* harmless residue (unique emails), inherent to the legitimate "root register, no org" signup.
|
|
55
69
|
*/
|
|
56
|
-
export const
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
const victimBusinessId = sdk.userInfo.businessId
|
|
60
|
-
const password = 'testpassword123!'
|
|
61
|
-
const termsVersion = '1'
|
|
62
|
-
|
|
63
|
-
// ==================================================================================
|
|
64
|
-
// Scenario 1 — uninvited org join
|
|
65
|
-
// An anonymous caller registers with businessId set to the victim org. On vulnerable
|
|
66
|
-
// code this creates a Business user INSIDE the victim org that no one invited.
|
|
67
|
-
// ==================================================================================
|
|
68
|
-
const email1 = `dontsend+reg-inject-${Date.now()}@tellescope.com`
|
|
69
|
-
|
|
70
|
-
const before = await sdk.api.users.getOne({ email: email1 }).catch(() => null)
|
|
71
|
-
assert(before === null, `precondition failed: ${email1} already present in victim org`, 'precondition: victim org has no such user')
|
|
72
|
-
|
|
73
|
-
const res1 = await post('/v1/users/register', { email: email1, password, termsVersion, businessId: victimBusinessId })
|
|
74
|
-
console.log(` register(businessId=victim) -> HTTP ${res1.status}`)
|
|
75
|
-
|
|
76
|
-
const planted1: any = await sdk.api.users.getOne({ email: email1 }).catch(() => null)
|
|
77
|
-
const injectedIntoVictimOrg = !!planted1 && planted1.businessId === victimBusinessId
|
|
78
|
-
|
|
79
|
-
// Clean up BEFORE asserting (a failed assert calls process.exit(1) and would skip cleanup).
|
|
80
|
-
if (planted1?.id) await sdk.api.users.deleteOne(planted1.id).catch(() => {})
|
|
70
|
+
export const register_business_id_injection_checks = async (): Promise<Check[]> => {
|
|
71
|
+
const checks: Check[] = []
|
|
72
|
+
const record = (label: string, pass: boolean, detail: string) => checks.push({ label, pass, detail })
|
|
81
73
|
|
|
82
|
-
|
|
83
|
-
!injectedIntoVictimOrg,
|
|
84
|
-
`❌ EXPLOIT CONFIRMED: anonymous POST /v1/users/register with businessId=${victimBusinessId} created user `
|
|
85
|
-
+ `${email1} (accountType=${planted1?.accountType}) inside the victim org — no invite required`,
|
|
86
|
-
'✅ register ignores caller-supplied businessId — no user injected into victim org',
|
|
87
|
-
)
|
|
74
|
+
let tenant: Awaited<ReturnType<typeof setup_isolated_tenant>> | undefined
|
|
88
75
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
76
|
+
try {
|
|
77
|
+
tenant = await setup_isolated_tenant({
|
|
78
|
+
name: `register businessId injection ${RAND()}`,
|
|
79
|
+
users: [{ isAdmin: true }],
|
|
80
|
+
apiKeys: 0,
|
|
81
|
+
})
|
|
82
|
+
const { sdk } = tenant
|
|
83
|
+
|
|
84
|
+
const victimBusinessId = tenant.businessId
|
|
85
|
+
const password = 'testpassword123!'
|
|
86
|
+
const termsVersion = '1'
|
|
87
|
+
|
|
88
|
+
// ==================================================================================
|
|
89
|
+
// Scenario 1 — uninvited org join
|
|
90
|
+
// An anonymous caller registers with businessId set to the victim org. On vulnerable
|
|
91
|
+
// code this creates a Business user INSIDE the victim org that no one invited.
|
|
92
|
+
// ==================================================================================
|
|
93
|
+
const email1 = `dontsend+reg-inject-${Date.now()}-${RAND()}@tellescope.com`
|
|
94
|
+
|
|
95
|
+
const before = await sdk.api.users.getOne({ email: email1 }).catch(() => null)
|
|
96
|
+
record(
|
|
97
|
+
'precondition: victim org has no such user',
|
|
98
|
+
before === null,
|
|
99
|
+
before === null ? `${email1} absent from the victim org` : `precondition failed: ${email1} already present in victim org`,
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
const res1 = await register_request({ email: email1, password, termsVersion, businessId: victimBusinessId })
|
|
103
|
+
console.log(` register(businessId=victim) -> HTTP ${res1.status}`)
|
|
104
|
+
|
|
105
|
+
const planted1: any = await sdk.api.users.getOne({ email: email1 }).catch(() => null)
|
|
106
|
+
const injectedIntoVictimOrg = !!planted1 && planted1.businessId === victimBusinessId
|
|
107
|
+
|
|
108
|
+
record(
|
|
109
|
+
'✅ register ignores caller-supplied businessId — no user injected into victim org',
|
|
110
|
+
!injectedIntoVictimOrg,
|
|
111
|
+
injectedIntoVictimOrg
|
|
112
|
+
? `❌ EXPLOIT CONFIRMED: anonymous POST /v1/users/register with businessId=${victimBusinessId} created user `
|
|
113
|
+
+ `${email1} (accountType=${planted1?.accountType}) inside the victim org — no invite required`
|
|
114
|
+
: `register -> HTTP ${res1.status}; no ${email1} user inside the victim org`,
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
await wait(undefined, 1200) // register endpoint rate-limits ~1/sec per IP
|
|
118
|
+
|
|
119
|
+
// ==================================================================================
|
|
120
|
+
// Scenario 2 — cross-org duplicate for the same email
|
|
121
|
+
// First register with NO businessId (the legitimate "root register, no org" record —
|
|
122
|
+
// the "oldest" account in the report). Then register the SAME email WITH the victim
|
|
123
|
+
// businessId. On vulnerable code the scoped duplicate check misses the org-less record,
|
|
124
|
+
// so a SECOND user record for the same email is created inside the victim org.
|
|
125
|
+
// ==================================================================================
|
|
126
|
+
const email2 = `dontsend+reg-dup-${Date.now()}-${RAND()}@tellescope.com`
|
|
127
|
+
|
|
128
|
+
const resRoot = await register_request({ email: email2, password, termsVersion })
|
|
129
|
+
console.log(` register(no businessId) -> HTTP ${resRoot.status}`)
|
|
130
|
+
|
|
131
|
+
await wait(undefined, 1200)
|
|
132
|
+
|
|
133
|
+
const resDup = await register_request({ email: email2, password, termsVersion, businessId: victimBusinessId })
|
|
134
|
+
console.log(` register(same email, businessId=victim) -> HTTP ${resDup.status}`)
|
|
135
|
+
|
|
136
|
+
const planted2: any = await sdk.api.users.getOne({ email: email2 }).catch(() => null)
|
|
137
|
+
const duplicateInVictimOrg = !!planted2 && planted2.businessId === victimBusinessId
|
|
138
|
+
|
|
139
|
+
record(
|
|
140
|
+
'✅ register enforces global email uniqueness — no cross-org duplicate created',
|
|
141
|
+
!duplicateInVictimOrg,
|
|
142
|
+
duplicateInVictimOrg
|
|
143
|
+
? `❌ EXPLOIT CONFIRMED: same email ${email2} registered into a second org — duplicate user `
|
|
144
|
+
+ `(accountType=${planted2?.accountType}) created in victim org ${victimBusinessId}`
|
|
145
|
+
: `register(no org) -> HTTP ${resRoot.status}, register(businessId=victim) -> HTTP ${resDup.status}; `
|
|
146
|
+
+ `no ${email2} user inside the victim org`,
|
|
147
|
+
)
|
|
148
|
+
} finally {
|
|
149
|
+
// Teardown BEFORE anything asserts — assert calls process.exit, which would strand this tenant.
|
|
150
|
+
if (tenant) { try { await tenant.teardown() } catch (e) { console.error('teardown failed', e) } }
|
|
151
|
+
}
|
|
107
152
|
|
|
108
|
-
|
|
109
|
-
|
|
153
|
+
return checks
|
|
154
|
+
}
|
|
110
155
|
|
|
111
|
-
|
|
156
|
+
/** Asserting wrapper, for standalone runs. */
|
|
157
|
+
export const register_business_id_injection_tests = async () => {
|
|
158
|
+
assert_checks('register businessId injection', await register_business_id_injection_checks())
|
|
159
|
+
}
|
|
112
160
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
'✅ register enforces global email uniqueness — no cross-org duplicate created',
|
|
118
|
-
)
|
|
161
|
+
/** Enrolls this suite in the auto-discovered parallel pool — see run_discovered_isolated_suites. */
|
|
162
|
+
export const ISOLATED_SUITE: IsolatedSuite = {
|
|
163
|
+
name: 'register businessId injection',
|
|
164
|
+
run: register_business_id_injection_checks,
|
|
119
165
|
}
|
|
120
166
|
|
|
121
167
|
// Allow running this test file independently
|
|
122
168
|
if (require.main === module) {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
const runTests = async () => {
|
|
127
|
-
await setup_tests(sdk, sdkNonAdmin)
|
|
128
|
-
await register_business_id_injection_tests({ sdk, sdkNonAdmin })
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
runTests()
|
|
169
|
+
console.log(`🌐 Using API URL: ${host}`)
|
|
170
|
+
register_business_id_injection_tests()
|
|
132
171
|
.then(() => {
|
|
133
172
|
console.log("✅ register businessId injection test suite completed successfully")
|
|
134
173
|
process.exit(0)
|
|
@@ -208,6 +208,133 @@ export const sanitize_user_html_with_iframes_tests = async () => {
|
|
|
208
208
|
if (!endToEnd.includes('<iframe')) fail(`patient markup not escaped to inert text: ${endToEnd}`)
|
|
209
209
|
if ((endToEnd.toLowerCase().match(/<iframe/g) || []).length !== 1) fail(`patient-injected iframe became a live frame: ${endToEnd}`)
|
|
210
210
|
|
|
211
|
+
// ---------------------------------------------------------------------------------------------
|
|
212
|
+
// 7. sanitize-html 2.18.0 behaviour pins
|
|
213
|
+
//
|
|
214
|
+
// Added with the 2.17.7 -> 2.18.0 bump. 2.18.0 changes how markup *inside a disallowed tag* is
|
|
215
|
+
// emitted: where 2.17.7 entity-escaped it into visible literal text, 2.18.0 parses it and runs it
|
|
216
|
+
// back through the allowlist. That is a rendering change on every surface, so the vectors it
|
|
217
|
+
// could plausibly reopen are pinned here rather than left to a future release to rediscover.
|
|
218
|
+
// ---------------------------------------------------------------------------------------------
|
|
219
|
+
|
|
220
|
+
// --- meta refresh -------------------------------------------------------------------------
|
|
221
|
+
// <meta> is not allowlisted by either shared sanitizer, so an http-equiv="refresh" redirect must
|
|
222
|
+
// never survive. The portal's custom-page sanitizer allowlists <meta> for charset/name/content
|
|
223
|
+
// and deliberately omits http-equiv for exactly this reason (CustomPage.tsx), which is why this
|
|
224
|
+
// vector is worth pinning on the shared pair too.
|
|
225
|
+
const metaRefreshCases: [string, string][] = [
|
|
226
|
+
['lowercase', `<meta http-equiv="refresh" content="0;url=https://evil.example">`],
|
|
227
|
+
['uppercase', `<META HTTP-EQUIV="REFRESH" CONTENT="0;url=https://evil.example">`],
|
|
228
|
+
['nested in allowed block', `<div><meta http-equiv="refresh" content="0;url=https://evil.example"><p>after</p></div>`],
|
|
229
|
+
]
|
|
230
|
+
for (const [name, payload] of metaRefreshCases) {
|
|
231
|
+
for (const [fnName, fn] of [['with_iframes', sanitize_user_html_with_iframes], ['base', sanitize_user_html]] as const) {
|
|
232
|
+
const out = fn(payload).toLowerCase()
|
|
233
|
+
if (out.includes('<meta')) fail(`meta survived [${fnName}/${name}] -> ${out}`)
|
|
234
|
+
if (out.includes('http-equiv')) fail(`http-equiv survived [${fnName}/${name}] -> ${out}`)
|
|
235
|
+
if (out.includes('evil.example')) fail(`meta refresh target survived [${fnName}/${name}] -> ${out}`)
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
// the redirect is dropped without taking the surrounding content with it
|
|
239
|
+
const metaSibling = sanitize_user_html_with_iframes(`<div><meta http-equiv="refresh" content="0;url=https://evil.example"><p>after</p></div>`)
|
|
240
|
+
if (!metaSibling.includes('<p>after</p>')) fail(`content after a dropped meta refresh was lost: ${metaSibling}`)
|
|
241
|
+
|
|
242
|
+
// --- svg:animate --------------------------------------------------------------------------
|
|
243
|
+
// SMIL animation can rewrite an attribute after sanitization: <animate attributeName="href"
|
|
244
|
+
// values="javascript:..."> turns an inert <a> into a javascript: link at render time, which no
|
|
245
|
+
// amount of href filtering catches. <svg> is not allowlisted, so animate must never survive —
|
|
246
|
+
// and with 2.18.0 now re-parsing disallowed-tag contents, "the parent is dropped" is no longer
|
|
247
|
+
// on its own enough to assume the child went with it.
|
|
248
|
+
const svgAnimateCases: [string, string][] = [
|
|
249
|
+
['animate onbegin', `<svg><animate onbegin="alert(1)" attributeName="x" dur="1s"></svg>`],
|
|
250
|
+
['animate href values', `<svg><a><animate attributeName="href" values="javascript:alert(1)"/><text>x</text></a></svg>`],
|
|
251
|
+
['set href to', `<svg><a><set attributeName="href" to="javascript:alert(1)"/><text>x</text></a></svg>`],
|
|
252
|
+
['animate onrepeat', `<svg><animate attributeName="x" begin="0s" onrepeat="alert(1)"/></svg>`],
|
|
253
|
+
['animate inside dropped iframe', `<iframe><svg><a><animate attributeName="href" values="javascript:alert(1)"/><text>x</text></a></svg></iframe>`],
|
|
254
|
+
]
|
|
255
|
+
for (const [name, payload] of svgAnimateCases) {
|
|
256
|
+
for (const [fnName, fn] of [['with_iframes', sanitize_user_html_with_iframes], ['base', sanitize_user_html]] as const) {
|
|
257
|
+
const out = fn(payload).toLowerCase()
|
|
258
|
+
if (out.includes('<animate') || out.includes('<set')) fail(`SMIL animation element survived [${fnName}/${name}] -> ${out}`)
|
|
259
|
+
if (out.includes('<svg')) fail(`svg survived [${fnName}/${name}] -> ${out}`)
|
|
260
|
+
if (out.includes('attributename')) fail(`attributeName survived [${fnName}/${name}] -> ${out}`)
|
|
261
|
+
if (out.includes('javascript:')) fail(`javascript: payload survived [${fnName}/${name}] -> ${out}`)
|
|
262
|
+
if (/\son[a-z]+\s*=/.test(out.replace(/"[^"]*"/g, '""'))) fail(`SMIL event handler survived [${fnName}/${name}] -> ${out}`)
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// --- noscript (the nonTextTags vector) ------------------------------------------------------
|
|
267
|
+
// The classic noscript context-confusion payload: a browser parses <noscript> contents as raw
|
|
268
|
+
// text when scripting is enabled and as markup when it isn't, so a sanitizer that disagrees with
|
|
269
|
+
// the renderer can be walked out of the attribute it thinks it is inside. Neither shared
|
|
270
|
+
// sanitizer sets nonTextTags, but the portal's custom-page sanitizer lists 'noscript' there
|
|
271
|
+
// (CustomPage.tsx), so the dependency's handling of the tag is pinned here.
|
|
272
|
+
const noscriptCases: [string, string][] = [
|
|
273
|
+
['attribute break-out', `<noscript><p title="</noscript><img src=x onerror=alert(1)>">`],
|
|
274
|
+
['style comment mXSS', `<noscript><style><!--</style><img src=x onerror=alert(1)>`],
|
|
275
|
+
['plain content', `<noscript>hidden</noscript><p>after</p>`],
|
|
276
|
+
['markup content', `<noscript><b>bold</b></noscript><p>after</p>`],
|
|
277
|
+
['inside dropped iframe', `<iframe><noscript><p title="</noscript><img src=x onerror=alert(1)>"></iframe>`],
|
|
278
|
+
]
|
|
279
|
+
for (const [name, payload] of noscriptCases) {
|
|
280
|
+
for (const [fnName, fn] of [['with_iframes', sanitize_user_html_with_iframes], ['base', sanitize_user_html]] as const) {
|
|
281
|
+
const out = fn(payload)
|
|
282
|
+
if (out.toLowerCase().includes('<noscript')) fail(`noscript survived [${fnName}/${name}] -> ${out}`)
|
|
283
|
+
// The breakout payload may legitimately remain as inert escaped text inside an attribute
|
|
284
|
+
// value; what must never happen is it coming back as a live handler. Values are blanked
|
|
285
|
+
// before the handler check for exactly that reason.
|
|
286
|
+
if (/\son[a-z]+\s*=/.test(out.toLowerCase().replace(/"[^"]*"/g, '""').replace(/'[^']*'/g, "''"))) {
|
|
287
|
+
fail(`live event handler escaped the noscript context [${fnName}/${name}] -> ${out}`)
|
|
288
|
+
}
|
|
289
|
+
if (out.toLowerCase().includes('<script')) fail(`script escaped the noscript context [${fnName}/${name}] -> ${out}`)
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
// content after a noscript block is not swallowed (the "page ends early" regression)
|
|
293
|
+
const afterNoscript = sanitize_user_html(`<noscript>a</noscript><p>para1</p><div>para2</div><span>tail</span>`)
|
|
294
|
+
for (const frag of ['<p>para1</p>', '<div>para2</div>', '<span>tail</span>']) {
|
|
295
|
+
if (!afterNoscript.includes(frag)) fail(`content after noscript was swallowed (missing ${frag}): ${afterNoscript}`)
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// --- disallowed-iframe fallback content (the actual 2.18.0 delta) ---------------------------
|
|
299
|
+
// This is what changed. In sanitize_user_html (no iframe in allowedTags) the markup inside a
|
|
300
|
+
// dropped <iframe> used to be emitted as escaped literal text; from 2.18.0 it is parsed and
|
|
301
|
+
// allowlisted instead, so a patient reading a form answer now sees bold text where they used to
|
|
302
|
+
// see "<b>FB</b>". Safe — the allowlist still applies — but it is a visible change, so both the
|
|
303
|
+
// containment and the rendering are pinned.
|
|
304
|
+
const baseFallback = sanitize_user_html(`<iframe src="http://evil.example"><b>FB</b></iframe>`)
|
|
305
|
+
if (baseFallback.toLowerCase().includes('<iframe')) fail(`base sanitizer kept the frame: ${baseFallback}`)
|
|
306
|
+
if (baseFallback.toLowerCase().includes('evil.example')) fail(`base sanitizer kept the frame src: ${baseFallback}`)
|
|
307
|
+
// The markup form, not just the characters "FB": on 2.17.7 this came back as the escaped text
|
|
308
|
+
// <b>FB</b>, which also contains "FB". Asserting the live tag is what makes this pin
|
|
309
|
+
// the 2.18.0 behaviour rather than pass identically on either version.
|
|
310
|
+
if (!baseFallback.includes('<b>FB</b>')) fail(`fallback markup was not parsed back into live markup: ${baseFallback}`)
|
|
311
|
+
if (baseFallback.includes('<b>')) fail(`fallback markup is still escaped (pre-2.18.0 behaviour): ${baseFallback}`)
|
|
312
|
+
|
|
313
|
+
// The hostile versions of the same shape must still come out inert, by the allowlist rather
|
|
314
|
+
// than by escaping.
|
|
315
|
+
const fallbackAttacks: [string, string][] = [
|
|
316
|
+
['img onerror', `<iframe><img src=x onerror=alert(1)></iframe>`],
|
|
317
|
+
['script', `<iframe><script>alert(1)</script></iframe>`],
|
|
318
|
+
['nested iframe', `<iframe><iframe src="https://evil.example"></iframe></iframe>`],
|
|
319
|
+
['javascript link', `<iframe><a href="javascript:alert(1)">x</a></iframe>`],
|
|
320
|
+
['object', `<iframe><object data="javascript:alert(1)"></object></iframe>`],
|
|
321
|
+
['base href', `<iframe><base href="https://evil.example"></iframe>`],
|
|
322
|
+
]
|
|
323
|
+
for (const [name, payload] of fallbackAttacks) {
|
|
324
|
+
const out = sanitize_user_html(payload)
|
|
325
|
+
if (!has_no_executable_vector_allowing_iframe(out) || out.toLowerCase().includes('<iframe')) {
|
|
326
|
+
fail(`iframe fallback content reopened a vector [${name}] -> ${out}`)
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
// sanitize_user_html_with_iframes is unaffected: exclusiveFilter removes a disallowed frame AND
|
|
331
|
+
// its children, so fallback markup never reaches the escaping path at all. Asserted explicitly
|
|
332
|
+
// so the two functions' different handling stays deliberate.
|
|
333
|
+
for (const [name, payload] of [...fallbackAttacks, ['bold fallback', `<iframe src="http://evil.example"><b>FB</b></iframe>`] as [string, string]]) {
|
|
334
|
+
const out = sanitize_user_html_with_iframes(payload)
|
|
335
|
+
if (out !== '') fail(`with_iframes should drop a disallowed frame and all its content [${name}] -> ${out}`)
|
|
336
|
+
}
|
|
337
|
+
|
|
211
338
|
console.log("✅ sanitize_user_html_with_iframes XSS regression tests passed")
|
|
212
339
|
}
|
|
213
340
|
|
|
@@ -3,12 +3,13 @@ require('source-map-support').install();
|
|
|
3
3
|
import axios from "axios"
|
|
4
4
|
|
|
5
5
|
import { Session } from "../../../sdk"
|
|
6
|
-
import {
|
|
7
|
-
assert,
|
|
8
|
-
log_header,
|
|
9
|
-
} from "@tellescope/testing"
|
|
10
6
|
import { PROVIDER_PERMISSIONS } from "@tellescope/constants"
|
|
11
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
assert_checks,
|
|
9
|
+
Check,
|
|
10
|
+
IsolatedSuite,
|
|
11
|
+
setup_isolated_tenant,
|
|
12
|
+
} from "../../setup_isolated"
|
|
12
13
|
|
|
13
14
|
const host = process.env.API_URL || 'http://localhost:8080' as const
|
|
14
15
|
|
|
@@ -17,12 +18,6 @@ const RAND = () => Math.random().toString(36).slice(2, 10)
|
|
|
17
18
|
const ALL = 'All' as const
|
|
18
19
|
const FULL_ACCESS = { create: ALL, read: ALL, update: ALL, delete: ALL }
|
|
19
20
|
|
|
20
|
-
type Check = {
|
|
21
|
-
label: string,
|
|
22
|
-
pass: boolean,
|
|
23
|
-
detail: string,
|
|
24
|
-
}
|
|
25
|
-
|
|
26
21
|
/**
|
|
27
22
|
* Regression test: `adminOnly` custom actions must be enforced at runtime, not merely declared.
|
|
28
23
|
*
|
|
@@ -61,10 +56,13 @@ type Check = {
|
|
|
61
56
|
*
|
|
62
57
|
* RED (pre-fix): the six group-B rows fail — each reaches its handler and returns a non-401.
|
|
63
58
|
* GREEN (post-fix): all six return 401 "Admin access only"; the group-A controls are unchanged.
|
|
59
|
+
*
|
|
60
|
+
* Runs on its own provisioned tenant, which makes the two environment-dependent probes deterministic
|
|
61
|
+
* rather than a function of whoever's local database the shared org came from: a fresh tenant has no
|
|
62
|
+
* Athena integration (so sync-athena is probed) and no twilioSID (so link-twilio, which can create a
|
|
63
|
+
* REAL Twilio subaccount, stays permanently on its skipped-for-safety path).
|
|
64
64
|
*/
|
|
65
|
-
export const
|
|
66
|
-
log_header("schema-declared adminOnly must be enforced on custom actions")
|
|
67
|
-
|
|
65
|
+
export const schema_adminonly_enforcement_checks = async (): Promise<Check[]> => {
|
|
68
66
|
const checks: Check[] = []
|
|
69
67
|
const record = (label: string, pass: boolean, detail: string) => checks.push({ label, pass, detail })
|
|
70
68
|
|
|
@@ -89,11 +87,19 @@ export const schema_adminonly_enforcement_tests = async ({ sdk } : { sdk: Sessio
|
|
|
89
87
|
`${r.status} ${(JSON.stringify(r.body) ?? '').slice(0, 120)}`
|
|
90
88
|
)
|
|
91
89
|
|
|
90
|
+
let tenant: Awaited<ReturnType<typeof setup_isolated_tenant>> | undefined
|
|
92
91
|
let roleId = ''
|
|
93
92
|
let attackerId = ''
|
|
94
93
|
let enduserId = ''
|
|
95
94
|
|
|
96
95
|
try {
|
|
96
|
+
tenant = await setup_isolated_tenant({
|
|
97
|
+
name: `Schema adminOnly enforcement ${RAND()}`,
|
|
98
|
+
users: [{ isAdmin: true }],
|
|
99
|
+
apiKeys: 0,
|
|
100
|
+
})
|
|
101
|
+
const { sdk } = tenant
|
|
102
|
+
|
|
97
103
|
/* ================= fixtures ================= */
|
|
98
104
|
|
|
99
105
|
const role = `f0191-staff-${RAND()}`
|
|
@@ -246,36 +252,35 @@ export const schema_adminonly_enforcement_tests = async ({ sdk } : { sdk: Sessio
|
|
|
246
252
|
`${summarize(r)} (expected a handler response, not 401 Admin access only)`,
|
|
247
253
|
)
|
|
248
254
|
}
|
|
249
|
-
|
|
250
|
-
/* ===== report: print full table first, then assert (harness exits on first failure) ===== */
|
|
251
|
-
console.log('\n check summary:')
|
|
252
|
-
for (const c of checks) {
|
|
253
|
-
console.log(` ${c.pass ? 'PASS' : 'FAIL'} ${c.label} — ${c.detail}`)
|
|
254
|
-
}
|
|
255
|
-
console.log('')
|
|
256
|
-
|
|
257
|
-
for (const c of checks) {
|
|
258
|
-
assert(c.pass, `${c.label} — ${c.detail}`, c.label)
|
|
259
|
-
}
|
|
260
255
|
} finally {
|
|
261
|
-
if (
|
|
262
|
-
|
|
263
|
-
|
|
256
|
+
if (tenant) {
|
|
257
|
+
const { sdk } = tenant
|
|
258
|
+
if (enduserId) { try { await sdk.api.endusers.deleteOne(enduserId) } catch {} }
|
|
259
|
+
if (attackerId) { try { await sdk.api.users.deleteOne(attackerId) } catch {} }
|
|
260
|
+
if (roleId) { try { await sdk.api.role_based_access_permissions.deleteOne(roleId) } catch {} }
|
|
261
|
+
// Teardown BEFORE anything asserts — assert calls process.exit, which would strand this tenant.
|
|
262
|
+
try { await tenant.teardown() } catch (e) { console.error('teardown failed', e) }
|
|
263
|
+
}
|
|
264
264
|
}
|
|
265
|
+
|
|
266
|
+
return checks
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/** Asserting wrapper, for standalone runs. */
|
|
270
|
+
export const schema_adminonly_enforcement_tests = async () => {
|
|
271
|
+
assert_checks('Schema adminOnly enforcement', await schema_adminonly_enforcement_checks())
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/** Enrolls this suite in the auto-discovered parallel pool — see run_discovered_isolated_suites. */
|
|
275
|
+
export const ISOLATED_SUITE: IsolatedSuite = {
|
|
276
|
+
name: 'Schema adminOnly enforcement',
|
|
277
|
+
run: schema_adminonly_enforcement_checks,
|
|
265
278
|
}
|
|
266
279
|
|
|
267
280
|
// Allow running this test file independently
|
|
268
281
|
if (require.main === module) {
|
|
269
282
|
console.log(`🌐 Using API URL: ${host}`)
|
|
270
|
-
|
|
271
|
-
const sdkNonAdmin = new Session({ host })
|
|
272
|
-
|
|
273
|
-
const runTests = async () => {
|
|
274
|
-
await setup_tests(sdk, sdkNonAdmin)
|
|
275
|
-
await schema_adminonly_enforcement_tests({ sdk, sdkNonAdmin })
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
runTests()
|
|
283
|
+
schema_adminonly_enforcement_tests()
|
|
279
284
|
.then(() => {
|
|
280
285
|
console.log("✅ schema adminOnly enforcement test suite completed successfully")
|
|
281
286
|
process.exit(0)
|