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