@tellescope/sdk 1.249.1 → 1.250.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.
- package/lib/cjs/enduser.d.ts +14 -2
- package/lib/cjs/enduser.d.ts.map +1 -1
- package/lib/cjs/enduser.js +14 -3
- package/lib/cjs/enduser.js.map +1 -1
- package/lib/cjs/sdk.d.ts +1 -0
- package/lib/cjs/sdk.d.ts.map +1 -1
- package/lib/cjs/sdk.js +3 -3
- package/lib/cjs/sdk.js.map +1 -1
- package/lib/cjs/tests/api_tests/beluga_pharmacy_mappings.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/beluga_pharmacy_mappings.test.js +46 -11
- package/lib/cjs/tests/api_tests/beluga_pharmacy_mappings.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/enduser_cross_access_isolation.test.d.ts +6 -0
- package/lib/cjs/tests/api_tests/enduser_cross_access_isolation.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/enduser_cross_access_isolation.test.js +782 -0
- package/lib/cjs/tests/api_tests/enduser_cross_access_isolation.test.js.map +1 -0
- package/lib/cjs/tests/tests.d.ts.map +1 -1
- package/lib/cjs/tests/tests.js +173 -156
- package/lib/cjs/tests/tests.js.map +1 -1
- package/lib/esm/enduser.d.ts +14 -2
- package/lib/esm/enduser.d.ts.map +1 -1
- package/lib/esm/enduser.js +14 -3
- package/lib/esm/enduser.js.map +1 -1
- package/lib/esm/sdk.d.ts +3 -2
- package/lib/esm/sdk.d.ts.map +1 -1
- package/lib/esm/sdk.js +3 -3
- package/lib/esm/sdk.js.map +1 -1
- package/lib/esm/tests/api_tests/beluga_pharmacy_mappings.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/beluga_pharmacy_mappings.test.js +46 -11
- package/lib/esm/tests/api_tests/beluga_pharmacy_mappings.test.js.map +1 -1
- package/lib/esm/tests/api_tests/enduser_cross_access_isolation.test.d.ts +6 -0
- package/lib/esm/tests/api_tests/enduser_cross_access_isolation.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/enduser_cross_access_isolation.test.js +778 -0
- package/lib/esm/tests/api_tests/enduser_cross_access_isolation.test.js.map +1 -0
- package/lib/esm/tests/tests.d.ts.map +1 -1
- package/lib/esm/tests/tests.js +173 -156
- package/lib/esm/tests/tests.js.map +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +10 -10
- package/src/enduser.ts +12 -6
- package/src/sdk.ts +3 -3
- package/src/tests/api_tests/beluga_pharmacy_mappings.test.ts +55 -0
- package/src/tests/api_tests/enduser_cross_access_isolation.test.ts +542 -0
- package/src/tests/tests.ts +29 -8
- package/test_generated.pdf +0 -0
|
@@ -0,0 +1,778 @@
|
|
|
1
|
+
var __assign = (this && this.__assign) || function () {
|
|
2
|
+
__assign = Object.assign || function(t) {
|
|
3
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
4
|
+
s = arguments[i];
|
|
5
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
6
|
+
t[p] = s[p];
|
|
7
|
+
}
|
|
8
|
+
return t;
|
|
9
|
+
};
|
|
10
|
+
return __assign.apply(this, arguments);
|
|
11
|
+
};
|
|
12
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
13
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
14
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
15
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
16
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
17
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
18
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
19
|
+
});
|
|
20
|
+
};
|
|
21
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
22
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
23
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
24
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
25
|
+
function step(op) {
|
|
26
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
27
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
28
|
+
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;
|
|
29
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
30
|
+
switch (op[0]) {
|
|
31
|
+
case 0: case 1: t = op; break;
|
|
32
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
33
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
34
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
35
|
+
default:
|
|
36
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
37
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
38
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
39
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
40
|
+
if (t[2]) _.ops.pop();
|
|
41
|
+
_.trys.pop(); continue;
|
|
42
|
+
}
|
|
43
|
+
op = body.call(thisArg, _);
|
|
44
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
45
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
require('source-map-support').install();
|
|
49
|
+
import { Session, EnduserSession } from "../../sdk";
|
|
50
|
+
import { assert, async_test, handleAnyError, log_header, } from "@tellescope/testing";
|
|
51
|
+
import { schema } from "@tellescope/schema";
|
|
52
|
+
import { setup_tests } from "../setup";
|
|
53
|
+
var host = process.env.API_URL || 'http://localhost:8080';
|
|
54
|
+
var businessId = '60398b1131a295e64f084ff6';
|
|
55
|
+
var buildAttendees = function (enduserId) { return [{ id: enduserId, type: 'enduser' }]; };
|
|
56
|
+
// Per-model coverage of every enduser-scoped read / ownership-mutation endpoint.
|
|
57
|
+
// New enduser-scoped models added with a FilterAccessConstraint on enduserId,
|
|
58
|
+
// enduserIds, or attendees.id MUST be added here (or to EXEMPT_MODELS) — the
|
|
59
|
+
// schema drift guard below will fail the test until coverage is added.
|
|
60
|
+
var MODEL_CASES = [
|
|
61
|
+
{
|
|
62
|
+
model: 'tickets',
|
|
63
|
+
ownerField: 'enduserId',
|
|
64
|
+
buildPayload: function (enduserBId) { return ({ enduserId: enduserBId, title: 'isolation: ticket' }); },
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
model: 'engagement_events',
|
|
68
|
+
ownerField: 'enduserId',
|
|
69
|
+
buildPayload: function (enduserBId) { return ({ enduserId: enduserBId, type: 'isolation', significance: 1 }); },
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
model: 'enduser_observations',
|
|
73
|
+
ownerField: 'enduserId',
|
|
74
|
+
buildPayload: function (enduserBId) { return ({
|
|
75
|
+
enduserId: enduserBId,
|
|
76
|
+
status: 'final',
|
|
77
|
+
category: 'vital-signs',
|
|
78
|
+
measurement: { unit: 'mmHg', value: 120 },
|
|
79
|
+
}); },
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
model: 'enduser_tasks',
|
|
83
|
+
ownerField: 'enduserId',
|
|
84
|
+
buildPayload: function (enduserBId) { return ({ enduserId: enduserBId, title: 'isolation: task' }); },
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
model: 'care_plans',
|
|
88
|
+
ownerField: 'enduserId',
|
|
89
|
+
buildPayload: function (enduserBId) { return ({ enduserId: enduserBId, title: 'isolation: care plan' }); },
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
model: 'enduser_medications',
|
|
93
|
+
ownerField: 'enduserId',
|
|
94
|
+
buildPayload: function (enduserBId) { return ({ enduserId: enduserBId, title: 'isolation: medication' }); },
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
model: 'enduser_orders',
|
|
98
|
+
ownerField: 'enduserId',
|
|
99
|
+
buildPayload: function (enduserBId) { return ({
|
|
100
|
+
enduserId: enduserBId,
|
|
101
|
+
title: 'isolation: order',
|
|
102
|
+
status: 'pending',
|
|
103
|
+
source: 'isolation-test',
|
|
104
|
+
externalId: "iso-".concat(Date.now()),
|
|
105
|
+
}); },
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
model: 'enduser_problems',
|
|
109
|
+
ownerField: 'enduserId',
|
|
110
|
+
buildPayload: function (enduserBId) { return ({
|
|
111
|
+
enduserId: enduserBId,
|
|
112
|
+
title: 'isolation: problem',
|
|
113
|
+
}); },
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
model: 'managed_content_record_assignments',
|
|
117
|
+
ownerField: 'enduserId',
|
|
118
|
+
setup: function (sdk, _enduserBId) { return __awaiter(void 0, void 0, void 0, function () {
|
|
119
|
+
var content;
|
|
120
|
+
return __generator(this, function (_a) {
|
|
121
|
+
switch (_a.label) {
|
|
122
|
+
case 0: return [4 /*yield*/, sdk.api.managed_content_records.createOne({
|
|
123
|
+
title: "isolation content ".concat(Date.now()),
|
|
124
|
+
textContent: 'isolation',
|
|
125
|
+
htmlContent: '<p>isolation</p>',
|
|
126
|
+
})];
|
|
127
|
+
case 1:
|
|
128
|
+
content = _a.sent();
|
|
129
|
+
return [2 /*return*/, {
|
|
130
|
+
payloadOverride: { contentId: content.id },
|
|
131
|
+
cleanup: function () { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) {
|
|
132
|
+
switch (_a.label) {
|
|
133
|
+
case 0: return [4 /*yield*/, sdk.api.managed_content_records.deleteOne(content.id).catch(function () { })];
|
|
134
|
+
case 1:
|
|
135
|
+
_a.sent();
|
|
136
|
+
return [2 /*return*/];
|
|
137
|
+
}
|
|
138
|
+
}); }); },
|
|
139
|
+
}];
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
}); },
|
|
143
|
+
buildPayload: function (enduserBId) { return ({ enduserId: enduserBId }); },
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
model: 'purchases',
|
|
147
|
+
ownerField: 'enduserId',
|
|
148
|
+
buildPayload: function (enduserBId) { return ({
|
|
149
|
+
enduserId: enduserBId,
|
|
150
|
+
title: 'isolation: purchase',
|
|
151
|
+
cost: { amount: 100, currency: 'USD' },
|
|
152
|
+
processor: 'Stripe',
|
|
153
|
+
}); },
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
model: 'purchase_credits',
|
|
157
|
+
ownerField: 'enduserId',
|
|
158
|
+
buildPayload: function (enduserBId) { return ({
|
|
159
|
+
enduserId: enduserBId,
|
|
160
|
+
title: 'isolation: credit',
|
|
161
|
+
value: { type: 'Credit', info: { amount: 50, currency: 'USD' } },
|
|
162
|
+
}); },
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
model: 'chat_rooms',
|
|
166
|
+
ownerField: 'enduserIds',
|
|
167
|
+
buildPayload: function (enduserBId) { return ({
|
|
168
|
+
type: 'internal',
|
|
169
|
+
userIds: [],
|
|
170
|
+
enduserIds: [enduserBId],
|
|
171
|
+
title: 'isolation: chat_room',
|
|
172
|
+
}); },
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
model: 'chats',
|
|
176
|
+
ownerField: 'enduserId',
|
|
177
|
+
setup: function (sdk, enduserBId) { return __awaiter(void 0, void 0, void 0, function () {
|
|
178
|
+
var room;
|
|
179
|
+
return __generator(this, function (_a) {
|
|
180
|
+
switch (_a.label) {
|
|
181
|
+
case 0: return [4 /*yield*/, sdk.api.chat_rooms.createOne({
|
|
182
|
+
type: 'internal',
|
|
183
|
+
userIds: [],
|
|
184
|
+
enduserIds: [enduserBId],
|
|
185
|
+
title: 'isolation: chats parent',
|
|
186
|
+
})];
|
|
187
|
+
case 1:
|
|
188
|
+
room = _a.sent();
|
|
189
|
+
return [2 /*return*/, {
|
|
190
|
+
payloadOverride: { roomId: room.id, senderId: enduserBId },
|
|
191
|
+
cleanup: function () { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) {
|
|
192
|
+
switch (_a.label) {
|
|
193
|
+
case 0: return [4 /*yield*/, sdk.api.chat_rooms.deleteOne(room.id).catch(function () { })];
|
|
194
|
+
case 1:
|
|
195
|
+
_a.sent();
|
|
196
|
+
return [2 /*return*/];
|
|
197
|
+
}
|
|
198
|
+
}); }); },
|
|
199
|
+
}];
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
}); },
|
|
203
|
+
buildPayload: function (enduserBId) { return ({ message: 'isolation chat', enduserId: enduserBId }); },
|
|
204
|
+
},
|
|
205
|
+
{
|
|
206
|
+
model: 'calendar_events',
|
|
207
|
+
ownerField: 'attendees.id',
|
|
208
|
+
buildPayload: function (enduserBId) { return ({
|
|
209
|
+
title: 'isolation: calendar_event',
|
|
210
|
+
durationInMinutes: 30,
|
|
211
|
+
startTimeInMS: Date.now() + 86400000,
|
|
212
|
+
attendees: buildAttendees(enduserBId),
|
|
213
|
+
}); },
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
model: 'ticket_threads',
|
|
217
|
+
ownerField: 'enduserId',
|
|
218
|
+
buildPayload: function (enduserBId) { return ({
|
|
219
|
+
enduserId: enduserBId,
|
|
220
|
+
subject: 'isolation: thread',
|
|
221
|
+
}); },
|
|
222
|
+
},
|
|
223
|
+
{
|
|
224
|
+
model: 'ticket_thread_comments',
|
|
225
|
+
ownerField: 'enduserId',
|
|
226
|
+
setup: function (sdk, enduserBId) { return __awaiter(void 0, void 0, void 0, function () {
|
|
227
|
+
var thread;
|
|
228
|
+
return __generator(this, function (_a) {
|
|
229
|
+
switch (_a.label) {
|
|
230
|
+
case 0: return [4 /*yield*/, sdk.api.ticket_threads.createOne({
|
|
231
|
+
enduserId: enduserBId,
|
|
232
|
+
subject: 'isolation: thread comments parent',
|
|
233
|
+
})];
|
|
234
|
+
case 1:
|
|
235
|
+
thread = _a.sent();
|
|
236
|
+
return [2 /*return*/, {
|
|
237
|
+
payloadOverride: { ticketThreadId: thread.id },
|
|
238
|
+
cleanup: function () { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) {
|
|
239
|
+
switch (_a.label) {
|
|
240
|
+
case 0: return [4 /*yield*/, sdk.api.ticket_threads.deleteOne(thread.id).catch(function () { })];
|
|
241
|
+
case 1:
|
|
242
|
+
_a.sent();
|
|
243
|
+
return [2 /*return*/];
|
|
244
|
+
}
|
|
245
|
+
}); }); },
|
|
246
|
+
}];
|
|
247
|
+
}
|
|
248
|
+
});
|
|
249
|
+
}); },
|
|
250
|
+
buildPayload: function (enduserBId) { return ({
|
|
251
|
+
enduserId: enduserBId,
|
|
252
|
+
ticketThreadId: '',
|
|
253
|
+
html: '<p>isolation</p>',
|
|
254
|
+
plaintext: 'isolation',
|
|
255
|
+
inbound: true,
|
|
256
|
+
public: false,
|
|
257
|
+
}); },
|
|
258
|
+
},
|
|
259
|
+
{
|
|
260
|
+
model: 'form_responses',
|
|
261
|
+
ownerField: 'enduserId',
|
|
262
|
+
setup: function (sdk, _enduserBId) { return __awaiter(void 0, void 0, void 0, function () {
|
|
263
|
+
var form;
|
|
264
|
+
return __generator(this, function (_a) {
|
|
265
|
+
switch (_a.label) {
|
|
266
|
+
case 0: return [4 /*yield*/, sdk.api.forms.createOne({ title: "isolation form ".concat(Date.now()) })];
|
|
267
|
+
case 1:
|
|
268
|
+
form = _a.sent();
|
|
269
|
+
return [2 /*return*/, {
|
|
270
|
+
payloadOverride: { formId: form.id },
|
|
271
|
+
cleanup: function () { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) {
|
|
272
|
+
switch (_a.label) {
|
|
273
|
+
case 0: return [4 /*yield*/, sdk.api.forms.deleteOne(form.id).catch(function () { })];
|
|
274
|
+
case 1:
|
|
275
|
+
_a.sent();
|
|
276
|
+
return [2 /*return*/];
|
|
277
|
+
}
|
|
278
|
+
}); }); },
|
|
279
|
+
}];
|
|
280
|
+
}
|
|
281
|
+
});
|
|
282
|
+
}); },
|
|
283
|
+
buildPayload: function (enduserBId) { return ({
|
|
284
|
+
enduserId: enduserBId,
|
|
285
|
+
formId: '',
|
|
286
|
+
formTitle: 'isolation form',
|
|
287
|
+
}); },
|
|
288
|
+
},
|
|
289
|
+
{
|
|
290
|
+
model: 'enduser_eligibility_results',
|
|
291
|
+
ownerField: 'enduserId',
|
|
292
|
+
buildPayload: function (enduserBId) { return ({
|
|
293
|
+
enduserId: enduserBId,
|
|
294
|
+
title: 'isolation: eligibility',
|
|
295
|
+
type: 'Prescription',
|
|
296
|
+
externalId: "iso-".concat(Date.now()),
|
|
297
|
+
source: 'isolation-test',
|
|
298
|
+
status: 'Pending',
|
|
299
|
+
}); },
|
|
300
|
+
},
|
|
301
|
+
];
|
|
302
|
+
var COVERED_MODELS = new Set(MODEL_CASES.map(function (c) { return c.model; }));
|
|
303
|
+
// Models that have a FilterAccessConstraint on enduserId / enduserIds /
|
|
304
|
+
// attendees.id but are intentionally NOT exercised here. Each entry must
|
|
305
|
+
// include a one-line reason. Empty by default; add only with justification.
|
|
306
|
+
var EXEMPT_MODELS = [
|
|
307
|
+
{
|
|
308
|
+
model: 'meetings',
|
|
309
|
+
reason: 'No default CRUD ops — created via admin-only start_meeting and read by endusers via custom my_meetings/read/join_meeting_for_event actions, which do not match this fixture pattern.',
|
|
310
|
+
},
|
|
311
|
+
];
|
|
312
|
+
var RELEVANT_OWNER_FIELDS = new Set(['enduserId', 'enduserIds', 'attendees.id']);
|
|
313
|
+
var discoverEnduserScopedModels = function () {
|
|
314
|
+
var _a;
|
|
315
|
+
var found = [];
|
|
316
|
+
for (var _i = 0, _b = Object.keys(schema); _i < _b.length; _i++) {
|
|
317
|
+
var name_1 = _b[_i];
|
|
318
|
+
var model = schema[name_1];
|
|
319
|
+
var access = (_a = model === null || model === void 0 ? void 0 : model.constraints) === null || _a === void 0 ? void 0 : _a.access;
|
|
320
|
+
if (!access)
|
|
321
|
+
continue;
|
|
322
|
+
var hasFilter = access.some(function (c) { return (c === null || c === void 0 ? void 0 : c.type) === 'filter' && typeof c.field === 'string' && RELEVANT_OWNER_FIELDS.has(c.field); });
|
|
323
|
+
if (hasFilter)
|
|
324
|
+
found.push(name_1);
|
|
325
|
+
}
|
|
326
|
+
return found;
|
|
327
|
+
};
|
|
328
|
+
var assertNotPresent = function (records, id, label) {
|
|
329
|
+
assert(!records.find(function (r) { return r.id === id; }), "".concat(label, " returned record owned by other enduser (id=").concat(id, ")"), label);
|
|
330
|
+
};
|
|
331
|
+
var expectForbidden = function (label, run) { return async_test(label, run, handleAnyError); };
|
|
332
|
+
var expectEmptyOrForbidden = function (label, run) { return async_test(label, function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
333
|
+
var r, _e_1;
|
|
334
|
+
return __generator(this, function (_a) {
|
|
335
|
+
switch (_a.label) {
|
|
336
|
+
case 0:
|
|
337
|
+
_a.trys.push([0, 2, , 3]);
|
|
338
|
+
return [4 /*yield*/, run()];
|
|
339
|
+
case 1:
|
|
340
|
+
r = _a.sent();
|
|
341
|
+
return [2 /*return*/, { rejected: false, length: r.length }];
|
|
342
|
+
case 2:
|
|
343
|
+
_e_1 = _a.sent();
|
|
344
|
+
return [2 /*return*/, { rejected: true, length: 0 }];
|
|
345
|
+
case 3: return [2 /*return*/];
|
|
346
|
+
}
|
|
347
|
+
});
|
|
348
|
+
}); }, { onResult: function (r) { return r.rejected || r.length === 0; } }); };
|
|
349
|
+
var expectMatchesEmptyOrForbidden = function (label, run) { return async_test(label, function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
350
|
+
var r, _e_2;
|
|
351
|
+
var _a;
|
|
352
|
+
return __generator(this, function (_b) {
|
|
353
|
+
switch (_b.label) {
|
|
354
|
+
case 0:
|
|
355
|
+
_b.trys.push([0, 2, , 3]);
|
|
356
|
+
return [4 /*yield*/, run()];
|
|
357
|
+
case 1:
|
|
358
|
+
r = _b.sent();
|
|
359
|
+
return [2 /*return*/, { rejected: false, length: ((_a = r === null || r === void 0 ? void 0 : r.matches) !== null && _a !== void 0 ? _a : []).length }];
|
|
360
|
+
case 2:
|
|
361
|
+
_e_2 = _b.sent();
|
|
362
|
+
return [2 /*return*/, { rejected: true, length: 0 }];
|
|
363
|
+
case 3: return [2 /*return*/];
|
|
364
|
+
}
|
|
365
|
+
});
|
|
366
|
+
}); }, { onResult: function (r) { return r.rejected || r.length === 0; } }); };
|
|
367
|
+
var expectGetOneFails = function (label, run) { return async_test(label, function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
368
|
+
var r, _e_3;
|
|
369
|
+
return __generator(this, function (_a) {
|
|
370
|
+
switch (_a.label) {
|
|
371
|
+
case 0:
|
|
372
|
+
_a.trys.push([0, 2, , 3]);
|
|
373
|
+
return [4 /*yield*/, run()
|
|
374
|
+
// some models may return undefined on no-match; that's also acceptable
|
|
375
|
+
];
|
|
376
|
+
case 1:
|
|
377
|
+
r = _a.sent();
|
|
378
|
+
// some models may return undefined on no-match; that's also acceptable
|
|
379
|
+
return [2 /*return*/, { rejected: false, found: !!r }];
|
|
380
|
+
case 2:
|
|
381
|
+
_e_3 = _a.sent();
|
|
382
|
+
return [2 /*return*/, { rejected: true, found: false }];
|
|
383
|
+
case 3: return [2 /*return*/];
|
|
384
|
+
}
|
|
385
|
+
});
|
|
386
|
+
}); }, { onResult: function (r) { return r.rejected || !r.found; } }); };
|
|
387
|
+
var recordHasOwner = function (record, ownerField, enduserId) {
|
|
388
|
+
if (!record)
|
|
389
|
+
return false;
|
|
390
|
+
if (ownerField === 'enduserId')
|
|
391
|
+
return record.enduserId === enduserId;
|
|
392
|
+
if (ownerField === 'enduserIds')
|
|
393
|
+
return Array.isArray(record.enduserIds) && record.enduserIds.includes(enduserId);
|
|
394
|
+
if (ownerField === 'attendees.id')
|
|
395
|
+
return Array.isArray(record.attendees) && record.attendees.some(function (a) { return (a === null || a === void 0 ? void 0 : a.id) === enduserId; });
|
|
396
|
+
return false;
|
|
397
|
+
};
|
|
398
|
+
export var enduser_cross_access_isolation_tests = function (_a) {
|
|
399
|
+
var sdk = _a.sdk, _sdkNonAdmin = _a.sdkNonAdmin;
|
|
400
|
+
return __awaiter(void 0, void 0, void 0, function () {
|
|
401
|
+
var discovered, exemptSet, missing, password, ts, enduserA, enduserB, sdkA, sdkB, _loop_1, _i, MODEL_CASES_1, c;
|
|
402
|
+
var _b;
|
|
403
|
+
return __generator(this, function (_c) {
|
|
404
|
+
switch (_c.label) {
|
|
405
|
+
case 0:
|
|
406
|
+
log_header("Enduser cross-access isolation");
|
|
407
|
+
discovered = discoverEnduserScopedModels();
|
|
408
|
+
exemptSet = new Set(EXEMPT_MODELS.map(function (e) { return e.model; }));
|
|
409
|
+
missing = discovered.filter(function (m) { return !COVERED_MODELS.has(m) && !exemptSet.has(m); });
|
|
410
|
+
assert(missing.length === 0, "Missing isolation coverage for enduser-scoped models: ".concat(missing.join(', '), ". ") +
|
|
411
|
+
"Add to MODEL_CASES or EXEMPT_MODELS in enduser_cross_access_isolation.test.ts.", 'schema drift guard: every FilterAccessConstraint on enduserId/enduserIds/attendees.id is covered');
|
|
412
|
+
password = 'IsolationTestPassword123!';
|
|
413
|
+
ts = Date.now();
|
|
414
|
+
return [4 /*yield*/, sdk.api.endusers.createOne({ email: "iso_a_".concat(ts, "@test.tellescope.com") })];
|
|
415
|
+
case 1:
|
|
416
|
+
enduserA = _c.sent();
|
|
417
|
+
return [4 /*yield*/, sdk.api.endusers.createOne({ email: "iso_b_".concat(ts, "@test.tellescope.com") })];
|
|
418
|
+
case 2:
|
|
419
|
+
enduserB = _c.sent();
|
|
420
|
+
return [4 /*yield*/, sdk.api.endusers.set_password({ id: enduserA.id, password: password })];
|
|
421
|
+
case 3:
|
|
422
|
+
_c.sent();
|
|
423
|
+
return [4 /*yield*/, sdk.api.endusers.set_password({ id: enduserB.id, password: password })];
|
|
424
|
+
case 4:
|
|
425
|
+
_c.sent();
|
|
426
|
+
sdkA = new EnduserSession({ host: host, businessId: businessId });
|
|
427
|
+
sdkB = new EnduserSession({ host: host, businessId: businessId });
|
|
428
|
+
_c.label = 5;
|
|
429
|
+
case 5:
|
|
430
|
+
_c.trys.push([5, , 12, 15]);
|
|
431
|
+
// Sanity check: each enduser session can authenticate. We only use sdkA
|
|
432
|
+
// for negative assertions, but a failed sdkB auth would mean the test
|
|
433
|
+
// data setup itself is malformed.
|
|
434
|
+
return [4 /*yield*/, sdkA.authenticate(enduserA.email, password)];
|
|
435
|
+
case 6:
|
|
436
|
+
// Sanity check: each enduser session can authenticate. We only use sdkA
|
|
437
|
+
// for negative assertions, but a failed sdkB auth would mean the test
|
|
438
|
+
// data setup itself is malformed.
|
|
439
|
+
_c.sent();
|
|
440
|
+
return [4 /*yield*/, sdkB.authenticate(enduserB.email, password)];
|
|
441
|
+
case 7:
|
|
442
|
+
_c.sent();
|
|
443
|
+
_loop_1 = function (c) {
|
|
444
|
+
var sublog, setupResult, e_1, payload, createdId, created, e_2, enduserApi, _d;
|
|
445
|
+
return __generator(this, function (_f) {
|
|
446
|
+
switch (_f.label) {
|
|
447
|
+
case 0:
|
|
448
|
+
sublog = function (variant) { return "".concat(c.model, ": ").concat(variant); };
|
|
449
|
+
setupResult = void 0;
|
|
450
|
+
if (!c.setup) return [3 /*break*/, 4];
|
|
451
|
+
_f.label = 1;
|
|
452
|
+
case 1:
|
|
453
|
+
_f.trys.push([1, 3, , 4]);
|
|
454
|
+
return [4 /*yield*/, c.setup(sdk, enduserB.id)];
|
|
455
|
+
case 2:
|
|
456
|
+
setupResult = _f.sent();
|
|
457
|
+
return [3 /*break*/, 4];
|
|
458
|
+
case 3:
|
|
459
|
+
e_1 = _f.sent();
|
|
460
|
+
assert(false, "".concat(c.model, ": setup hook failed: ").concat(e_1.message), sublog('setup'));
|
|
461
|
+
return [2 /*return*/, "continue"];
|
|
462
|
+
case 4:
|
|
463
|
+
payload = __assign(__assign({}, c.buildPayload(enduserB.id)), ((_b = setupResult === null || setupResult === void 0 ? void 0 : setupResult.payloadOverride) !== null && _b !== void 0 ? _b : {}));
|
|
464
|
+
_f.label = 5;
|
|
465
|
+
case 5:
|
|
466
|
+
_f.trys.push([5, 7, , 10]);
|
|
467
|
+
return [4 /*yield*/, sdk.api[c.model].createOne(payload)];
|
|
468
|
+
case 6:
|
|
469
|
+
created = _f.sent();
|
|
470
|
+
createdId = created === null || created === void 0 ? void 0 : created.id;
|
|
471
|
+
return [3 /*break*/, 10];
|
|
472
|
+
case 7:
|
|
473
|
+
e_2 = _f.sent();
|
|
474
|
+
assert(false, "".concat(c.model, ": admin createOne failed: ").concat(e_2.message), sublog('admin createOne'));
|
|
475
|
+
if (!setupResult) return [3 /*break*/, 9];
|
|
476
|
+
return [4 /*yield*/, setupResult.cleanup().catch(function () { })];
|
|
477
|
+
case 8:
|
|
478
|
+
_f.sent();
|
|
479
|
+
_f.label = 9;
|
|
480
|
+
case 9: return [2 /*return*/, "continue"];
|
|
481
|
+
case 10:
|
|
482
|
+
if (!!createdId) return [3 /*break*/, 13];
|
|
483
|
+
assert(false, "".concat(c.model, ": admin createOne did not return an id"), sublog('admin createOne'));
|
|
484
|
+
if (!setupResult) return [3 /*break*/, 12];
|
|
485
|
+
return [4 /*yield*/, setupResult.cleanup().catch(function () { })];
|
|
486
|
+
case 11:
|
|
487
|
+
_f.sent();
|
|
488
|
+
_f.label = 12;
|
|
489
|
+
case 12: return [2 /*return*/, "continue"];
|
|
490
|
+
case 13:
|
|
491
|
+
enduserApi = sdkA.api[c.model];
|
|
492
|
+
_f.label = 14;
|
|
493
|
+
case 14:
|
|
494
|
+
_f.trys.push([14, , 27, 33]);
|
|
495
|
+
// 0a. Fixture sanity: admin can re-fetch the record AND its owner
|
|
496
|
+
// field is actually set to enduser B. Without this, A's negative
|
|
497
|
+
// assertions could pass trivially (e.g. if createOne silently
|
|
498
|
+
// dropped the ownership field, no enduser would ever match).
|
|
499
|
+
return [4 /*yield*/, async_test(sublog('fixture: admin re-fetch confirms ownership set to enduser B'), function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
500
|
+
var fetched;
|
|
501
|
+
return __generator(this, function (_a) {
|
|
502
|
+
switch (_a.label) {
|
|
503
|
+
case 0: return [4 /*yield*/, sdk.api[c.model].getOne(createdId)];
|
|
504
|
+
case 1:
|
|
505
|
+
fetched = _a.sent();
|
|
506
|
+
return [2 /*return*/, { fetched: fetched, owned: recordHasOwner(fetched, c.ownerField, enduserB.id) }];
|
|
507
|
+
}
|
|
508
|
+
});
|
|
509
|
+
}); }, { onResult: function (r) { return !!r.fetched && r.owned === true; } })
|
|
510
|
+
// 0b. Fixture sanity: enduser B (the legitimate owner) can see the
|
|
511
|
+
// record via getOne. Models that block all enduser reads (empty
|
|
512
|
+
// enduserActions) will reject — that's accepted. The check fails
|
|
513
|
+
// only if B is "found" returns a different record id.
|
|
514
|
+
];
|
|
515
|
+
case 15:
|
|
516
|
+
// 0a. Fixture sanity: admin can re-fetch the record AND its owner
|
|
517
|
+
// field is actually set to enduser B. Without this, A's negative
|
|
518
|
+
// assertions could pass trivially (e.g. if createOne silently
|
|
519
|
+
// dropped the ownership field, no enduser would ever match).
|
|
520
|
+
_f.sent();
|
|
521
|
+
// 0b. Fixture sanity: enduser B (the legitimate owner) can see the
|
|
522
|
+
// record via getOne. Models that block all enduser reads (empty
|
|
523
|
+
// enduserActions) will reject — that's accepted. The check fails
|
|
524
|
+
// only if B is "found" returns a different record id.
|
|
525
|
+
return [4 /*yield*/, async_test(sublog('fixture: owner enduser B can fetch own record (or model blocks endusers)'), function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
526
|
+
var fetched, _e_4;
|
|
527
|
+
return __generator(this, function (_a) {
|
|
528
|
+
switch (_a.label) {
|
|
529
|
+
case 0:
|
|
530
|
+
_a.trys.push([0, 2, , 3]);
|
|
531
|
+
return [4 /*yield*/, sdkB.api[c.model].getOne(createdId)];
|
|
532
|
+
case 1:
|
|
533
|
+
fetched = _a.sent();
|
|
534
|
+
return [2 /*return*/, { rejected: false, matched: !!fetched && fetched.id === createdId }];
|
|
535
|
+
case 2:
|
|
536
|
+
_e_4 = _a.sent();
|
|
537
|
+
return [2 /*return*/, { rejected: true, matched: false }];
|
|
538
|
+
case 3: return [2 /*return*/];
|
|
539
|
+
}
|
|
540
|
+
});
|
|
541
|
+
}); }, { onResult: function (r) { return r.rejected || r.matched; } })
|
|
542
|
+
// 1. getOne by id — expect throw or undefined
|
|
543
|
+
];
|
|
544
|
+
case 16:
|
|
545
|
+
// 0b. Fixture sanity: enduser B (the legitimate owner) can see the
|
|
546
|
+
// record via getOne. Models that block all enduser reads (empty
|
|
547
|
+
// enduserActions) will reject — that's accepted. The check fails
|
|
548
|
+
// only if B is "found" returns a different record id.
|
|
549
|
+
_f.sent();
|
|
550
|
+
// 1. getOne by id — expect throw or undefined
|
|
551
|
+
return [4 /*yield*/, expectGetOneFails(sublog('getOne by id rejects or returns nothing'), function () { return enduserApi.getOne(createdId); })
|
|
552
|
+
// 2. getOne by ownership filter — expect throw or undefined
|
|
553
|
+
];
|
|
554
|
+
case 17:
|
|
555
|
+
// 1. getOne by id — expect throw or undefined
|
|
556
|
+
_f.sent();
|
|
557
|
+
// 2. getOne by ownership filter — expect throw or undefined
|
|
558
|
+
return [4 /*yield*/, expectGetOneFails(sublog('getOne by owner filter rejects or returns nothing'), function () {
|
|
559
|
+
var _a;
|
|
560
|
+
return enduserApi.getOne((_a = {}, _a[c.ownerField] = enduserB.id, _a));
|
|
561
|
+
})
|
|
562
|
+
// 3. getSome (no filter) — record must not appear (or call rejected)
|
|
563
|
+
];
|
|
564
|
+
case 18:
|
|
565
|
+
// 2. getOne by ownership filter — expect throw or undefined
|
|
566
|
+
_f.sent();
|
|
567
|
+
// 3. getSome (no filter) — record must not appear (or call rejected)
|
|
568
|
+
return [4 /*yield*/, async_test(sublog('getSome (no filter) excludes other-enduser record'), function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
569
|
+
var records, _e_5;
|
|
570
|
+
return __generator(this, function (_a) {
|
|
571
|
+
switch (_a.label) {
|
|
572
|
+
case 0:
|
|
573
|
+
_a.trys.push([0, 2, , 3]);
|
|
574
|
+
return [4 /*yield*/, enduserApi.getSome({})];
|
|
575
|
+
case 1:
|
|
576
|
+
records = _a.sent();
|
|
577
|
+
return [2 /*return*/, { rejected: false, hasRecord: !!records.find(function (r) { return r.id === createdId; }) }];
|
|
578
|
+
case 2:
|
|
579
|
+
_e_5 = _a.sent();
|
|
580
|
+
return [2 /*return*/, { rejected: true, hasRecord: false }];
|
|
581
|
+
case 3: return [2 /*return*/];
|
|
582
|
+
}
|
|
583
|
+
});
|
|
584
|
+
}); }, { onResult: function (r) { return r.rejected || !r.hasRecord; } })
|
|
585
|
+
// 4. getSome (owner filter) — must be empty (or rejected)
|
|
586
|
+
];
|
|
587
|
+
case 19:
|
|
588
|
+
// 3. getSome (no filter) — record must not appear (or call rejected)
|
|
589
|
+
_f.sent();
|
|
590
|
+
// 4. getSome (owner filter) — must be empty (or rejected)
|
|
591
|
+
return [4 /*yield*/, expectEmptyOrForbidden(sublog('getSome (owner filter) returns empty or rejects'), function () {
|
|
592
|
+
var _a;
|
|
593
|
+
return enduserApi.getSome({ filter: (_a = {}, _a[c.ownerField] = enduserB.id, _a) });
|
|
594
|
+
})
|
|
595
|
+
// 5. getByIds — matches must be empty (or rejected)
|
|
596
|
+
];
|
|
597
|
+
case 20:
|
|
598
|
+
// 4. getSome (owner filter) — must be empty (or rejected)
|
|
599
|
+
_f.sent();
|
|
600
|
+
// 5. getByIds — matches must be empty (or rejected)
|
|
601
|
+
return [4 /*yield*/, expectMatchesEmptyOrForbidden(sublog('getByIds returns no matches or rejects'), function () { return enduserApi.getByIds({ ids: [createdId] }); })
|
|
602
|
+
// 6. /bulk-actions/read with owner filter
|
|
603
|
+
];
|
|
604
|
+
case 21:
|
|
605
|
+
// 5. getByIds — matches must be empty (or rejected)
|
|
606
|
+
_f.sent();
|
|
607
|
+
// 6. /bulk-actions/read with owner filter
|
|
608
|
+
return [4 /*yield*/, async_test(sublog('bulk_load (owner filter) returns null or empty for other-enduser data'), function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
609
|
+
var r, result, _e_6;
|
|
610
|
+
var _a;
|
|
611
|
+
return __generator(this, function (_b) {
|
|
612
|
+
switch (_b.label) {
|
|
613
|
+
case 0:
|
|
614
|
+
_b.trys.push([0, 2, , 3]);
|
|
615
|
+
return [4 /*yield*/, sdkA.bulk_load({
|
|
616
|
+
load: [{
|
|
617
|
+
model: c.model,
|
|
618
|
+
options: { filter: (_a = {}, _a[c.ownerField] = enduserB.id, _a) },
|
|
619
|
+
}],
|
|
620
|
+
})];
|
|
621
|
+
case 1:
|
|
622
|
+
r = _b.sent();
|
|
623
|
+
result = r.results[0];
|
|
624
|
+
if (result === null)
|
|
625
|
+
return [2 /*return*/, { ok: true }];
|
|
626
|
+
return [2 /*return*/, { ok: result.records.length === 0, count: result.records.length }];
|
|
627
|
+
case 2:
|
|
628
|
+
_e_6 = _b.sent();
|
|
629
|
+
return [2 /*return*/, { ok: true }]; // rejection is also safe
|
|
630
|
+
case 3: return [2 /*return*/];
|
|
631
|
+
}
|
|
632
|
+
});
|
|
633
|
+
}); }, { onResult: function (r) { return r.ok === true; } })
|
|
634
|
+
// 7. /bulk-actions/read with no filter — record must not appear
|
|
635
|
+
];
|
|
636
|
+
case 22:
|
|
637
|
+
// 6. /bulk-actions/read with owner filter
|
|
638
|
+
_f.sent();
|
|
639
|
+
// 7. /bulk-actions/read with no filter — record must not appear
|
|
640
|
+
return [4 /*yield*/, async_test(sublog('bulk_load (no filter) excludes other-enduser record'), function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
641
|
+
var r, result, _e_7;
|
|
642
|
+
return __generator(this, function (_a) {
|
|
643
|
+
switch (_a.label) {
|
|
644
|
+
case 0:
|
|
645
|
+
_a.trys.push([0, 2, , 3]);
|
|
646
|
+
return [4 /*yield*/, sdkA.bulk_load({
|
|
647
|
+
load: [{ model: c.model, options: {} }],
|
|
648
|
+
})];
|
|
649
|
+
case 1:
|
|
650
|
+
r = _a.sent();
|
|
651
|
+
result = r.results[0];
|
|
652
|
+
if (result === null)
|
|
653
|
+
return [2 /*return*/, { ok: true }];
|
|
654
|
+
return [2 /*return*/, { ok: !result.records.find(function (rec) { return rec.id === createdId; }) }];
|
|
655
|
+
case 2:
|
|
656
|
+
_e_7 = _a.sent();
|
|
657
|
+
return [2 /*return*/, { ok: true }];
|
|
658
|
+
case 3: return [2 /*return*/];
|
|
659
|
+
}
|
|
660
|
+
});
|
|
661
|
+
}); }, { onResult: function (r) { return r.ok === true; } })
|
|
662
|
+
// 8. updateOne — expect throw
|
|
663
|
+
];
|
|
664
|
+
case 23:
|
|
665
|
+
// 7. /bulk-actions/read with no filter — record must not appear
|
|
666
|
+
_f.sent();
|
|
667
|
+
// 8. updateOne — expect throw
|
|
668
|
+
return [4 /*yield*/, expectForbidden(sublog('updateOne rejects'), function () { return enduserApi.updateOne(createdId, { /* no-op-ish update */}); })
|
|
669
|
+
// 9. deleteOne — expect throw
|
|
670
|
+
];
|
|
671
|
+
case 24:
|
|
672
|
+
// 8. updateOne — expect throw
|
|
673
|
+
_f.sent();
|
|
674
|
+
// 9. deleteOne — expect throw
|
|
675
|
+
return [4 /*yield*/, expectForbidden(sublog('deleteOne rejects'), function () { return enduserApi.deleteOne(createdId); })
|
|
676
|
+
// After all attempted writes, confirm the record still exists when
|
|
677
|
+
// fetched as admin — i.e. enduser A's failed update/delete were no-ops.
|
|
678
|
+
];
|
|
679
|
+
case 25:
|
|
680
|
+
// 9. deleteOne — expect throw
|
|
681
|
+
_f.sent();
|
|
682
|
+
// After all attempted writes, confirm the record still exists when
|
|
683
|
+
// fetched as admin — i.e. enduser A's failed update/delete were no-ops.
|
|
684
|
+
return [4 /*yield*/, async_test(sublog('record still exists after failed enduser writes (admin verify)'), function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
685
|
+
var found, _a;
|
|
686
|
+
return __generator(this, function (_b) {
|
|
687
|
+
switch (_b.label) {
|
|
688
|
+
case 0:
|
|
689
|
+
_b.trys.push([0, 2, , 3]);
|
|
690
|
+
return [4 /*yield*/, sdk.api[c.model].getOne(createdId)];
|
|
691
|
+
case 1:
|
|
692
|
+
found = _b.sent();
|
|
693
|
+
return [2 /*return*/, !!found && found.id === createdId];
|
|
694
|
+
case 2:
|
|
695
|
+
_a = _b.sent();
|
|
696
|
+
return [2 /*return*/, false];
|
|
697
|
+
case 3: return [2 /*return*/];
|
|
698
|
+
}
|
|
699
|
+
});
|
|
700
|
+
}); }, { onResult: function (r) { return r === true; } })];
|
|
701
|
+
case 26:
|
|
702
|
+
// After all attempted writes, confirm the record still exists when
|
|
703
|
+
// fetched as admin — i.e. enduser A's failed update/delete were no-ops.
|
|
704
|
+
_f.sent();
|
|
705
|
+
return [3 /*break*/, 33];
|
|
706
|
+
case 27:
|
|
707
|
+
_f.trys.push([27, 29, , 30]);
|
|
708
|
+
return [4 /*yield*/, sdk.api[c.model].deleteOne(createdId).catch(function () { })];
|
|
709
|
+
case 28:
|
|
710
|
+
_f.sent();
|
|
711
|
+
return [3 /*break*/, 30];
|
|
712
|
+
case 29:
|
|
713
|
+
_d = _f.sent();
|
|
714
|
+
return [3 /*break*/, 30];
|
|
715
|
+
case 30:
|
|
716
|
+
if (!setupResult) return [3 /*break*/, 32];
|
|
717
|
+
return [4 /*yield*/, setupResult.cleanup().catch(function () { })];
|
|
718
|
+
case 31:
|
|
719
|
+
_f.sent();
|
|
720
|
+
_f.label = 32;
|
|
721
|
+
case 32: return [7 /*endfinally*/];
|
|
722
|
+
case 33: return [2 /*return*/];
|
|
723
|
+
}
|
|
724
|
+
});
|
|
725
|
+
};
|
|
726
|
+
_i = 0, MODEL_CASES_1 = MODEL_CASES;
|
|
727
|
+
_c.label = 8;
|
|
728
|
+
case 8:
|
|
729
|
+
if (!(_i < MODEL_CASES_1.length)) return [3 /*break*/, 11];
|
|
730
|
+
c = MODEL_CASES_1[_i];
|
|
731
|
+
return [5 /*yield**/, _loop_1(c)];
|
|
732
|
+
case 9:
|
|
733
|
+
_c.sent();
|
|
734
|
+
_c.label = 10;
|
|
735
|
+
case 10:
|
|
736
|
+
_i++;
|
|
737
|
+
return [3 /*break*/, 8];
|
|
738
|
+
case 11: return [3 /*break*/, 15];
|
|
739
|
+
case 12: return [4 /*yield*/, sdk.api.endusers.deleteOne(enduserA.id).catch(function () { })];
|
|
740
|
+
case 13:
|
|
741
|
+
_c.sent();
|
|
742
|
+
return [4 /*yield*/, sdk.api.endusers.deleteOne(enduserB.id).catch(function () { })];
|
|
743
|
+
case 14:
|
|
744
|
+
_c.sent();
|
|
745
|
+
return [7 /*endfinally*/];
|
|
746
|
+
case 15: return [2 /*return*/];
|
|
747
|
+
}
|
|
748
|
+
});
|
|
749
|
+
});
|
|
750
|
+
};
|
|
751
|
+
if (require.main === module) {
|
|
752
|
+
console.log("Using API URL: ".concat(host));
|
|
753
|
+
var sdk_1 = new Session({ host: host });
|
|
754
|
+
var sdkNonAdmin_1 = new Session({ host: host });
|
|
755
|
+
var runTests = function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
756
|
+
return __generator(this, function (_a) {
|
|
757
|
+
switch (_a.label) {
|
|
758
|
+
case 0: return [4 /*yield*/, setup_tests(sdk_1, sdkNonAdmin_1)];
|
|
759
|
+
case 1:
|
|
760
|
+
_a.sent();
|
|
761
|
+
return [4 /*yield*/, enduser_cross_access_isolation_tests({ sdk: sdk_1, sdkNonAdmin: sdkNonAdmin_1 })];
|
|
762
|
+
case 2:
|
|
763
|
+
_a.sent();
|
|
764
|
+
return [2 /*return*/];
|
|
765
|
+
}
|
|
766
|
+
});
|
|
767
|
+
}); };
|
|
768
|
+
runTests()
|
|
769
|
+
.then(function () {
|
|
770
|
+
console.log("Enduser cross-access isolation test suite completed successfully");
|
|
771
|
+
process.exit(0);
|
|
772
|
+
})
|
|
773
|
+
.catch(function (error) {
|
|
774
|
+
console.error("Enduser cross-access isolation test suite failed:", error);
|
|
775
|
+
process.exit(1);
|
|
776
|
+
});
|
|
777
|
+
}
|
|
778
|
+
//# sourceMappingURL=enduser_cross_access_isolation.test.js.map
|