@bytescale/sdk 3.55.0 → 3.56.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/dist/browser/cjs/main.js +148 -43
- package/dist/browser/esm/main.mjs +148 -43
- package/dist/types/private/dtos/AuthSwConfigEntryDto.d.ts +4 -0
- package/dist/types/private/model/AuthManagerInterface.d.ts +22 -1
- package/dist/types/private/model/AuthSession.d.ts +1 -0
- package/dist/types/public/browser/AuthManagerBrowser.d.ts +7 -1
- package/dist/types/public/node/AuthManagerNode.d.ts +3 -1
- package/package.json +1 -1
- package/tests/AuthManagerBrowser.test.ts +234 -0
package/dist/browser/cjs/main.js
CHANGED
|
@@ -3196,6 +3196,12 @@ function AuthManagerBrowser_awaitIgnored(value, direct) {
|
|
|
3196
3196
|
return value && value.then ? value.then(AuthManagerBrowser_empty) : Promise.resolve();
|
|
3197
3197
|
}
|
|
3198
3198
|
}
|
|
3199
|
+
function AuthManagerBrowser_invokeIgnored(body) {
|
|
3200
|
+
var result = body();
|
|
3201
|
+
if (result && result.then) {
|
|
3202
|
+
return result.then(AuthManagerBrowser_empty);
|
|
3203
|
+
}
|
|
3204
|
+
}
|
|
3199
3205
|
function AuthManagerBrowser_await(value, then, direct) {
|
|
3200
3206
|
if (direct) {
|
|
3201
3207
|
return then ? then(value) : value;
|
|
@@ -3217,12 +3223,6 @@ function AuthManagerBrowser_async(f) {
|
|
|
3217
3223
|
}
|
|
3218
3224
|
};
|
|
3219
3225
|
}
|
|
3220
|
-
function AuthManagerBrowser_invokeIgnored(body) {
|
|
3221
|
-
var result = body();
|
|
3222
|
-
if (result && result.then) {
|
|
3223
|
-
return result.then(AuthManagerBrowser_empty);
|
|
3224
|
-
}
|
|
3225
|
-
}
|
|
3226
3226
|
function AuthManagerBrowser_invoke(body, then) {
|
|
3227
3227
|
var result = body();
|
|
3228
3228
|
if (result && result.then) {
|
|
@@ -3261,8 +3261,14 @@ function AuthManagerBrowser_continueIgnored(value) {
|
|
|
3261
3261
|
return value.then(AuthManagerBrowser_empty);
|
|
3262
3262
|
}
|
|
3263
3263
|
}
|
|
3264
|
+
function AuthManagerBrowser_continue(value, then) {
|
|
3265
|
+
return value && value.then ? value.then(then) : then(value);
|
|
3266
|
+
}
|
|
3264
3267
|
function AuthManagerBrowser_typeof(o) { "@babel/helpers - typeof"; return AuthManagerBrowser_typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, AuthManagerBrowser_typeof(o); }
|
|
3265
3268
|
function AuthManagerBrowser_defineProperty(e, r, t) { return (r = AuthManagerBrowser_toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
3269
|
+
function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = AuthManagerBrowser_unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
|
|
3270
|
+
function AuthManagerBrowser_unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return AuthManagerBrowser_arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? AuthManagerBrowser_arrayLikeToArray(r, a) : void 0; } }
|
|
3271
|
+
function AuthManagerBrowser_arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
3266
3272
|
function AuthManagerBrowser_classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
|
|
3267
3273
|
function AuthManagerBrowser_defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, AuthManagerBrowser_toPropertyKey(o.key), o); } }
|
|
3268
3274
|
function AuthManagerBrowser_createClass(e, r, t) { return r && AuthManagerBrowser_defineProperties(e.prototype, r), t && AuthManagerBrowser_defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
|
|
@@ -3296,8 +3302,8 @@ var AuthManagerImpl = /*#__PURE__*/function () {
|
|
|
3296
3302
|
}, {
|
|
3297
3303
|
key: "isAuthSessionReady",
|
|
3298
3304
|
value: function isAuthSessionReady() {
|
|
3299
|
-
var
|
|
3300
|
-
return (
|
|
3305
|
+
var session = AuthSessionState.getSession();
|
|
3306
|
+
return (session === null || session === void 0 ? void 0 : session.isReady) === true || (session === null || session === void 0 ? void 0 : session.accessToken) !== undefined;
|
|
3301
3307
|
}
|
|
3302
3308
|
}, {
|
|
3303
3309
|
key: "beginAuthSession",
|
|
@@ -3309,12 +3315,17 @@ var AuthManagerImpl = /*#__PURE__*/function () {
|
|
|
3309
3315
|
if (_this.isAuthSessionActive()) {
|
|
3310
3316
|
throw new Error("Auth session already active. Please call 'await endAuthSession()' and then call 'await beginAuthSession(...)' to start a new auth session.");
|
|
3311
3317
|
}
|
|
3318
|
+
var canUseServiceWorkers = _this.serviceWorkerUtils.canUseServiceWorkers();
|
|
3319
|
+
if (_this.isV2(params) && !canUseServiceWorkers) {
|
|
3320
|
+
throw new Error("This auth session requires service workers, but this browser does not support them.");
|
|
3321
|
+
}
|
|
3312
3322
|
var newSession = {
|
|
3313
3323
|
accessToken: undefined,
|
|
3314
3324
|
accessTokenRefreshHandle: undefined,
|
|
3315
3325
|
params: params,
|
|
3316
3326
|
isActive: true,
|
|
3317
|
-
|
|
3327
|
+
isReady: false,
|
|
3328
|
+
authServiceWorker: params.serviceWorkerScript !== undefined && canUseServiceWorkers ? {
|
|
3318
3329
|
serviceWorkerScript: params.serviceWorkerScript,
|
|
3319
3330
|
type: "Uninitialized"
|
|
3320
3331
|
} : undefined
|
|
@@ -3323,7 +3334,13 @@ var AuthManagerImpl = /*#__PURE__*/function () {
|
|
|
3323
3334
|
return newSession;
|
|
3324
3335
|
})), function (session) {
|
|
3325
3336
|
// IMPORTANT: must be called outside the above, else re-entrant deadlock will occur.
|
|
3326
|
-
return
|
|
3337
|
+
return AuthManagerBrowser_invokeIgnored(function () {
|
|
3338
|
+
if (_this.isV2(session.params)) {
|
|
3339
|
+
return AuthManagerBrowser_awaitIgnored(_this.refreshServiceWorkerConfig(session, session.params));
|
|
3340
|
+
} else {
|
|
3341
|
+
return AuthManagerBrowser_awaitIgnored(_this.refreshAccessToken(session, session.params));
|
|
3342
|
+
}
|
|
3343
|
+
});
|
|
3327
3344
|
});
|
|
3328
3345
|
} catch (e) {
|
|
3329
3346
|
return Promise.reject(e);
|
|
@@ -3344,14 +3361,15 @@ var AuthManagerImpl = /*#__PURE__*/function () {
|
|
|
3344
3361
|
if (session.accessTokenRefreshHandle !== undefined) {
|
|
3345
3362
|
_this2.scheduler.unschedule(session.accessTokenRefreshHandle);
|
|
3346
3363
|
}
|
|
3347
|
-
return
|
|
3364
|
+
return AuthManagerBrowser_invoke(function () {
|
|
3365
|
+
if (!_this2.isV2(session.params)) {
|
|
3366
|
+
return AuthManagerBrowser_awaitIgnored(_this2.deleteAccessToken(session.params));
|
|
3367
|
+
}
|
|
3368
|
+
}, function () {
|
|
3348
3369
|
return AuthManagerBrowser_invokeIgnored(function () {
|
|
3349
3370
|
if (session.authServiceWorker !== undefined) {
|
|
3350
3371
|
// Prevent service worker from authorizing subsequent requests.
|
|
3351
|
-
return AuthManagerBrowser_awaitIgnored(_this2.
|
|
3352
|
-
type: "SET_BYTESCALE_AUTH_CONFIG",
|
|
3353
|
-
config: []
|
|
3354
|
-
}, session.authServiceWorker, _this2.serviceWorkerScriptFieldName));
|
|
3372
|
+
return AuthManagerBrowser_awaitIgnored(_this2.sendServiceWorkerConfig(session, []));
|
|
3355
3373
|
}
|
|
3356
3374
|
});
|
|
3357
3375
|
});
|
|
@@ -3362,7 +3380,7 @@ var AuthManagerImpl = /*#__PURE__*/function () {
|
|
|
3362
3380
|
}
|
|
3363
3381
|
}, {
|
|
3364
3382
|
key: "refreshAccessToken",
|
|
3365
|
-
value: function refreshAccessToken(session) {
|
|
3383
|
+
value: function refreshAccessToken(session, params) {
|
|
3366
3384
|
try {
|
|
3367
3385
|
var _this3 = this;
|
|
3368
3386
|
return AuthManagerBrowser_await(AuthManagerBrowser_awaitIgnored(_this3.authSessionMutex.safe(AuthManagerBrowser_async(function () {
|
|
@@ -3375,30 +3393,26 @@ var AuthManagerImpl = /*#__PURE__*/function () {
|
|
|
3375
3393
|
var expires = secondsFromNow(_this3.retryAuthAfterErrorSeconds);
|
|
3376
3394
|
return AuthManagerBrowser_continueIgnored(AuthManagerBrowser_finallyRethrows(function () {
|
|
3377
3395
|
return AuthManagerBrowser_catch(function () {
|
|
3378
|
-
var _getAccessToken = _this3.getAccessToken
|
|
3379
|
-
|
|
3380
|
-
|
|
3381
|
-
return AuthManagerBrowser_await(_getAccessToken.call(_this3, _session$params, _session$params$authH), function (jwt) {
|
|
3396
|
+
var _getAccessToken = _this3.getAccessToken;
|
|
3397
|
+
return AuthManagerBrowser_await(params.authHeaders(), function (_params$authHeaders) {
|
|
3398
|
+
return AuthManagerBrowser_await(_getAccessToken.call(_this3, params, _params$authHeaders), function (jwt) {
|
|
3382
3399
|
// We don't use cookie-based auth if the browser supports service worker-based auth, as using both will cause
|
|
3383
3400
|
// confusion for us in the future (i.e. we may question "do we need to use both together? was there a reason?").
|
|
3384
3401
|
// Also: if the user has omitted "allowedOrigins" from their JWT, then service worker-based auth is more secure
|
|
3385
3402
|
// than cookie-based auth, which is another reason to prevent these cookies from being set unless required.
|
|
3386
3403
|
var setCookie = session.authServiceWorker === undefined;
|
|
3387
|
-
return AuthManagerBrowser_await(_this3.setAccessToken(
|
|
3404
|
+
return AuthManagerBrowser_await(_this3.setAccessToken(params, jwt, setCookie), function (setTokenResult) {
|
|
3388
3405
|
return AuthManagerBrowser_invoke(function () {
|
|
3389
3406
|
if (session.authServiceWorker !== undefined) {
|
|
3390
|
-
return AuthManagerBrowser_await(_this3.
|
|
3391
|
-
|
|
3392
|
-
|
|
3393
|
-
|
|
3394
|
-
|
|
3395
|
-
|
|
3396
|
-
|
|
3397
|
-
|
|
3398
|
-
|
|
3399
|
-
urlPrefix: "".concat(session.params.sourceUrlPrefixes === undefined ? "" : _this3.sourceScopedUrlPrefixMarker).concat(_this3.getCdnUrl(session.params), "/").concat(session.params.accountId, "/")
|
|
3400
|
-
}]
|
|
3401
|
-
}, session.authServiceWorker, _this3.serviceWorkerScriptFieldName), function () {
|
|
3407
|
+
return AuthManagerBrowser_await(_this3.sendServiceWorkerConfig(session, [{
|
|
3408
|
+
headers: [{
|
|
3409
|
+
key: "Authorization",
|
|
3410
|
+
value: "Bearer ".concat(jwt)
|
|
3411
|
+
}],
|
|
3412
|
+
expires: secondsFromNow(setTokenResult.ttlSeconds),
|
|
3413
|
+
sourceUrlPrefixes: params.sourceUrlPrefixes,
|
|
3414
|
+
urlPrefix: "".concat(_this3.getCdnUrl(params), "/").concat(params.accountId, "/")
|
|
3415
|
+
}]), function () {
|
|
3402
3416
|
// Allow time for the service worker to receive and process the message. Since this is asynchronous and not
|
|
3403
3417
|
// synchronized, we need to wait for a sufficient amount of time to ensure the service worker is ready to
|
|
3404
3418
|
// authenticate requests, so that after 'beginAuthSession' completes, users can start making requests.
|
|
@@ -3416,6 +3430,7 @@ var AuthManagerImpl = /*#__PURE__*/function () {
|
|
|
3416
3430
|
expires = secondsFromNow(actualTtl);
|
|
3417
3431
|
// Set this at the end, as it's also used to signal 'isAuthSessionReady', so must be set after configuring the Service Worker, etc.
|
|
3418
3432
|
session.accessToken = setTokenResult.accessToken;
|
|
3433
|
+
session.isReady = true;
|
|
3419
3434
|
});
|
|
3420
3435
|
});
|
|
3421
3436
|
});
|
|
@@ -3428,7 +3443,7 @@ var AuthManagerImpl = /*#__PURE__*/function () {
|
|
|
3428
3443
|
// 'setTimeout' can be paused (e.g., during hibernation), risking JWT expiration before it triggers. We use a
|
|
3429
3444
|
// scheduler to check wall-clock time every second and execute the callback at the scheduled time (below).
|
|
3430
3445
|
session.accessTokenRefreshHandle = _this3.scheduler.schedule(expires, function () {
|
|
3431
|
-
_this3.refreshAccessToken(session).then(function () {},
|
|
3446
|
+
_this3.refreshAccessToken(session, params).then(function () {},
|
|
3432
3447
|
// Should not occur, as this method shouldn't throw errors.
|
|
3433
3448
|
function (e) {
|
|
3434
3449
|
return ConsoleUtils.error("Unexpected error when refreshing JWT access token: ".concat(e));
|
|
@@ -3441,6 +3456,91 @@ var AuthManagerImpl = /*#__PURE__*/function () {
|
|
|
3441
3456
|
return Promise.reject(e);
|
|
3442
3457
|
}
|
|
3443
3458
|
}
|
|
3459
|
+
}, {
|
|
3460
|
+
key: "refreshServiceWorkerConfig",
|
|
3461
|
+
value: function refreshServiceWorkerConfig(session, params) {
|
|
3462
|
+
try {
|
|
3463
|
+
var _this4 = this;
|
|
3464
|
+
return AuthManagerBrowser_await(AuthManagerBrowser_awaitIgnored(_this4.authSessionMutex.safe(AuthManagerBrowser_async(function () {
|
|
3465
|
+
var _exit = false;
|
|
3466
|
+
if (!session.isActive) {
|
|
3467
|
+
return;
|
|
3468
|
+
}
|
|
3469
|
+
var refreshAt;
|
|
3470
|
+
return AuthManagerBrowser_continue(AuthManagerBrowser_catch(function () {
|
|
3471
|
+
return AuthManagerBrowser_await(params.getServiceWorkerConfig(), function (config) {
|
|
3472
|
+
if (!Array.isArray(config)) {
|
|
3473
|
+
throw new Error("The 'getServiceWorkerConfig' callback must return an array.");
|
|
3474
|
+
}
|
|
3475
|
+
return AuthManagerBrowser_await(_this4.sendServiceWorkerConfig(session, config), function () {
|
|
3476
|
+
return AuthManagerBrowser_await(new Promise(function (resolve) {
|
|
3477
|
+
return setTimeout(resolve, 100);
|
|
3478
|
+
}), function () {
|
|
3479
|
+
session.isReady = true;
|
|
3480
|
+
refreshAt = _this4.getServiceWorkerConfigRefreshEpoch(config);
|
|
3481
|
+
});
|
|
3482
|
+
});
|
|
3483
|
+
});
|
|
3484
|
+
}, function (e) {
|
|
3485
|
+
ConsoleUtils.warn("Unable to refresh service worker auth config: ".concat(e));
|
|
3486
|
+
refreshAt = Date.now() + _this4.retryAuthAfterErrorSeconds * 1000;
|
|
3487
|
+
}), function (_result2) {
|
|
3488
|
+
if (_exit) return _result2;
|
|
3489
|
+
if (refreshAt !== undefined) {
|
|
3490
|
+
session.accessTokenRefreshHandle = _this4.scheduler.schedule(refreshAt, function () {
|
|
3491
|
+
_this4.refreshServiceWorkerConfig(session, params).then(function () {}, function (e) {
|
|
3492
|
+
return ConsoleUtils.error("Unexpected error when refreshing service worker auth config: ".concat(e));
|
|
3493
|
+
});
|
|
3494
|
+
});
|
|
3495
|
+
}
|
|
3496
|
+
});
|
|
3497
|
+
}))));
|
|
3498
|
+
} catch (e) {
|
|
3499
|
+
return Promise.reject(e);
|
|
3500
|
+
}
|
|
3501
|
+
}
|
|
3502
|
+
}, {
|
|
3503
|
+
key: "getServiceWorkerConfigRefreshEpoch",
|
|
3504
|
+
value: function getServiceWorkerConfigRefreshEpoch(config) {
|
|
3505
|
+
var earliestExpiry;
|
|
3506
|
+
var _iterator = _createForOfIteratorHelper(config),
|
|
3507
|
+
_step;
|
|
3508
|
+
try {
|
|
3509
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
3510
|
+
var entry = _step.value;
|
|
3511
|
+
if (entry.expires !== undefined && (earliestExpiry === undefined || entry.expires < earliestExpiry)) {
|
|
3512
|
+
earliestExpiry = entry.expires;
|
|
3513
|
+
}
|
|
3514
|
+
}
|
|
3515
|
+
} catch (err) {
|
|
3516
|
+
_iterator.e(err);
|
|
3517
|
+
} finally {
|
|
3518
|
+
_iterator.f();
|
|
3519
|
+
}
|
|
3520
|
+
return earliestExpiry === undefined ? undefined : earliestExpiry - this.refreshBeforeExpirySeconds * 1000;
|
|
3521
|
+
}
|
|
3522
|
+
}, {
|
|
3523
|
+
key: "sendServiceWorkerConfig",
|
|
3524
|
+
value: function sendServiceWorkerConfig(session, config) {
|
|
3525
|
+
try {
|
|
3526
|
+
var _this5 = this;
|
|
3527
|
+
if (session.authServiceWorker === undefined) {
|
|
3528
|
+
throw new Error("Service worker configuration cannot be applied because service workers are unavailable.");
|
|
3529
|
+
}
|
|
3530
|
+
return AuthManagerBrowser_await(_this5.serviceWorkerUtils.sendMessage({
|
|
3531
|
+
type: "SET_BYTESCALE_AUTH_CONFIG",
|
|
3532
|
+
config: config.map(function (entry) {
|
|
3533
|
+
return Object.assign(Object.assign({}, entry), {
|
|
3534
|
+
urlPrefix: "".concat(entry.sourceUrlPrefixes === undefined ? "" : _this5.sourceScopedUrlPrefixMarker).concat(entry.urlPrefix)
|
|
3535
|
+
});
|
|
3536
|
+
})
|
|
3537
|
+
}, session.authServiceWorker, _this5.serviceWorkerScriptFieldName), function (_this5$serviceWorkerU) {
|
|
3538
|
+
session.authServiceWorker = _this5$serviceWorkerU;
|
|
3539
|
+
});
|
|
3540
|
+
} catch (e) {
|
|
3541
|
+
return Promise.reject(e);
|
|
3542
|
+
}
|
|
3543
|
+
}
|
|
3444
3544
|
}, {
|
|
3445
3545
|
key: "getAccessTokenUrl",
|
|
3446
3546
|
value: function getAccessTokenUrl(params, setCookie) {
|
|
@@ -3456,9 +3556,9 @@ var AuthManagerImpl = /*#__PURE__*/function () {
|
|
|
3456
3556
|
key: "deleteAccessToken",
|
|
3457
3557
|
value: function deleteAccessToken(params) {
|
|
3458
3558
|
try {
|
|
3459
|
-
var
|
|
3559
|
+
var _this6 = this;
|
|
3460
3560
|
var _a;
|
|
3461
|
-
return AuthManagerBrowser_await(AuthManagerBrowser_awaitIgnored(BaseAPI.fetch(
|
|
3561
|
+
return AuthManagerBrowser_await(AuthManagerBrowser_awaitIgnored(BaseAPI.fetch(_this6.getAccessTokenUrl(params, true), {
|
|
3462
3562
|
method: "DELETE",
|
|
3463
3563
|
credentials: "include",
|
|
3464
3564
|
headers: {}
|
|
@@ -3474,15 +3574,15 @@ var AuthManagerImpl = /*#__PURE__*/function () {
|
|
|
3474
3574
|
key: "setAccessToken",
|
|
3475
3575
|
value: function setAccessToken(params, jwt, setCookie) {
|
|
3476
3576
|
try {
|
|
3477
|
-
var
|
|
3577
|
+
var _this7 = this;
|
|
3478
3578
|
var _a;
|
|
3479
3579
|
var request = {
|
|
3480
3580
|
accessToken: jwt
|
|
3481
3581
|
};
|
|
3482
|
-
return AuthManagerBrowser_await(BaseAPI.fetch(
|
|
3582
|
+
return AuthManagerBrowser_await(BaseAPI.fetch(_this7.getAccessTokenUrl(params, setCookie), {
|
|
3483
3583
|
method: "PUT",
|
|
3484
3584
|
credentials: "include",
|
|
3485
|
-
headers: AuthManagerBrowser_defineProperty({},
|
|
3585
|
+
headers: AuthManagerBrowser_defineProperty({}, _this7.contentType, _this7.contentTypeJson),
|
|
3486
3586
|
body: JSON.stringify(request)
|
|
3487
3587
|
}, {
|
|
3488
3588
|
isBytescaleApi: true,
|
|
@@ -3498,10 +3598,10 @@ var AuthManagerImpl = /*#__PURE__*/function () {
|
|
|
3498
3598
|
key: "getAccessToken",
|
|
3499
3599
|
value: function getAccessToken(params, headers) {
|
|
3500
3600
|
try {
|
|
3501
|
-
var
|
|
3601
|
+
var _this8 = this;
|
|
3502
3602
|
var _a, _b;
|
|
3503
3603
|
var endpointName = "Your auth API endpoint";
|
|
3504
|
-
var requiredContentType =
|
|
3604
|
+
var requiredContentType = _this8.contentTypeText;
|
|
3505
3605
|
return AuthManagerBrowser_await(BaseAPI.fetch(params.authUrl, {
|
|
3506
3606
|
method: "GET",
|
|
3507
3607
|
headers: headers
|
|
@@ -3509,10 +3609,10 @@ var AuthManagerImpl = /*#__PURE__*/function () {
|
|
|
3509
3609
|
isBytescaleApi: false,
|
|
3510
3610
|
fetchApi: (_a = params.options) === null || _a === void 0 ? void 0 : _a.fetchApi
|
|
3511
3611
|
}), function (result) {
|
|
3512
|
-
var actualContentType = (_b = result.headers.get(
|
|
3612
|
+
var actualContentType = (_b = result.headers.get(_this8.contentType)) !== null && _b !== void 0 ? _b : "";
|
|
3513
3613
|
// Support content types like "text/plain; charset=utf-8" and "text/plain"
|
|
3514
3614
|
if (actualContentType.split(";")[0] !== requiredContentType) {
|
|
3515
|
-
throw new Error("".concat(endpointName, " returned \"").concat(actualContentType, "\" for the ").concat(
|
|
3615
|
+
throw new Error("".concat(endpointName, " returned \"").concat(actualContentType, "\" for the ").concat(_this8.contentType, " response header, but the Bytescale SDK requires \"").concat(requiredContentType, "\"."));
|
|
3516
3616
|
}
|
|
3517
3617
|
return AuthManagerBrowser_await(result.text(), function (jwt) {
|
|
3518
3618
|
if (jwt.length === 0) {
|
|
@@ -3529,6 +3629,11 @@ var AuthManagerImpl = /*#__PURE__*/function () {
|
|
|
3529
3629
|
return Promise.reject(e);
|
|
3530
3630
|
}
|
|
3531
3631
|
}
|
|
3632
|
+
}, {
|
|
3633
|
+
key: "isV2",
|
|
3634
|
+
value: function isV2(params) {
|
|
3635
|
+
return "getServiceWorkerConfig" in params;
|
|
3636
|
+
}
|
|
3532
3637
|
}]);
|
|
3533
3638
|
}();
|
|
3534
3639
|
/**
|
|
@@ -3156,6 +3156,12 @@ function AuthManagerBrowser_awaitIgnored(value, direct) {
|
|
|
3156
3156
|
return value && value.then ? value.then(AuthManagerBrowser_empty) : Promise.resolve();
|
|
3157
3157
|
}
|
|
3158
3158
|
}
|
|
3159
|
+
function AuthManagerBrowser_invokeIgnored(body) {
|
|
3160
|
+
var result = body();
|
|
3161
|
+
if (result && result.then) {
|
|
3162
|
+
return result.then(AuthManagerBrowser_empty);
|
|
3163
|
+
}
|
|
3164
|
+
}
|
|
3159
3165
|
function AuthManagerBrowser_await(value, then, direct) {
|
|
3160
3166
|
if (direct) {
|
|
3161
3167
|
return then ? then(value) : value;
|
|
@@ -3177,12 +3183,6 @@ function AuthManagerBrowser_async(f) {
|
|
|
3177
3183
|
}
|
|
3178
3184
|
};
|
|
3179
3185
|
}
|
|
3180
|
-
function AuthManagerBrowser_invokeIgnored(body) {
|
|
3181
|
-
var result = body();
|
|
3182
|
-
if (result && result.then) {
|
|
3183
|
-
return result.then(AuthManagerBrowser_empty);
|
|
3184
|
-
}
|
|
3185
|
-
}
|
|
3186
3186
|
function AuthManagerBrowser_invoke(body, then) {
|
|
3187
3187
|
var result = body();
|
|
3188
3188
|
if (result && result.then) {
|
|
@@ -3221,8 +3221,14 @@ function AuthManagerBrowser_continueIgnored(value) {
|
|
|
3221
3221
|
return value.then(AuthManagerBrowser_empty);
|
|
3222
3222
|
}
|
|
3223
3223
|
}
|
|
3224
|
+
function AuthManagerBrowser_continue(value, then) {
|
|
3225
|
+
return value && value.then ? value.then(then) : then(value);
|
|
3226
|
+
}
|
|
3224
3227
|
function AuthManagerBrowser_typeof(o) { "@babel/helpers - typeof"; return AuthManagerBrowser_typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, AuthManagerBrowser_typeof(o); }
|
|
3225
3228
|
function AuthManagerBrowser_defineProperty(e, r, t) { return (r = AuthManagerBrowser_toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
3229
|
+
function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = AuthManagerBrowser_unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
|
|
3230
|
+
function AuthManagerBrowser_unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return AuthManagerBrowser_arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? AuthManagerBrowser_arrayLikeToArray(r, a) : void 0; } }
|
|
3231
|
+
function AuthManagerBrowser_arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
3226
3232
|
function AuthManagerBrowser_classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
|
|
3227
3233
|
function AuthManagerBrowser_defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, AuthManagerBrowser_toPropertyKey(o.key), o); } }
|
|
3228
3234
|
function AuthManagerBrowser_createClass(e, r, t) { return r && AuthManagerBrowser_defineProperties(e.prototype, r), t && AuthManagerBrowser_defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
|
|
@@ -3256,8 +3262,8 @@ var AuthManagerImpl = /*#__PURE__*/function () {
|
|
|
3256
3262
|
}, {
|
|
3257
3263
|
key: "isAuthSessionReady",
|
|
3258
3264
|
value: function isAuthSessionReady() {
|
|
3259
|
-
var
|
|
3260
|
-
return (
|
|
3265
|
+
var session = AuthSessionState.getSession();
|
|
3266
|
+
return (session === null || session === void 0 ? void 0 : session.isReady) === true || (session === null || session === void 0 ? void 0 : session.accessToken) !== undefined;
|
|
3261
3267
|
}
|
|
3262
3268
|
}, {
|
|
3263
3269
|
key: "beginAuthSession",
|
|
@@ -3269,12 +3275,17 @@ var AuthManagerImpl = /*#__PURE__*/function () {
|
|
|
3269
3275
|
if (_this.isAuthSessionActive()) {
|
|
3270
3276
|
throw new Error("Auth session already active. Please call 'await endAuthSession()' and then call 'await beginAuthSession(...)' to start a new auth session.");
|
|
3271
3277
|
}
|
|
3278
|
+
var canUseServiceWorkers = _this.serviceWorkerUtils.canUseServiceWorkers();
|
|
3279
|
+
if (_this.isV2(params) && !canUseServiceWorkers) {
|
|
3280
|
+
throw new Error("This auth session requires service workers, but this browser does not support them.");
|
|
3281
|
+
}
|
|
3272
3282
|
var newSession = {
|
|
3273
3283
|
accessToken: undefined,
|
|
3274
3284
|
accessTokenRefreshHandle: undefined,
|
|
3275
3285
|
params: params,
|
|
3276
3286
|
isActive: true,
|
|
3277
|
-
|
|
3287
|
+
isReady: false,
|
|
3288
|
+
authServiceWorker: params.serviceWorkerScript !== undefined && canUseServiceWorkers ? {
|
|
3278
3289
|
serviceWorkerScript: params.serviceWorkerScript,
|
|
3279
3290
|
type: "Uninitialized"
|
|
3280
3291
|
} : undefined
|
|
@@ -3283,7 +3294,13 @@ var AuthManagerImpl = /*#__PURE__*/function () {
|
|
|
3283
3294
|
return newSession;
|
|
3284
3295
|
})), function (session) {
|
|
3285
3296
|
// IMPORTANT: must be called outside the above, else re-entrant deadlock will occur.
|
|
3286
|
-
return
|
|
3297
|
+
return AuthManagerBrowser_invokeIgnored(function () {
|
|
3298
|
+
if (_this.isV2(session.params)) {
|
|
3299
|
+
return AuthManagerBrowser_awaitIgnored(_this.refreshServiceWorkerConfig(session, session.params));
|
|
3300
|
+
} else {
|
|
3301
|
+
return AuthManagerBrowser_awaitIgnored(_this.refreshAccessToken(session, session.params));
|
|
3302
|
+
}
|
|
3303
|
+
});
|
|
3287
3304
|
});
|
|
3288
3305
|
} catch (e) {
|
|
3289
3306
|
return Promise.reject(e);
|
|
@@ -3304,14 +3321,15 @@ var AuthManagerImpl = /*#__PURE__*/function () {
|
|
|
3304
3321
|
if (session.accessTokenRefreshHandle !== undefined) {
|
|
3305
3322
|
_this2.scheduler.unschedule(session.accessTokenRefreshHandle);
|
|
3306
3323
|
}
|
|
3307
|
-
return
|
|
3324
|
+
return AuthManagerBrowser_invoke(function () {
|
|
3325
|
+
if (!_this2.isV2(session.params)) {
|
|
3326
|
+
return AuthManagerBrowser_awaitIgnored(_this2.deleteAccessToken(session.params));
|
|
3327
|
+
}
|
|
3328
|
+
}, function () {
|
|
3308
3329
|
return AuthManagerBrowser_invokeIgnored(function () {
|
|
3309
3330
|
if (session.authServiceWorker !== undefined) {
|
|
3310
3331
|
// Prevent service worker from authorizing subsequent requests.
|
|
3311
|
-
return AuthManagerBrowser_awaitIgnored(_this2.
|
|
3312
|
-
type: "SET_BYTESCALE_AUTH_CONFIG",
|
|
3313
|
-
config: []
|
|
3314
|
-
}, session.authServiceWorker, _this2.serviceWorkerScriptFieldName));
|
|
3332
|
+
return AuthManagerBrowser_awaitIgnored(_this2.sendServiceWorkerConfig(session, []));
|
|
3315
3333
|
}
|
|
3316
3334
|
});
|
|
3317
3335
|
});
|
|
@@ -3322,7 +3340,7 @@ var AuthManagerImpl = /*#__PURE__*/function () {
|
|
|
3322
3340
|
}
|
|
3323
3341
|
}, {
|
|
3324
3342
|
key: "refreshAccessToken",
|
|
3325
|
-
value: function refreshAccessToken(session) {
|
|
3343
|
+
value: function refreshAccessToken(session, params) {
|
|
3326
3344
|
try {
|
|
3327
3345
|
var _this3 = this;
|
|
3328
3346
|
return AuthManagerBrowser_await(AuthManagerBrowser_awaitIgnored(_this3.authSessionMutex.safe(AuthManagerBrowser_async(function () {
|
|
@@ -3335,30 +3353,26 @@ var AuthManagerImpl = /*#__PURE__*/function () {
|
|
|
3335
3353
|
var expires = secondsFromNow(_this3.retryAuthAfterErrorSeconds);
|
|
3336
3354
|
return AuthManagerBrowser_continueIgnored(AuthManagerBrowser_finallyRethrows(function () {
|
|
3337
3355
|
return AuthManagerBrowser_catch(function () {
|
|
3338
|
-
var _getAccessToken = _this3.getAccessToken
|
|
3339
|
-
|
|
3340
|
-
|
|
3341
|
-
return AuthManagerBrowser_await(_getAccessToken.call(_this3, _session$params, _session$params$authH), function (jwt) {
|
|
3356
|
+
var _getAccessToken = _this3.getAccessToken;
|
|
3357
|
+
return AuthManagerBrowser_await(params.authHeaders(), function (_params$authHeaders) {
|
|
3358
|
+
return AuthManagerBrowser_await(_getAccessToken.call(_this3, params, _params$authHeaders), function (jwt) {
|
|
3342
3359
|
// We don't use cookie-based auth if the browser supports service worker-based auth, as using both will cause
|
|
3343
3360
|
// confusion for us in the future (i.e. we may question "do we need to use both together? was there a reason?").
|
|
3344
3361
|
// Also: if the user has omitted "allowedOrigins" from their JWT, then service worker-based auth is more secure
|
|
3345
3362
|
// than cookie-based auth, which is another reason to prevent these cookies from being set unless required.
|
|
3346
3363
|
var setCookie = session.authServiceWorker === undefined;
|
|
3347
|
-
return AuthManagerBrowser_await(_this3.setAccessToken(
|
|
3364
|
+
return AuthManagerBrowser_await(_this3.setAccessToken(params, jwt, setCookie), function (setTokenResult) {
|
|
3348
3365
|
return AuthManagerBrowser_invoke(function () {
|
|
3349
3366
|
if (session.authServiceWorker !== undefined) {
|
|
3350
|
-
return AuthManagerBrowser_await(_this3.
|
|
3351
|
-
|
|
3352
|
-
|
|
3353
|
-
|
|
3354
|
-
|
|
3355
|
-
|
|
3356
|
-
|
|
3357
|
-
|
|
3358
|
-
|
|
3359
|
-
urlPrefix: "".concat(session.params.sourceUrlPrefixes === undefined ? "" : _this3.sourceScopedUrlPrefixMarker).concat(_this3.getCdnUrl(session.params), "/").concat(session.params.accountId, "/")
|
|
3360
|
-
}]
|
|
3361
|
-
}, session.authServiceWorker, _this3.serviceWorkerScriptFieldName), function () {
|
|
3367
|
+
return AuthManagerBrowser_await(_this3.sendServiceWorkerConfig(session, [{
|
|
3368
|
+
headers: [{
|
|
3369
|
+
key: "Authorization",
|
|
3370
|
+
value: "Bearer ".concat(jwt)
|
|
3371
|
+
}],
|
|
3372
|
+
expires: secondsFromNow(setTokenResult.ttlSeconds),
|
|
3373
|
+
sourceUrlPrefixes: params.sourceUrlPrefixes,
|
|
3374
|
+
urlPrefix: "".concat(_this3.getCdnUrl(params), "/").concat(params.accountId, "/")
|
|
3375
|
+
}]), function () {
|
|
3362
3376
|
// Allow time for the service worker to receive and process the message. Since this is asynchronous and not
|
|
3363
3377
|
// synchronized, we need to wait for a sufficient amount of time to ensure the service worker is ready to
|
|
3364
3378
|
// authenticate requests, so that after 'beginAuthSession' completes, users can start making requests.
|
|
@@ -3376,6 +3390,7 @@ var AuthManagerImpl = /*#__PURE__*/function () {
|
|
|
3376
3390
|
expires = secondsFromNow(actualTtl);
|
|
3377
3391
|
// Set this at the end, as it's also used to signal 'isAuthSessionReady', so must be set after configuring the Service Worker, etc.
|
|
3378
3392
|
session.accessToken = setTokenResult.accessToken;
|
|
3393
|
+
session.isReady = true;
|
|
3379
3394
|
});
|
|
3380
3395
|
});
|
|
3381
3396
|
});
|
|
@@ -3388,7 +3403,7 @@ var AuthManagerImpl = /*#__PURE__*/function () {
|
|
|
3388
3403
|
// 'setTimeout' can be paused (e.g., during hibernation), risking JWT expiration before it triggers. We use a
|
|
3389
3404
|
// scheduler to check wall-clock time every second and execute the callback at the scheduled time (below).
|
|
3390
3405
|
session.accessTokenRefreshHandle = _this3.scheduler.schedule(expires, function () {
|
|
3391
|
-
_this3.refreshAccessToken(session).then(function () {},
|
|
3406
|
+
_this3.refreshAccessToken(session, params).then(function () {},
|
|
3392
3407
|
// Should not occur, as this method shouldn't throw errors.
|
|
3393
3408
|
function (e) {
|
|
3394
3409
|
return ConsoleUtils.error("Unexpected error when refreshing JWT access token: ".concat(e));
|
|
@@ -3401,6 +3416,91 @@ var AuthManagerImpl = /*#__PURE__*/function () {
|
|
|
3401
3416
|
return Promise.reject(e);
|
|
3402
3417
|
}
|
|
3403
3418
|
}
|
|
3419
|
+
}, {
|
|
3420
|
+
key: "refreshServiceWorkerConfig",
|
|
3421
|
+
value: function refreshServiceWorkerConfig(session, params) {
|
|
3422
|
+
try {
|
|
3423
|
+
var _this4 = this;
|
|
3424
|
+
return AuthManagerBrowser_await(AuthManagerBrowser_awaitIgnored(_this4.authSessionMutex.safe(AuthManagerBrowser_async(function () {
|
|
3425
|
+
var _exit = false;
|
|
3426
|
+
if (!session.isActive) {
|
|
3427
|
+
return;
|
|
3428
|
+
}
|
|
3429
|
+
var refreshAt;
|
|
3430
|
+
return AuthManagerBrowser_continue(AuthManagerBrowser_catch(function () {
|
|
3431
|
+
return AuthManagerBrowser_await(params.getServiceWorkerConfig(), function (config) {
|
|
3432
|
+
if (!Array.isArray(config)) {
|
|
3433
|
+
throw new Error("The 'getServiceWorkerConfig' callback must return an array.");
|
|
3434
|
+
}
|
|
3435
|
+
return AuthManagerBrowser_await(_this4.sendServiceWorkerConfig(session, config), function () {
|
|
3436
|
+
return AuthManagerBrowser_await(new Promise(function (resolve) {
|
|
3437
|
+
return setTimeout(resolve, 100);
|
|
3438
|
+
}), function () {
|
|
3439
|
+
session.isReady = true;
|
|
3440
|
+
refreshAt = _this4.getServiceWorkerConfigRefreshEpoch(config);
|
|
3441
|
+
});
|
|
3442
|
+
});
|
|
3443
|
+
});
|
|
3444
|
+
}, function (e) {
|
|
3445
|
+
ConsoleUtils.warn("Unable to refresh service worker auth config: ".concat(e));
|
|
3446
|
+
refreshAt = Date.now() + _this4.retryAuthAfterErrorSeconds * 1000;
|
|
3447
|
+
}), function (_result2) {
|
|
3448
|
+
if (_exit) return _result2;
|
|
3449
|
+
if (refreshAt !== undefined) {
|
|
3450
|
+
session.accessTokenRefreshHandle = _this4.scheduler.schedule(refreshAt, function () {
|
|
3451
|
+
_this4.refreshServiceWorkerConfig(session, params).then(function () {}, function (e) {
|
|
3452
|
+
return ConsoleUtils.error("Unexpected error when refreshing service worker auth config: ".concat(e));
|
|
3453
|
+
});
|
|
3454
|
+
});
|
|
3455
|
+
}
|
|
3456
|
+
});
|
|
3457
|
+
}))));
|
|
3458
|
+
} catch (e) {
|
|
3459
|
+
return Promise.reject(e);
|
|
3460
|
+
}
|
|
3461
|
+
}
|
|
3462
|
+
}, {
|
|
3463
|
+
key: "getServiceWorkerConfigRefreshEpoch",
|
|
3464
|
+
value: function getServiceWorkerConfigRefreshEpoch(config) {
|
|
3465
|
+
var earliestExpiry;
|
|
3466
|
+
var _iterator = _createForOfIteratorHelper(config),
|
|
3467
|
+
_step;
|
|
3468
|
+
try {
|
|
3469
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
3470
|
+
var entry = _step.value;
|
|
3471
|
+
if (entry.expires !== undefined && (earliestExpiry === undefined || entry.expires < earliestExpiry)) {
|
|
3472
|
+
earliestExpiry = entry.expires;
|
|
3473
|
+
}
|
|
3474
|
+
}
|
|
3475
|
+
} catch (err) {
|
|
3476
|
+
_iterator.e(err);
|
|
3477
|
+
} finally {
|
|
3478
|
+
_iterator.f();
|
|
3479
|
+
}
|
|
3480
|
+
return earliestExpiry === undefined ? undefined : earliestExpiry - this.refreshBeforeExpirySeconds * 1000;
|
|
3481
|
+
}
|
|
3482
|
+
}, {
|
|
3483
|
+
key: "sendServiceWorkerConfig",
|
|
3484
|
+
value: function sendServiceWorkerConfig(session, config) {
|
|
3485
|
+
try {
|
|
3486
|
+
var _this5 = this;
|
|
3487
|
+
if (session.authServiceWorker === undefined) {
|
|
3488
|
+
throw new Error("Service worker configuration cannot be applied because service workers are unavailable.");
|
|
3489
|
+
}
|
|
3490
|
+
return AuthManagerBrowser_await(_this5.serviceWorkerUtils.sendMessage({
|
|
3491
|
+
type: "SET_BYTESCALE_AUTH_CONFIG",
|
|
3492
|
+
config: config.map(function (entry) {
|
|
3493
|
+
return Object.assign(Object.assign({}, entry), {
|
|
3494
|
+
urlPrefix: "".concat(entry.sourceUrlPrefixes === undefined ? "" : _this5.sourceScopedUrlPrefixMarker).concat(entry.urlPrefix)
|
|
3495
|
+
});
|
|
3496
|
+
})
|
|
3497
|
+
}, session.authServiceWorker, _this5.serviceWorkerScriptFieldName), function (_this5$serviceWorkerU) {
|
|
3498
|
+
session.authServiceWorker = _this5$serviceWorkerU;
|
|
3499
|
+
});
|
|
3500
|
+
} catch (e) {
|
|
3501
|
+
return Promise.reject(e);
|
|
3502
|
+
}
|
|
3503
|
+
}
|
|
3404
3504
|
}, {
|
|
3405
3505
|
key: "getAccessTokenUrl",
|
|
3406
3506
|
value: function getAccessTokenUrl(params, setCookie) {
|
|
@@ -3416,9 +3516,9 @@ var AuthManagerImpl = /*#__PURE__*/function () {
|
|
|
3416
3516
|
key: "deleteAccessToken",
|
|
3417
3517
|
value: function deleteAccessToken(params) {
|
|
3418
3518
|
try {
|
|
3419
|
-
var
|
|
3519
|
+
var _this6 = this;
|
|
3420
3520
|
var _a;
|
|
3421
|
-
return AuthManagerBrowser_await(AuthManagerBrowser_awaitIgnored(BaseAPI.fetch(
|
|
3521
|
+
return AuthManagerBrowser_await(AuthManagerBrowser_awaitIgnored(BaseAPI.fetch(_this6.getAccessTokenUrl(params, true), {
|
|
3422
3522
|
method: "DELETE",
|
|
3423
3523
|
credentials: "include",
|
|
3424
3524
|
headers: {}
|
|
@@ -3434,15 +3534,15 @@ var AuthManagerImpl = /*#__PURE__*/function () {
|
|
|
3434
3534
|
key: "setAccessToken",
|
|
3435
3535
|
value: function setAccessToken(params, jwt, setCookie) {
|
|
3436
3536
|
try {
|
|
3437
|
-
var
|
|
3537
|
+
var _this7 = this;
|
|
3438
3538
|
var _a;
|
|
3439
3539
|
var request = {
|
|
3440
3540
|
accessToken: jwt
|
|
3441
3541
|
};
|
|
3442
|
-
return AuthManagerBrowser_await(BaseAPI.fetch(
|
|
3542
|
+
return AuthManagerBrowser_await(BaseAPI.fetch(_this7.getAccessTokenUrl(params, setCookie), {
|
|
3443
3543
|
method: "PUT",
|
|
3444
3544
|
credentials: "include",
|
|
3445
|
-
headers: AuthManagerBrowser_defineProperty({},
|
|
3545
|
+
headers: AuthManagerBrowser_defineProperty({}, _this7.contentType, _this7.contentTypeJson),
|
|
3446
3546
|
body: JSON.stringify(request)
|
|
3447
3547
|
}, {
|
|
3448
3548
|
isBytescaleApi: true,
|
|
@@ -3458,10 +3558,10 @@ var AuthManagerImpl = /*#__PURE__*/function () {
|
|
|
3458
3558
|
key: "getAccessToken",
|
|
3459
3559
|
value: function getAccessToken(params, headers) {
|
|
3460
3560
|
try {
|
|
3461
|
-
var
|
|
3561
|
+
var _this8 = this;
|
|
3462
3562
|
var _a, _b;
|
|
3463
3563
|
var endpointName = "Your auth API endpoint";
|
|
3464
|
-
var requiredContentType =
|
|
3564
|
+
var requiredContentType = _this8.contentTypeText;
|
|
3465
3565
|
return AuthManagerBrowser_await(BaseAPI.fetch(params.authUrl, {
|
|
3466
3566
|
method: "GET",
|
|
3467
3567
|
headers: headers
|
|
@@ -3469,10 +3569,10 @@ var AuthManagerImpl = /*#__PURE__*/function () {
|
|
|
3469
3569
|
isBytescaleApi: false,
|
|
3470
3570
|
fetchApi: (_a = params.options) === null || _a === void 0 ? void 0 : _a.fetchApi
|
|
3471
3571
|
}), function (result) {
|
|
3472
|
-
var actualContentType = (_b = result.headers.get(
|
|
3572
|
+
var actualContentType = (_b = result.headers.get(_this8.contentType)) !== null && _b !== void 0 ? _b : "";
|
|
3473
3573
|
// Support content types like "text/plain; charset=utf-8" and "text/plain"
|
|
3474
3574
|
if (actualContentType.split(";")[0] !== requiredContentType) {
|
|
3475
|
-
throw new Error("".concat(endpointName, " returned \"").concat(actualContentType, "\" for the ").concat(
|
|
3575
|
+
throw new Error("".concat(endpointName, " returned \"").concat(actualContentType, "\" for the ").concat(_this8.contentType, " response header, but the Bytescale SDK requires \"").concat(requiredContentType, "\"."));
|
|
3476
3576
|
}
|
|
3477
3577
|
return AuthManagerBrowser_await(result.text(), function (jwt) {
|
|
3478
3578
|
if (jwt.length === 0) {
|
|
@@ -3489,6 +3589,11 @@ var AuthManagerImpl = /*#__PURE__*/function () {
|
|
|
3489
3589
|
return Promise.reject(e);
|
|
3490
3590
|
}
|
|
3491
3591
|
}
|
|
3592
|
+
}, {
|
|
3593
|
+
key: "isV2",
|
|
3594
|
+
value: function isV2(params) {
|
|
3595
|
+
return "getServiceWorkerConfig" in params;
|
|
3596
|
+
}
|
|
3492
3597
|
}]);
|
|
3493
3598
|
}();
|
|
3494
3599
|
/**
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import { AuthSwHeaderDto } from "./AuthSwHeaderDto";
|
|
2
2
|
export interface AuthSwConfigEntryDto {
|
|
3
|
+
/** Epoch time in milliseconds. Omit the value to keep the entry until the config is replaced. */
|
|
3
4
|
expires: number | undefined;
|
|
5
|
+
/** Headers to add to matching requests. */
|
|
4
6
|
headers: AuthSwHeaderDto[];
|
|
7
|
+
/** Optional page or iframe URL prefixes. An empty array matches no clients. */
|
|
5
8
|
sourceUrlPrefixes?: string[];
|
|
9
|
+
/** Request URL prefix. Use the actual URL; AuthManager applies any internal compatibility marker. */
|
|
6
10
|
urlPrefix: string;
|
|
7
11
|
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { BytescaleApiClientConfig } from "../../public/shared";
|
|
2
|
-
|
|
2
|
+
import { AuthSwConfigEntryDto } from "../dtos/AuthSwConfigEntryDto";
|
|
3
|
+
export type BeginAuthSessionParams = BeginAuthSessionParamsV1 | BeginAuthSessionParamsV2;
|
|
4
|
+
export interface BeginAuthSessionParamsV1 {
|
|
3
5
|
/**
|
|
4
6
|
* The account ID to authorize requests for.
|
|
5
7
|
*/
|
|
@@ -71,10 +73,29 @@ export interface BeginAuthSessionParams {
|
|
|
71
73
|
*/
|
|
72
74
|
sourceUrlPrefixes?: string[];
|
|
73
75
|
}
|
|
76
|
+
export interface BeginAuthSessionParamsV2 {
|
|
77
|
+
/**
|
|
78
|
+
* Returns the complete replacement service-worker authorization config. Called when the session begins and again
|
|
79
|
+
* 20 seconds before the earliest configured expiry. Entries without an expiry do not trigger a refresh.
|
|
80
|
+
*
|
|
81
|
+
* IMPORTANT: do not call 'AuthManager.beginAuthSession' or 'AuthManager.endAuthSession' inside this callback, as this will cause a deadlock.
|
|
82
|
+
*/
|
|
83
|
+
getServiceWorkerConfig: () => Promise<AuthSwConfigEntryDto[]>;
|
|
84
|
+
/**
|
|
85
|
+
* The path to the service worker JavaScript file hosted at the root of your website.
|
|
86
|
+
*
|
|
87
|
+
* Unlike V1 sessions, V2 sessions require service-worker support and do not create an SDK API access token or use
|
|
88
|
+
* CDN cookies as a fallback.
|
|
89
|
+
*/
|
|
90
|
+
serviceWorkerScript: string;
|
|
91
|
+
}
|
|
74
92
|
export interface AuthManagerInterface {
|
|
75
93
|
/**
|
|
76
94
|
* Begins a JWT auth session with the Bytescale API and Bytescale CDN.
|
|
77
95
|
*
|
|
96
|
+
* V1 sessions fetch and refresh a JWT using the supplied auth endpoint. V2 sessions instead refresh the complete
|
|
97
|
+
* service-worker configuration using `getServiceWorkerConfig`.
|
|
98
|
+
*
|
|
78
99
|
* Specifically, calling this method will cause the SDK to periodically acquire a JWT from your JWT endpoint. The SDK will then automatically include this JWT in all subsequent Bytescale API requests (via the 'authorization-token' request header) and also in all Bytescale CDN download requests (via a session cookie, or an 'authorization' header if service workers are being used).
|
|
79
100
|
*
|
|
80
101
|
* You can only call this method if 'isAuthSessionActive() === false', else an error will be returned.
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { AuthManagerInterface, BeginAuthSessionParams } from "../../private/model/AuthManagerInterface";
|
|
2
2
|
import { AuthSwSetConfigDto } from "../../private/dtos/AuthSwSetConfigDto";
|
|
3
3
|
import { ServiceWorkerUtils } from "../../private/ServiceWorkerUtils";
|
|
4
|
+
export type { AuthSwConfigEntryDto } from "../../private/dtos/AuthSwConfigEntryDto";
|
|
5
|
+
export type { AuthSwHeaderDto } from "../../private/dtos/AuthSwHeaderDto";
|
|
6
|
+
export type { BeginAuthSessionParams, BeginAuthSessionParamsV1, BeginAuthSessionParamsV2 } from "../../private/model/AuthManagerInterface";
|
|
4
7
|
declare class AuthManagerImpl implements AuthManagerInterface {
|
|
5
8
|
private readonly serviceWorkerUtils;
|
|
6
9
|
private readonly authSessionMutex;
|
|
@@ -19,14 +22,17 @@ declare class AuthManagerImpl implements AuthManagerInterface {
|
|
|
19
22
|
beginAuthSession(params: BeginAuthSessionParams): Promise<void>;
|
|
20
23
|
endAuthSession(): Promise<void>;
|
|
21
24
|
private refreshAccessToken;
|
|
25
|
+
private refreshServiceWorkerConfig;
|
|
26
|
+
private getServiceWorkerConfigRefreshEpoch;
|
|
27
|
+
private sendServiceWorkerConfig;
|
|
22
28
|
private getAccessTokenUrl;
|
|
23
29
|
private getCdnUrl;
|
|
24
30
|
private deleteAccessToken;
|
|
25
31
|
private setAccessToken;
|
|
26
32
|
private getAccessToken;
|
|
33
|
+
private isV2;
|
|
27
34
|
}
|
|
28
35
|
/**
|
|
29
36
|
* Alternative way of implementing a static class (i.e. all methods static). We do this so we can use a interface on the class (interfaces can't define static methods).
|
|
30
37
|
*/
|
|
31
38
|
export declare const AuthManager: AuthManagerImpl;
|
|
32
|
-
export {};
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { AuthManagerInterface, BeginAuthSessionParams } from "../../private/model/AuthManagerInterface";
|
|
2
|
+
export type { AuthSwConfigEntryDto } from "../../private/dtos/AuthSwConfigEntryDto";
|
|
3
|
+
export type { AuthSwHeaderDto } from "../../private/dtos/AuthSwHeaderDto";
|
|
4
|
+
export type { BeginAuthSessionParams, BeginAuthSessionParamsV1, BeginAuthSessionParamsV2 } from "../../private/model/AuthManagerInterface";
|
|
2
5
|
declare class AuthManagerImpl implements AuthManagerInterface {
|
|
3
6
|
beginAuthSession(_params: BeginAuthSessionParams): Promise<void>;
|
|
4
7
|
endAuthSession(): Promise<void>;
|
|
@@ -9,4 +12,3 @@ declare class AuthManagerImpl implements AuthManagerInterface {
|
|
|
9
12
|
* Alternative way of implementing a static class (i.e. all methods static). We do this so we can use a interface on the class (interfaces can't define static methods).
|
|
10
13
|
*/
|
|
11
14
|
export declare const AuthManager: AuthManagerImpl;
|
|
12
|
-
export {};
|
package/package.json
CHANGED
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
import { jest } from "@jest/globals";
|
|
2
|
+
import { Response as NodeFetchResponse } from "node-fetch";
|
|
3
|
+
import type { AuthSwConfigEntryDto, BeginAuthSessionParamsV1, BeginAuthSessionParamsV2 } from "../src/index.browser";
|
|
4
|
+
|
|
5
|
+
interface AuthManagerApi {
|
|
6
|
+
beginAuthSession: (params: BeginAuthSessionParamsV1 | BeginAuthSessionParamsV2) => Promise<void>;
|
|
7
|
+
endAuthSession: () => Promise<void>;
|
|
8
|
+
isAuthSessionActive: () => boolean;
|
|
9
|
+
isAuthSessionReady: () => boolean;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
describe("AuthManager browser service-worker config", () => {
|
|
13
|
+
const originalNavigator = Object.getOwnPropertyDescriptor(globalThis, "navigator");
|
|
14
|
+
const originalFetch = Object.getOwnPropertyDescriptor(globalThis, "fetch");
|
|
15
|
+
const originalWindow = Object.getOwnPropertyDescriptor(globalThis, "window");
|
|
16
|
+
const globalFetch = jest.fn(async (): Promise<Response> => {
|
|
17
|
+
throw new Error("This test must not use the global fetch API.");
|
|
18
|
+
});
|
|
19
|
+
const postMessage = jest.fn((_message: unknown): void => {});
|
|
20
|
+
const activeWorker = { postMessage, state: "activated" } as unknown as ServiceWorker;
|
|
21
|
+
const registration = {
|
|
22
|
+
active: activeWorker,
|
|
23
|
+
installing: null,
|
|
24
|
+
scope: "https://app.example.com/",
|
|
25
|
+
waiting: null
|
|
26
|
+
} as unknown as ServiceWorkerRegistration;
|
|
27
|
+
const serviceWorkerApi = {
|
|
28
|
+
controller: activeWorker,
|
|
29
|
+
getRegistrations: jest.fn(async (): Promise<ServiceWorkerRegistration[]> => [registration]),
|
|
30
|
+
register: jest.fn(async (): Promise<ServiceWorkerRegistration> => registration)
|
|
31
|
+
};
|
|
32
|
+
const navigatorValue: { serviceWorker?: typeof serviceWorkerApi } = { serviceWorker: serviceWorkerApi };
|
|
33
|
+
let AuthManager: AuthManagerApi;
|
|
34
|
+
|
|
35
|
+
beforeAll(async () => {
|
|
36
|
+
Object.defineProperty(globalThis, "fetch", { configurable: true, value: globalFetch });
|
|
37
|
+
Object.defineProperty(globalThis, "window", { configurable: true, value: {} });
|
|
38
|
+
Object.defineProperty(globalThis, "navigator", { configurable: true, value: navigatorValue });
|
|
39
|
+
AuthManager = (await import("../src/public/browser/AuthManagerBrowser")).AuthManager;
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
beforeEach(() => {
|
|
43
|
+
navigatorValue.serviceWorker = serviceWorkerApi;
|
|
44
|
+
globalFetch.mockClear();
|
|
45
|
+
postMessage.mockClear();
|
|
46
|
+
serviceWorkerApi.getRegistrations.mockClear();
|
|
47
|
+
serviceWorkerApi.register.mockClear();
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
afterAll(() => {
|
|
51
|
+
for (const [key, descriptor] of [
|
|
52
|
+
["fetch", originalFetch],
|
|
53
|
+
["navigator", originalNavigator],
|
|
54
|
+
["window", originalWindow]
|
|
55
|
+
] as const) {
|
|
56
|
+
if (descriptor === undefined) {
|
|
57
|
+
Reflect.deleteProperty(globalThis, key);
|
|
58
|
+
} else {
|
|
59
|
+
Object.defineProperty(globalThis, key, descriptor);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
afterEach(async () => {
|
|
65
|
+
navigatorValue.serviceWorker = serviceWorkerApi;
|
|
66
|
+
await AuthManager.endAuthSession();
|
|
67
|
+
jest.restoreAllMocks();
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
test("V2 applies multiple entries and refreshes before the earliest expiry", async () => {
|
|
71
|
+
const firstConfig: AuthSwConfigEntryDto[] = [
|
|
72
|
+
{
|
|
73
|
+
expires: Date.now() + 21_000,
|
|
74
|
+
headers: [{ key: "Authorization", value: "Bearer account-a" }],
|
|
75
|
+
sourceUrlPrefixes: ["https://app.example.com/account-a/"],
|
|
76
|
+
urlPrefix: "https://upcdn.io/account-a/"
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
expires: Date.now() + 60_000,
|
|
80
|
+
headers: [{ key: "Authorization", value: "Bearer account-b" }],
|
|
81
|
+
urlPrefix: "https://upcdn.io/account-b/"
|
|
82
|
+
}
|
|
83
|
+
];
|
|
84
|
+
const refreshedConfig: AuthSwConfigEntryDto[] = [
|
|
85
|
+
{
|
|
86
|
+
expires: undefined,
|
|
87
|
+
headers: [{ key: "Authorization", value: "Bearer refreshed" }],
|
|
88
|
+
urlPrefix: "https://upcdn.io/account-a/"
|
|
89
|
+
}
|
|
90
|
+
];
|
|
91
|
+
const getServiceWorkerConfig = jest
|
|
92
|
+
.fn<BeginAuthSessionParamsV2["getServiceWorkerConfig"]>()
|
|
93
|
+
.mockResolvedValueOnce(firstConfig)
|
|
94
|
+
.mockResolvedValueOnce(refreshedConfig);
|
|
95
|
+
|
|
96
|
+
await AuthManager.beginAuthSession({
|
|
97
|
+
getServiceWorkerConfig,
|
|
98
|
+
serviceWorkerScript: "/bytescale-auth-sw.js"
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
expect(AuthManager.isAuthSessionActive()).toBe(true);
|
|
102
|
+
expect(AuthManager.isAuthSessionReady()).toBe(true);
|
|
103
|
+
expect(postMessage.mock.calls[0][0]).toEqual({
|
|
104
|
+
config: [
|
|
105
|
+
{
|
|
106
|
+
...firstConfig[0],
|
|
107
|
+
urlPrefix: "!bytescale-source-scoped!https://upcdn.io/account-a/"
|
|
108
|
+
},
|
|
109
|
+
firstConfig[1]
|
|
110
|
+
],
|
|
111
|
+
type: "SET_BYTESCALE_AUTH_CONFIG"
|
|
112
|
+
});
|
|
113
|
+
expect(firstConfig[0].urlPrefix).toBe("https://upcdn.io/account-a/");
|
|
114
|
+
|
|
115
|
+
await new Promise(resolve => setTimeout(resolve, 1_500));
|
|
116
|
+
|
|
117
|
+
expect(getServiceWorkerConfig).toHaveBeenCalledTimes(2);
|
|
118
|
+
expect(postMessage.mock.calls[1][0]).toEqual({
|
|
119
|
+
config: refreshedConfig,
|
|
120
|
+
type: "SET_BYTESCALE_AUTH_CONFIG"
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
test("V2 clears service-worker config without calling access-token endpoints", async () => {
|
|
125
|
+
await AuthManager.beginAuthSession({
|
|
126
|
+
getServiceWorkerConfig: async () => [
|
|
127
|
+
{
|
|
128
|
+
expires: undefined,
|
|
129
|
+
headers: [{ key: "Authorization", value: "Bearer account-a" }],
|
|
130
|
+
urlPrefix: "https://upcdn.io/account-a/"
|
|
131
|
+
}
|
|
132
|
+
],
|
|
133
|
+
serviceWorkerScript: "/bytescale-auth-sw.js"
|
|
134
|
+
});
|
|
135
|
+
await AuthManager.endAuthSession();
|
|
136
|
+
|
|
137
|
+
expect(globalFetch).not.toHaveBeenCalled();
|
|
138
|
+
expect(postMessage.mock.calls[1][0]).toEqual({ config: [], type: "SET_BYTESCALE_AUTH_CONFIG" });
|
|
139
|
+
expect(AuthManager.isAuthSessionActive()).toBe(false);
|
|
140
|
+
expect(AuthManager.isAuthSessionReady()).toBe(false);
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
test("V2 rejects instead of falling back to cookies when service workers are unavailable", async () => {
|
|
144
|
+
delete navigatorValue.serviceWorker;
|
|
145
|
+
const getServiceWorkerConfig = jest.fn(async (): Promise<AuthSwConfigEntryDto[]> => []);
|
|
146
|
+
|
|
147
|
+
await expect(
|
|
148
|
+
AuthManager.beginAuthSession({ getServiceWorkerConfig, serviceWorkerScript: "/bytescale-auth-sw.js" })
|
|
149
|
+
).rejects.toThrow("requires service workers");
|
|
150
|
+
|
|
151
|
+
expect(getServiceWorkerConfig).not.toHaveBeenCalled();
|
|
152
|
+
expect(AuthManager.isAuthSessionActive()).toBe(false);
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
test("V1 retains cookie fallback when service workers are unavailable", async () => {
|
|
156
|
+
delete navigatorValue.serviceWorker;
|
|
157
|
+
const fetchApi = jest.fn(async (_input: RequestInfo | URL, init?: RequestInit): Promise<Response> => {
|
|
158
|
+
switch (init?.method) {
|
|
159
|
+
case "GET":
|
|
160
|
+
return new NodeFetchResponse("jwt-a", {
|
|
161
|
+
headers: { "Content-Type": "text/plain" }
|
|
162
|
+
}) as unknown as Response;
|
|
163
|
+
case "PUT":
|
|
164
|
+
return new NodeFetchResponse(
|
|
165
|
+
JSON.stringify({ accessToken: "access-a", ttlSeconds: 3600 })
|
|
166
|
+
) as unknown as Response;
|
|
167
|
+
case "DELETE":
|
|
168
|
+
return new NodeFetchResponse(null, { status: 204 }) as unknown as Response;
|
|
169
|
+
default:
|
|
170
|
+
throw new Error(`Unexpected method: ${init?.method ?? "undefined"}`);
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
await AuthManager.beginAuthSession({
|
|
175
|
+
accountId: "account-a",
|
|
176
|
+
authHeaders: async (): Promise<Record<string, string>> => ({}),
|
|
177
|
+
authUrl: "https://app.example.com/auth",
|
|
178
|
+
options: { fetchApi },
|
|
179
|
+
serviceWorkerScript: "/bytescale-auth-sw.js"
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
expect((fetchApi.mock.calls[1][0] as string).endsWith("?set-cookie=true")).toBe(true);
|
|
183
|
+
expect(postMessage).not.toHaveBeenCalled();
|
|
184
|
+
expect(AuthManager.isAuthSessionReady()).toBe(true);
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
test("V1 retains the existing JWT, access-token, and single-entry service-worker flow", async () => {
|
|
188
|
+
const fetchApi = jest.fn(async (_input: RequestInfo | URL, init?: RequestInit): Promise<Response> => {
|
|
189
|
+
switch (init?.method) {
|
|
190
|
+
case "GET":
|
|
191
|
+
return new NodeFetchResponse("jwt-a", {
|
|
192
|
+
headers: { "Content-Type": "text/plain" }
|
|
193
|
+
}) as unknown as Response;
|
|
194
|
+
case "PUT":
|
|
195
|
+
return new NodeFetchResponse(
|
|
196
|
+
JSON.stringify({ accessToken: "access-a", ttlSeconds: 3600 })
|
|
197
|
+
) as unknown as Response;
|
|
198
|
+
case "DELETE":
|
|
199
|
+
return new NodeFetchResponse(null, { status: 204 }) as unknown as Response;
|
|
200
|
+
default:
|
|
201
|
+
throw new Error(`Unexpected method: ${init?.method ?? "undefined"}`);
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
const params: BeginAuthSessionParamsV1 = {
|
|
205
|
+
accountId: "account-a",
|
|
206
|
+
authHeaders: async (): Promise<Record<string, string>> => ({ "X-App-Authorization": "app-token" }),
|
|
207
|
+
authUrl: "https://app.example.com/auth",
|
|
208
|
+
options: { fetchApi },
|
|
209
|
+
serviceWorkerScript: "/bytescale-auth-sw.js",
|
|
210
|
+
sourceUrlPrefixes: ["https://app.example.com/"]
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
await AuthManager.beginAuthSession(params);
|
|
214
|
+
|
|
215
|
+
expect(AuthManager.isAuthSessionReady()).toBe(true);
|
|
216
|
+
expect(postMessage.mock.calls[0][0]).toEqual({
|
|
217
|
+
config: [
|
|
218
|
+
{
|
|
219
|
+
expires: expect.any(Number),
|
|
220
|
+
headers: [{ key: "Authorization", value: "Bearer jwt-a" }],
|
|
221
|
+
sourceUrlPrefixes: params.sourceUrlPrefixes,
|
|
222
|
+
urlPrefix: "!bytescale-source-scoped!https://upcdn.io/account-a/"
|
|
223
|
+
}
|
|
224
|
+
],
|
|
225
|
+
type: "SET_BYTESCALE_AUTH_CONFIG"
|
|
226
|
+
});
|
|
227
|
+
expect(fetchApi.mock.calls.map(([, init]) => init?.method)).toEqual(["GET", "PUT"]);
|
|
228
|
+
|
|
229
|
+
await AuthManager.endAuthSession();
|
|
230
|
+
|
|
231
|
+
expect(fetchApi.mock.calls.map(([, init]) => init?.method)).toEqual(["GET", "PUT", "DELETE"]);
|
|
232
|
+
expect(postMessage.mock.calls[1][0]).toEqual({ config: [], type: "SET_BYTESCALE_AUTH_CONFIG" });
|
|
233
|
+
});
|
|
234
|
+
});
|