@tellescope/sdk 1.246.2 → 1.248.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 (83) hide show
  1. package/lib/cjs/sdk.d.ts +7 -1
  2. package/lib/cjs/sdk.d.ts.map +1 -1
  3. package/lib/cjs/sdk.js +2 -0
  4. package/lib/cjs/sdk.js.map +1 -1
  5. package/lib/cjs/tests/api_tests/date_string_validation.test.d.ts +6 -0
  6. package/lib/cjs/tests/api_tests/date_string_validation.test.d.ts.map +1 -0
  7. package/lib/cjs/tests/api_tests/date_string_validation.test.js +142 -0
  8. package/lib/cjs/tests/api_tests/date_string_validation.test.js.map +1 -0
  9. package/lib/cjs/tests/api_tests/enduser_session_invalidation.test.d.ts +6 -0
  10. package/lib/cjs/tests/api_tests/enduser_session_invalidation.test.d.ts.map +1 -0
  11. package/lib/cjs/tests/api_tests/enduser_session_invalidation.test.js +243 -0
  12. package/lib/cjs/tests/api_tests/enduser_session_invalidation.test.js.map +1 -0
  13. package/lib/cjs/tests/api_tests/field_redaction.test.d.ts +13 -0
  14. package/lib/cjs/tests/api_tests/field_redaction.test.d.ts.map +1 -0
  15. package/lib/cjs/tests/api_tests/field_redaction.test.js +818 -0
  16. package/lib/cjs/tests/api_tests/field_redaction.test.js.map +1 -0
  17. package/lib/cjs/tests/api_tests/form_submitted_trigger.test.d.ts +6 -0
  18. package/lib/cjs/tests/api_tests/form_submitted_trigger.test.d.ts.map +1 -0
  19. package/lib/cjs/tests/api_tests/form_submitted_trigger.test.js +429 -0
  20. package/lib/cjs/tests/api_tests/form_submitted_trigger.test.js.map +1 -0
  21. package/lib/cjs/tests/api_tests/integrations_redacted.test.d.ts +6 -0
  22. package/lib/cjs/tests/api_tests/integrations_redacted.test.d.ts.map +1 -0
  23. package/lib/cjs/tests/api_tests/integrations_redacted.test.js +273 -0
  24. package/lib/cjs/tests/api_tests/integrations_redacted.test.js.map +1 -0
  25. package/lib/cjs/tests/api_tests/mdb_sort.test.d.ts +6 -0
  26. package/lib/cjs/tests/api_tests/mdb_sort.test.d.ts.map +1 -0
  27. package/lib/cjs/tests/api_tests/mdb_sort.test.js +370 -0
  28. package/lib/cjs/tests/api_tests/mdb_sort.test.js.map +1 -0
  29. package/lib/cjs/tests/api_tests/openloop_webhooks.test.d.ts.map +1 -1
  30. package/lib/cjs/tests/api_tests/openloop_webhooks.test.js +108 -24
  31. package/lib/cjs/tests/api_tests/openloop_webhooks.test.js.map +1 -1
  32. package/lib/cjs/tests/tests.d.ts.map +1 -1
  33. package/lib/cjs/tests/tests.js +303 -180
  34. package/lib/cjs/tests/tests.js.map +1 -1
  35. package/lib/esm/sdk.d.ts +7 -1
  36. package/lib/esm/sdk.d.ts.map +1 -1
  37. package/lib/esm/sdk.js +2 -0
  38. package/lib/esm/sdk.js.map +1 -1
  39. package/lib/esm/tests/api_tests/date_string_validation.test.d.ts +6 -0
  40. package/lib/esm/tests/api_tests/date_string_validation.test.d.ts.map +1 -0
  41. package/lib/esm/tests/api_tests/date_string_validation.test.js +138 -0
  42. package/lib/esm/tests/api_tests/date_string_validation.test.js.map +1 -0
  43. package/lib/esm/tests/api_tests/enduser_session_invalidation.test.d.ts +6 -0
  44. package/lib/esm/tests/api_tests/enduser_session_invalidation.test.d.ts.map +1 -0
  45. package/lib/esm/tests/api_tests/enduser_session_invalidation.test.js +239 -0
  46. package/lib/esm/tests/api_tests/enduser_session_invalidation.test.js.map +1 -0
  47. package/lib/esm/tests/api_tests/field_redaction.test.d.ts +13 -0
  48. package/lib/esm/tests/api_tests/field_redaction.test.d.ts.map +1 -0
  49. package/lib/esm/tests/api_tests/field_redaction.test.js +814 -0
  50. package/lib/esm/tests/api_tests/field_redaction.test.js.map +1 -0
  51. package/lib/esm/tests/api_tests/form_submitted_trigger.test.d.ts +6 -0
  52. package/lib/esm/tests/api_tests/form_submitted_trigger.test.d.ts.map +1 -0
  53. package/lib/esm/tests/api_tests/form_submitted_trigger.test.js +425 -0
  54. package/lib/esm/tests/api_tests/form_submitted_trigger.test.js.map +1 -0
  55. package/lib/esm/tests/api_tests/integrations_redacted.test.d.ts +6 -0
  56. package/lib/esm/tests/api_tests/integrations_redacted.test.d.ts.map +1 -0
  57. package/lib/esm/tests/api_tests/integrations_redacted.test.js +269 -0
  58. package/lib/esm/tests/api_tests/integrations_redacted.test.js.map +1 -0
  59. package/lib/esm/tests/api_tests/mdb_sort.test.d.ts +6 -0
  60. package/lib/esm/tests/api_tests/mdb_sort.test.d.ts.map +1 -0
  61. package/lib/esm/tests/api_tests/mdb_sort.test.js +366 -0
  62. package/lib/esm/tests/api_tests/mdb_sort.test.js.map +1 -0
  63. package/lib/esm/tests/api_tests/openloop_webhooks.test.d.ts.map +1 -1
  64. package/lib/esm/tests/api_tests/openloop_webhooks.test.js +108 -24
  65. package/lib/esm/tests/api_tests/openloop_webhooks.test.js.map +1 -1
  66. package/lib/esm/tests/tests.d.ts.map +1 -1
  67. package/lib/esm/tests/tests.js +303 -180
  68. package/lib/esm/tests/tests.js.map +1 -1
  69. package/lib/tsconfig.tsbuildinfo +1 -1
  70. package/package.json +10 -10
  71. package/src/sdk.ts +11 -0
  72. package/src/tests/api_tests/calendar_events_bulk_update.test.ts +418 -0
  73. package/src/tests/api_tests/date_string_validation.test.ts +107 -0
  74. package/src/tests/api_tests/enduser_session_invalidation.test.ts +138 -0
  75. package/src/tests/api_tests/field_redaction.test.ts +669 -0
  76. package/src/tests/api_tests/form_started_trigger.test.ts +1 -1
  77. package/src/tests/api_tests/form_submitted_trigger.test.ts +281 -0
  78. package/src/tests/api_tests/integrations_redacted.test.ts +245 -0
  79. package/src/tests/api_tests/mdb_sort.test.ts +259 -0
  80. package/src/tests/api_tests/openloop_webhooks.test.ts +64 -0
  81. package/src/tests/api_tests/organization_settings_duplicates.test.ts +201 -0
  82. package/src/tests/tests.ts +92 -6
  83. package/test_generated.pdf +0 -0
@@ -0,0 +1,818 @@
1
+ "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
13
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
14
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
15
+ return new (P || (P = Promise))(function (resolve, reject) {
16
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
17
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
18
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
19
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
20
+ });
21
+ };
22
+ var __generator = (this && this.__generator) || function (thisArg, body) {
23
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
24
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
25
+ function verb(n) { return function (v) { return step([n, v]); }; }
26
+ function step(op) {
27
+ if (f) throw new TypeError("Generator is already executing.");
28
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
29
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
30
+ if (y = 0, t) op = [op[0] & 2, t.value];
31
+ switch (op[0]) {
32
+ case 0: case 1: t = op; break;
33
+ case 4: _.label++; return { value: op[1], done: false };
34
+ case 5: _.label++; y = op[1]; op = [0]; continue;
35
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
36
+ default:
37
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
38
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
39
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
40
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
41
+ if (t[2]) _.ops.pop();
42
+ _.trys.pop(); continue;
43
+ }
44
+ op = body.call(thisArg, _);
45
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
46
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
47
+ }
48
+ };
49
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
50
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
51
+ if (ar || !(i in from)) {
52
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
53
+ ar[i] = from[i];
54
+ }
55
+ }
56
+ return to.concat(ar || Array.prototype.slice.call(from));
57
+ };
58
+ Object.defineProperty(exports, "__esModule", { value: true });
59
+ exports.field_redaction_tests = void 0;
60
+ require('source-map-support').install();
61
+ var sdk_1 = require("../../sdk");
62
+ var testing_1 = require("@tellescope/testing");
63
+ var setup_1 = require("../setup");
64
+ var constants_1 = require("@tellescope/constants");
65
+ var host = process.env.API_URL || 'http://localhost:8080';
66
+ var _a = [process.env.NON_ADMIN_EMAIL, process.env.NON_ADMIN_PASSWORD], nonAdminEmail = _a[0], nonAdminPassword = _a[1];
67
+ var RECORDING_FIELDS = ['recordingURI', 'recordingId', 'recordingDurationInSeconds'];
68
+ var ALL_REDACTABLE_FIELDS = __spreadArray(__spreadArray([], RECORDING_FIELDS, true), ['transcription', 'recordingTranscriptionData', 'aiSummary'], false);
69
+ var hasFields = function (record, fields) {
70
+ return fields.every(function (f) { return f in record && record[f] !== undefined; });
71
+ };
72
+ var lacksFields = function (record, fields) {
73
+ return fields.every(function (f) { return !(f in record) || record[f] === undefined; });
74
+ };
75
+ /**
76
+ * Tests for role-based field redactions on phone_calls.
77
+ *
78
+ * Verifies that fieldRedactions configured on a RoleBasedAccessPermission
79
+ * properly hide specified fields from API responses across all read paths
80
+ * (getOne, getSome) and write responses (updateOne).
81
+ */
82
+ var field_redaction_tests = function (_a) {
83
+ var sdk = _a.sdk, sdkNonAdmin = _a.sdkNonAdmin;
84
+ return __awaiter(void 0, void 0, void 0, function () {
85
+ var testEnduser, testPhoneCall, FULL_ACCESS, fullRedactionRole, rbapFull, originalRoles, partialRedactionRole, rbapPartial, createdPhoneCallId_1, e_1, adminCreatedPhoneCallId_1, e_2, noRedactionRole, rbapNoRedaction, syncFrom_1, e_3, e_4, e_5;
86
+ return __generator(this, function (_b) {
87
+ switch (_b.label) {
88
+ case 0:
89
+ (0, testing_1.log_header)("Field Redaction Tests");
90
+ return [4 /*yield*/, sdk.api.endusers.createOne({
91
+ fname: 'FieldRedactionTest',
92
+ lname: 'User',
93
+ email: 'field-redaction-test@example.com',
94
+ })];
95
+ case 1:
96
+ testEnduser = _b.sent();
97
+ return [4 /*yield*/, sdk.api.phone_calls.createOne({
98
+ enduserId: testEnduser.id,
99
+ inbound: true,
100
+ from: '+15551234567',
101
+ to: '+15559876543',
102
+ isVoicemail: true,
103
+ recordingURI: 'https://example.com/recording.wav',
104
+ recordingId: 'rec_test_123',
105
+ recordingDurationInSeconds: 45,
106
+ transcription: 'Hello, this is a voicemail transcription.',
107
+ recordingTranscriptionData: '{"results":{"transcripts":[{"transcript":"full call transcription data"}]}}',
108
+ aiSummary: 'Patient called about prescription refill.',
109
+ })
110
+ // Create role with full field redactions for phone_calls
111
+ ];
112
+ case 2:
113
+ testPhoneCall = _b.sent();
114
+ FULL_ACCESS = { create: 'All', read: 'All', update: 'All', delete: 'All' };
115
+ fullRedactionRole = 'full-redaction-test-role';
116
+ return [4 /*yield*/, sdk.api.role_based_access_permissions.createOne({
117
+ role: fullRedactionRole,
118
+ permissions: __assign(__assign({}, constants_1.PROVIDER_PERMISSIONS), { phone_calls: FULL_ACCESS, endusers: FULL_ACCESS }),
119
+ fieldRedactions: {
120
+ phone_calls: __spreadArray([], ALL_REDACTABLE_FIELDS, true),
121
+ },
122
+ })];
123
+ case 3:
124
+ rbapFull = _b.sent();
125
+ originalRoles = sdkNonAdmin.userInfo.roles;
126
+ _b.label = 4;
127
+ case 4:
128
+ _b.trys.push([4, , 57, 71]);
129
+ // Assign full-redaction role to non-admin
130
+ return [4 /*yield*/, sdk.api.users.updateOne(sdkNonAdmin.userInfo.id, { roles: [fullRedactionRole] }, { replaceObjectFields: true })];
131
+ case 5:
132
+ // Assign full-redaction role to non-admin
133
+ _b.sent();
134
+ return [4 /*yield*/, (0, testing_1.wait)(undefined, 1500)];
135
+ case 6:
136
+ _b.sent();
137
+ return [4 /*yield*/, sdkNonAdmin.authenticate(nonAdminEmail, nonAdminPassword)
138
+ // ========================================
139
+ // Test 1: Full redaction on getOne
140
+ // ========================================
141
+ ];
142
+ case 7:
143
+ _b.sent();
144
+ // ========================================
145
+ // Test 1: Full redaction on getOne
146
+ // ========================================
147
+ (0, testing_1.log_header)("Test 1: Full redaction on getOne");
148
+ return [4 /*yield*/, (0, testing_1.async_test)("getOne - all redactable fields should be absent for redacted role", function () { return sdkNonAdmin.api.phone_calls.getOne(testPhoneCall.id); }, {
149
+ onResult: function (r) {
150
+ var redacted = lacksFields(r, __spreadArray([], ALL_REDACTABLE_FIELDS, true));
151
+ var corePresent = hasFields(r, ['enduserId', 'inbound', 'from', 'to']);
152
+ if (!redacted) {
153
+ var leaked = ALL_REDACTABLE_FIELDS.filter(function (f) { return f in r && r[f] !== undefined; });
154
+ console.log(" \u274C VULNERABILITY: getOne leaked redacted fields: ".concat(leaked.join(', ')));
155
+ }
156
+ else {
157
+ console.log(" ✅ SAFE: all redactable fields properly redacted on getOne");
158
+ }
159
+ if (!corePresent) {
160
+ console.log(" ❌ ERROR: core fields (enduserId, inbound, from, to) are missing");
161
+ }
162
+ return redacted && corePresent;
163
+ }
164
+ })
165
+ // ========================================
166
+ // Test 2: Admin sees all fields
167
+ // ========================================
168
+ ];
169
+ case 8:
170
+ _b.sent();
171
+ // ========================================
172
+ // Test 2: Admin sees all fields
173
+ // ========================================
174
+ (0, testing_1.log_header)("Test 2: Admin sees all fields");
175
+ return [4 /*yield*/, (0, testing_1.async_test)("getOne (admin) - all fields should be visible", function () { return sdk.api.phone_calls.getOne(testPhoneCall.id); }, {
176
+ onResult: function (r) {
177
+ var allPresent = hasFields(r, __spreadArray([], ALL_REDACTABLE_FIELDS, true));
178
+ if (!allPresent) {
179
+ var missing = ALL_REDACTABLE_FIELDS.filter(function (f) { return !(f in r) || r[f] === undefined; });
180
+ console.log(" \u274C ERROR: admin is missing fields: ".concat(missing.join(', ')));
181
+ }
182
+ else {
183
+ console.log(" ✅ Admin can see all fields");
184
+ }
185
+ return allPresent;
186
+ }
187
+ })
188
+ // ========================================
189
+ // Test 3: Partial redaction (recordings only)
190
+ // ========================================
191
+ ];
192
+ case 9:
193
+ _b.sent();
194
+ // ========================================
195
+ // Test 3: Partial redaction (recordings only)
196
+ // ========================================
197
+ (0, testing_1.log_header)("Test 3: Partial redaction (recordings only)");
198
+ partialRedactionRole = 'partial-redaction-test-role';
199
+ return [4 /*yield*/, sdk.api.role_based_access_permissions.createOne({
200
+ role: partialRedactionRole,
201
+ permissions: __assign(__assign({}, constants_1.PROVIDER_PERMISSIONS), { phone_calls: FULL_ACCESS, endusers: FULL_ACCESS }),
202
+ fieldRedactions: {
203
+ phone_calls: __spreadArray([], RECORDING_FIELDS, true),
204
+ },
205
+ })];
206
+ case 10:
207
+ rbapPartial = _b.sent();
208
+ _b.label = 11;
209
+ case 11:
210
+ _b.trys.push([11, , 16, 21]);
211
+ return [4 /*yield*/, sdk.api.users.updateOne(sdkNonAdmin.userInfo.id, { roles: [partialRedactionRole] }, { replaceObjectFields: true })];
212
+ case 12:
213
+ _b.sent();
214
+ return [4 /*yield*/, (0, testing_1.wait)(undefined, 1500)];
215
+ case 13:
216
+ _b.sent();
217
+ return [4 /*yield*/, sdkNonAdmin.authenticate(nonAdminEmail, nonAdminPassword)];
218
+ case 14:
219
+ _b.sent();
220
+ return [4 /*yield*/, (0, testing_1.async_test)("getOne - only recording fields should be redacted, transcription/summary visible", function () { return sdkNonAdmin.api.phone_calls.getOne(testPhoneCall.id); }, {
221
+ onResult: function (r) {
222
+ var recordingRedacted = lacksFields(r, __spreadArray([], RECORDING_FIELDS, true));
223
+ var nonRecordingPresent = hasFields(r, ['transcription', 'recordingTranscriptionData', 'aiSummary']);
224
+ if (!recordingRedacted) {
225
+ var leaked = RECORDING_FIELDS.filter(function (f) { return f in r && r[f] !== undefined; });
226
+ console.log(" \u274C VULNERABILITY: recording fields leaked: ".concat(leaked.join(', ')));
227
+ }
228
+ if (!nonRecordingPresent) {
229
+ var missing = ['transcription', 'recordingTranscriptionData', 'aiSummary'].filter(function (f) { return !(f in r) || r[f] === undefined; });
230
+ console.log(" \u274C ERROR: non-redacted fields missing: ".concat(missing.join(', ')));
231
+ }
232
+ if (recordingRedacted && nonRecordingPresent) {
233
+ console.log(" ✅ SAFE: partial redaction works correctly");
234
+ }
235
+ return recordingRedacted && nonRecordingPresent;
236
+ }
237
+ })];
238
+ case 15:
239
+ _b.sent();
240
+ return [3 /*break*/, 21];
241
+ case 16:
242
+ // Restore full-redaction role and clean up partial role
243
+ return [4 /*yield*/, sdk.api.users.updateOne(sdkNonAdmin.userInfo.id, { roles: [fullRedactionRole] }, { replaceObjectFields: true })];
244
+ case 17:
245
+ // Restore full-redaction role and clean up partial role
246
+ _b.sent();
247
+ return [4 /*yield*/, (0, testing_1.wait)(undefined, 1500)];
248
+ case 18:
249
+ _b.sent();
250
+ return [4 /*yield*/, sdkNonAdmin.authenticate(nonAdminEmail, nonAdminPassword)];
251
+ case 19:
252
+ _b.sent();
253
+ return [4 /*yield*/, sdk.api.role_based_access_permissions.deleteOne(rbapPartial.id)];
254
+ case 20:
255
+ _b.sent();
256
+ return [7 /*endfinally*/];
257
+ case 21:
258
+ // ========================================
259
+ // Test 4: getSome/readMany consistency
260
+ // ========================================
261
+ (0, testing_1.log_header)("Test 4: getSome/readMany consistency");
262
+ return [4 /*yield*/, (0, testing_1.async_test)("getSome - redacted fields should be absent on readMany results", function () { return sdkNonAdmin.api.phone_calls.getSome(); }, {
263
+ onResult: function (r) {
264
+ var matches = r.filter(function (pc) { return pc.id === testPhoneCall.id; });
265
+ if (matches.length === 0) {
266
+ console.log(" ⚠️ SKIPPED: test phone call not found in getSome results");
267
+ return true;
268
+ }
269
+ var record = matches[0];
270
+ var redacted = lacksFields(record, __spreadArray([], ALL_REDACTABLE_FIELDS, true));
271
+ if (!redacted) {
272
+ var leaked = ALL_REDACTABLE_FIELDS.filter(function (f) { return f in record && record[f] !== undefined; });
273
+ console.log(" \u274C VULNERABILITY: getSome leaked redacted fields: ".concat(leaked.join(', ')));
274
+ }
275
+ else {
276
+ console.log(" ✅ SAFE: getSome properly redacts fields");
277
+ }
278
+ return redacted;
279
+ }
280
+ })];
281
+ case 22:
282
+ _b.sent();
283
+ return [4 /*yield*/, (0, testing_1.async_test)("getSome (admin) - all fields should be visible", function () { return sdk.api.phone_calls.getSome(); }, {
284
+ onResult: function (r) {
285
+ var match = r.find(function (pc) { return pc.id === testPhoneCall.id; });
286
+ if (!match) {
287
+ console.log(" ⚠️ SKIPPED: test phone call not found in admin getSome results");
288
+ return true;
289
+ }
290
+ var allPresent = hasFields(match, __spreadArray([], ALL_REDACTABLE_FIELDS, true));
291
+ if (!allPresent) {
292
+ var missing = ALL_REDACTABLE_FIELDS.filter(function (f) { return !(f in match) || match[f] === undefined; });
293
+ console.log(" \u274C FALSE POSITIVE: admin getSome missing fields: ".concat(missing.join(', ')));
294
+ }
295
+ else {
296
+ console.log(" ✅ Admin getSome sees all fields");
297
+ }
298
+ return allPresent;
299
+ }
300
+ })
301
+ // ========================================
302
+ // Test 5: Update response doesn't leak
303
+ // ========================================
304
+ ];
305
+ case 23:
306
+ _b.sent();
307
+ // ========================================
308
+ // Test 5: Update response doesn't leak
309
+ // ========================================
310
+ (0, testing_1.log_header)("Test 5: Update response doesn't leak redacted fields");
311
+ return [4 /*yield*/, (0, testing_1.async_test)("updateOne - response should not contain redacted fields", function () { return sdkNonAdmin.api.phone_calls.updateOne(testPhoneCall.id, { note: 'updated by redaction test' }); }, {
312
+ onResult: function (r) {
313
+ var redacted = lacksFields(r, __spreadArray([], ALL_REDACTABLE_FIELDS, true));
314
+ if (!redacted) {
315
+ var leaked = ALL_REDACTABLE_FIELDS.filter(function (f) { return f in r && r[f] !== undefined; });
316
+ console.log(" \u274C VULNERABILITY: updateOne response leaked redacted fields: ".concat(leaked.join(', ')));
317
+ }
318
+ else {
319
+ console.log(" ✅ SAFE: updateOne response does not contain redacted fields");
320
+ }
321
+ return redacted;
322
+ }
323
+ })];
324
+ case 24:
325
+ _b.sent();
326
+ return [4 /*yield*/, (0, testing_1.async_test)("updateOne (admin) - all fields should be visible in response", function () { return sdk.api.phone_calls.updateOne(testPhoneCall.id, { note: 'admin update test' }); }, {
327
+ onResult: function (r) {
328
+ var allPresent = hasFields(r, __spreadArray([], ALL_REDACTABLE_FIELDS, true));
329
+ if (!allPresent) {
330
+ var missing = ALL_REDACTABLE_FIELDS.filter(function (f) { return !(f in r) || r[f] === undefined; });
331
+ console.log(" \u274C FALSE POSITIVE: admin updateOne missing fields: ".concat(missing.join(', ')));
332
+ }
333
+ else {
334
+ console.log(" ✅ Admin updateOne sees all fields");
335
+ }
336
+ return allPresent;
337
+ }
338
+ })
339
+ // ========================================
340
+ // Test 6: Create response doesn't leak
341
+ // ========================================
342
+ ];
343
+ case 25:
344
+ _b.sent();
345
+ // ========================================
346
+ // Test 6: Create response doesn't leak
347
+ // ========================================
348
+ (0, testing_1.log_header)("Test 6: Create response doesn't leak redacted fields");
349
+ return [4 /*yield*/, (0, testing_1.async_test)("createOne - response should not contain redacted fields", function () { return sdkNonAdmin.api.phone_calls.createOne({
350
+ enduserId: testEnduser.id,
351
+ inbound: false,
352
+ from: '+15551111111',
353
+ to: '+15552222222',
354
+ recordingURI: 'https://example.com/leak-test.wav',
355
+ recordingId: 'rec_leak_test',
356
+ recordingDurationInSeconds: 10,
357
+ transcription: 'Leak test transcription.',
358
+ recordingTranscriptionData: '{"test":"data"}',
359
+ aiSummary: 'Leak test summary.',
360
+ }); }, {
361
+ onResult: function (r) {
362
+ createdPhoneCallId_1 = r.id;
363
+ var redacted = lacksFields(r, __spreadArray([], ALL_REDACTABLE_FIELDS, true));
364
+ if (!redacted) {
365
+ var leaked = ALL_REDACTABLE_FIELDS.filter(function (f) { return f in r && r[f] !== undefined; });
366
+ console.log(" \u274C VULNERABILITY: createOne response leaked redacted fields: ".concat(leaked.join(', ')));
367
+ }
368
+ else {
369
+ console.log(" ✅ SAFE: createOne response does not contain redacted fields");
370
+ }
371
+ return redacted;
372
+ }
373
+ })
374
+ // Cleanup the created phone call
375
+ ];
376
+ case 26:
377
+ _b.sent();
378
+ if (!createdPhoneCallId_1) return [3 /*break*/, 30];
379
+ _b.label = 27;
380
+ case 27:
381
+ _b.trys.push([27, 29, , 30]);
382
+ return [4 /*yield*/, sdk.api.phone_calls.deleteOne(createdPhoneCallId_1)];
383
+ case 28:
384
+ _b.sent();
385
+ return [3 /*break*/, 30];
386
+ case 29:
387
+ e_1 = _b.sent();
388
+ return [3 /*break*/, 30];
389
+ case 30: return [4 /*yield*/, (0, testing_1.async_test)("createOne (admin) - all fields should be visible in response", function () { return sdk.api.phone_calls.createOne({
390
+ enduserId: testEnduser.id,
391
+ inbound: false,
392
+ from: '+15553333333',
393
+ to: '+15554444444',
394
+ recordingURI: 'https://example.com/admin-test.wav',
395
+ recordingId: 'rec_admin_test',
396
+ recordingDurationInSeconds: 20,
397
+ transcription: 'Admin create test transcription.',
398
+ recordingTranscriptionData: '{"admin":"test"}',
399
+ aiSummary: 'Admin create test summary.',
400
+ }); }, {
401
+ onResult: function (r) {
402
+ adminCreatedPhoneCallId_1 = r.id;
403
+ var allPresent = hasFields(r, __spreadArray([], ALL_REDACTABLE_FIELDS, true));
404
+ if (!allPresent) {
405
+ var missing = ALL_REDACTABLE_FIELDS.filter(function (f) { return !(f in r) || r[f] === undefined; });
406
+ console.log(" \u274C FALSE POSITIVE: admin createOne missing fields: ".concat(missing.join(', ')));
407
+ }
408
+ else {
409
+ console.log(" ✅ Admin createOne sees all fields");
410
+ }
411
+ return allPresent;
412
+ }
413
+ })];
414
+ case 31:
415
+ _b.sent();
416
+ if (!adminCreatedPhoneCallId_1) return [3 /*break*/, 35];
417
+ _b.label = 32;
418
+ case 32:
419
+ _b.trys.push([32, 34, , 35]);
420
+ return [4 /*yield*/, sdk.api.phone_calls.deleteOne(adminCreatedPhoneCallId_1)];
421
+ case 33:
422
+ _b.sent();
423
+ return [3 /*break*/, 35];
424
+ case 34:
425
+ e_2 = _b.sent();
426
+ return [3 /*break*/, 35];
427
+ case 35:
428
+ // ========================================
429
+ // Test 7: bulk_load redaction
430
+ // ========================================
431
+ (0, testing_1.log_header)("Test 7: bulk_load redaction");
432
+ return [4 /*yield*/, (0, testing_1.async_test)("bulk_load - redacted fields should be absent", function () { return sdkNonAdmin.bulk_load({ load: [{ model: 'phone_calls', options: { limit: 100 } }] }); }, {
433
+ onResult: function (r) {
434
+ var phoneCallResult = r.results[0];
435
+ if (!phoneCallResult || phoneCallResult.records.length === 0) {
436
+ console.log(" ⚠️ SKIPPED: no phone_calls returned from bulk_load");
437
+ return true;
438
+ }
439
+ var match = phoneCallResult.records.find(function (pc) { return pc.id === testPhoneCall.id; });
440
+ if (!match) {
441
+ console.log(" ⚠️ SKIPPED: test phone call not found in bulk_load results");
442
+ return true;
443
+ }
444
+ var redacted = lacksFields(match, __spreadArray([], ALL_REDACTABLE_FIELDS, true));
445
+ if (!redacted) {
446
+ var leaked = ALL_REDACTABLE_FIELDS.filter(function (f) { return f in match && match[f] !== undefined; });
447
+ console.log(" \u274C VULNERABILITY: bulk_load leaked redacted fields: ".concat(leaked.join(', ')));
448
+ }
449
+ else {
450
+ console.log(" ✅ SAFE: bulk_load properly redacts fields");
451
+ }
452
+ return redacted;
453
+ }
454
+ })];
455
+ case 36:
456
+ _b.sent();
457
+ return [4 /*yield*/, (0, testing_1.async_test)("bulk_load (admin) - all fields should be visible", function () { return sdk.bulk_load({ load: [{ model: 'phone_calls', options: { limit: 100 } }] }); }, {
458
+ onResult: function (r) {
459
+ var phoneCallResult = r.results[0];
460
+ if (!phoneCallResult || phoneCallResult.records.length === 0) {
461
+ console.log(" ⚠️ SKIPPED: no phone_calls returned from admin bulk_load");
462
+ return true;
463
+ }
464
+ var match = phoneCallResult.records.find(function (pc) { return pc.id === testPhoneCall.id; });
465
+ if (!match) {
466
+ console.log(" ⚠️ SKIPPED: test phone call not found in admin bulk_load results");
467
+ return true;
468
+ }
469
+ var allPresent = hasFields(match, __spreadArray([], ALL_REDACTABLE_FIELDS, true));
470
+ if (!allPresent) {
471
+ var missing = ALL_REDACTABLE_FIELDS.filter(function (f) { return !(f in match) || match[f] === undefined; });
472
+ console.log(" \u274C FALSE POSITIVE: admin bulk_load missing fields: ".concat(missing.join(', ')));
473
+ }
474
+ else {
475
+ console.log(" ✅ Admin bulk_load sees all fields");
476
+ }
477
+ return allPresent;
478
+ }
479
+ })
480
+ // ========================================
481
+ // Test 7b: bulk-read (getByIds) redaction
482
+ // ========================================
483
+ ];
484
+ case 37:
485
+ _b.sent();
486
+ // ========================================
487
+ // Test 7b: bulk-read (getByIds) redaction
488
+ // ========================================
489
+ (0, testing_1.log_header)("Test 7b: bulk-read (getByIds) redaction");
490
+ return [4 /*yield*/, (0, testing_1.async_test)("getByIds - redacted fields should be absent", function () { return sdkNonAdmin.api.phone_calls.getByIds({ ids: [testPhoneCall.id] }); }, {
491
+ onResult: function (r) {
492
+ if (!r.matches || r.matches.length === 0) {
493
+ console.log(" ⚠️ SKIPPED: no phone_calls returned from getByIds");
494
+ return true;
495
+ }
496
+ var match = r.matches.find(function (pc) { return pc.id === testPhoneCall.id; });
497
+ if (!match) {
498
+ console.log(" ⚠️ SKIPPED: test phone call not found in getByIds results");
499
+ return true;
500
+ }
501
+ var redacted = lacksFields(match, __spreadArray([], ALL_REDACTABLE_FIELDS, true));
502
+ if (!redacted) {
503
+ var leaked = ALL_REDACTABLE_FIELDS.filter(function (f) { return f in match && match[f] !== undefined; });
504
+ console.log(" \u274C VULNERABILITY: getByIds leaked redacted fields: ".concat(leaked.join(', ')));
505
+ }
506
+ else {
507
+ console.log(" ✅ SAFE: getByIds properly redacts fields");
508
+ }
509
+ return redacted;
510
+ }
511
+ })];
512
+ case 38:
513
+ _b.sent();
514
+ return [4 /*yield*/, (0, testing_1.async_test)("getByIds (admin) - all fields should be visible", function () { return sdk.api.phone_calls.getByIds({ ids: [testPhoneCall.id] }); }, {
515
+ onResult: function (r) {
516
+ if (!r.matches || r.matches.length === 0) {
517
+ console.log(" ⚠️ SKIPPED: no phone_calls returned from admin getByIds");
518
+ return true;
519
+ }
520
+ var match = r.matches.find(function (pc) { return pc.id === testPhoneCall.id; });
521
+ if (!match) {
522
+ console.log(" ⚠️ SKIPPED: test phone call not found in admin getByIds results");
523
+ return true;
524
+ }
525
+ var allPresent = hasFields(match, __spreadArray([], ALL_REDACTABLE_FIELDS, true));
526
+ if (!allPresent) {
527
+ var missing = ALL_REDACTABLE_FIELDS.filter(function (f) { return !(f in match) || match[f] === undefined; });
528
+ console.log(" \u274C FALSE POSITIVE: admin getByIds missing fields: ".concat(missing.join(', ')));
529
+ }
530
+ else {
531
+ console.log(" ✅ Admin getByIds sees all fields");
532
+ }
533
+ return allPresent;
534
+ }
535
+ })
536
+ // ========================================
537
+ // Test 8: load_inbox_data redaction
538
+ // ========================================
539
+ ];
540
+ case 39:
541
+ _b.sent();
542
+ // ========================================
543
+ // Test 8: load_inbox_data redaction
544
+ // ========================================
545
+ (0, testing_1.log_header)("Test 8: load_inbox_data redaction");
546
+ return [4 /*yield*/, (0, testing_1.async_test)("load_inbox_data - phone_calls should have redacted fields absent", function () { return sdkNonAdmin.api.endusers.load_inbox_data({ enduserIds: [testEnduser.id] }); }, {
547
+ onResult: function (r) {
548
+ if (!r.phone_calls || r.phone_calls.length === 0) {
549
+ console.log(" ⚠️ SKIPPED: no phone_calls returned from load_inbox_data");
550
+ return true;
551
+ }
552
+ var match = r.phone_calls.find(function (pc) { return pc.id === testPhoneCall.id; });
553
+ if (!match) {
554
+ console.log(" ⚠️ SKIPPED: test phone call not found in load_inbox_data results");
555
+ return true;
556
+ }
557
+ var redacted = lacksFields(match, __spreadArray([], ALL_REDACTABLE_FIELDS, true));
558
+ if (!redacted) {
559
+ var leaked = ALL_REDACTABLE_FIELDS.filter(function (f) { return f in match && match[f] !== undefined; });
560
+ console.log(" \u274C VULNERABILITY: load_inbox_data leaked redacted fields: ".concat(leaked.join(', ')));
561
+ }
562
+ else {
563
+ console.log(" ✅ SAFE: load_inbox_data properly redacts phone_call fields");
564
+ }
565
+ return redacted;
566
+ }
567
+ })];
568
+ case 40:
569
+ _b.sent();
570
+ return [4 /*yield*/, (0, testing_1.async_test)("load_inbox_data (admin) - all phone_call fields should be visible", function () { return sdk.api.endusers.load_inbox_data({ enduserIds: [testEnduser.id] }); }, {
571
+ onResult: function (r) {
572
+ if (!r.phone_calls || r.phone_calls.length === 0) {
573
+ console.log(" ⚠️ SKIPPED: no phone_calls returned from admin load_inbox_data");
574
+ return true;
575
+ }
576
+ var match = r.phone_calls.find(function (pc) { return pc.id === testPhoneCall.id; });
577
+ if (!match) {
578
+ console.log(" ⚠️ SKIPPED: test phone call not found in admin load_inbox_data results");
579
+ return true;
580
+ }
581
+ var allPresent = hasFields(match, __spreadArray([], ALL_REDACTABLE_FIELDS, true));
582
+ if (!allPresent) {
583
+ var missing = ALL_REDACTABLE_FIELDS.filter(function (f) { return !(f in match) || match[f] === undefined; });
584
+ console.log(" \u274C FALSE POSITIVE: admin load_inbox_data missing fields: ".concat(missing.join(', ')));
585
+ }
586
+ else {
587
+ console.log(" ✅ Admin load_inbox_data sees all phone_call fields");
588
+ }
589
+ return allPresent;
590
+ }
591
+ })
592
+ // ========================================
593
+ // Test 9: No-redaction role sees all fields
594
+ // ========================================
595
+ ];
596
+ case 41:
597
+ _b.sent();
598
+ // ========================================
599
+ // Test 9: No-redaction role sees all fields
600
+ // ========================================
601
+ (0, testing_1.log_header)("Test 9: Role without fieldRedactions sees all fields");
602
+ noRedactionRole = 'no-redaction-test-role';
603
+ return [4 /*yield*/, sdk.api.role_based_access_permissions.createOne({
604
+ role: noRedactionRole,
605
+ permissions: __assign(__assign({}, constants_1.PROVIDER_PERMISSIONS), { phone_calls: FULL_ACCESS, endusers: FULL_ACCESS }),
606
+ // No fieldRedactions
607
+ })];
608
+ case 42:
609
+ rbapNoRedaction = _b.sent();
610
+ _b.label = 43;
611
+ case 43:
612
+ _b.trys.push([43, , 48, 53]);
613
+ return [4 /*yield*/, sdk.api.users.updateOne(sdkNonAdmin.userInfo.id, { roles: [noRedactionRole] }, { replaceObjectFields: true })];
614
+ case 44:
615
+ _b.sent();
616
+ return [4 /*yield*/, (0, testing_1.wait)(undefined, 1500)];
617
+ case 45:
618
+ _b.sent();
619
+ return [4 /*yield*/, sdkNonAdmin.authenticate(nonAdminEmail, nonAdminPassword)];
620
+ case 46:
621
+ _b.sent();
622
+ return [4 /*yield*/, (0, testing_1.async_test)("getOne - role without fieldRedactions should see all fields", function () { return sdkNonAdmin.api.phone_calls.getOne(testPhoneCall.id); }, {
623
+ onResult: function (r) {
624
+ var allPresent = hasFields(r, __spreadArray([], ALL_REDACTABLE_FIELDS, true));
625
+ if (!allPresent) {
626
+ var missing = ALL_REDACTABLE_FIELDS.filter(function (f) { return !(f in r) || r[f] === undefined; });
627
+ console.log(" \u274C ERROR: no-redaction role is missing fields: ".concat(missing.join(', ')));
628
+ }
629
+ else {
630
+ console.log(" ✅ No-redaction role can see all fields");
631
+ }
632
+ return allPresent;
633
+ }
634
+ })];
635
+ case 47:
636
+ _b.sent();
637
+ return [3 /*break*/, 53];
638
+ case 48: return [4 /*yield*/, sdk.api.users.updateOne(sdkNonAdmin.userInfo.id, { roles: [fullRedactionRole] }, { replaceObjectFields: true })];
639
+ case 49:
640
+ _b.sent();
641
+ return [4 /*yield*/, (0, testing_1.wait)(undefined, 1500)];
642
+ case 50:
643
+ _b.sent();
644
+ return [4 /*yield*/, sdkNonAdmin.authenticate(nonAdminEmail, nonAdminPassword)];
645
+ case 51:
646
+ _b.sent();
647
+ return [4 /*yield*/, sdk.api.role_based_access_permissions.deleteOne(rbapNoRedaction.id)];
648
+ case 52:
649
+ _b.sent();
650
+ return [7 /*endfinally*/];
651
+ case 53:
652
+ // ========================================
653
+ // Test 10: Redaction scoped to model
654
+ // ========================================
655
+ (0, testing_1.log_header)("Test 10: phone_calls redaction doesn't affect other models");
656
+ return [4 /*yield*/, (0, testing_1.async_test)("enduser read - phone_calls fieldRedactions should not affect enduser fields", function () { return sdkNonAdmin.api.endusers.getOne(testEnduser.id); }, {
657
+ onResult: function (r) {
658
+ var corePresent = hasFields(r, ['fname', 'lname', 'email']);
659
+ if (!corePresent) {
660
+ console.log(" ❌ ERROR: enduser fields missing — phone_calls redaction may be leaking across models");
661
+ }
662
+ else {
663
+ console.log(" ✅ SAFE: phone_calls redaction does not affect enduser fields");
664
+ }
665
+ return corePresent;
666
+ }
667
+ })
668
+ // ========================================
669
+ // Test 11: data-sync redaction
670
+ // ========================================
671
+ ];
672
+ case 54:
673
+ _b.sent();
674
+ // ========================================
675
+ // Test 11: data-sync redaction
676
+ // ========================================
677
+ (0, testing_1.log_header)("Test 11: data-sync redaction");
678
+ syncFrom_1 = new Date(0) // far enough back to capture the test phone call
679
+ ;
680
+ return [4 /*yield*/, (0, testing_1.async_test)("data-sync - redacted fields should be absent in parsed data", function () { return sdkNonAdmin.sync({ from: syncFrom_1 }); }, {
681
+ onResult: function (r) {
682
+ var match = r.results.find(function (rec) { return rec.recordId === testPhoneCall.id && rec.modelName === 'phone_calls'; });
683
+ if (!match) {
684
+ console.log(" ⚠️ SKIPPED: test phone call not found in data-sync results");
685
+ return true;
686
+ }
687
+ if (match.data === 'deleted') {
688
+ console.log(" ⚠️ SKIPPED: test phone call marked as deleted in data-sync");
689
+ return true;
690
+ }
691
+ var parsed = JSON.parse(match.data);
692
+ var redacted = lacksFields(parsed, __spreadArray([], ALL_REDACTABLE_FIELDS, true));
693
+ var corePresent = hasFields(parsed, ['enduserId', 'inbound', 'from', 'to']);
694
+ if (!redacted) {
695
+ var leaked = ALL_REDACTABLE_FIELDS.filter(function (f) { return f in parsed && parsed[f] !== undefined; });
696
+ console.log(" \u274C VULNERABILITY: data-sync leaked redacted fields: ".concat(leaked.join(', ')));
697
+ }
698
+ else {
699
+ console.log(" ✅ SAFE: data-sync properly redacts fields in parsed data");
700
+ }
701
+ if (!corePresent) {
702
+ console.log(" ❌ ERROR: core fields (enduserId, inbound, from, to) are missing from data-sync record");
703
+ }
704
+ return redacted && corePresent;
705
+ }
706
+ })];
707
+ case 55:
708
+ _b.sent();
709
+ return [4 /*yield*/, (0, testing_1.async_test)("data-sync (admin) - all fields should be visible in parsed data", function () { return sdk.sync({ from: syncFrom_1 }); }, {
710
+ onResult: function (r) {
711
+ var match = r.results.find(function (rec) { return rec.recordId === testPhoneCall.id && rec.modelName === 'phone_calls'; });
712
+ if (!match) {
713
+ console.log(" ⚠️ SKIPPED: test phone call not found in admin data-sync results");
714
+ return true;
715
+ }
716
+ if (match.data === 'deleted') {
717
+ console.log(" ⚠️ SKIPPED: test phone call marked as deleted in admin data-sync");
718
+ return true;
719
+ }
720
+ var parsed = JSON.parse(match.data);
721
+ var allPresent = hasFields(parsed, __spreadArray([], ALL_REDACTABLE_FIELDS, true));
722
+ if (!allPresent) {
723
+ var missing = ALL_REDACTABLE_FIELDS.filter(function (f) { return !(f in parsed) || parsed[f] === undefined; });
724
+ console.log(" \u274C FALSE POSITIVE: admin data-sync missing fields: ".concat(missing.join(', ')));
725
+ }
726
+ else {
727
+ console.log(" ✅ Admin data-sync sees all fields");
728
+ }
729
+ return allPresent;
730
+ }
731
+ })];
732
+ case 56:
733
+ _b.sent();
734
+ console.log("\n" + "=".repeat(60));
735
+ console.log("Field Redaction Tests Complete");
736
+ console.log("=".repeat(60));
737
+ return [3 /*break*/, 71];
738
+ case 57:
739
+ // Restore original roles
740
+ return [4 /*yield*/, sdk.api.users.updateOne(sdkNonAdmin.userInfo.id, { roles: originalRoles }, { replaceObjectFields: true })];
741
+ case 58:
742
+ // Restore original roles
743
+ _b.sent();
744
+ return [4 /*yield*/, (0, testing_1.wait)(undefined, 1000)];
745
+ case 59:
746
+ _b.sent();
747
+ return [4 /*yield*/, sdkNonAdmin.authenticate(nonAdminEmail, nonAdminPassword)
748
+ // Cleanup test data
749
+ ];
750
+ case 60:
751
+ _b.sent();
752
+ _b.label = 61;
753
+ case 61:
754
+ _b.trys.push([61, 63, , 64]);
755
+ return [4 /*yield*/, sdk.api.role_based_access_permissions.deleteOne(rbapFull.id)];
756
+ case 62:
757
+ _b.sent();
758
+ return [3 /*break*/, 64];
759
+ case 63:
760
+ e_3 = _b.sent();
761
+ console.error('Cleanup error (rbap):', e_3);
762
+ return [3 /*break*/, 64];
763
+ case 64:
764
+ _b.trys.push([64, 66, , 67]);
765
+ return [4 /*yield*/, sdk.api.phone_calls.deleteOne(testPhoneCall.id)];
766
+ case 65:
767
+ _b.sent();
768
+ return [3 /*break*/, 67];
769
+ case 66:
770
+ e_4 = _b.sent();
771
+ console.error('Cleanup error (phone_call):', e_4);
772
+ return [3 /*break*/, 67];
773
+ case 67:
774
+ _b.trys.push([67, 69, , 70]);
775
+ return [4 /*yield*/, sdk.api.endusers.deleteOne(testEnduser.id)];
776
+ case 68:
777
+ _b.sent();
778
+ return [3 /*break*/, 70];
779
+ case 69:
780
+ e_5 = _b.sent();
781
+ console.error('Cleanup error (enduser):', e_5);
782
+ return [3 /*break*/, 70];
783
+ case 70: return [7 /*endfinally*/];
784
+ case 71: return [2 /*return*/];
785
+ }
786
+ });
787
+ });
788
+ };
789
+ exports.field_redaction_tests = field_redaction_tests;
790
+ // Allow running this test file independently
791
+ if (require.main === module) {
792
+ console.log("Using API URL: ".concat(host));
793
+ var sdk_2 = new sdk_1.Session({ host: host });
794
+ var sdkNonAdmin_1 = new sdk_1.Session({ host: host });
795
+ var runTests = function () { return __awaiter(void 0, void 0, void 0, function () {
796
+ return __generator(this, function (_a) {
797
+ switch (_a.label) {
798
+ case 0: return [4 /*yield*/, (0, setup_1.setup_tests)(sdk_2, sdkNonAdmin_1)];
799
+ case 1:
800
+ _a.sent();
801
+ return [4 /*yield*/, (0, exports.field_redaction_tests)({ sdk: sdk_2, sdkNonAdmin: sdkNonAdmin_1 })];
802
+ case 2:
803
+ _a.sent();
804
+ return [2 /*return*/];
805
+ }
806
+ });
807
+ }); };
808
+ runTests()
809
+ .then(function () {
810
+ console.log("✅ Field redaction test suite completed successfully");
811
+ process.exit(0);
812
+ })
813
+ .catch(function (error) {
814
+ console.error("❌ Field redaction test suite failed:", error);
815
+ process.exit(1);
816
+ });
817
+ }
818
+ //# sourceMappingURL=field_redaction.test.js.map