@tellescope/sdk 1.248.0 → 1.249.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/.env +3 -0
  2. package/lib/cjs/sdk.d.ts +1 -0
  3. package/lib/cjs/sdk.d.ts.map +1 -1
  4. package/lib/cjs/sdk.js +1 -0
  5. package/lib/cjs/sdk.js.map +1 -1
  6. package/lib/cjs/tests/api_tests/chats_analytics.test.d.ts +6 -0
  7. package/lib/cjs/tests/api_tests/chats_analytics.test.d.ts.map +1 -0
  8. package/lib/cjs/tests/api_tests/chats_analytics.test.js +256 -0
  9. package/lib/cjs/tests/api_tests/chats_analytics.test.js.map +1 -0
  10. package/lib/cjs/tests/api_tests/cross_org_api_key.test.d.ts +6 -0
  11. package/lib/cjs/tests/api_tests/cross_org_api_key.test.d.ts.map +1 -0
  12. package/lib/cjs/tests/api_tests/cross_org_api_key.test.js +748 -0
  13. package/lib/cjs/tests/api_tests/cross_org_api_key.test.js.map +1 -0
  14. package/lib/cjs/tests/api_tests/enduser_session_invalidation.test.d.ts.map +1 -1
  15. package/lib/cjs/tests/api_tests/enduser_session_invalidation.test.js +426 -2
  16. package/lib/cjs/tests/api_tests/enduser_session_invalidation.test.js.map +1 -1
  17. package/lib/cjs/tests/api_tests/eom_billing_codes.test.d.ts +6 -0
  18. package/lib/cjs/tests/api_tests/eom_billing_codes.test.d.ts.map +1 -0
  19. package/lib/cjs/tests/api_tests/eom_billing_codes.test.js +162 -0
  20. package/lib/cjs/tests/api_tests/eom_billing_codes.test.js.map +1 -0
  21. package/lib/cjs/tests/api_tests/eom_procedure_codes.test.d.ts +6 -0
  22. package/lib/cjs/tests/api_tests/eom_procedure_codes.test.d.ts.map +1 -0
  23. package/lib/cjs/tests/api_tests/eom_procedure_codes.test.js +339 -0
  24. package/lib/cjs/tests/api_tests/eom_procedure_codes.test.js.map +1 -0
  25. package/lib/cjs/tests/api_tests/managed_content_file_access.test.d.ts +13 -0
  26. package/lib/cjs/tests/api_tests/managed_content_file_access.test.d.ts.map +1 -0
  27. package/lib/cjs/tests/api_tests/managed_content_file_access.test.js +385 -0
  28. package/lib/cjs/tests/api_tests/managed_content_file_access.test.js.map +1 -0
  29. package/lib/cjs/tests/api_tests/organization_settings_duplicates.test.d.ts.map +1 -1
  30. package/lib/cjs/tests/api_tests/organization_settings_duplicates.test.js +25 -2
  31. package/lib/cjs/tests/api_tests/organization_settings_duplicates.test.js.map +1 -1
  32. package/lib/cjs/tests/tests.d.ts.map +1 -1
  33. package/lib/cjs/tests/tests.js +148 -132
  34. package/lib/cjs/tests/tests.js.map +1 -1
  35. package/lib/esm/sdk.d.ts +3 -2
  36. package/lib/esm/sdk.d.ts.map +1 -1
  37. package/lib/esm/sdk.js +1 -0
  38. package/lib/esm/sdk.js.map +1 -1
  39. package/lib/esm/session.d.ts +1 -0
  40. package/lib/esm/session.d.ts.map +1 -1
  41. package/lib/esm/tests/api_tests/chats_analytics.test.d.ts +6 -0
  42. package/lib/esm/tests/api_tests/chats_analytics.test.d.ts.map +1 -0
  43. package/lib/esm/tests/api_tests/chats_analytics.test.js +252 -0
  44. package/lib/esm/tests/api_tests/chats_analytics.test.js.map +1 -0
  45. package/lib/esm/tests/api_tests/cross_org_api_key.test.d.ts +6 -0
  46. package/lib/esm/tests/api_tests/cross_org_api_key.test.d.ts.map +1 -0
  47. package/lib/esm/tests/api_tests/cross_org_api_key.test.js +744 -0
  48. package/lib/esm/tests/api_tests/cross_org_api_key.test.js.map +1 -0
  49. package/lib/esm/tests/api_tests/enduser_session_invalidation.test.d.ts.map +1 -1
  50. package/lib/esm/tests/api_tests/enduser_session_invalidation.test.js +426 -2
  51. package/lib/esm/tests/api_tests/enduser_session_invalidation.test.js.map +1 -1
  52. package/lib/esm/tests/api_tests/eom_billing_codes.test.d.ts +6 -0
  53. package/lib/esm/tests/api_tests/eom_billing_codes.test.d.ts.map +1 -0
  54. package/lib/esm/tests/api_tests/eom_billing_codes.test.js +158 -0
  55. package/lib/esm/tests/api_tests/eom_billing_codes.test.js.map +1 -0
  56. package/lib/esm/tests/api_tests/eom_procedure_codes.test.d.ts +6 -0
  57. package/lib/esm/tests/api_tests/eom_procedure_codes.test.d.ts.map +1 -0
  58. package/lib/esm/tests/api_tests/eom_procedure_codes.test.js +335 -0
  59. package/lib/esm/tests/api_tests/eom_procedure_codes.test.js.map +1 -0
  60. package/lib/esm/tests/api_tests/managed_content_file_access.test.d.ts +13 -0
  61. package/lib/esm/tests/api_tests/managed_content_file_access.test.d.ts.map +1 -0
  62. package/lib/esm/tests/api_tests/managed_content_file_access.test.js +358 -0
  63. package/lib/esm/tests/api_tests/managed_content_file_access.test.js.map +1 -0
  64. package/lib/esm/tests/api_tests/organization_settings_duplicates.test.d.ts.map +1 -1
  65. package/lib/esm/tests/api_tests/organization_settings_duplicates.test.js +25 -2
  66. package/lib/esm/tests/api_tests/organization_settings_duplicates.test.js.map +1 -1
  67. package/lib/esm/tests/tests.d.ts.map +1 -1
  68. package/lib/esm/tests/tests.js +148 -132
  69. package/lib/esm/tests/tests.js.map +1 -1
  70. package/lib/tsconfig.tsbuildinfo +1 -1
  71. package/package.json +10 -10
  72. package/src/sdk.ts +4 -0
  73. package/src/tests/api_tests/chats_analytics.test.ts +182 -0
  74. package/src/tests/api_tests/cross_org_api_key.test.ts +665 -0
  75. package/src/tests/api_tests/enduser_session_invalidation.test.ts +223 -0
  76. package/src/tests/api_tests/eom_procedure_codes.test.ts +296 -0
  77. package/src/tests/api_tests/managed_content_file_access.test.ts +214 -0
  78. package/src/tests/api_tests/organization_settings_duplicates.test.ts +14 -0
  79. package/src/tests/tests.ts +10 -2
  80. package/test_generated.pdf +0 -0
@@ -0,0 +1,214 @@
1
+ require('source-map-support').install();
2
+
3
+ import * as buffer from 'buffer'
4
+ import { Session, EnduserSession } from "../../sdk"
5
+ import {
6
+ async_test,
7
+ log_header,
8
+ } from "@tellescope/testing"
9
+ import { setup_tests } from "../setup"
10
+
11
+ const host = process.env.API_URL || 'http://localhost:8080' as const
12
+ const businessId = '60398b1131a295e64f084ff6'
13
+
14
+ /**
15
+ * Tests for file_download_URL enduser access via managed content fallback.
16
+ *
17
+ * Verifies the backend fallback logic that allows endusers to access files
18
+ * attached to managed content records they have access to, even when the
19
+ * file itself does not have enduserId set or publicRead: true.
20
+ */
21
+ export const managed_content_file_access_tests = async ({ sdk, sdkNonAdmin }: { sdk: Session, sdkNonAdmin: Session }) => {
22
+ log_header("Managed Content File Access Tests")
23
+
24
+ const contentRecordIds: string[] = []
25
+ const assignmentIds: string[] = []
26
+ const fileIds: string[] = []
27
+ let testEnduserId: string | undefined
28
+ let otherEnduserId: string | undefined
29
+ let enduserSDK: EnduserSession | undefined
30
+ let otherEnduserSDK: EnduserSession | undefined
31
+
32
+ const uploadFile = async (
33
+ name: string,
34
+ opts: { enduserId?: string, publicRead?: boolean } = {}
35
+ ) => {
36
+ const buff = buffer.Buffer.from(`test file content for ${name}`)
37
+ const { presignedUpload, file } = await sdk.api.files.prepare_file_upload({
38
+ name,
39
+ type: 'text/plain',
40
+ size: buff.byteLength,
41
+ ...opts,
42
+ })
43
+ await sdk.UPLOAD(presignedUpload as any, buff)
44
+ await sdk.api.files.confirm_file_upload({ id: file.id })
45
+ fileIds.push(file.id)
46
+ return file
47
+ }
48
+
49
+ try {
50
+ console.log("Setting up test data...")
51
+
52
+ const testEnduser = await sdk.api.endusers.createOne({
53
+ email: `mcr_file_access_test_${Date.now()}@test.tellescope.com`,
54
+ })
55
+ testEnduserId = testEnduser.id
56
+ await sdk.api.endusers.set_password({ id: testEnduser.id, password: 'TestPassword123!' })
57
+
58
+ const otherEnduser = await sdk.api.endusers.createOne({
59
+ email: `mcr_file_access_other_${Date.now()}@test.tellescope.com`,
60
+ })
61
+ otherEnduserId = otherEnduser.id
62
+ await sdk.api.endusers.set_password({ id: otherEnduser.id, password: 'TestPassword123!' })
63
+
64
+ enduserSDK = new EnduserSession({ host, businessId })
65
+ await enduserSDK.authenticate(testEnduser.email!, 'TestPassword123!')
66
+
67
+ otherEnduserSDK = new EnduserSession({ host, businessId })
68
+ await otherEnduserSDK.authenticate(otherEnduser.email!, 'TestPassword123!')
69
+
70
+ // ===== Test 1: File attached to assignmentType: 'All' content - enduser CAN access =====
71
+ const fileForAll = await uploadFile('mcr-file-all.txt')
72
+ const contentAll = await sdk.api.managed_content_records.createOne({
73
+ title: 'MCR File Access - All',
74
+ htmlContent: '<p>All</p>',
75
+ textContent: 'All',
76
+ assignmentType: 'All',
77
+ attachments: [{ secureName: fileForAll.secureName, type: 'file', name: fileForAll.name }],
78
+ })
79
+ contentRecordIds.push(contentAll.id)
80
+
81
+ await async_test(
82
+ 'staff-uploaded file in assignmentType:All content - enduser CAN access',
83
+ async () => {
84
+ const result = await enduserSDK!.api.files.file_download_URL({ secureName: fileForAll.secureName })
85
+ return !!result?.downloadURL
86
+ },
87
+ { onResult: (r) => r === true }
88
+ )
89
+
90
+ // ===== Test 2: File attached to Individual content for enduser A - enduser B CANNOT access =====
91
+ const fileForIndividual = await uploadFile('mcr-file-individual.txt')
92
+ const contentIndividual = await sdk.api.managed_content_records.createOne({
93
+ title: 'MCR File Access - Individual',
94
+ htmlContent: '<p>Individual</p>',
95
+ textContent: 'Individual',
96
+ enduserId: testEnduser.id,
97
+ attachments: [{ secureName: fileForIndividual.secureName, type: 'file', name: fileForIndividual.name }],
98
+ })
99
+ contentRecordIds.push(contentIndividual.id)
100
+
101
+ await async_test(
102
+ 'file attached to Individual content - assigned enduser CAN access',
103
+ async () => {
104
+ const result = await enduserSDK!.api.files.file_download_URL({ secureName: fileForIndividual.secureName })
105
+ return !!result?.downloadURL
106
+ },
107
+ { onResult: (r) => r === true }
108
+ )
109
+
110
+ await async_test(
111
+ 'file attached to Individual content - unassigned enduser CANNOT access',
112
+ async () => {
113
+ try {
114
+ await otherEnduserSDK!.api.files.file_download_URL({ secureName: fileForIndividual.secureName })
115
+ return false
116
+ } catch (err) {
117
+ return true
118
+ }
119
+ },
120
+ { onResult: (r) => r === true }
121
+ )
122
+
123
+ // ===== Test 3: File not attached to any managed content - enduser CANNOT access =====
124
+ const fileNoContent = await uploadFile('mcr-file-no-content.txt')
125
+
126
+ await async_test(
127
+ 'file not attached to any managed content - enduser CANNOT access',
128
+ async () => {
129
+ try {
130
+ await enduserSDK!.api.files.file_download_URL({ secureName: fileNoContent.secureName })
131
+ return false
132
+ } catch (err) {
133
+ return true
134
+ }
135
+ },
136
+ { onResult: (r) => r === true }
137
+ )
138
+
139
+ // ===== Test 4: File with enduserId set - existing behavior preserved =====
140
+ const fileWithEnduser = await uploadFile('mcr-file-with-enduser.txt', { enduserId: testEnduser.id })
141
+
142
+ await async_test(
143
+ 'file with enduserId set - enduser CAN access (no fallback needed)',
144
+ async () => {
145
+ const result = await enduserSDK!.api.files.file_download_URL({ secureName: fileWithEnduser.secureName })
146
+ return !!result?.downloadURL
147
+ },
148
+ { onResult: (r) => r === true }
149
+ )
150
+
151
+ // ===== Test 5: File with publicRead: true - existing behavior preserved =====
152
+ const filePublic = await uploadFile('mcr-file-public.txt', { publicRead: true })
153
+
154
+ await async_test(
155
+ 'file with publicRead - enduser CAN access',
156
+ async () => {
157
+ const result = await enduserSDK!.api.files.file_download_URL({ secureName: filePublic.secureName })
158
+ return !!result?.downloadURL
159
+ },
160
+ { onResult: (r) => r === true }
161
+ )
162
+
163
+ console.log("All Managed Content File Access tests passed!")
164
+
165
+ } finally {
166
+ console.log("Cleaning up test data...")
167
+
168
+ try {
169
+ for (const assignmentId of assignmentIds) {
170
+ await sdk.api.managed_content_record_assignments.deleteOne(assignmentId).catch(() => {})
171
+ }
172
+
173
+ for (const recordId of contentRecordIds) {
174
+ await sdk.api.managed_content_records.deleteOne(recordId).catch(() => {})
175
+ }
176
+
177
+ for (const fileId of fileIds) {
178
+ await sdk.api.files.deleteOne(fileId).catch(() => {})
179
+ }
180
+
181
+ if (testEnduserId) {
182
+ await sdk.api.endusers.deleteOne(testEnduserId).catch(() => {})
183
+ }
184
+ if (otherEnduserId) {
185
+ await sdk.api.endusers.deleteOne(otherEnduserId).catch(() => {})
186
+ }
187
+
188
+ console.log("Cleanup completed")
189
+ } catch (error) {
190
+ console.error('Cleanup error:', error)
191
+ }
192
+ }
193
+ }
194
+
195
+ if (require.main === module) {
196
+ console.log(`Using API URL: ${host}`)
197
+ const sdk = new Session({ host })
198
+ const sdkNonAdmin = new Session({ host })
199
+
200
+ const runTests = async () => {
201
+ await setup_tests(sdk, sdkNonAdmin)
202
+ await managed_content_file_access_tests({ sdk, sdkNonAdmin })
203
+ }
204
+
205
+ runTests()
206
+ .then(() => {
207
+ console.log("Managed content file access test suite completed successfully")
208
+ process.exit(0)
209
+ })
210
+ .catch((error) => {
211
+ console.error("Managed content file access test suite failed:", error)
212
+ process.exit(1)
213
+ })
214
+ }
@@ -176,6 +176,20 @@ export const organization_settings_duplicates_tests = async ({ sdk, sdkNonAdmin
176
176
  },
177
177
  }
178
178
  }, { replaceObjectFields: true })
179
+
180
+ // === D. subdomain is readonly ===
181
+ const orgBefore = await sdk.api.organizations.getOne(orgId)
182
+ await async_test(
183
+ "subdomain field is readonly — update does not change persisted value",
184
+ async () => {
185
+ await sdk.api.organizations.updateOne(orgId, {
186
+ subdomain: `readonly-attempt-${Date.now()}`,
187
+ } as any).catch(() => undefined) // tolerate either silent-drop or unknown-field rejection
188
+ const orgAfter = await sdk.api.organizations.getOne(orgId)
189
+ return orgAfter.subdomain === orgBefore.subdomain
190
+ },
191
+ { onResult: (unchanged: boolean) => unchanged === true }
192
+ )
179
193
  }
180
194
 
181
195
  // Allow running this test file independently
@@ -74,16 +74,20 @@ import {
74
74
 
75
75
  import fs from "fs"
76
76
  import { load_inbox_data_tests } from "./api_tests/load_inbox_data.test";
77
+ import { eom_procedure_codes_tests } from "./api_tests/eom_procedure_codes.test";
78
+ import { cross_org_api_key_tests } from "./api_tests/cross_org_api_key.test";
77
79
  import { custom_dashboards_tests } from "./api_tests/custom_dashboards.test";
78
80
  import { message_assignment_trigger_tests } from "./api_tests/message_assignment_trigger.test";
79
81
  import { time_tracks_tests, time_tracks_historical_tests, time_tracks_correction_tests, time_tracks_review_tests, time_tracks_lock_tests, time_tracks_edge_case_tests } from "./api_tests/time_tracks.test";
80
82
  import { monthly_availability_restrictions_tests } from "./api_tests/monthly_availability_restrictions.test";
81
83
  import { calendar_event_limits_tests } from "./api_tests/calendar_event_limits.test";
82
84
  import { custom_aggregation_tests } from "./api_tests/custom_aggregation.test";
85
+ import { chats_analytics_tests } from "./api_tests/chats_analytics.test";
83
86
  import { no_access_permission_checks_tests } from "./api_tests/no_access_permission_checks.test";
84
87
  import { field_redaction_tests } from "./api_tests/field_redaction.test";
85
88
  import { bulk_assignment_tests } from "./api_tests/bulk_assignment.test";
86
89
  import { managed_content_enduser_access_tests } from "./api_tests/managed_content_enduser_access.test";
90
+ import { managed_content_file_access_tests } from "./api_tests/managed_content_file_access.test";
87
91
  import { auto_merge_form_submission_tests } from "./api_tests/auto_merge_form_submission.test";
88
92
  import { database_cascade_delete_tests } from "./api_tests/database_cascade_delete.test";
89
93
  import { ai_conversations_tests } from "./api_tests/ai_conversations.test";
@@ -14201,6 +14205,11 @@ const ip_address_form_tests = async () => {
14201
14205
  await replace_enduser_template_values_tests()
14202
14206
  await mfa_tests()
14203
14207
  await setup_tests(sdk, sdkNonAdmin)
14208
+ await eom_procedure_codes_tests({ sdk, sdkNonAdmin })
14209
+ await cross_org_api_key_tests({ sdk, sdkNonAdmin })
14210
+ await organization_settings_duplicates_tests({ sdk, sdkNonAdmin })
14211
+ await enduser_session_invalidation_tests({ sdk, sdkNonAdmin })
14212
+ await chats_analytics_tests({ sdk, sdkNonAdmin })
14204
14213
  await field_redaction_tests({ sdk, sdkNonAdmin })
14205
14214
  await form_submitted_trigger_tests({ sdk, sdkNonAdmin })
14206
14215
  await date_string_validation_tests({ sdk, sdkNonAdmin })
@@ -14208,7 +14217,6 @@ const ip_address_form_tests = async () => {
14208
14217
  await automation_trigger_tests()
14209
14218
  await integrations_redacted_tests({ sdk, sdkNonAdmin })
14210
14219
  await mdb_sort_tests({ sdk, sdkNonAdmin })
14211
- await organization_settings_duplicates_tests({ sdk, sdkNonAdmin })
14212
14220
  await search_tests()
14213
14221
  await time_tracks_tests({ sdk, sdkNonAdmin })
14214
14222
  await time_tracks_historical_tests({ sdk, sdkNonAdmin })
@@ -14235,6 +14243,7 @@ const ip_address_form_tests = async () => {
14235
14243
  await beluga_pharmacy_mappings_tests({ sdk, sdkNonAdmin })
14236
14244
  await threadKeyTests()
14237
14245
  await managed_content_enduser_access_tests({ sdk, sdkNonAdmin })
14246
+ await managed_content_file_access_tests({ sdk, sdkNonAdmin })
14238
14247
  await afteraction_day_of_month_delay_tests({ sdk, sdkNonAdmin })
14239
14248
  await bulk_assignment_tests({ sdk, sdkNonAdmin })
14240
14249
  await formsort_tests()
@@ -14247,7 +14256,6 @@ const ip_address_form_tests = async () => {
14247
14256
  await inbox_threads_loading_tests()
14248
14257
  await load_inbox_data_tests({ sdk, sdkNonAdmin })
14249
14258
  await enduser_observations_acknowledge_tests({ sdk, sdkNonAdmin })
14250
- await enduser_session_invalidation_tests({ sdk, sdkNonAdmin })
14251
14259
  await create_user_notifications_trigger_tests({ sdk })
14252
14260
  await group_mms_active_tests()
14253
14261
  await auto_reply_tests()
Binary file