@tellescope/sdk 1.255.19 → 1.256.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/tests/api_tests/custom_dashboards.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/custom_dashboards.test.js +99 -8
- package/lib/cjs/tests/api_tests/custom_dashboards.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/default_summary_journey.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/default_summary_journey.test.js.map +1 -0
- package/lib/cjs/tests/api_tests/file_download_unicode_names.test.d.ts +6 -0
- package/lib/cjs/tests/api_tests/file_download_unicode_names.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/file_download_unicode_names.test.js +278 -0
- package/lib/cjs/tests/api_tests/file_download_unicode_names.test.js.map +1 -0
- package/lib/cjs/tests/api_tests/openloop_webhooks.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/openloop_webhooks.test.js +212 -33
- package/lib/cjs/tests/api_tests/openloop_webhooks.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/phone_calls_cold_transfer.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/phone_calls_cold_transfer.test.js +85 -9
- package/lib/cjs/tests/api_tests/phone_calls_cold_transfer.test.js.map +1 -1
- package/lib/cjs/tests/api_tests/security/F-0013-sanitize-user-html-with-iframes.test.d.ts +2 -0
- package/lib/cjs/tests/api_tests/security/F-0013-sanitize-user-html-with-iframes.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/security/F-0013-sanitize-user-html-with-iframes.test.js +242 -0
- package/lib/cjs/tests/api_tests/security/F-0013-sanitize-user-html-with-iframes.test.js.map +1 -0
- package/lib/cjs/tests/api_tests/security/F-0015-webhook-outbound-ssrf.test.d.ts +29 -0
- package/lib/cjs/tests/api_tests/security/F-0015-webhook-outbound-ssrf.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/security/F-0015-webhook-outbound-ssrf.test.js +443 -0
- package/lib/cjs/tests/api_tests/security/F-0015-webhook-outbound-ssrf.test.js.map +1 -0
- package/lib/cjs/tests/api_tests/security/F-0025-proxy-image-unauth-ssrf.test.d.ts +35 -0
- package/lib/cjs/tests/api_tests/security/F-0025-proxy-image-unauth-ssrf.test.d.ts.map +1 -0
- package/lib/cjs/tests/api_tests/security/F-0025-proxy-image-unauth-ssrf.test.js +231 -0
- package/lib/cjs/tests/api_tests/security/F-0025-proxy-image-unauth-ssrf.test.js.map +1 -0
- package/lib/cjs/tests/api_tests/security/F-0166-allowed-paths-wildcard-bypass.test.d.ts.map +1 -1
- package/lib/cjs/tests/api_tests/security/F-0166-allowed-paths-wildcard-bypass.test.js +524 -294
- package/lib/cjs/tests/api_tests/security/F-0166-allowed-paths-wildcard-bypass.test.js.map +1 -1
- package/lib/cjs/tests/tests.d.ts.map +1 -1
- package/lib/cjs/tests/tests.js +431 -230
- package/lib/cjs/tests/tests.js.map +1 -1
- package/lib/esm/enduser.d.ts +0 -1
- package/lib/esm/enduser.d.ts.map +1 -1
- package/lib/esm/sdk.d.ts +2 -3
- package/lib/esm/sdk.d.ts.map +1 -1
- package/lib/esm/session.d.ts +0 -1
- package/lib/esm/session.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/custom_dashboards.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/custom_dashboards.test.js +99 -8
- package/lib/esm/tests/api_tests/custom_dashboards.test.js.map +1 -1
- package/lib/esm/tests/api_tests/default_summary_journey.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/default_summary_journey.test.js.map +1 -0
- package/lib/esm/tests/api_tests/file_download_unicode_names.test.d.ts +6 -0
- package/lib/esm/tests/api_tests/file_download_unicode_names.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/file_download_unicode_names.test.js +248 -0
- package/lib/esm/tests/api_tests/file_download_unicode_names.test.js.map +1 -0
- package/lib/esm/tests/api_tests/openloop_webhooks.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/openloop_webhooks.test.js +213 -34
- package/lib/esm/tests/api_tests/openloop_webhooks.test.js.map +1 -1
- package/lib/esm/tests/api_tests/phone_calls_cold_transfer.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/phone_calls_cold_transfer.test.js +85 -9
- package/lib/esm/tests/api_tests/phone_calls_cold_transfer.test.js.map +1 -1
- package/lib/esm/tests/api_tests/security/F-0013-sanitize-user-html-with-iframes.test.d.ts +2 -0
- package/lib/esm/tests/api_tests/security/F-0013-sanitize-user-html-with-iframes.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/security/F-0013-sanitize-user-html-with-iframes.test.js +238 -0
- package/lib/esm/tests/api_tests/security/F-0013-sanitize-user-html-with-iframes.test.js.map +1 -0
- package/lib/esm/tests/api_tests/security/F-0015-webhook-outbound-ssrf.test.d.ts +29 -0
- package/lib/esm/tests/api_tests/security/F-0015-webhook-outbound-ssrf.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/security/F-0015-webhook-outbound-ssrf.test.js +436 -0
- package/lib/esm/tests/api_tests/security/F-0015-webhook-outbound-ssrf.test.js.map +1 -0
- package/lib/esm/tests/api_tests/security/F-0025-proxy-image-unauth-ssrf.test.d.ts +35 -0
- package/lib/esm/tests/api_tests/security/F-0025-proxy-image-unauth-ssrf.test.d.ts.map +1 -0
- package/lib/esm/tests/api_tests/security/F-0025-proxy-image-unauth-ssrf.test.js +224 -0
- package/lib/esm/tests/api_tests/security/F-0025-proxy-image-unauth-ssrf.test.js.map +1 -0
- package/lib/esm/tests/api_tests/security/F-0166-allowed-paths-wildcard-bypass.test.d.ts.map +1 -1
- package/lib/esm/tests/api_tests/security/F-0166-allowed-paths-wildcard-bypass.test.js +524 -294
- package/lib/esm/tests/api_tests/security/F-0166-allowed-paths-wildcard-bypass.test.js.map +1 -1
- package/lib/esm/tests/tests.d.ts.map +1 -1
- package/lib/esm/tests/tests.js +431 -230
- package/lib/esm/tests/tests.js.map +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +10 -10
- package/src/tests/api_tests/custom_dashboards.test.ts +92 -0
- package/src/tests/api_tests/file_download_unicode_names.test.ts +223 -0
- package/src/tests/api_tests/openloop_webhooks.test.ts +138 -0
- package/src/tests/api_tests/phone_calls_cold_transfer.test.ts +54 -0
- package/src/tests/api_tests/security/F-0013-sanitize-user-html-with-iframes.test.ts +215 -0
- package/src/tests/api_tests/security/F-0166-allowed-paths-wildcard-bypass.test.ts +215 -0
- package/src/tests/tests.ts +212 -1
- package/test_generated.pdf +0 -0
|
@@ -102,10 +102,11 @@ var OBJECT_ID = '68a1b2c3d4e5f60718293a4b';
|
|
|
102
102
|
var allowed_paths_confinement_tests = function (_a) {
|
|
103
103
|
var sdk = _a.sdk;
|
|
104
104
|
return __awaiter(void 0, void 0, void 0, function () {
|
|
105
|
-
var probes, request, isPathDenial, expectDenied, expectAllowed, formId, productId, joinEnduserId, formEnduserEmail, hostUserId, eventIds, businessId, form, publicFormSession, product, joinEnduser, joinLinkToken, joinEvent, unrelatedEvent, joinSession, hostUser, startLinkToken, startEvent, startSession, baselineEnduserToken, baselineUserToken, S1, S2, refreshedJoin, refreshedJoinToken, S3, refreshedStart, refreshedStartToken, S4, prefixGranted,
|
|
106
|
-
var
|
|
107
|
-
|
|
108
|
-
|
|
105
|
+
var probes, request, isPathDenial, expectDenied, expectAllowed, formId, productId, joinEnduserId, formEnduserEmail, hostUserId, templateId, bookingEnduserId, eventIds, businessId, form, publicFormSession, product, joinEnduser, joinLinkToken, joinEvent, unrelatedEvent, joinSession, hostUser, startLinkToken, startEvent, startSession, baselineEnduserToken, baselineUserToken, S1, formEnduserId, publicRefresh, refreshedEnduser_1, withheld, consentEcho, echoedKeys, leakedKeys, fieldsThatMustBeRefused, _i, fieldsThatMustBeRefused_1, _b, field, value, r, mixed, afterProbes, S2, attendanceWrite, echoedEvent, refreshedJoin, refreshedJoinToken, S3, refreshedStart, refreshedStartToken, S4, prefixGranted, _c, prefixGranted_1, _d, method, path, r, S6, ABSENT_ID_A, ABSENT_ID_B, INVALID_EMAIL, consentAttempt, refreshedForScopes, rescopedToken, S7, bookingTemplate, bookingEnduserEmail, bookingEnduser, bookingSession, bookingEcho, bookingLeaked, _e, _f, _g, field, value, r, S5, _h, _j, path, _k, _l, path, adminAuthenticated, apiKeySDK, _m, _o, path, r, failures, scenarios, _loop_1, _p, scenarios_1, scenario, _q, probes_1, p, _r, eventIds_1, id, _s, _t, e, _u, _v, _w, _x, _y, _z;
|
|
106
|
+
var _0, _1;
|
|
107
|
+
var _2, _3, _4, _5, _6, _7, _8, _9, _10;
|
|
108
|
+
return __generator(this, function (_11) {
|
|
109
|
+
switch (_11.label) {
|
|
109
110
|
case 0:
|
|
110
111
|
(0, testing_1.log_header)("F-0166: allowedPaths wildcard bypasses session path confinement");
|
|
111
112
|
probes = [];
|
|
@@ -172,16 +173,16 @@ var allowed_paths_confinement_tests = function (_a) {
|
|
|
172
173
|
});
|
|
173
174
|
};
|
|
174
175
|
eventIds = [];
|
|
175
|
-
|
|
176
|
+
_11.label = 1;
|
|
176
177
|
case 1:
|
|
177
|
-
|
|
178
|
+
_11.trys.push([1, , 123, 160]);
|
|
178
179
|
businessId = sdk.userInfo.businessId;
|
|
179
180
|
return [4 /*yield*/, sdk.api.forms.createOne({
|
|
180
181
|
title: "F-0166 path confinement ".concat(RAND()),
|
|
181
182
|
allowPublicURL: true,
|
|
182
183
|
})];
|
|
183
184
|
case 2:
|
|
184
|
-
form =
|
|
185
|
+
form = _11.sent();
|
|
185
186
|
formId = form.id;
|
|
186
187
|
return [4 /*yield*/, sdk.api.form_fields.createOne({
|
|
187
188
|
formId: form.id,
|
|
@@ -190,7 +191,7 @@ var allowed_paths_confinement_tests = function (_a) {
|
|
|
190
191
|
previousFields: [{ type: 'root', info: {} }],
|
|
191
192
|
})];
|
|
192
193
|
case 3:
|
|
193
|
-
|
|
194
|
+
_11.sent();
|
|
194
195
|
formEnduserEmail = "f0166-form-".concat(RAND(), "@tellescope.example");
|
|
195
196
|
return [4 /*yield*/, new sdk_1.EnduserSession({ host: host, businessId: businessId })
|
|
196
197
|
.api.form_responses.session_for_public_form({
|
|
@@ -202,20 +203,20 @@ var allowed_paths_confinement_tests = function (_a) {
|
|
|
202
203
|
skipMatch: true, // also skips the intake-phone requirement
|
|
203
204
|
})];
|
|
204
205
|
case 4:
|
|
205
|
-
publicFormSession =
|
|
206
|
+
publicFormSession = _11.sent();
|
|
206
207
|
return [4 /*yield*/, sdk.api.products.createOne({
|
|
207
208
|
title: "F-0166 product ".concat(RAND()),
|
|
208
209
|
cost: { amount: 500, currency: 'USD' },
|
|
209
210
|
processor: 'Stripe',
|
|
210
211
|
})];
|
|
211
212
|
case 5:
|
|
212
|
-
product =
|
|
213
|
+
product = _11.sent();
|
|
213
214
|
productId = product.id;
|
|
214
215
|
return [4 /*yield*/, sdk.api.endusers.createOne({
|
|
215
216
|
email: "f0166-join-".concat(RAND(), "@tellescope.example"),
|
|
216
217
|
})];
|
|
217
218
|
case 6:
|
|
218
|
-
joinEnduser =
|
|
219
|
+
joinEnduser = _11.sent();
|
|
219
220
|
joinEnduserId = joinEnduser.id;
|
|
220
221
|
joinLinkToken = "f0166-join-".concat(RAND()).concat(RAND());
|
|
221
222
|
return [4 /*yield*/, sdk.api.calendar_events.createOne({
|
|
@@ -223,14 +224,14 @@ var allowed_paths_confinement_tests = function (_a) {
|
|
|
223
224
|
attendees: [{ type: 'enduser', id: joinEnduser.id, joinLinkToken: joinLinkToken }],
|
|
224
225
|
})];
|
|
225
226
|
case 7:
|
|
226
|
-
joinEvent =
|
|
227
|
+
joinEvent = _11.sent();
|
|
227
228
|
eventIds.push(joinEvent.id);
|
|
228
229
|
return [4 /*yield*/, sdk.api.calendar_events.createOne({
|
|
229
230
|
title: 'F-0166 unrelated', durationInMinutes: 30, startTimeInMS: Date.now() + 3600000,
|
|
230
231
|
attendees: [{ type: 'enduser', id: joinEnduser.id }],
|
|
231
232
|
})];
|
|
232
233
|
case 8:
|
|
233
|
-
unrelatedEvent =
|
|
234
|
+
unrelatedEvent = _11.sent();
|
|
234
235
|
eventIds.push(unrelatedEvent.id);
|
|
235
236
|
return [4 /*yield*/, new sdk_1.EnduserSession({ host: host, businessId: businessId })
|
|
236
237
|
.api.calendar_events.session_for_join_link({ token: joinLinkToken })
|
|
@@ -238,7 +239,7 @@ var allowed_paths_confinement_tests = function (_a) {
|
|
|
238
239
|
// throwaway user; verifiedEmail must be set at create time (it is rejected on update)
|
|
239
240
|
];
|
|
240
241
|
case 9:
|
|
241
|
-
joinSession =
|
|
242
|
+
joinSession = _11.sent();
|
|
242
243
|
return [4 /*yield*/, sdk.api.users.createOne({
|
|
243
244
|
email: "f0166-host-".concat(RAND(), "@tellescope.example"),
|
|
244
245
|
fname: 'Path', lname: 'Host',
|
|
@@ -246,7 +247,7 @@ var allowed_paths_confinement_tests = function (_a) {
|
|
|
246
247
|
notificationEmailsDisabled: true,
|
|
247
248
|
})];
|
|
248
249
|
case 10:
|
|
249
|
-
hostUser =
|
|
250
|
+
hostUser = _11.sent();
|
|
250
251
|
hostUserId = hostUser.id;
|
|
251
252
|
startLinkToken = "f0166-start-".concat(RAND()).concat(RAND());
|
|
252
253
|
return [4 /*yield*/, sdk.api.calendar_events.createOne({
|
|
@@ -255,204 +256,333 @@ var allowed_paths_confinement_tests = function (_a) {
|
|
|
255
256
|
startLinkToken: startLinkToken,
|
|
256
257
|
})];
|
|
257
258
|
case 11:
|
|
258
|
-
startEvent =
|
|
259
|
+
startEvent = _11.sent();
|
|
259
260
|
eventIds.push(startEvent.id);
|
|
260
261
|
return [4 /*yield*/, sdk.api.calendar_events.session_for_start_link({ token: startLinkToken })
|
|
261
262
|
// -- unconfined baselines of each session type (generate_auth_token, never .authenticate)
|
|
262
263
|
];
|
|
263
264
|
case 12:
|
|
264
|
-
startSession =
|
|
265
|
+
startSession = _11.sent();
|
|
265
266
|
return [4 /*yield*/, sdk.api.endusers.generate_auth_token({ id: joinEnduser.id })];
|
|
266
267
|
case 13:
|
|
267
|
-
baselineEnduserToken = (
|
|
268
|
+
baselineEnduserToken = (_11.sent()).authToken;
|
|
268
269
|
return [4 /*yield*/, sdk.api.users.generate_auth_token({ id: hostUser.id })
|
|
269
270
|
/* ============ S1: public-form session — no wildcard, correctly confined already ============ */
|
|
270
271
|
];
|
|
271
272
|
case 14:
|
|
272
|
-
baselineUserToken = (
|
|
273
|
+
baselineUserToken = (_11.sent()).authToken;
|
|
273
274
|
S1 = 'S1 public-form';
|
|
274
275
|
return [4 /*yield*/, expectAllowed(S1, 'always-allowed path', publicFormSession.authToken, 'get', '/test-authenticated')];
|
|
275
276
|
case 15:
|
|
276
|
-
|
|
277
|
+
_11.sent();
|
|
277
278
|
return [4 /*yield*/, expectAllowed(S1, 'listed: form info for access code', publicFormSession.authToken, 'get', '/form-info-for-access-code', { accessCode: publicFormSession.accessCode })];
|
|
278
279
|
case 16:
|
|
279
|
-
|
|
280
|
+
_11.sent();
|
|
280
281
|
return [4 /*yield*/, expectAllowed(S1, 'listed: refresh enduser session', publicFormSession.authToken, 'post', '/refresh-enduser-session')];
|
|
281
282
|
case 17:
|
|
282
|
-
|
|
283
|
+
_11.sent();
|
|
283
284
|
return [4 /*yield*/, expectAllowed(S1, 'listed: product by id', publicFormSession.authToken, 'get', "/product/".concat(productId))];
|
|
284
285
|
case 18:
|
|
285
|
-
|
|
286
|
+
_11.sent();
|
|
286
287
|
return [4 /*yield*/, expectDenied(S1, 'unlisted: calendar events', publicFormSession.authToken, baselineEnduserToken, 'get', '/calendar-events')];
|
|
287
288
|
case 19:
|
|
288
|
-
|
|
289
|
+
_11.sent();
|
|
289
290
|
return [4 /*yield*/, expectDenied(S1, 'unlisted: form responses', publicFormSession.authToken, baselineEnduserToken, 'get', '/form-responses')];
|
|
290
291
|
case 20:
|
|
291
|
-
|
|
292
|
+
_11.sent();
|
|
292
293
|
return [4 /*yield*/, expectDenied(S1, 'unlisted: files', publicFormSession.authToken, baselineEnduserToken, 'get', '/files')
|
|
293
294
|
// 'get:/product' names one route, so it no longer leaks the whole /products namespace the way a
|
|
294
295
|
// bare '/product' prefix entry did — that used to reach /products/prepare-stripe-checkout too
|
|
295
296
|
];
|
|
296
297
|
case 21:
|
|
297
|
-
|
|
298
|
+
_11.sent();
|
|
298
299
|
// 'get:/product' names one route, so it no longer leaks the whole /products namespace the way a
|
|
299
300
|
// bare '/product' prefix entry did — that used to reach /products/prepare-stripe-checkout too
|
|
300
301
|
return [4 /*yield*/, expectDenied(S1, 'exact matching: /products not granted by get:/product', publicFormSession.authToken, baselineEnduserToken, 'get', '/products')
|
|
301
|
-
/*
|
|
302
|
+
/* ---- field confinement on the granted generic update route ----
|
|
303
|
+
* 'patch:/enduser/:id' is granted for Portal V2's terms gate, so the route check alone no longer
|
|
304
|
+
* protects this session — SESSION_SCOPE_WRITABLE_FIELDS does. These probes are the live control:
|
|
305
|
+
* the consent write lands, and every contactable/identity field is refused. Without them the
|
|
306
|
+
* module test is the only thing standing between a scope-table edit and account takeover.
|
|
307
|
+
*/
|
|
302
308
|
];
|
|
303
309
|
case 22:
|
|
304
310
|
// 'get:/product' names one route, so it no longer leaks the whole /products namespace the way a
|
|
305
311
|
// bare '/product' prefix entry did — that used to reach /products/prepare-stripe-checkout too
|
|
306
|
-
|
|
312
|
+
_11.sent();
|
|
313
|
+
formEnduserId = publicFormSession.enduserId;
|
|
314
|
+
return [4 /*yield*/, request(publicFormSession.authToken, 'post', '/refresh-enduser-session', {})];
|
|
315
|
+
case 23:
|
|
316
|
+
publicRefresh = _11.sent();
|
|
317
|
+
refreshedEnduser_1 = (_3 = (_2 = publicRefresh.body) === null || _2 === void 0 ? void 0 : _2.enduser) !== null && _3 !== void 0 ? _3 : {};
|
|
318
|
+
probes.push({
|
|
319
|
+
scenario: S1,
|
|
320
|
+
label: 'public refresh exposes the session\'s own id',
|
|
321
|
+
path: '/refresh-enduser-session',
|
|
322
|
+
expected: 'allowed',
|
|
323
|
+
status: refreshedEnduser_1.id === formEnduserId ? 200 : 500,
|
|
324
|
+
pass: refreshedEnduser_1.id === formEnduserId,
|
|
325
|
+
note: "id=".concat(refreshedEnduser_1.id),
|
|
326
|
+
});
|
|
327
|
+
withheld = ['email', 'phone', 'dateOfBirth', 'fname', 'lname', 'note', 'insurance', 'tags']
|
|
328
|
+
.filter(function (f) { return refreshedEnduser_1[f] !== undefined; });
|
|
329
|
+
probes.push({
|
|
330
|
+
scenario: S1,
|
|
331
|
+
label: 'public refresh still withholds the patient record',
|
|
332
|
+
path: '/refresh-enduser-session',
|
|
333
|
+
expected: 'denied',
|
|
334
|
+
status: withheld.length ? 200 : 403,
|
|
335
|
+
pass: withheld.length === 0,
|
|
336
|
+
note: withheld.length ? "LEAKED [".concat(withheld, "]") : "keys=[".concat(Object.keys(refreshedEnduser_1), "]"),
|
|
337
|
+
});
|
|
338
|
+
return [4 /*yield*/, expectAllowed(S1, 'field-restricted: may record terms consent', publicFormSession.authToken, 'patch', "/enduser/".concat(formEnduserId), { updates: { termsSigned: new Date().toISOString(), termsVersion: '1' } })
|
|
339
|
+
// The write being confined is not enough: the update RESPONSE is not redacted for enduser sessions
|
|
340
|
+
// (applyRedactions runs only for user sessions on that path), so an unprojected echo would hand
|
|
341
|
+
// this session the record it can't otherwise read — GET /enduser/:id is not even in this scope.
|
|
342
|
+
// Assert the response carries ONLY what the session was allowed to write.
|
|
343
|
+
];
|
|
344
|
+
case 24:
|
|
345
|
+
_11.sent();
|
|
346
|
+
return [4 /*yield*/, request(publicFormSession.authToken, 'patch', "/enduser/".concat(formEnduserId), { updates: { termsVersion: '2' } })];
|
|
347
|
+
case 25:
|
|
348
|
+
consentEcho = _11.sent();
|
|
349
|
+
echoedKeys = Object.keys((_4 = consentEcho.body) !== null && _4 !== void 0 ? _4 : {});
|
|
350
|
+
leakedKeys = echoedKeys.filter(function (k) { return !['id', 'termsSigned', 'termsVersion'].includes(k); });
|
|
351
|
+
probes.push({
|
|
352
|
+
scenario: S1,
|
|
353
|
+
label: 'field-restricted: update response echoes only the writable fields',
|
|
354
|
+
path: "/enduser/".concat(formEnduserId),
|
|
355
|
+
expected: 'allowed',
|
|
356
|
+
status: leakedKeys.length === 0 ? consentEcho.status : 500,
|
|
357
|
+
pass: consentEcho.status === 200 && leakedKeys.length === 0,
|
|
358
|
+
note: leakedKeys.length ? "LEAKED [".concat(leakedKeys, "]") : "echoed [".concat(echoedKeys, "]"),
|
|
359
|
+
});
|
|
360
|
+
fieldsThatMustBeRefused = [
|
|
361
|
+
['email', "f0166-takeover-".concat(RAND(), "@tellescope.example")],
|
|
362
|
+
['phone', '+15555550123'],
|
|
363
|
+
['landline', '+15555550124'],
|
|
364
|
+
['dateOfBirth', '1990-01-01'],
|
|
365
|
+
['fname', 'F0166Overwritten'],
|
|
366
|
+
];
|
|
367
|
+
_i = 0, fieldsThatMustBeRefused_1 = fieldsThatMustBeRefused;
|
|
368
|
+
_11.label = 26;
|
|
369
|
+
case 26:
|
|
370
|
+
if (!(_i < fieldsThatMustBeRefused_1.length)) return [3 /*break*/, 29];
|
|
371
|
+
_b = fieldsThatMustBeRefused_1[_i], field = _b[0], value = _b[1];
|
|
372
|
+
return [4 /*yield*/, request(publicFormSession.authToken, 'patch', "/enduser/".concat(formEnduserId), { updates: (_0 = {}, _0[field] = value, _0) })];
|
|
373
|
+
case 27:
|
|
374
|
+
r = _11.sent();
|
|
375
|
+
probes.push({
|
|
376
|
+
scenario: S1,
|
|
377
|
+
label: "field-restricted: cannot write enduser '".concat(field, "'"),
|
|
378
|
+
path: "/enduser/".concat(formEnduserId),
|
|
379
|
+
expected: 'denied',
|
|
380
|
+
status: r.status,
|
|
381
|
+
pass: r.status === 403,
|
|
382
|
+
note: 'route is granted; the field allowlist is what refuses this',
|
|
383
|
+
});
|
|
384
|
+
_11.label = 28;
|
|
385
|
+
case 28:
|
|
386
|
+
_i++;
|
|
387
|
+
return [3 /*break*/, 26];
|
|
388
|
+
case 29: return [4 /*yield*/, request(publicFormSession.authToken, 'patch', "/enduser/".concat(formEnduserId), { updates: { termsVersion: '2', email: "f0166-mixed-".concat(RAND(), "@tellescope.example") } })];
|
|
389
|
+
case 30:
|
|
390
|
+
mixed = _11.sent();
|
|
391
|
+
probes.push({
|
|
392
|
+
scenario: S1,
|
|
393
|
+
label: 'field-restricted: a mixed allowed+denied update is refused whole',
|
|
394
|
+
path: "/enduser/".concat(formEnduserId),
|
|
395
|
+
expected: 'denied',
|
|
396
|
+
status: mixed.status,
|
|
397
|
+
pass: mixed.status === 403,
|
|
398
|
+
note: 'no partial application — email must not ride along with termsVersion',
|
|
399
|
+
});
|
|
400
|
+
return [4 /*yield*/, sdk.api.endusers.getOne(formEnduserId)];
|
|
401
|
+
case 31:
|
|
402
|
+
afterProbes = _11.sent();
|
|
403
|
+
probes.push({
|
|
404
|
+
scenario: S1,
|
|
405
|
+
label: 'field-restricted: stored email survived every attempt',
|
|
406
|
+
path: "/enduser/".concat(formEnduserId),
|
|
407
|
+
expected: 'denied',
|
|
408
|
+
status: afterProbes.email === formEnduserEmail ? 403 : 200,
|
|
409
|
+
pass: afterProbes.email === formEnduserEmail,
|
|
410
|
+
note: "stored=".concat(afterProbes.email),
|
|
411
|
+
});
|
|
307
412
|
S2 = 'S2 join-link (enduser)';
|
|
308
413
|
return [4 /*yield*/, expectDenied(S2, 'unlisted: form responses', joinSession.authToken, baselineEnduserToken, 'get', '/form-responses')];
|
|
309
|
-
case
|
|
310
|
-
|
|
414
|
+
case 32:
|
|
415
|
+
_11.sent();
|
|
311
416
|
return [4 /*yield*/, expectDenied(S2, 'unlisted: files', joinSession.authToken, baselineEnduserToken, 'get', '/files')];
|
|
312
|
-
case
|
|
313
|
-
|
|
417
|
+
case 33:
|
|
418
|
+
_11.sent();
|
|
314
419
|
return [4 /*yield*/, expectDenied(S2, 'unlisted: portal customizations', joinSession.authToken, baselineEnduserToken, 'get', '/portal-customizations')];
|
|
315
|
-
case
|
|
316
|
-
|
|
420
|
+
case 34:
|
|
421
|
+
_11.sent();
|
|
317
422
|
return [4 /*yield*/, expectDenied(S2, 'unlisted: UNRELATED calendar event', joinSession.authToken, baselineEnduserToken, 'get', "/calendar-event/".concat(unrelatedEvent.id))];
|
|
318
|
-
case
|
|
319
|
-
|
|
423
|
+
case 35:
|
|
424
|
+
_11.sent();
|
|
320
425
|
return [4 /*yield*/, expectAllowed(S2, 'always-allowed path', joinSession.authToken, 'get', '/test-authenticated')];
|
|
321
|
-
case
|
|
322
|
-
|
|
426
|
+
case 36:
|
|
427
|
+
_11.sent();
|
|
323
428
|
return [4 /*yield*/, expectAllowed(S2, 'listed: my meetings', joinSession.authToken, 'get', '/my-meetings')
|
|
324
429
|
// enduserActions for organizations is {}, so an enduser 401s here regardless of confinement
|
|
325
430
|
];
|
|
326
|
-
case
|
|
327
|
-
|
|
431
|
+
case 37:
|
|
432
|
+
_11.sent();
|
|
328
433
|
// enduserActions for organizations is {}, so an enduser 401s here regardless of confinement
|
|
329
434
|
return [4 /*yield*/, expectAllowed(S2, 'listed: organizations', joinSession.authToken, 'get', '/organizations', undefined, { allow401: true })];
|
|
330
|
-
case
|
|
435
|
+
case 38:
|
|
331
436
|
// enduserActions for organizations is {}, so an enduser 401s here regardless of confinement
|
|
332
|
-
|
|
437
|
+
_11.sent();
|
|
333
438
|
return [4 /*yield*/, expectAllowed(S2, 'listed: users', joinSession.authToken, 'get', '/users')];
|
|
334
|
-
case
|
|
335
|
-
|
|
439
|
+
case 39:
|
|
440
|
+
_11.sent();
|
|
336
441
|
return [4 /*yield*/, expectAllowed(S2, 'listed: pinned calendar event', joinSession.authToken, 'get', "/calendar-event/".concat(joinEvent.id))];
|
|
337
|
-
case
|
|
338
|
-
|
|
442
|
+
case 40:
|
|
443
|
+
_11.sent();
|
|
339
444
|
return [4 /*yield*/, expectAllowed(S2, 'wildcard: meeting by id', joinSession.authToken, 'get', "/meeting/".concat(OBJECT_ID))
|
|
340
445
|
// the two paths widened in this change so the portal video flow keeps working
|
|
341
446
|
];
|
|
342
|
-
case
|
|
343
|
-
|
|
447
|
+
case 41:
|
|
448
|
+
_11.sent();
|
|
344
449
|
// the two paths widened in this change so the portal video flow keeps working
|
|
345
450
|
return [4 /*yield*/, expectAllowed(S2, 'widened: calendar events list', joinSession.authToken, 'get', '/calendar-events')];
|
|
346
|
-
case
|
|
451
|
+
case 42:
|
|
347
452
|
// the two paths widened in this change so the portal video flow keeps working
|
|
348
|
-
|
|
453
|
+
_11.sent();
|
|
349
454
|
return [4 /*yield*/, expectAllowed(S2, 'widened: join meeting for event', joinSession.authToken, 'post', '/join-meeting-for-event', { calendarEventId: joinEvent.id })
|
|
350
|
-
//
|
|
455
|
+
// The WaitingRoom marks attendance here. This write is deliberately NOT field-restricted: the
|
|
456
|
+
// portal reads the event back through useCalendarEvents, whose updateElement REPLACES the local
|
|
457
|
+
// record with the update response (react state.tsx), so a truncated response would drop event
|
|
458
|
+
// fields out of local state mid-visit and break a live Twilio call. Assert both halves of that
|
|
459
|
+
// contract — the write lands, AND the response is still a whole event.
|
|
351
460
|
];
|
|
352
|
-
case
|
|
353
|
-
|
|
461
|
+
case 43:
|
|
462
|
+
_11.sent();
|
|
463
|
+
return [4 /*yield*/, request(joinSession.authToken, 'patch', "/calendar-event/".concat(joinEvent.id), { updates: { joinedVideoCall: [{ id: joinEnduserId, at: new Date().toISOString() }] } })];
|
|
464
|
+
case 44:
|
|
465
|
+
attendanceWrite = _11.sent();
|
|
466
|
+
probes.push({
|
|
467
|
+
scenario: S2,
|
|
468
|
+
label: 'marks joinedVideoCall on its pinned event',
|
|
469
|
+
path: "/calendar-event/".concat(joinEvent.id),
|
|
470
|
+
expected: 'allowed',
|
|
471
|
+
status: attendanceWrite.status,
|
|
472
|
+
pass: attendanceWrite.status === 200,
|
|
473
|
+
});
|
|
474
|
+
echoedEvent = (_5 = attendanceWrite.body) !== null && _5 !== void 0 ? _5 : {};
|
|
475
|
+
probes.push({
|
|
476
|
+
scenario: S2,
|
|
477
|
+
label: 'attendance write returns the WHOLE event (client replaces local state from it)',
|
|
478
|
+
path: "/calendar-event/".concat(joinEvent.id),
|
|
479
|
+
expected: 'allowed',
|
|
480
|
+
status: (echoedEvent.title && echoedEvent.durationInMinutes) ? 200 : 500,
|
|
481
|
+
pass: !!echoedEvent.title && !!echoedEvent.durationInMinutes && !!echoedEvent.joinedVideoCall,
|
|
482
|
+
note: "echoed ".concat(Object.keys(echoedEvent).length, " keys"),
|
|
483
|
+
});
|
|
354
484
|
return [4 /*yield*/, request(joinSession.authToken, 'post', '/refresh-enduser-session', {})];
|
|
355
|
-
case
|
|
356
|
-
refreshedJoin =
|
|
357
|
-
refreshedJoinToken = (
|
|
485
|
+
case 45:
|
|
486
|
+
refreshedJoin = _11.sent();
|
|
487
|
+
refreshedJoinToken = (_6 = refreshedJoin.body) === null || _6 === void 0 ? void 0 : _6.authToken;
|
|
358
488
|
probes.push({
|
|
359
489
|
scenario: S2, label: 'refresh returned a new token', path: '/refresh-enduser-session',
|
|
360
490
|
expected: 'allowed', status: refreshedJoin.status, pass: !!refreshedJoinToken,
|
|
361
491
|
});
|
|
362
|
-
if (!refreshedJoinToken) return [3 /*break*/,
|
|
492
|
+
if (!refreshedJoinToken) return [3 /*break*/, 48];
|
|
363
493
|
return [4 /*yield*/, expectDenied(S2, 'after refresh: still denied form responses', refreshedJoinToken, baselineEnduserToken, 'get', '/form-responses')];
|
|
364
|
-
case
|
|
365
|
-
|
|
494
|
+
case 46:
|
|
495
|
+
_11.sent();
|
|
366
496
|
return [4 /*yield*/, expectAllowed(S2, 'after refresh: still allowed my meetings', refreshedJoinToken, 'get', '/my-meetings')];
|
|
367
|
-
case
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
case
|
|
497
|
+
case 47:
|
|
498
|
+
_11.sent();
|
|
499
|
+
_11.label = 48;
|
|
500
|
+
case 48:
|
|
371
501
|
S3 = 'S3 start-link (STAFF)';
|
|
372
502
|
return [4 /*yield*/, expectDenied(S3, 'unlisted: form responses', startSession.authToken, baselineUserToken, 'get', '/form-responses')];
|
|
373
|
-
case
|
|
374
|
-
|
|
503
|
+
case 49:
|
|
504
|
+
_11.sent();
|
|
375
505
|
return [4 /*yield*/, expectDenied(S3, 'unlisted: journeys', startSession.authToken, baselineUserToken, 'get', '/journeys')];
|
|
376
|
-
case
|
|
377
|
-
|
|
506
|
+
case 50:
|
|
507
|
+
_11.sent();
|
|
378
508
|
return [4 /*yield*/, expectDenied(S3, 'unlisted: tickets', startSession.authToken, baselineUserToken, 'get', '/tickets')];
|
|
379
|
-
case
|
|
380
|
-
|
|
509
|
+
case 51:
|
|
510
|
+
_11.sent();
|
|
381
511
|
return [4 /*yield*/, expectDenied(S3, 'unlisted: data sync (org-wide change firehose)', startSession.authToken, baselineUserToken, 'get', '/data-sync', { from: new Date(Date.now() - 60000).toISOString() })];
|
|
382
|
-
case
|
|
383
|
-
|
|
512
|
+
case 52:
|
|
513
|
+
_11.sent();
|
|
384
514
|
return [4 /*yield*/, expectDenied(S3, 'unlisted: file download URL', startSession.authToken, baselineUserToken, 'get', '/file-download-URL', { secureName: 'f0166-does-not-exist' })];
|
|
385
|
-
case
|
|
386
|
-
|
|
515
|
+
case 53:
|
|
516
|
+
_11.sent();
|
|
387
517
|
return [4 /*yield*/, expectDenied(S3, 'unlisted: UNRELATED calendar event', startSession.authToken, baselineUserToken, 'get', "/calendar-event/".concat(unrelatedEvent.id))];
|
|
388
|
-
case
|
|
389
|
-
|
|
518
|
+
case 54:
|
|
519
|
+
_11.sent();
|
|
390
520
|
return [4 /*yield*/, expectAllowed(S3, 'always-allowed path', startSession.authToken, 'get', '/test-authenticated')];
|
|
391
|
-
case
|
|
392
|
-
|
|
521
|
+
case 55:
|
|
522
|
+
_11.sent();
|
|
393
523
|
return [4 /*yield*/, expectAllowed(S3, 'listed: my meetings', startSession.authToken, 'get', '/my-meetings')];
|
|
394
|
-
case
|
|
395
|
-
|
|
524
|
+
case 56:
|
|
525
|
+
_11.sent();
|
|
396
526
|
return [4 /*yield*/, expectAllowed(S3, 'listed: calendar events', startSession.authToken, 'get', '/calendar-events')];
|
|
397
|
-
case
|
|
398
|
-
|
|
527
|
+
case 57:
|
|
528
|
+
_11.sent();
|
|
399
529
|
return [4 /*yield*/, expectAllowed(S3, 'listed: organizations', startSession.authToken, 'get', '/organizations')];
|
|
400
|
-
case
|
|
401
|
-
|
|
530
|
+
case 58:
|
|
531
|
+
_11.sent();
|
|
402
532
|
return [4 /*yield*/, expectAllowed(S3, 'listed: users', startSession.authToken, 'get', '/users')];
|
|
403
|
-
case
|
|
404
|
-
|
|
533
|
+
case 59:
|
|
534
|
+
_11.sent();
|
|
405
535
|
return [4 /*yield*/, expectAllowed(S3, 'listed: endusers', startSession.authToken, 'get', '/endusers')];
|
|
406
|
-
case
|
|
407
|
-
|
|
536
|
+
case 60:
|
|
537
|
+
_11.sent();
|
|
408
538
|
return [4 /*yield*/, expectAllowed(S3, 'listed: pinned calendar event', startSession.authToken, 'get', "/calendar-event/".concat(startEvent.id))];
|
|
409
|
-
case
|
|
410
|
-
|
|
539
|
+
case 61:
|
|
540
|
+
_11.sent();
|
|
411
541
|
return [4 /*yield*/, expectAllowed(S3, 'wildcard: meeting by id', startSession.authToken, 'get', "/meeting/".concat(OBJECT_ID))];
|
|
412
|
-
case
|
|
413
|
-
|
|
542
|
+
case 62:
|
|
543
|
+
_11.sent();
|
|
414
544
|
return [4 /*yield*/, expectAllowed(S3, 'prefix descendant: users bulk-read', startSession.authToken, 'post', '/users/bulk-read', { ids: [hostUser.id] })];
|
|
415
|
-
case
|
|
416
|
-
|
|
545
|
+
case 63:
|
|
546
|
+
_11.sent();
|
|
417
547
|
return [4 /*yield*/, expectAllowed(S3, 'prefix descendant: endusers bulk-read', startSession.authToken, 'post', '/endusers/bulk-read', { ids: [joinEnduser.id] })];
|
|
418
|
-
case
|
|
419
|
-
|
|
548
|
+
case 64:
|
|
549
|
+
_11.sent();
|
|
420
550
|
return [4 /*yield*/, expectAllowed(S3, 'widened: join meeting for event', startSession.authToken, 'post', '/join-meeting-for-event', { calendarEventId: startEvent.id })];
|
|
421
|
-
case
|
|
422
|
-
|
|
551
|
+
case 65:
|
|
552
|
+
_11.sent();
|
|
423
553
|
return [4 /*yield*/, expectAllowed(S3, 'widened: add attendees to meeting', startSession.authToken, 'post', '/add-attendees-to-meeting', { id: OBJECT_ID })
|
|
424
554
|
// login_user propagates allowedPaths implicitly through its ...toSign rest spread — the
|
|
425
555
|
// "(ASSUMPTION)" comments in the mint sites depend on this, so assert it explicitly
|
|
426
556
|
];
|
|
427
|
-
case
|
|
428
|
-
|
|
557
|
+
case 66:
|
|
558
|
+
_11.sent();
|
|
429
559
|
return [4 /*yield*/, request(startSession.authToken, 'post', '/refresh-session', {})];
|
|
430
|
-
case
|
|
431
|
-
refreshedStart =
|
|
432
|
-
refreshedStartToken = (
|
|
560
|
+
case 67:
|
|
561
|
+
refreshedStart = _11.sent();
|
|
562
|
+
refreshedStartToken = (_7 = refreshedStart.body) === null || _7 === void 0 ? void 0 : _7.authToken;
|
|
433
563
|
probes.push({
|
|
434
564
|
scenario: S3, label: 'refresh returned a new token', path: '/refresh-session',
|
|
435
565
|
expected: 'allowed', status: refreshedStart.status, pass: !!refreshedStartToken,
|
|
436
566
|
});
|
|
437
|
-
if (!refreshedStartToken) return [3 /*break*/,
|
|
567
|
+
if (!refreshedStartToken) return [3 /*break*/, 70];
|
|
438
568
|
return [4 /*yield*/, expectDenied(S3, 'after refresh: still denied journeys', refreshedStartToken, baselineUserToken, 'get', '/journeys')];
|
|
439
|
-
case
|
|
440
|
-
|
|
569
|
+
case 68:
|
|
570
|
+
_11.sent();
|
|
441
571
|
return [4 /*yield*/, expectAllowed(S3, 'after refresh: still allowed my meetings', refreshedStartToken, 'get', '/my-meetings')];
|
|
442
|
-
case
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
case
|
|
572
|
+
case 69:
|
|
573
|
+
_11.sent();
|
|
574
|
+
_11.label = 70;
|
|
575
|
+
case 70:
|
|
446
576
|
S4 = 'S4 widening side-effects';
|
|
447
577
|
prefixGranted = [
|
|
448
578
|
['patch', '/calendar-events/bulk-update'],
|
|
449
579
|
['post', '/calendar-events/report'],
|
|
450
580
|
];
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
case
|
|
454
|
-
if (!(
|
|
455
|
-
|
|
581
|
+
_c = 0, prefixGranted_1 = prefixGranted;
|
|
582
|
+
_11.label = 71;
|
|
583
|
+
case 71:
|
|
584
|
+
if (!(_c < prefixGranted_1.length)) return [3 /*break*/, 74];
|
|
585
|
+
_d = prefixGranted_1[_c], method = _d[0], path = _d[1];
|
|
456
586
|
return [4 /*yield*/, axios_1.default.request({
|
|
457
587
|
method: method,
|
|
458
588
|
url: "".concat(host, "/v1").concat(path),
|
|
@@ -460,8 +590,8 @@ var allowed_paths_confinement_tests = function (_a) {
|
|
|
460
590
|
headers: { Authorization: "Bearer ".concat(joinSession.authToken) },
|
|
461
591
|
validateStatus: function () { return true; },
|
|
462
592
|
})];
|
|
463
|
-
case
|
|
464
|
-
r =
|
|
593
|
+
case 72:
|
|
594
|
+
r = _11.sent();
|
|
465
595
|
probes.push({
|
|
466
596
|
scenario: S4,
|
|
467
597
|
label: "enduser action gating blocks ".concat(method.toUpperCase(), " ").concat(path),
|
|
@@ -471,146 +601,222 @@ var allowed_paths_confinement_tests = function (_a) {
|
|
|
471
601
|
pass: r.status === 401 || r.status === 403,
|
|
472
602
|
note: 'prefix-granted by /calendar-events; blocked by enduserActions instead',
|
|
473
603
|
});
|
|
474
|
-
|
|
475
|
-
case
|
|
476
|
-
|
|
477
|
-
return [3 /*break*/,
|
|
478
|
-
case
|
|
604
|
+
_11.label = 73;
|
|
605
|
+
case 73:
|
|
606
|
+
_c++;
|
|
607
|
+
return [3 /*break*/, 71];
|
|
608
|
+
case 74:
|
|
479
609
|
S6 = 'S6 namespace escapes';
|
|
480
610
|
ABSENT_ID_A = '68a1b2c3d4e5f60718293a4b';
|
|
481
611
|
ABSENT_ID_B = '68a1b2c3d4e5f60718293a4c';
|
|
482
612
|
INVALID_EMAIL = 'f0166-not-an-email';
|
|
483
613
|
return [4 /*yield*/, expectDenied(S6, 'ESCAPE: /users/consent (minted an unconfined token)', startSession.authToken, baselineUserToken, 'patch', '/users/consent', { termsVersion: '1' })];
|
|
484
|
-
case
|
|
485
|
-
|
|
614
|
+
case 75:
|
|
615
|
+
_11.sent();
|
|
486
616
|
return [4 /*yield*/, expectDenied(S6, 'ESCAPE: /users/switch-account', startSession.authToken, baselineUserToken, 'post', '/users/switch-account', { targetUserId: ABSENT_ID_A })];
|
|
487
|
-
case
|
|
488
|
-
|
|
617
|
+
case 76:
|
|
618
|
+
_11.sent();
|
|
489
619
|
return [4 /*yield*/, expectDenied(S6, 'ESCAPE: /users/configure-inbox', startSession.authToken, baselineUserToken, 'post', '/users/configure-inbox', {})];
|
|
490
|
-
case
|
|
491
|
-
|
|
620
|
+
case 77:
|
|
621
|
+
_11.sent();
|
|
492
622
|
return [4 /*yield*/, expectDenied(S6, 'PHI: /endusers/load-inbox-data', startSession.authToken, baselineUserToken, 'get', '/endusers/load-inbox-data')];
|
|
493
|
-
case
|
|
494
|
-
|
|
623
|
+
case 78:
|
|
624
|
+
_11.sent();
|
|
495
625
|
return [4 /*yield*/, expectDenied(S6, 'PHI: /endusers/report', startSession.authToken, baselineUserToken, 'get', '/endusers/report')];
|
|
496
|
-
case
|
|
497
|
-
|
|
626
|
+
case 79:
|
|
627
|
+
_11.sent();
|
|
498
628
|
return [4 /*yield*/, expectDenied(S6, 'PHI: /endusers/engagement', startSession.authToken, baselineUserToken, 'get', '/endusers/engagement')];
|
|
499
|
-
case
|
|
500
|
-
|
|
629
|
+
case 80:
|
|
630
|
+
_11.sent();
|
|
501
631
|
return [4 /*yield*/, expectDenied(S6, 'DESTRUCTIVE: /endusers/merge', startSession.authToken, baselineUserToken, 'post', '/endusers/merge', { sourceEnduserId: ABSENT_ID_A, destinationEnduserId: ABSENT_ID_B })];
|
|
502
|
-
case
|
|
503
|
-
|
|
632
|
+
case 81:
|
|
633
|
+
_11.sent();
|
|
504
634
|
return [4 /*yield*/, expectDenied(S6, 'DESTRUCTIVE: /endusers/bulk-update', startSession.authToken, baselineUserToken, 'patch', '/endusers/bulk-update', { ids: [ABSENT_ID_A], fields: {} })
|
|
505
635
|
// method scoping, end to end: the same path is readable but not writable.
|
|
506
636
|
// Baselines use the ADMIN token — the throwaway host user cannot create users or endusers, so it
|
|
507
637
|
// would 403 on permissions and the probe could not distinguish that from a confinement denial.
|
|
508
638
|
];
|
|
509
|
-
case
|
|
510
|
-
|
|
639
|
+
case 82:
|
|
640
|
+
_11.sent();
|
|
511
641
|
// method scoping, end to end: the same path is readable but not writable.
|
|
512
642
|
// Baselines use the ADMIN token — the throwaway host user cannot create users or endusers, so it
|
|
513
643
|
// would 403 on permissions and the probe could not distinguish that from a confinement denial.
|
|
514
644
|
return [4 /*yield*/, expectAllowed(S6, 'method scoping: GET /endusers allowed', startSession.authToken, 'get', '/endusers')];
|
|
515
|
-
case
|
|
645
|
+
case 83:
|
|
516
646
|
// method scoping, end to end: the same path is readable but not writable.
|
|
517
647
|
// Baselines use the ADMIN token — the throwaway host user cannot create users or endusers, so it
|
|
518
648
|
// would 403 on permissions and the probe could not distinguish that from a confinement denial.
|
|
519
|
-
|
|
649
|
+
_11.sent();
|
|
520
650
|
return [4 /*yield*/, expectDenied(S6, 'method scoping: POST /endusers (create) denied', startSession.authToken, sdk.authToken, 'post', '/endusers', { email: INVALID_EMAIL })];
|
|
521
|
-
case
|
|
522
|
-
|
|
651
|
+
case 84:
|
|
652
|
+
_11.sent();
|
|
523
653
|
return [4 /*yield*/, expectAllowed(S6, 'method scoping: GET /users allowed', startSession.authToken, 'get', '/users')];
|
|
524
|
-
case
|
|
525
|
-
|
|
654
|
+
case 85:
|
|
655
|
+
_11.sent();
|
|
526
656
|
return [4 /*yield*/, expectDenied(S6, 'method scoping: POST /users (create) denied', startSession.authToken, sdk.authToken, 'post', '/users', { email: INVALID_EMAIL })
|
|
527
657
|
// even if consent were reachable, the token it mints must stay confined (defense in depth)
|
|
528
658
|
];
|
|
529
|
-
case
|
|
530
|
-
|
|
659
|
+
case 86:
|
|
660
|
+
_11.sent();
|
|
531
661
|
return [4 /*yield*/, request(startSession.authToken, 'patch', '/users/consent', { termsVersion: '1' })];
|
|
532
|
-
case
|
|
533
|
-
consentAttempt =
|
|
534
|
-
if (!(consentAttempt.status === 200 && ((
|
|
662
|
+
case 87:
|
|
663
|
+
consentAttempt = _11.sent();
|
|
664
|
+
if (!(consentAttempt.status === 200 && ((_8 = consentAttempt.body) === null || _8 === void 0 ? void 0 : _8.authToken))) return [3 /*break*/, 89];
|
|
535
665
|
return [4 /*yield*/, expectDenied(S6, 'consent-minted token is still confined', consentAttempt.body.authToken, baselineUserToken, 'get', '/journeys')];
|
|
536
|
-
case
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
case
|
|
540
|
-
case
|
|
541
|
-
refreshedForScopes =
|
|
542
|
-
rescopedToken = (
|
|
666
|
+
case 88:
|
|
667
|
+
_11.sent();
|
|
668
|
+
_11.label = 89;
|
|
669
|
+
case 89: return [4 /*yield*/, request(startSession.authToken, 'post', '/refresh-session', {})];
|
|
670
|
+
case 90:
|
|
671
|
+
refreshedForScopes = _11.sent();
|
|
672
|
+
rescopedToken = (_9 = refreshedForScopes.body) === null || _9 === void 0 ? void 0 : _9.authToken;
|
|
543
673
|
probes.push({
|
|
544
674
|
scenario: S6, label: 'refresh returned a new token', path: '/refresh-session',
|
|
545
675
|
expected: 'allowed', status: refreshedForScopes.status, pass: !!rescopedToken,
|
|
546
676
|
});
|
|
547
|
-
if (!rescopedToken) return [3 /*break*/,
|
|
677
|
+
if (!rescopedToken) return [3 /*break*/, 96];
|
|
548
678
|
return [4 /*yield*/, expectDenied(S6, 'after refresh: still cannot reach /users/consent', rescopedToken, baselineUserToken, 'patch', '/users/consent', { termsVersion: '1' })];
|
|
549
|
-
case
|
|
550
|
-
|
|
679
|
+
case 91:
|
|
680
|
+
_11.sent();
|
|
551
681
|
return [4 /*yield*/, expectDenied(S6, 'after refresh: still cannot reach /endusers/load-inbox-data', rescopedToken, baselineUserToken, 'get', '/endusers/load-inbox-data')];
|
|
552
|
-
case
|
|
553
|
-
|
|
682
|
+
case 92:
|
|
683
|
+
_11.sent();
|
|
554
684
|
return [4 /*yield*/, expectDenied(S6, 'after refresh: POST /endusers still denied', rescopedToken, baselineUserToken, 'post', '/endusers', { email: "f0166-should-not-exist-".concat(RAND(), "@tellescope.example") })];
|
|
555
|
-
case
|
|
556
|
-
|
|
685
|
+
case 93:
|
|
686
|
+
_11.sent();
|
|
557
687
|
return [4 /*yield*/, expectAllowed(S6, 'after refresh: GET /endusers still allowed', rescopedToken, 'get', '/endusers')];
|
|
558
|
-
case
|
|
559
|
-
|
|
688
|
+
case 94:
|
|
689
|
+
_11.sent();
|
|
560
690
|
return [4 /*yield*/, expectAllowed(S6, 'after refresh: my-meetings still allowed', rescopedToken, 'get', '/my-meetings')];
|
|
561
|
-
case
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
case
|
|
691
|
+
case 95:
|
|
692
|
+
_11.sent();
|
|
693
|
+
_11.label = 96;
|
|
694
|
+
case 96:
|
|
695
|
+
S7 = 'S7 appointment-booking';
|
|
696
|
+
return [4 /*yield*/, sdk.api.calendar_event_templates.createOne({
|
|
697
|
+
title: "F-0166 booking ".concat(RAND()), durationInMinutes: 30,
|
|
698
|
+
})];
|
|
699
|
+
case 97:
|
|
700
|
+
bookingTemplate = _11.sent();
|
|
701
|
+
templateId = bookingTemplate.id;
|
|
702
|
+
bookingEnduserEmail = "f0166-booking-".concat(RAND(), "@tellescope.example");
|
|
703
|
+
return [4 /*yield*/, sdk.api.endusers.createOne({
|
|
704
|
+
email: bookingEnduserEmail, fname: 'Booking', lname: 'Confinement',
|
|
705
|
+
})];
|
|
706
|
+
case 98:
|
|
707
|
+
bookingEnduser = _11.sent();
|
|
708
|
+
bookingEnduserId = bookingEnduser.id;
|
|
709
|
+
return [4 /*yield*/, new sdk_1.EnduserSession({ host: host, businessId: businessId })
|
|
710
|
+
.api.calendar_events.session_for_public_appointment_booking({
|
|
711
|
+
businessId: businessId,
|
|
712
|
+
calendarEventTemplateId: bookingTemplate.id,
|
|
713
|
+
email: bookingEnduserEmail,
|
|
714
|
+
fname: 'Booking',
|
|
715
|
+
lname: 'Confinement',
|
|
716
|
+
})];
|
|
717
|
+
case 99:
|
|
718
|
+
bookingSession = _11.sent();
|
|
719
|
+
return [4 /*yield*/, expectAllowed(S7, 'field-restricted: may record terms consent', bookingSession.authToken, 'patch', "/enduser/".concat(bookingEnduser.id), { updates: { termsSigned: new Date().toISOString(), termsVersion: '1' } })];
|
|
720
|
+
case 100:
|
|
721
|
+
_11.sent();
|
|
722
|
+
return [4 /*yield*/, request(bookingSession.authToken, 'patch', "/enduser/".concat(bookingEnduser.id), { updates: { termsVersion: '2' } })];
|
|
723
|
+
case 101:
|
|
724
|
+
bookingEcho = _11.sent();
|
|
725
|
+
bookingLeaked = Object.keys((_10 = bookingEcho.body) !== null && _10 !== void 0 ? _10 : {})
|
|
726
|
+
.filter(function (k) { return !['id', 'termsSigned', 'termsVersion'].includes(k); });
|
|
727
|
+
probes.push({
|
|
728
|
+
scenario: S7,
|
|
729
|
+
label: 'field-restricted: update response echoes only the writable fields',
|
|
730
|
+
path: "/enduser/".concat(bookingEnduser.id),
|
|
731
|
+
expected: 'allowed',
|
|
732
|
+
status: bookingLeaked.length === 0 ? bookingEcho.status : 500,
|
|
733
|
+
pass: bookingEcho.status === 200 && bookingLeaked.length === 0,
|
|
734
|
+
note: bookingLeaked.length ? "LEAKED [".concat(bookingLeaked, "]") : undefined,
|
|
735
|
+
});
|
|
736
|
+
_e = 0, _f = [['email', "f0166-bt-".concat(RAND(), "@tellescope.example")], ['phone', '+15555550188']];
|
|
737
|
+
_11.label = 102;
|
|
738
|
+
case 102:
|
|
739
|
+
if (!(_e < _f.length)) return [3 /*break*/, 105];
|
|
740
|
+
_g = _f[_e], field = _g[0], value = _g[1];
|
|
741
|
+
return [4 /*yield*/, request(bookingSession.authToken, 'patch', "/enduser/".concat(bookingEnduser.id), { updates: (_1 = {}, _1[field] = value, _1) })];
|
|
742
|
+
case 103:
|
|
743
|
+
r = _11.sent();
|
|
744
|
+
probes.push({
|
|
745
|
+
scenario: S7,
|
|
746
|
+
label: "field-restricted: cannot write enduser '".concat(field, "'"),
|
|
747
|
+
path: "/enduser/".concat(bookingEnduser.id),
|
|
748
|
+
expected: 'denied',
|
|
749
|
+
status: r.status,
|
|
750
|
+
pass: r.status === 403,
|
|
751
|
+
note: 'route is granted; the field allowlist is what refuses this',
|
|
752
|
+
});
|
|
753
|
+
_11.label = 104;
|
|
754
|
+
case 104:
|
|
755
|
+
_e++;
|
|
756
|
+
return [3 /*break*/, 102];
|
|
757
|
+
case 105:
|
|
758
|
+
// the booking scope must not have gained anything else along with the enduser write
|
|
759
|
+
return [4 /*yield*/, expectDenied(S7, 'unlisted: form responses', bookingSession.authToken, baselineEnduserToken, 'get', '/form-responses')];
|
|
760
|
+
case 106:
|
|
761
|
+
// the booking scope must not have gained anything else along with the enduser write
|
|
762
|
+
_11.sent();
|
|
763
|
+
return [4 /*yield*/, expectDenied(S7, 'unlisted: calendar events', bookingSession.authToken, baselineEnduserToken, 'get', '/calendar-events')];
|
|
764
|
+
case 107:
|
|
765
|
+
_11.sent();
|
|
766
|
+
return [4 /*yield*/, expectAllowed(S7, 'listed: refresh enduser session', bookingSession.authToken, 'post', '/refresh-enduser-session')
|
|
767
|
+
/* ============ S5: ordinary sessions with no allowedPaths claim ============ */
|
|
768
|
+
];
|
|
769
|
+
case 108:
|
|
770
|
+
_11.sent();
|
|
565
771
|
S5 = 'S5 unconfined sessions';
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
case
|
|
569
|
-
if (!(
|
|
570
|
-
path =
|
|
772
|
+
_h = 0, _j = ['/journeys', '/form-responses', '/endusers', '/calendar-events', '/tickets'];
|
|
773
|
+
_11.label = 109;
|
|
774
|
+
case 109:
|
|
775
|
+
if (!(_h < _j.length)) return [3 /*break*/, 112];
|
|
776
|
+
path = _j[_h];
|
|
571
777
|
return [4 /*yield*/, expectAllowed(S5, "staff session reaches ".concat(path), baselineUserToken, 'get', path)];
|
|
572
|
-
case
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
case
|
|
576
|
-
|
|
577
|
-
return [3 /*break*/,
|
|
578
|
-
case
|
|
579
|
-
case
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
case
|
|
584
|
-
if (!(
|
|
585
|
-
path =
|
|
778
|
+
case 110:
|
|
779
|
+
_11.sent();
|
|
780
|
+
_11.label = 111;
|
|
781
|
+
case 111:
|
|
782
|
+
_h++;
|
|
783
|
+
return [3 /*break*/, 109];
|
|
784
|
+
case 112: return [4 /*yield*/, expectAllowed(S5, 'staff session reaches /data-sync', baselineUserToken, 'get', '/data-sync', { from: new Date(Date.now() - 60000).toISOString() })];
|
|
785
|
+
case 113:
|
|
786
|
+
_11.sent();
|
|
787
|
+
_k = 0, _l = ['/form-responses', '/calendar-events', '/files'];
|
|
788
|
+
_11.label = 114;
|
|
789
|
+
case 114:
|
|
790
|
+
if (!(_k < _l.length)) return [3 /*break*/, 117];
|
|
791
|
+
path = _l[_k];
|
|
586
792
|
return [4 /*yield*/, expectAllowed(S5, "enduser session reaches ".concat(path), baselineEnduserToken, 'get', path)];
|
|
587
|
-
case
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
case
|
|
591
|
-
|
|
592
|
-
return [3 /*break*/,
|
|
593
|
-
case
|
|
594
|
-
case
|
|
595
|
-
adminAuthenticated =
|
|
793
|
+
case 115:
|
|
794
|
+
_11.sent();
|
|
795
|
+
_11.label = 116;
|
|
796
|
+
case 116:
|
|
797
|
+
_k++;
|
|
798
|
+
return [3 /*break*/, 114];
|
|
799
|
+
case 117: return [4 /*yield*/, sdk.test_authenticated()];
|
|
800
|
+
case 118:
|
|
801
|
+
adminAuthenticated = _11.sent();
|
|
596
802
|
probes.push({
|
|
597
803
|
scenario: S5, label: 'admin sdk still authenticated', path: '/test-authenticated',
|
|
598
804
|
expected: 'allowed', status: 200, pass: adminAuthenticated === 'Authenticated!',
|
|
599
805
|
});
|
|
600
806
|
apiKeySDK = new sdk_1.Session({ host: host, apiKey: '3n5q0SCBT_iUvZz-b9BJtX7o7HQUVJ9v132PgHJNJsg.' });
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
case
|
|
604
|
-
if (!(
|
|
605
|
-
path =
|
|
807
|
+
_m = 0, _o = ['/journeys', '/form-responses', '/endusers', '/calendar-events', '/files'];
|
|
808
|
+
_11.label = 119;
|
|
809
|
+
case 119:
|
|
810
|
+
if (!(_m < _o.length)) return [3 /*break*/, 122];
|
|
811
|
+
path = _o[_m];
|
|
606
812
|
return [4 /*yield*/, axios_1.default.request({
|
|
607
813
|
method: 'get',
|
|
608
814
|
url: "".concat(host, "/v1").concat(path),
|
|
609
815
|
headers: { Authorization: "API_KEY ".concat(apiKeySDK.apiKey) },
|
|
610
816
|
validateStatus: function () { return true; },
|
|
611
817
|
})];
|
|
612
|
-
case
|
|
613
|
-
r =
|
|
818
|
+
case 120:
|
|
819
|
+
r = _11.sent();
|
|
614
820
|
probes.push({
|
|
615
821
|
scenario: S5,
|
|
616
822
|
label: "API key (headless) reaches ".concat(path),
|
|
@@ -619,11 +825,11 @@ var allowed_paths_confinement_tests = function (_a) {
|
|
|
619
825
|
status: r.status,
|
|
620
826
|
pass: r.status !== 403,
|
|
621
827
|
});
|
|
622
|
-
|
|
623
|
-
case
|
|
624
|
-
|
|
625
|
-
return [3 /*break*/,
|
|
626
|
-
case
|
|
828
|
+
_11.label = 121;
|
|
829
|
+
case 121:
|
|
830
|
+
_m++;
|
|
831
|
+
return [3 /*break*/, 119];
|
|
832
|
+
case 122:
|
|
627
833
|
failures = probes.filter(function (p) { return !p.pass; });
|
|
628
834
|
console.log('');
|
|
629
835
|
console.log(' F-0166 — full probe table');
|
|
@@ -633,111 +839,135 @@ var allowed_paths_confinement_tests = function (_a) {
|
|
|
633
839
|
var inScenario = probes.filter(function (p) { return p.scenario === scenario; });
|
|
634
840
|
var failed = inScenario.filter(function (p) { return !p.pass; }).length;
|
|
635
841
|
console.log(" ".concat(scenario, ": ").concat(inScenario.length - failed, "/").concat(inScenario.length, " passing").concat(failed ? " <-- ".concat(failed, " FAILING") : ''));
|
|
636
|
-
for (var
|
|
637
|
-
var p = inScenario_1[
|
|
842
|
+
for (var _12 = 0, inScenario_1 = inScenario; _12 < inScenario_1.length; _12++) {
|
|
843
|
+
var p = inScenario_1[_12];
|
|
638
844
|
var baseline = p.baselineStatus !== undefined ? " baseline=".concat(p.baselineStatus) : '';
|
|
639
845
|
console.log(" ".concat(p.pass ? ' ok ' : 'FAIL', " want=").concat(p.expected.padEnd(7), " got=").concat(p.status).concat(baseline, " ").concat(p.label).concat(p.note ? " (".concat(p.note, ")") : ''));
|
|
640
846
|
}
|
|
641
847
|
};
|
|
642
|
-
for (
|
|
643
|
-
scenario = scenarios_1[
|
|
848
|
+
for (_p = 0, scenarios_1 = scenarios; _p < scenarios_1.length; _p++) {
|
|
849
|
+
scenario = scenarios_1[_p];
|
|
644
850
|
_loop_1(scenario);
|
|
645
851
|
}
|
|
646
852
|
console.log(' ' + '-'.repeat(112));
|
|
647
853
|
console.log(" TOTAL: ".concat(probes.length - failures.length, "/").concat(probes.length, " passing, ").concat(failures.length, " failing"));
|
|
648
854
|
console.log('');
|
|
649
|
-
for (
|
|
650
|
-
p = probes_1[
|
|
855
|
+
for (_q = 0, probes_1 = probes; _q < probes_1.length; _q++) {
|
|
856
|
+
p = probes_1[_q];
|
|
651
857
|
(0, testing_1.assert)(p.pass, "".concat(p.scenario, " \u2014 ").concat(p.label, " (").concat(p.path, "): wanted ").concat(p.expected, ", got status ").concat(p.status)
|
|
652
858
|
+ (p.baselineStatus !== undefined ? " (unconfined baseline got ".concat(p.baselineStatus, ")") : ''), "".concat(p.scenario, " \u2014 ").concat(p.label));
|
|
653
859
|
}
|
|
654
|
-
return [3 /*break*/,
|
|
655
|
-
case
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
case
|
|
659
|
-
if (!(
|
|
660
|
-
id = eventIds_1[
|
|
661
|
-
|
|
662
|
-
case
|
|
663
|
-
|
|
860
|
+
return [3 /*break*/, 160];
|
|
861
|
+
case 123:
|
|
862
|
+
_r = 0, eventIds_1 = eventIds;
|
|
863
|
+
_11.label = 124;
|
|
864
|
+
case 124:
|
|
865
|
+
if (!(_r < eventIds_1.length)) return [3 /*break*/, 129];
|
|
866
|
+
id = eventIds_1[_r];
|
|
867
|
+
_11.label = 125;
|
|
868
|
+
case 125:
|
|
869
|
+
_11.trys.push([125, 127, , 128]);
|
|
664
870
|
return [4 /*yield*/, sdk.api.calendar_events.deleteOne(id)];
|
|
665
|
-
case
|
|
666
|
-
|
|
667
|
-
return [3 /*break*/,
|
|
668
|
-
case
|
|
669
|
-
|
|
670
|
-
return [3 /*break*/,
|
|
671
|
-
case
|
|
672
|
-
|
|
673
|
-
return [3 /*break*/,
|
|
674
|
-
case
|
|
675
|
-
if (!joinEnduserId) return [3 /*break*/,
|
|
676
|
-
|
|
677
|
-
case
|
|
678
|
-
|
|
871
|
+
case 126:
|
|
872
|
+
_11.sent();
|
|
873
|
+
return [3 /*break*/, 128];
|
|
874
|
+
case 127:
|
|
875
|
+
_s = _11.sent();
|
|
876
|
+
return [3 /*break*/, 128];
|
|
877
|
+
case 128:
|
|
878
|
+
_r++;
|
|
879
|
+
return [3 /*break*/, 124];
|
|
880
|
+
case 129:
|
|
881
|
+
if (!joinEnduserId) return [3 /*break*/, 133];
|
|
882
|
+
_11.label = 130;
|
|
883
|
+
case 130:
|
|
884
|
+
_11.trys.push([130, 132, , 133]);
|
|
679
885
|
return [4 /*yield*/, sdk.api.endusers.deleteOne(joinEnduserId)];
|
|
680
|
-
case
|
|
681
|
-
|
|
682
|
-
return [3 /*break*/,
|
|
683
|
-
case
|
|
684
|
-
|
|
685
|
-
return [3 /*break*/,
|
|
686
|
-
case
|
|
687
|
-
if (!formEnduserEmail) return [3 /*break*/,
|
|
688
|
-
|
|
689
|
-
case
|
|
690
|
-
|
|
886
|
+
case 131:
|
|
887
|
+
_11.sent();
|
|
888
|
+
return [3 /*break*/, 133];
|
|
889
|
+
case 132:
|
|
890
|
+
_t = _11.sent();
|
|
891
|
+
return [3 /*break*/, 133];
|
|
892
|
+
case 133:
|
|
893
|
+
if (!formEnduserEmail) return [3 /*break*/, 139];
|
|
894
|
+
_11.label = 134;
|
|
895
|
+
case 134:
|
|
896
|
+
_11.trys.push([134, 138, , 139]);
|
|
691
897
|
return [4 /*yield*/, sdk.api.endusers.getOne({ email: formEnduserEmail })];
|
|
692
|
-
case
|
|
693
|
-
e =
|
|
694
|
-
if (!(e === null || e === void 0 ? void 0 : e.id)) return [3 /*break*/,
|
|
898
|
+
case 135:
|
|
899
|
+
e = _11.sent();
|
|
900
|
+
if (!(e === null || e === void 0 ? void 0 : e.id)) return [3 /*break*/, 137];
|
|
695
901
|
return [4 /*yield*/, sdk.api.endusers.deleteOne(e.id)];
|
|
696
|
-
case
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
case
|
|
700
|
-
case
|
|
701
|
-
|
|
702
|
-
return [3 /*break*/,
|
|
703
|
-
case
|
|
704
|
-
if (!hostUserId) return [3 /*break*/,
|
|
705
|
-
|
|
706
|
-
case
|
|
707
|
-
|
|
902
|
+
case 136:
|
|
903
|
+
_11.sent();
|
|
904
|
+
_11.label = 137;
|
|
905
|
+
case 137: return [3 /*break*/, 139];
|
|
906
|
+
case 138:
|
|
907
|
+
_u = _11.sent();
|
|
908
|
+
return [3 /*break*/, 139];
|
|
909
|
+
case 139:
|
|
910
|
+
if (!hostUserId) return [3 /*break*/, 143];
|
|
911
|
+
_11.label = 140;
|
|
912
|
+
case 140:
|
|
913
|
+
_11.trys.push([140, 142, , 143]);
|
|
708
914
|
return [4 /*yield*/, sdk.api.users.deleteOne(hostUserId)];
|
|
709
|
-
case
|
|
710
|
-
|
|
711
|
-
return [3 /*break*/,
|
|
712
|
-
case
|
|
713
|
-
|
|
714
|
-
return [3 /*break*/,
|
|
715
|
-
case
|
|
716
|
-
if (!
|
|
717
|
-
|
|
718
|
-
case
|
|
719
|
-
|
|
915
|
+
case 141:
|
|
916
|
+
_11.sent();
|
|
917
|
+
return [3 /*break*/, 143];
|
|
918
|
+
case 142:
|
|
919
|
+
_v = _11.sent();
|
|
920
|
+
return [3 /*break*/, 143];
|
|
921
|
+
case 143:
|
|
922
|
+
if (!bookingEnduserId) return [3 /*break*/, 147];
|
|
923
|
+
_11.label = 144;
|
|
924
|
+
case 144:
|
|
925
|
+
_11.trys.push([144, 146, , 147]);
|
|
926
|
+
return [4 /*yield*/, sdk.api.endusers.deleteOne(bookingEnduserId)];
|
|
927
|
+
case 145:
|
|
928
|
+
_11.sent();
|
|
929
|
+
return [3 /*break*/, 147];
|
|
930
|
+
case 146:
|
|
931
|
+
_w = _11.sent();
|
|
932
|
+
return [3 /*break*/, 147];
|
|
933
|
+
case 147:
|
|
934
|
+
if (!templateId) return [3 /*break*/, 151];
|
|
935
|
+
_11.label = 148;
|
|
936
|
+
case 148:
|
|
937
|
+
_11.trys.push([148, 150, , 151]);
|
|
938
|
+
return [4 /*yield*/, sdk.api.calendar_event_templates.deleteOne(templateId)];
|
|
939
|
+
case 149:
|
|
940
|
+
_11.sent();
|
|
941
|
+
return [3 /*break*/, 151];
|
|
942
|
+
case 150:
|
|
943
|
+
_x = _11.sent();
|
|
944
|
+
return [3 /*break*/, 151];
|
|
945
|
+
case 151:
|
|
946
|
+
if (!productId) return [3 /*break*/, 155];
|
|
947
|
+
_11.label = 152;
|
|
948
|
+
case 152:
|
|
949
|
+
_11.trys.push([152, 154, , 155]);
|
|
720
950
|
return [4 /*yield*/, sdk.api.products.deleteOne(productId)];
|
|
721
|
-
case
|
|
722
|
-
|
|
723
|
-
return [3 /*break*/,
|
|
724
|
-
case
|
|
725
|
-
|
|
726
|
-
return [3 /*break*/,
|
|
727
|
-
case
|
|
728
|
-
if (!formId) return [3 /*break*/,
|
|
729
|
-
|
|
730
|
-
case
|
|
731
|
-
|
|
951
|
+
case 153:
|
|
952
|
+
_11.sent();
|
|
953
|
+
return [3 /*break*/, 155];
|
|
954
|
+
case 154:
|
|
955
|
+
_y = _11.sent();
|
|
956
|
+
return [3 /*break*/, 155];
|
|
957
|
+
case 155:
|
|
958
|
+
if (!formId) return [3 /*break*/, 159];
|
|
959
|
+
_11.label = 156;
|
|
960
|
+
case 156:
|
|
961
|
+
_11.trys.push([156, 158, , 159]);
|
|
732
962
|
return [4 /*yield*/, sdk.api.forms.deleteOne(formId)];
|
|
733
|
-
case
|
|
734
|
-
|
|
735
|
-
return [3 /*break*/,
|
|
736
|
-
case
|
|
737
|
-
|
|
738
|
-
return [3 /*break*/,
|
|
739
|
-
case
|
|
740
|
-
case
|
|
963
|
+
case 157:
|
|
964
|
+
_11.sent();
|
|
965
|
+
return [3 /*break*/, 159];
|
|
966
|
+
case 158:
|
|
967
|
+
_z = _11.sent();
|
|
968
|
+
return [3 /*break*/, 159];
|
|
969
|
+
case 159: return [7 /*endfinally*/];
|
|
970
|
+
case 160: return [2 /*return*/];
|
|
741
971
|
}
|
|
742
972
|
});
|
|
743
973
|
});
|