@bytescale/sdk 3.16.0 → 3.18.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 +219 -85
- package/dist/browser/esm/main.mjs +219 -85
- package/dist/types/private/ServiceWorkerUtils.d.ts +21 -0
- package/dist/types/private/dtos/AuthSwSetConfigDto.d.ts +7 -1
- package/dist/types/private/model/AuthSession.d.ts +2 -1
- package/dist/types/private/model/ServiceWorkerConfig.d.ts +4 -0
- package/dist/types/public/browser/AuthManagerBrowser.d.ts +4 -9
- package/package.json +1 -1
package/dist/browser/cjs/main.js
CHANGED
|
@@ -2394,6 +2394,164 @@ var ConsoleUtils = /*#__PURE__*/function () {
|
|
|
2394
2394
|
}]);
|
|
2395
2395
|
return ConsoleUtils;
|
|
2396
2396
|
}();
|
|
2397
|
+
;// CONCATENATED MODULE: ./src/private/ServiceWorkerUtils.ts
|
|
2398
|
+
function ServiceWorkerUtils_typeof(obj) { "@babel/helpers - typeof"; return ServiceWorkerUtils_typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, ServiceWorkerUtils_typeof(obj); }
|
|
2399
|
+
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = ServiceWorkerUtils_unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, 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 normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
|
|
2400
|
+
function ServiceWorkerUtils_unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return ServiceWorkerUtils_arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return ServiceWorkerUtils_arrayLikeToArray(o, minLen); }
|
|
2401
|
+
function ServiceWorkerUtils_arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
|
|
2402
|
+
function ServiceWorkerUtils_await(value, then, direct) {
|
|
2403
|
+
if (direct) {
|
|
2404
|
+
return then ? then(value) : value;
|
|
2405
|
+
}
|
|
2406
|
+
if (!value || !value.then) {
|
|
2407
|
+
value = Promise.resolve(value);
|
|
2408
|
+
}
|
|
2409
|
+
return then ? value.then(then) : value;
|
|
2410
|
+
}
|
|
2411
|
+
function ServiceWorkerUtils_catch(body, recover) {
|
|
2412
|
+
try {
|
|
2413
|
+
var result = body();
|
|
2414
|
+
} catch (e) {
|
|
2415
|
+
return recover(e);
|
|
2416
|
+
}
|
|
2417
|
+
if (result && result.then) {
|
|
2418
|
+
return result.then(void 0, recover);
|
|
2419
|
+
}
|
|
2420
|
+
return result;
|
|
2421
|
+
}
|
|
2422
|
+
function ServiceWorkerUtils_classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
2423
|
+
function ServiceWorkerUtils_defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, ServiceWorkerUtils_toPropertyKey(descriptor.key), descriptor); } }
|
|
2424
|
+
function ServiceWorkerUtils_createClass(Constructor, protoProps, staticProps) { if (protoProps) ServiceWorkerUtils_defineProperties(Constructor.prototype, protoProps); if (staticProps) ServiceWorkerUtils_defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
|
|
2425
|
+
function ServiceWorkerUtils_toPropertyKey(arg) { var key = ServiceWorkerUtils_toPrimitive(arg, "string"); return ServiceWorkerUtils_typeof(key) === "symbol" ? key : String(key); }
|
|
2426
|
+
function ServiceWorkerUtils_toPrimitive(input, hint) { if (ServiceWorkerUtils_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (ServiceWorkerUtils_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
|
|
2427
|
+
|
|
2428
|
+
var ServiceWorkerUtils = /*#__PURE__*/function () {
|
|
2429
|
+
function ServiceWorkerUtils() {
|
|
2430
|
+
ServiceWorkerUtils_classCallCheck(this, ServiceWorkerUtils);
|
|
2431
|
+
}
|
|
2432
|
+
ServiceWorkerUtils_createClass(ServiceWorkerUtils, [{
|
|
2433
|
+
key: "registerServiceWorkerIfSupported",
|
|
2434
|
+
value:
|
|
2435
|
+
/**
|
|
2436
|
+
* Idempotent.
|
|
2437
|
+
*
|
|
2438
|
+
* Only returns once the service worker has been activated.
|
|
2439
|
+
*
|
|
2440
|
+
* We don't need to unregister it: we just need to clear the config when auth ends.
|
|
2441
|
+
*/
|
|
2442
|
+
function registerServiceWorkerIfSupported(serviceWorkerScript, configFieldName, fallbackMessage) {
|
|
2443
|
+
try {
|
|
2444
|
+
var _this2 = this;
|
|
2445
|
+
if (serviceWorkerScript === undefined) {
|
|
2446
|
+
return undefined;
|
|
2447
|
+
}
|
|
2448
|
+
if (!("serviceWorker" in navigator)) {
|
|
2449
|
+
ConsoleUtils.warn("Service workers not supported by browser. ".concat(fallbackMessage));
|
|
2450
|
+
return undefined;
|
|
2451
|
+
}
|
|
2452
|
+
if (!serviceWorkerScript.startsWith("/")) {
|
|
2453
|
+
throw new Error("The '".concat(configFieldName, "' field must start with a '/' and reference a script at the root of your website."));
|
|
2454
|
+
}
|
|
2455
|
+
var forwardSlashCount = serviceWorkerScript.split("/").length - 1;
|
|
2456
|
+
if (forwardSlashCount > 1) {
|
|
2457
|
+
ConsoleUtils.warn("The '".concat(configFieldName, "' field should be a root script (e.g. '/script.js'). The Bytescale SDK can only authorize requests originating from webpages that are at the same level as the script or below."));
|
|
2458
|
+
}
|
|
2459
|
+
return ServiceWorkerUtils_await(_this2.registerAuthServiceWorker(serviceWorkerScript), function (_this$registerAuthSer) {
|
|
2460
|
+
return _this$registerAuthSer.config;
|
|
2461
|
+
});
|
|
2462
|
+
} catch (e) {
|
|
2463
|
+
return Promise.reject(e);
|
|
2464
|
+
}
|
|
2465
|
+
}
|
|
2466
|
+
}, {
|
|
2467
|
+
key: "getActiveServiceWorkerElseRegister",
|
|
2468
|
+
value: function getActiveServiceWorkerElseRegister(_ref) {
|
|
2469
|
+
var serviceWorkerScope = _ref.serviceWorkerScope,
|
|
2470
|
+
serviceWorkerScript = _ref.serviceWorkerScript;
|
|
2471
|
+
try {
|
|
2472
|
+
var _this4 = this;
|
|
2473
|
+
return ServiceWorkerUtils_await(_this4.getActiveServiceWorker(serviceWorkerScope), function (serviceWorker) {
|
|
2474
|
+
return serviceWorker !== undefined ? serviceWorker : ServiceWorkerUtils_await(_this4.registerAuthServiceWorker(serviceWorkerScript), function (_this3$registerAuthSe) {
|
|
2475
|
+
return _this3$registerAuthSe.serviceWorker;
|
|
2476
|
+
});
|
|
2477
|
+
});
|
|
2478
|
+
} catch (e) {
|
|
2479
|
+
return Promise.reject(e);
|
|
2480
|
+
}
|
|
2481
|
+
}
|
|
2482
|
+
/**
|
|
2483
|
+
* Idempotent.
|
|
2484
|
+
*
|
|
2485
|
+
* Only returns once the service worker has been activated.
|
|
2486
|
+
*
|
|
2487
|
+
* We don't need to unregister it: we just need to clear the config when auth ends.
|
|
2488
|
+
*/
|
|
2489
|
+
}, {
|
|
2490
|
+
key: "registerAuthServiceWorker",
|
|
2491
|
+
value: function registerAuthServiceWorker(serviceWorkerScript) {
|
|
2492
|
+
try {
|
|
2493
|
+
return ServiceWorkerUtils_catch(function () {
|
|
2494
|
+
return ServiceWorkerUtils_await(navigator.serviceWorker.register(serviceWorkerScript), function (registration) {
|
|
2495
|
+
return registration.active !== null ? {
|
|
2496
|
+
serviceWorker: registration.active,
|
|
2497
|
+
config: {
|
|
2498
|
+
serviceWorkerScript: serviceWorkerScript,
|
|
2499
|
+
serviceWorkerScope: registration.scope
|
|
2500
|
+
}
|
|
2501
|
+
} : ServiceWorkerUtils_await(new Promise(function (resolve) {
|
|
2502
|
+
registration.addEventListener("updatefound", function () {
|
|
2503
|
+
var newWorker = registration.installing;
|
|
2504
|
+
if (newWorker !== null) {
|
|
2505
|
+
newWorker.addEventListener("statechange", function () {
|
|
2506
|
+
if (newWorker.state === "activated") {
|
|
2507
|
+
resolve({
|
|
2508
|
+
config: {
|
|
2509
|
+
serviceWorkerScript: serviceWorkerScript,
|
|
2510
|
+
serviceWorkerScope: registration.scope
|
|
2511
|
+
},
|
|
2512
|
+
serviceWorker: newWorker
|
|
2513
|
+
});
|
|
2514
|
+
}
|
|
2515
|
+
});
|
|
2516
|
+
}
|
|
2517
|
+
});
|
|
2518
|
+
}));
|
|
2519
|
+
}); // Occurs when: (service worker is already registered AND there's been no code changes) OR (service worker was not previously registered).
|
|
2520
|
+
}, function (e) {
|
|
2521
|
+
throw new Error("Failed to install Bytescale Service Worker (SW). ".concat(e.name, ": ").concat(e.message));
|
|
2522
|
+
});
|
|
2523
|
+
} catch (e) {
|
|
2524
|
+
return Promise.reject(e);
|
|
2525
|
+
}
|
|
2526
|
+
}
|
|
2527
|
+
}, {
|
|
2528
|
+
key: "getActiveServiceWorker",
|
|
2529
|
+
value: function getActiveServiceWorker(serviceWorkerScope) {
|
|
2530
|
+
try {
|
|
2531
|
+
return ServiceWorkerUtils_await(navigator.serviceWorker.getRegistrations(), function (registrations) {
|
|
2532
|
+
var _iterator = _createForOfIteratorHelper(registrations),
|
|
2533
|
+
_step;
|
|
2534
|
+
try {
|
|
2535
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
2536
|
+
var registration = _step.value;
|
|
2537
|
+
if (registration.active !== null && registration.scope === serviceWorkerScope) {
|
|
2538
|
+
return registration.active;
|
|
2539
|
+
}
|
|
2540
|
+
}
|
|
2541
|
+
} catch (err) {
|
|
2542
|
+
_iterator.e(err);
|
|
2543
|
+
} finally {
|
|
2544
|
+
_iterator.f();
|
|
2545
|
+
}
|
|
2546
|
+
return undefined;
|
|
2547
|
+
});
|
|
2548
|
+
} catch (e) {
|
|
2549
|
+
return Promise.reject(e);
|
|
2550
|
+
}
|
|
2551
|
+
}
|
|
2552
|
+
}]);
|
|
2553
|
+
return ServiceWorkerUtils;
|
|
2554
|
+
}();
|
|
2397
2555
|
;// CONCATENATED MODULE: ./src/public/browser/AuthManagerBrowser.ts
|
|
2398
2556
|
function AuthManagerBrowser_typeof(obj) { "@babel/helpers - typeof"; return AuthManagerBrowser_typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, AuthManagerBrowser_typeof(obj); }
|
|
2399
2557
|
function AuthManagerBrowser_defineProperty(obj, key, value) { key = AuthManagerBrowser_toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
@@ -2463,9 +2621,11 @@ function AuthManagerBrowser_toPrimitive(input, hint) { if (AuthManagerBrowser_ty
|
|
|
2463
2621
|
|
|
2464
2622
|
|
|
2465
2623
|
|
|
2624
|
+
|
|
2466
2625
|
var AuthManagerImpl = /*#__PURE__*/function () {
|
|
2467
|
-
function AuthManagerImpl() {
|
|
2626
|
+
function AuthManagerImpl(serviceWorkerUtils) {
|
|
2468
2627
|
AuthManagerBrowser_classCallCheck(this, AuthManagerImpl);
|
|
2628
|
+
this.serviceWorkerUtils = serviceWorkerUtils;
|
|
2469
2629
|
this.contentType = "content-type";
|
|
2470
2630
|
this.contentTypeJson = "application/json";
|
|
2471
2631
|
this.contentTypeText = "text/plain";
|
|
@@ -2490,13 +2650,14 @@ var AuthManagerImpl = /*#__PURE__*/function () {
|
|
|
2490
2650
|
if (_this2.isAuthSessionActive()) {
|
|
2491
2651
|
throw new Error("Auth session already active. Please call 'await endAuthSession()' and then call 'await beginAuthSession(...)' to start a new auth session.");
|
|
2492
2652
|
}
|
|
2493
|
-
|
|
2653
|
+
var serviceWorkerScriptField = "serviceWorkerScript";
|
|
2654
|
+
return AuthManagerBrowser_await(_this2.serviceWorkerUtils.registerServiceWorkerIfSupported(params.serviceWorkerScript, serviceWorkerScriptField, "Falling back to Bytescale CDN cookies for auth. These are third-party cookies, which some modern browsers block."), function (_this2$serviceWorkerU) {
|
|
2494
2655
|
var newSession = {
|
|
2495
2656
|
accessToken: undefined,
|
|
2496
2657
|
accessTokenRefreshHandle: undefined,
|
|
2497
2658
|
params: params,
|
|
2498
2659
|
isActive: true,
|
|
2499
|
-
authServiceWorker: _this2$
|
|
2660
|
+
authServiceWorker: _this2$serviceWorkerU
|
|
2500
2661
|
};
|
|
2501
2662
|
AuthSessionState.setSession(newSession);
|
|
2502
2663
|
return newSession;
|
|
@@ -2525,62 +2686,13 @@ var AuthManagerImpl = /*#__PURE__*/function () {
|
|
|
2525
2686
|
clearTimeout(session.accessTokenRefreshHandle);
|
|
2526
2687
|
}
|
|
2527
2688
|
return AuthManagerBrowser_await(_this4.deleteAccessToken(session.params), function () {
|
|
2528
|
-
_this4.setServiceWorkerConfig(session, []); // Prevent service worker from authorizing subsequent requests.
|
|
2689
|
+
return AuthManagerBrowser_awaitIgnored(_this4.setServiceWorkerConfig(session, [])); // Prevent service worker from authorizing subsequent requests.
|
|
2529
2690
|
});
|
|
2530
2691
|
})));
|
|
2531
2692
|
} catch (e) {
|
|
2532
2693
|
return Promise.reject(e);
|
|
2533
2694
|
}
|
|
2534
2695
|
}
|
|
2535
|
-
/**
|
|
2536
|
-
* Idempotent.
|
|
2537
|
-
*
|
|
2538
|
-
* Only returns once the service worker has been activated.
|
|
2539
|
-
*
|
|
2540
|
-
* We don't need to unregister it: we just need to clear the config when auth ends.
|
|
2541
|
-
*/
|
|
2542
|
-
}, {
|
|
2543
|
-
key: "registerAuthServiceWorker",
|
|
2544
|
-
value: function registerAuthServiceWorker(_ref) {
|
|
2545
|
-
var serviceWorkerScript = _ref.serviceWorkerScript;
|
|
2546
|
-
try {
|
|
2547
|
-
if (serviceWorkerScript === undefined) {
|
|
2548
|
-
return undefined;
|
|
2549
|
-
}
|
|
2550
|
-
var field = "serviceWorkerScript";
|
|
2551
|
-
if (!serviceWorkerScript.startsWith("/")) {
|
|
2552
|
-
throw new Error("The '".concat(field, "' field must start with a '/' and reference a script at the root of your website."));
|
|
2553
|
-
}
|
|
2554
|
-
var forwardSlashCount = serviceWorkerScript.split("/").length - 1;
|
|
2555
|
-
if (forwardSlashCount > 1) {
|
|
2556
|
-
ConsoleUtils.warn("The '".concat(field, "' field should be a root script (e.g. '/bytescale-auth-sw.js'). The Bytescale SDK can only authorize requests originating from webpages that are at the same level as the script or below."));
|
|
2557
|
-
}
|
|
2558
|
-
return AuthManagerBrowser_catch(function () {
|
|
2559
|
-
if ("serviceWorker" in navigator) {
|
|
2560
|
-
return AuthManagerBrowser_await(navigator.serviceWorker.register(serviceWorkerScript), function (registration) {
|
|
2561
|
-
return registration.active !== null ? registration.active : AuthManagerBrowser_awaitIgnored(new Promise(function (resolve) {
|
|
2562
|
-
registration.addEventListener("updatefound", function () {
|
|
2563
|
-
var newWorker = registration.installing;
|
|
2564
|
-
if (newWorker !== null) {
|
|
2565
|
-
newWorker.addEventListener("statechange", function () {
|
|
2566
|
-
if (newWorker.state === "activated") {
|
|
2567
|
-
resolve(newWorker);
|
|
2568
|
-
}
|
|
2569
|
-
});
|
|
2570
|
-
}
|
|
2571
|
-
});
|
|
2572
|
-
}));
|
|
2573
|
-
}); // Occurs when: (service worker is already registered AND there's been no code changes) OR (service worker was not previously registered).
|
|
2574
|
-
} else {
|
|
2575
|
-
ConsoleUtils.warn("Service workers not supported by browser. Falling back to Bytescale CDN cookies for auth. These are third-party cookies, which some modern browsers block.");
|
|
2576
|
-
}
|
|
2577
|
-
}, function (e) {
|
|
2578
|
-
throw new Error("Failed to install Bytescale Auth Service Worker (SW). ".concat(e.name, ": ").concat(e.message));
|
|
2579
|
-
});
|
|
2580
|
-
} catch (e) {
|
|
2581
|
-
return Promise.reject(e);
|
|
2582
|
-
}
|
|
2583
|
-
}
|
|
2584
2696
|
}, {
|
|
2585
2697
|
key: "refreshAccessToken",
|
|
2586
2698
|
value: function refreshAccessToken(session) {
|
|
@@ -2597,23 +2709,29 @@ var AuthManagerImpl = /*#__PURE__*/function () {
|
|
|
2597
2709
|
_session$params = session.params;
|
|
2598
2710
|
return AuthManagerBrowser_await(session.params.authHeaders(), function (_session$params$authH) {
|
|
2599
2711
|
return AuthManagerBrowser_await(_getAccessToken.call(_this6, _session$params, _session$params$authH), function (jwt) {
|
|
2600
|
-
|
|
2601
|
-
|
|
2712
|
+
// We don't use cookie-based auth if the browser supports service worker-based auth, as using both will cause
|
|
2713
|
+
// confusion for us in the future (i.e. we may question "do we need to use both together? was there a reason?").
|
|
2714
|
+
// Also: if the user has omitted "allowedOrigins" from their JWT, then service worker-based auth is more secure
|
|
2715
|
+
// than cookie-based auth, which is another reason to prevent these cookies from being set unless required.
|
|
2716
|
+
var setCookie = !_this6.isUsingServiceWorker(session);
|
|
2717
|
+
return AuthManagerBrowser_await(_this6.setAccessToken(session.params, jwt, setCookie), function (setTokenResult) {
|
|
2718
|
+
return AuthManagerBrowser_await(_this6.setServiceWorkerConfig(session, [{
|
|
2602
2719
|
headers: [{
|
|
2603
2720
|
key: "Authorization",
|
|
2604
2721
|
value: "Bearer ".concat(jwt)
|
|
2605
2722
|
}],
|
|
2606
2723
|
expires: Date.now() + setTokenResult.ttlSeconds * 1000,
|
|
2607
2724
|
urlPrefix: "".concat(_this6.getCdnUrl(session.params), "/").concat(session.params.accountId, "/")
|
|
2608
|
-
}])
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2725
|
+
}]), function () {
|
|
2726
|
+
var desiredTtl = setTokenResult.ttlSeconds - _this6.refreshBeforeExpirySeconds;
|
|
2727
|
+
timeout = Math.max(desiredTtl, _this6.minJwtTtlSeconds);
|
|
2728
|
+
if (desiredTtl !== timeout) {
|
|
2729
|
+
ConsoleUtils.warn("JWT expiration is too short: waiting for ".concat(timeout, " seconds before refreshing."));
|
|
2730
|
+
}
|
|
2731
|
+
// There's no need to print a warning for this: it's OK to silently request the JWT before it expires. Also, this is 24 days in this case!
|
|
2732
|
+
timeout = Math.min(timeout, _this6.maxJwtTtlSeconds);
|
|
2733
|
+
session.accessToken = setTokenResult.accessToken;
|
|
2734
|
+
});
|
|
2617
2735
|
});
|
|
2618
2736
|
});
|
|
2619
2737
|
});
|
|
@@ -2621,7 +2739,7 @@ var AuthManagerImpl = /*#__PURE__*/function () {
|
|
|
2621
2739
|
// Use 'warn' instead of 'error' since this happens frequently, i.e. user goes through a tunnel, and some customers report these errors to systems like Sentry, so we don't want to spam.
|
|
2622
2740
|
ConsoleUtils.warn("Unable to refresh JWT access token: ".concat(e));
|
|
2623
2741
|
});
|
|
2624
|
-
}, function (_wasThrown,
|
|
2742
|
+
}, function (_wasThrown, _result) {
|
|
2625
2743
|
session.accessTokenRefreshHandle = window.setTimeout(function () {
|
|
2626
2744
|
_this6.refreshAccessToken(session).then(function () {},
|
|
2627
2745
|
// Should not occur, as this method shouldn't throw errors.
|
|
@@ -2629,27 +2747,43 @@ var AuthManagerImpl = /*#__PURE__*/function () {
|
|
|
2629
2747
|
return ConsoleUtils.error("Unexpected error when refreshing JWT access token: ".concat(e));
|
|
2630
2748
|
});
|
|
2631
2749
|
}, timeout * 1000);
|
|
2632
|
-
return AuthManagerBrowser_rethrow(_wasThrown,
|
|
2750
|
+
return AuthManagerBrowser_rethrow(_wasThrown, _result);
|
|
2633
2751
|
}));
|
|
2634
2752
|
})));
|
|
2635
2753
|
} catch (e) {
|
|
2636
2754
|
return Promise.reject(e);
|
|
2637
2755
|
}
|
|
2638
2756
|
}
|
|
2757
|
+
}, {
|
|
2758
|
+
key: "isUsingServiceWorker",
|
|
2759
|
+
value: function isUsingServiceWorker(session) {
|
|
2760
|
+
return session.authServiceWorker !== undefined;
|
|
2761
|
+
}
|
|
2639
2762
|
}, {
|
|
2640
2763
|
key: "setServiceWorkerConfig",
|
|
2641
2764
|
value: function setServiceWorkerConfig(session, config) {
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
|
|
2765
|
+
try {
|
|
2766
|
+
var _this8 = this;
|
|
2767
|
+
if (session.authServiceWorker === undefined) {
|
|
2768
|
+
return undefined;
|
|
2769
|
+
}
|
|
2770
|
+
// We re-fetch the latest active worker, as another tab may have registered a new one, and then the tab may be closed,
|
|
2771
|
+
// leaving us as the only open tab but with an old and ineffective service worker reference.
|
|
2772
|
+
return AuthManagerBrowser_await(_this8.serviceWorkerUtils.getActiveServiceWorkerElseRegister(session.authServiceWorker), function (serviceWorker) {
|
|
2773
|
+
var message = {
|
|
2774
|
+
type: "SET_BYTESCALE_AUTH_CONFIG",
|
|
2775
|
+
config: config
|
|
2776
|
+
};
|
|
2777
|
+
serviceWorker.postMessage(message);
|
|
2778
|
+
});
|
|
2779
|
+
} catch (e) {
|
|
2780
|
+
return Promise.reject(e);
|
|
2781
|
+
}
|
|
2648
2782
|
}
|
|
2649
2783
|
}, {
|
|
2650
2784
|
key: "getAccessTokenUrl",
|
|
2651
|
-
value: function getAccessTokenUrl(params) {
|
|
2652
|
-
return "".concat(this.getCdnUrl(params), "/api/v1/access_tokens/").concat(params.accountId);
|
|
2785
|
+
value: function getAccessTokenUrl(params, setCookie) {
|
|
2786
|
+
return "".concat(this.getCdnUrl(params), "/api/v1/access_tokens/").concat(params.accountId, "?set-cookie=").concat(setCookie ? "true" : "false");
|
|
2653
2787
|
}
|
|
2654
2788
|
}, {
|
|
2655
2789
|
key: "getCdnUrl",
|
|
@@ -2661,9 +2795,9 @@ var AuthManagerImpl = /*#__PURE__*/function () {
|
|
|
2661
2795
|
key: "deleteAccessToken",
|
|
2662
2796
|
value: function deleteAccessToken(params) {
|
|
2663
2797
|
try {
|
|
2664
|
-
var
|
|
2798
|
+
var _this10 = this;
|
|
2665
2799
|
var _a;
|
|
2666
|
-
return AuthManagerBrowser_awaitIgnored(BaseAPI.fetch(
|
|
2800
|
+
return AuthManagerBrowser_awaitIgnored(BaseAPI.fetch(_this10.getAccessTokenUrl(params, true), {
|
|
2667
2801
|
method: "DELETE",
|
|
2668
2802
|
credentials: "include",
|
|
2669
2803
|
headers: {}
|
|
@@ -2677,17 +2811,17 @@ var AuthManagerImpl = /*#__PURE__*/function () {
|
|
|
2677
2811
|
}
|
|
2678
2812
|
}, {
|
|
2679
2813
|
key: "setAccessToken",
|
|
2680
|
-
value: function setAccessToken(params, jwt) {
|
|
2814
|
+
value: function setAccessToken(params, jwt, setCookie) {
|
|
2681
2815
|
try {
|
|
2682
|
-
var
|
|
2816
|
+
var _this12 = this;
|
|
2683
2817
|
var _a;
|
|
2684
2818
|
var request = {
|
|
2685
2819
|
accessToken: jwt
|
|
2686
2820
|
};
|
|
2687
|
-
return AuthManagerBrowser_await(BaseAPI.fetch(
|
|
2821
|
+
return AuthManagerBrowser_await(BaseAPI.fetch(_this12.getAccessTokenUrl(params, setCookie), {
|
|
2688
2822
|
method: "PUT",
|
|
2689
2823
|
credentials: "include",
|
|
2690
|
-
headers: AuthManagerBrowser_defineProperty({},
|
|
2824
|
+
headers: AuthManagerBrowser_defineProperty({}, _this12.contentType, _this12.contentTypeJson),
|
|
2691
2825
|
body: JSON.stringify(request)
|
|
2692
2826
|
}, {
|
|
2693
2827
|
isBytescaleApi: true,
|
|
@@ -2703,10 +2837,10 @@ var AuthManagerImpl = /*#__PURE__*/function () {
|
|
|
2703
2837
|
key: "getAccessToken",
|
|
2704
2838
|
value: function getAccessToken(params, headers) {
|
|
2705
2839
|
try {
|
|
2706
|
-
var
|
|
2840
|
+
var _this14 = this;
|
|
2707
2841
|
var _a, _b;
|
|
2708
2842
|
var endpointName = "Your auth API endpoint";
|
|
2709
|
-
var requiredContentType =
|
|
2843
|
+
var requiredContentType = _this14.contentTypeText;
|
|
2710
2844
|
return AuthManagerBrowser_await(BaseAPI.fetch(params.authUrl, {
|
|
2711
2845
|
method: "GET",
|
|
2712
2846
|
headers: headers
|
|
@@ -2714,10 +2848,10 @@ var AuthManagerImpl = /*#__PURE__*/function () {
|
|
|
2714
2848
|
isBytescaleApi: false,
|
|
2715
2849
|
fetchApi: (_a = params.options) === null || _a === void 0 ? void 0 : _a.fetchApi
|
|
2716
2850
|
}), function (result) {
|
|
2717
|
-
var actualContentType = (_b = result.headers.get(
|
|
2851
|
+
var actualContentType = (_b = result.headers.get(_this14.contentType)) !== null && _b !== void 0 ? _b : "";
|
|
2718
2852
|
// Support content types like "text/plain; charset=utf-8" and "text/plain"
|
|
2719
2853
|
if (actualContentType.split(";")[0] !== requiredContentType) {
|
|
2720
|
-
throw new Error("".concat(endpointName, " returned \"").concat(actualContentType, "\" for the ").concat(
|
|
2854
|
+
throw new Error("".concat(endpointName, " returned \"").concat(actualContentType, "\" for the ").concat(_this14.contentType, " response header, but the Bytescale SDK requires \"").concat(requiredContentType, "\"."));
|
|
2721
2855
|
}
|
|
2722
2856
|
return AuthManagerBrowser_await(result.text(), function (jwt) {
|
|
2723
2857
|
if (jwt.length === 0) {
|
|
@@ -2740,7 +2874,7 @@ var AuthManagerImpl = /*#__PURE__*/function () {
|
|
|
2740
2874
|
/**
|
|
2741
2875
|
* 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).
|
|
2742
2876
|
*/
|
|
2743
|
-
var AuthManager = new AuthManagerImpl();
|
|
2877
|
+
var AuthManager = new AuthManagerImpl(new ServiceWorkerUtils());
|
|
2744
2878
|
;// CONCATENATED MODULE: ./src/public/browser/index.ts
|
|
2745
2879
|
|
|
2746
2880
|
|
|
@@ -2379,6 +2379,164 @@ var ConsoleUtils = /*#__PURE__*/function () {
|
|
|
2379
2379
|
}]);
|
|
2380
2380
|
return ConsoleUtils;
|
|
2381
2381
|
}();
|
|
2382
|
+
;// CONCATENATED MODULE: ./src/private/ServiceWorkerUtils.ts
|
|
2383
|
+
function ServiceWorkerUtils_typeof(obj) { "@babel/helpers - typeof"; return ServiceWorkerUtils_typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, ServiceWorkerUtils_typeof(obj); }
|
|
2384
|
+
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = ServiceWorkerUtils_unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, 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 normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
|
|
2385
|
+
function ServiceWorkerUtils_unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return ServiceWorkerUtils_arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return ServiceWorkerUtils_arrayLikeToArray(o, minLen); }
|
|
2386
|
+
function ServiceWorkerUtils_arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
|
|
2387
|
+
function ServiceWorkerUtils_await(value, then, direct) {
|
|
2388
|
+
if (direct) {
|
|
2389
|
+
return then ? then(value) : value;
|
|
2390
|
+
}
|
|
2391
|
+
if (!value || !value.then) {
|
|
2392
|
+
value = Promise.resolve(value);
|
|
2393
|
+
}
|
|
2394
|
+
return then ? value.then(then) : value;
|
|
2395
|
+
}
|
|
2396
|
+
function ServiceWorkerUtils_catch(body, recover) {
|
|
2397
|
+
try {
|
|
2398
|
+
var result = body();
|
|
2399
|
+
} catch (e) {
|
|
2400
|
+
return recover(e);
|
|
2401
|
+
}
|
|
2402
|
+
if (result && result.then) {
|
|
2403
|
+
return result.then(void 0, recover);
|
|
2404
|
+
}
|
|
2405
|
+
return result;
|
|
2406
|
+
}
|
|
2407
|
+
function ServiceWorkerUtils_classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
2408
|
+
function ServiceWorkerUtils_defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, ServiceWorkerUtils_toPropertyKey(descriptor.key), descriptor); } }
|
|
2409
|
+
function ServiceWorkerUtils_createClass(Constructor, protoProps, staticProps) { if (protoProps) ServiceWorkerUtils_defineProperties(Constructor.prototype, protoProps); if (staticProps) ServiceWorkerUtils_defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
|
|
2410
|
+
function ServiceWorkerUtils_toPropertyKey(arg) { var key = ServiceWorkerUtils_toPrimitive(arg, "string"); return ServiceWorkerUtils_typeof(key) === "symbol" ? key : String(key); }
|
|
2411
|
+
function ServiceWorkerUtils_toPrimitive(input, hint) { if (ServiceWorkerUtils_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (ServiceWorkerUtils_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
|
|
2412
|
+
|
|
2413
|
+
var ServiceWorkerUtils = /*#__PURE__*/function () {
|
|
2414
|
+
function ServiceWorkerUtils() {
|
|
2415
|
+
ServiceWorkerUtils_classCallCheck(this, ServiceWorkerUtils);
|
|
2416
|
+
}
|
|
2417
|
+
ServiceWorkerUtils_createClass(ServiceWorkerUtils, [{
|
|
2418
|
+
key: "registerServiceWorkerIfSupported",
|
|
2419
|
+
value:
|
|
2420
|
+
/**
|
|
2421
|
+
* Idempotent.
|
|
2422
|
+
*
|
|
2423
|
+
* Only returns once the service worker has been activated.
|
|
2424
|
+
*
|
|
2425
|
+
* We don't need to unregister it: we just need to clear the config when auth ends.
|
|
2426
|
+
*/
|
|
2427
|
+
function registerServiceWorkerIfSupported(serviceWorkerScript, configFieldName, fallbackMessage) {
|
|
2428
|
+
try {
|
|
2429
|
+
var _this2 = this;
|
|
2430
|
+
if (serviceWorkerScript === undefined) {
|
|
2431
|
+
return undefined;
|
|
2432
|
+
}
|
|
2433
|
+
if (!("serviceWorker" in navigator)) {
|
|
2434
|
+
ConsoleUtils.warn("Service workers not supported by browser. ".concat(fallbackMessage));
|
|
2435
|
+
return undefined;
|
|
2436
|
+
}
|
|
2437
|
+
if (!serviceWorkerScript.startsWith("/")) {
|
|
2438
|
+
throw new Error("The '".concat(configFieldName, "' field must start with a '/' and reference a script at the root of your website."));
|
|
2439
|
+
}
|
|
2440
|
+
var forwardSlashCount = serviceWorkerScript.split("/").length - 1;
|
|
2441
|
+
if (forwardSlashCount > 1) {
|
|
2442
|
+
ConsoleUtils.warn("The '".concat(configFieldName, "' field should be a root script (e.g. '/script.js'). The Bytescale SDK can only authorize requests originating from webpages that are at the same level as the script or below."));
|
|
2443
|
+
}
|
|
2444
|
+
return ServiceWorkerUtils_await(_this2.registerAuthServiceWorker(serviceWorkerScript), function (_this$registerAuthSer) {
|
|
2445
|
+
return _this$registerAuthSer.config;
|
|
2446
|
+
});
|
|
2447
|
+
} catch (e) {
|
|
2448
|
+
return Promise.reject(e);
|
|
2449
|
+
}
|
|
2450
|
+
}
|
|
2451
|
+
}, {
|
|
2452
|
+
key: "getActiveServiceWorkerElseRegister",
|
|
2453
|
+
value: function getActiveServiceWorkerElseRegister(_ref) {
|
|
2454
|
+
var serviceWorkerScope = _ref.serviceWorkerScope,
|
|
2455
|
+
serviceWorkerScript = _ref.serviceWorkerScript;
|
|
2456
|
+
try {
|
|
2457
|
+
var _this4 = this;
|
|
2458
|
+
return ServiceWorkerUtils_await(_this4.getActiveServiceWorker(serviceWorkerScope), function (serviceWorker) {
|
|
2459
|
+
return serviceWorker !== undefined ? serviceWorker : ServiceWorkerUtils_await(_this4.registerAuthServiceWorker(serviceWorkerScript), function (_this3$registerAuthSe) {
|
|
2460
|
+
return _this3$registerAuthSe.serviceWorker;
|
|
2461
|
+
});
|
|
2462
|
+
});
|
|
2463
|
+
} catch (e) {
|
|
2464
|
+
return Promise.reject(e);
|
|
2465
|
+
}
|
|
2466
|
+
}
|
|
2467
|
+
/**
|
|
2468
|
+
* Idempotent.
|
|
2469
|
+
*
|
|
2470
|
+
* Only returns once the service worker has been activated.
|
|
2471
|
+
*
|
|
2472
|
+
* We don't need to unregister it: we just need to clear the config when auth ends.
|
|
2473
|
+
*/
|
|
2474
|
+
}, {
|
|
2475
|
+
key: "registerAuthServiceWorker",
|
|
2476
|
+
value: function registerAuthServiceWorker(serviceWorkerScript) {
|
|
2477
|
+
try {
|
|
2478
|
+
return ServiceWorkerUtils_catch(function () {
|
|
2479
|
+
return ServiceWorkerUtils_await(navigator.serviceWorker.register(serviceWorkerScript), function (registration) {
|
|
2480
|
+
return registration.active !== null ? {
|
|
2481
|
+
serviceWorker: registration.active,
|
|
2482
|
+
config: {
|
|
2483
|
+
serviceWorkerScript: serviceWorkerScript,
|
|
2484
|
+
serviceWorkerScope: registration.scope
|
|
2485
|
+
}
|
|
2486
|
+
} : ServiceWorkerUtils_await(new Promise(function (resolve) {
|
|
2487
|
+
registration.addEventListener("updatefound", function () {
|
|
2488
|
+
var newWorker = registration.installing;
|
|
2489
|
+
if (newWorker !== null) {
|
|
2490
|
+
newWorker.addEventListener("statechange", function () {
|
|
2491
|
+
if (newWorker.state === "activated") {
|
|
2492
|
+
resolve({
|
|
2493
|
+
config: {
|
|
2494
|
+
serviceWorkerScript: serviceWorkerScript,
|
|
2495
|
+
serviceWorkerScope: registration.scope
|
|
2496
|
+
},
|
|
2497
|
+
serviceWorker: newWorker
|
|
2498
|
+
});
|
|
2499
|
+
}
|
|
2500
|
+
});
|
|
2501
|
+
}
|
|
2502
|
+
});
|
|
2503
|
+
}));
|
|
2504
|
+
}); // Occurs when: (service worker is already registered AND there's been no code changes) OR (service worker was not previously registered).
|
|
2505
|
+
}, function (e) {
|
|
2506
|
+
throw new Error("Failed to install Bytescale Service Worker (SW). ".concat(e.name, ": ").concat(e.message));
|
|
2507
|
+
});
|
|
2508
|
+
} catch (e) {
|
|
2509
|
+
return Promise.reject(e);
|
|
2510
|
+
}
|
|
2511
|
+
}
|
|
2512
|
+
}, {
|
|
2513
|
+
key: "getActiveServiceWorker",
|
|
2514
|
+
value: function getActiveServiceWorker(serviceWorkerScope) {
|
|
2515
|
+
try {
|
|
2516
|
+
return ServiceWorkerUtils_await(navigator.serviceWorker.getRegistrations(), function (registrations) {
|
|
2517
|
+
var _iterator = _createForOfIteratorHelper(registrations),
|
|
2518
|
+
_step;
|
|
2519
|
+
try {
|
|
2520
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
2521
|
+
var registration = _step.value;
|
|
2522
|
+
if (registration.active !== null && registration.scope === serviceWorkerScope) {
|
|
2523
|
+
return registration.active;
|
|
2524
|
+
}
|
|
2525
|
+
}
|
|
2526
|
+
} catch (err) {
|
|
2527
|
+
_iterator.e(err);
|
|
2528
|
+
} finally {
|
|
2529
|
+
_iterator.f();
|
|
2530
|
+
}
|
|
2531
|
+
return undefined;
|
|
2532
|
+
});
|
|
2533
|
+
} catch (e) {
|
|
2534
|
+
return Promise.reject(e);
|
|
2535
|
+
}
|
|
2536
|
+
}
|
|
2537
|
+
}]);
|
|
2538
|
+
return ServiceWorkerUtils;
|
|
2539
|
+
}();
|
|
2382
2540
|
;// CONCATENATED MODULE: ./src/public/browser/AuthManagerBrowser.ts
|
|
2383
2541
|
function AuthManagerBrowser_typeof(obj) { "@babel/helpers - typeof"; return AuthManagerBrowser_typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, AuthManagerBrowser_typeof(obj); }
|
|
2384
2542
|
function AuthManagerBrowser_defineProperty(obj, key, value) { key = AuthManagerBrowser_toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
@@ -2448,9 +2606,11 @@ function AuthManagerBrowser_toPrimitive(input, hint) { if (AuthManagerBrowser_ty
|
|
|
2448
2606
|
|
|
2449
2607
|
|
|
2450
2608
|
|
|
2609
|
+
|
|
2451
2610
|
var AuthManagerImpl = /*#__PURE__*/function () {
|
|
2452
|
-
function AuthManagerImpl() {
|
|
2611
|
+
function AuthManagerImpl(serviceWorkerUtils) {
|
|
2453
2612
|
AuthManagerBrowser_classCallCheck(this, AuthManagerImpl);
|
|
2613
|
+
this.serviceWorkerUtils = serviceWorkerUtils;
|
|
2454
2614
|
this.contentType = "content-type";
|
|
2455
2615
|
this.contentTypeJson = "application/json";
|
|
2456
2616
|
this.contentTypeText = "text/plain";
|
|
@@ -2475,13 +2635,14 @@ var AuthManagerImpl = /*#__PURE__*/function () {
|
|
|
2475
2635
|
if (_this2.isAuthSessionActive()) {
|
|
2476
2636
|
throw new Error("Auth session already active. Please call 'await endAuthSession()' and then call 'await beginAuthSession(...)' to start a new auth session.");
|
|
2477
2637
|
}
|
|
2478
|
-
|
|
2638
|
+
var serviceWorkerScriptField = "serviceWorkerScript";
|
|
2639
|
+
return AuthManagerBrowser_await(_this2.serviceWorkerUtils.registerServiceWorkerIfSupported(params.serviceWorkerScript, serviceWorkerScriptField, "Falling back to Bytescale CDN cookies for auth. These are third-party cookies, which some modern browsers block."), function (_this2$serviceWorkerU) {
|
|
2479
2640
|
var newSession = {
|
|
2480
2641
|
accessToken: undefined,
|
|
2481
2642
|
accessTokenRefreshHandle: undefined,
|
|
2482
2643
|
params: params,
|
|
2483
2644
|
isActive: true,
|
|
2484
|
-
authServiceWorker: _this2$
|
|
2645
|
+
authServiceWorker: _this2$serviceWorkerU
|
|
2485
2646
|
};
|
|
2486
2647
|
AuthSessionState.setSession(newSession);
|
|
2487
2648
|
return newSession;
|
|
@@ -2510,62 +2671,13 @@ var AuthManagerImpl = /*#__PURE__*/function () {
|
|
|
2510
2671
|
clearTimeout(session.accessTokenRefreshHandle);
|
|
2511
2672
|
}
|
|
2512
2673
|
return AuthManagerBrowser_await(_this4.deleteAccessToken(session.params), function () {
|
|
2513
|
-
_this4.setServiceWorkerConfig(session, []); // Prevent service worker from authorizing subsequent requests.
|
|
2674
|
+
return AuthManagerBrowser_awaitIgnored(_this4.setServiceWorkerConfig(session, [])); // Prevent service worker from authorizing subsequent requests.
|
|
2514
2675
|
});
|
|
2515
2676
|
})));
|
|
2516
2677
|
} catch (e) {
|
|
2517
2678
|
return Promise.reject(e);
|
|
2518
2679
|
}
|
|
2519
2680
|
}
|
|
2520
|
-
/**
|
|
2521
|
-
* Idempotent.
|
|
2522
|
-
*
|
|
2523
|
-
* Only returns once the service worker has been activated.
|
|
2524
|
-
*
|
|
2525
|
-
* We don't need to unregister it: we just need to clear the config when auth ends.
|
|
2526
|
-
*/
|
|
2527
|
-
}, {
|
|
2528
|
-
key: "registerAuthServiceWorker",
|
|
2529
|
-
value: function registerAuthServiceWorker(_ref) {
|
|
2530
|
-
var serviceWorkerScript = _ref.serviceWorkerScript;
|
|
2531
|
-
try {
|
|
2532
|
-
if (serviceWorkerScript === undefined) {
|
|
2533
|
-
return undefined;
|
|
2534
|
-
}
|
|
2535
|
-
var field = "serviceWorkerScript";
|
|
2536
|
-
if (!serviceWorkerScript.startsWith("/")) {
|
|
2537
|
-
throw new Error("The '".concat(field, "' field must start with a '/' and reference a script at the root of your website."));
|
|
2538
|
-
}
|
|
2539
|
-
var forwardSlashCount = serviceWorkerScript.split("/").length - 1;
|
|
2540
|
-
if (forwardSlashCount > 1) {
|
|
2541
|
-
ConsoleUtils.warn("The '".concat(field, "' field should be a root script (e.g. '/bytescale-auth-sw.js'). The Bytescale SDK can only authorize requests originating from webpages that are at the same level as the script or below."));
|
|
2542
|
-
}
|
|
2543
|
-
return AuthManagerBrowser_catch(function () {
|
|
2544
|
-
if ("serviceWorker" in navigator) {
|
|
2545
|
-
return AuthManagerBrowser_await(navigator.serviceWorker.register(serviceWorkerScript), function (registration) {
|
|
2546
|
-
return registration.active !== null ? registration.active : AuthManagerBrowser_awaitIgnored(new Promise(function (resolve) {
|
|
2547
|
-
registration.addEventListener("updatefound", function () {
|
|
2548
|
-
var newWorker = registration.installing;
|
|
2549
|
-
if (newWorker !== null) {
|
|
2550
|
-
newWorker.addEventListener("statechange", function () {
|
|
2551
|
-
if (newWorker.state === "activated") {
|
|
2552
|
-
resolve(newWorker);
|
|
2553
|
-
}
|
|
2554
|
-
});
|
|
2555
|
-
}
|
|
2556
|
-
});
|
|
2557
|
-
}));
|
|
2558
|
-
}); // Occurs when: (service worker is already registered AND there's been no code changes) OR (service worker was not previously registered).
|
|
2559
|
-
} else {
|
|
2560
|
-
ConsoleUtils.warn("Service workers not supported by browser. Falling back to Bytescale CDN cookies for auth. These are third-party cookies, which some modern browsers block.");
|
|
2561
|
-
}
|
|
2562
|
-
}, function (e) {
|
|
2563
|
-
throw new Error("Failed to install Bytescale Auth Service Worker (SW). ".concat(e.name, ": ").concat(e.message));
|
|
2564
|
-
});
|
|
2565
|
-
} catch (e) {
|
|
2566
|
-
return Promise.reject(e);
|
|
2567
|
-
}
|
|
2568
|
-
}
|
|
2569
2681
|
}, {
|
|
2570
2682
|
key: "refreshAccessToken",
|
|
2571
2683
|
value: function refreshAccessToken(session) {
|
|
@@ -2582,23 +2694,29 @@ var AuthManagerImpl = /*#__PURE__*/function () {
|
|
|
2582
2694
|
_session$params = session.params;
|
|
2583
2695
|
return AuthManagerBrowser_await(session.params.authHeaders(), function (_session$params$authH) {
|
|
2584
2696
|
return AuthManagerBrowser_await(_getAccessToken.call(_this6, _session$params, _session$params$authH), function (jwt) {
|
|
2585
|
-
|
|
2586
|
-
|
|
2697
|
+
// We don't use cookie-based auth if the browser supports service worker-based auth, as using both will cause
|
|
2698
|
+
// confusion for us in the future (i.e. we may question "do we need to use both together? was there a reason?").
|
|
2699
|
+
// Also: if the user has omitted "allowedOrigins" from their JWT, then service worker-based auth is more secure
|
|
2700
|
+
// than cookie-based auth, which is another reason to prevent these cookies from being set unless required.
|
|
2701
|
+
var setCookie = !_this6.isUsingServiceWorker(session);
|
|
2702
|
+
return AuthManagerBrowser_await(_this6.setAccessToken(session.params, jwt, setCookie), function (setTokenResult) {
|
|
2703
|
+
return AuthManagerBrowser_await(_this6.setServiceWorkerConfig(session, [{
|
|
2587
2704
|
headers: [{
|
|
2588
2705
|
key: "Authorization",
|
|
2589
2706
|
value: "Bearer ".concat(jwt)
|
|
2590
2707
|
}],
|
|
2591
2708
|
expires: Date.now() + setTokenResult.ttlSeconds * 1000,
|
|
2592
2709
|
urlPrefix: "".concat(_this6.getCdnUrl(session.params), "/").concat(session.params.accountId, "/")
|
|
2593
|
-
}])
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2710
|
+
}]), function () {
|
|
2711
|
+
var desiredTtl = setTokenResult.ttlSeconds - _this6.refreshBeforeExpirySeconds;
|
|
2712
|
+
timeout = Math.max(desiredTtl, _this6.minJwtTtlSeconds);
|
|
2713
|
+
if (desiredTtl !== timeout) {
|
|
2714
|
+
ConsoleUtils.warn("JWT expiration is too short: waiting for ".concat(timeout, " seconds before refreshing."));
|
|
2715
|
+
}
|
|
2716
|
+
// There's no need to print a warning for this: it's OK to silently request the JWT before it expires. Also, this is 24 days in this case!
|
|
2717
|
+
timeout = Math.min(timeout, _this6.maxJwtTtlSeconds);
|
|
2718
|
+
session.accessToken = setTokenResult.accessToken;
|
|
2719
|
+
});
|
|
2602
2720
|
});
|
|
2603
2721
|
});
|
|
2604
2722
|
});
|
|
@@ -2606,7 +2724,7 @@ var AuthManagerImpl = /*#__PURE__*/function () {
|
|
|
2606
2724
|
// Use 'warn' instead of 'error' since this happens frequently, i.e. user goes through a tunnel, and some customers report these errors to systems like Sentry, so we don't want to spam.
|
|
2607
2725
|
ConsoleUtils.warn("Unable to refresh JWT access token: ".concat(e));
|
|
2608
2726
|
});
|
|
2609
|
-
}, function (_wasThrown,
|
|
2727
|
+
}, function (_wasThrown, _result) {
|
|
2610
2728
|
session.accessTokenRefreshHandle = window.setTimeout(function () {
|
|
2611
2729
|
_this6.refreshAccessToken(session).then(function () {},
|
|
2612
2730
|
// Should not occur, as this method shouldn't throw errors.
|
|
@@ -2614,27 +2732,43 @@ var AuthManagerImpl = /*#__PURE__*/function () {
|
|
|
2614
2732
|
return ConsoleUtils.error("Unexpected error when refreshing JWT access token: ".concat(e));
|
|
2615
2733
|
});
|
|
2616
2734
|
}, timeout * 1000);
|
|
2617
|
-
return AuthManagerBrowser_rethrow(_wasThrown,
|
|
2735
|
+
return AuthManagerBrowser_rethrow(_wasThrown, _result);
|
|
2618
2736
|
}));
|
|
2619
2737
|
})));
|
|
2620
2738
|
} catch (e) {
|
|
2621
2739
|
return Promise.reject(e);
|
|
2622
2740
|
}
|
|
2623
2741
|
}
|
|
2742
|
+
}, {
|
|
2743
|
+
key: "isUsingServiceWorker",
|
|
2744
|
+
value: function isUsingServiceWorker(session) {
|
|
2745
|
+
return session.authServiceWorker !== undefined;
|
|
2746
|
+
}
|
|
2624
2747
|
}, {
|
|
2625
2748
|
key: "setServiceWorkerConfig",
|
|
2626
2749
|
value: function setServiceWorkerConfig(session, config) {
|
|
2627
|
-
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
|
|
2750
|
+
try {
|
|
2751
|
+
var _this8 = this;
|
|
2752
|
+
if (session.authServiceWorker === undefined) {
|
|
2753
|
+
return undefined;
|
|
2754
|
+
}
|
|
2755
|
+
// We re-fetch the latest active worker, as another tab may have registered a new one, and then the tab may be closed,
|
|
2756
|
+
// leaving us as the only open tab but with an old and ineffective service worker reference.
|
|
2757
|
+
return AuthManagerBrowser_await(_this8.serviceWorkerUtils.getActiveServiceWorkerElseRegister(session.authServiceWorker), function (serviceWorker) {
|
|
2758
|
+
var message = {
|
|
2759
|
+
type: "SET_BYTESCALE_AUTH_CONFIG",
|
|
2760
|
+
config: config
|
|
2761
|
+
};
|
|
2762
|
+
serviceWorker.postMessage(message);
|
|
2763
|
+
});
|
|
2764
|
+
} catch (e) {
|
|
2765
|
+
return Promise.reject(e);
|
|
2766
|
+
}
|
|
2633
2767
|
}
|
|
2634
2768
|
}, {
|
|
2635
2769
|
key: "getAccessTokenUrl",
|
|
2636
|
-
value: function getAccessTokenUrl(params) {
|
|
2637
|
-
return "".concat(this.getCdnUrl(params), "/api/v1/access_tokens/").concat(params.accountId);
|
|
2770
|
+
value: function getAccessTokenUrl(params, setCookie) {
|
|
2771
|
+
return "".concat(this.getCdnUrl(params), "/api/v1/access_tokens/").concat(params.accountId, "?set-cookie=").concat(setCookie ? "true" : "false");
|
|
2638
2772
|
}
|
|
2639
2773
|
}, {
|
|
2640
2774
|
key: "getCdnUrl",
|
|
@@ -2646,9 +2780,9 @@ var AuthManagerImpl = /*#__PURE__*/function () {
|
|
|
2646
2780
|
key: "deleteAccessToken",
|
|
2647
2781
|
value: function deleteAccessToken(params) {
|
|
2648
2782
|
try {
|
|
2649
|
-
var
|
|
2783
|
+
var _this10 = this;
|
|
2650
2784
|
var _a;
|
|
2651
|
-
return AuthManagerBrowser_awaitIgnored(BaseAPI.fetch(
|
|
2785
|
+
return AuthManagerBrowser_awaitIgnored(BaseAPI.fetch(_this10.getAccessTokenUrl(params, true), {
|
|
2652
2786
|
method: "DELETE",
|
|
2653
2787
|
credentials: "include",
|
|
2654
2788
|
headers: {}
|
|
@@ -2662,17 +2796,17 @@ var AuthManagerImpl = /*#__PURE__*/function () {
|
|
|
2662
2796
|
}
|
|
2663
2797
|
}, {
|
|
2664
2798
|
key: "setAccessToken",
|
|
2665
|
-
value: function setAccessToken(params, jwt) {
|
|
2799
|
+
value: function setAccessToken(params, jwt, setCookie) {
|
|
2666
2800
|
try {
|
|
2667
|
-
var
|
|
2801
|
+
var _this12 = this;
|
|
2668
2802
|
var _a;
|
|
2669
2803
|
var request = {
|
|
2670
2804
|
accessToken: jwt
|
|
2671
2805
|
};
|
|
2672
|
-
return AuthManagerBrowser_await(BaseAPI.fetch(
|
|
2806
|
+
return AuthManagerBrowser_await(BaseAPI.fetch(_this12.getAccessTokenUrl(params, setCookie), {
|
|
2673
2807
|
method: "PUT",
|
|
2674
2808
|
credentials: "include",
|
|
2675
|
-
headers: AuthManagerBrowser_defineProperty({},
|
|
2809
|
+
headers: AuthManagerBrowser_defineProperty({}, _this12.contentType, _this12.contentTypeJson),
|
|
2676
2810
|
body: JSON.stringify(request)
|
|
2677
2811
|
}, {
|
|
2678
2812
|
isBytescaleApi: true,
|
|
@@ -2688,10 +2822,10 @@ var AuthManagerImpl = /*#__PURE__*/function () {
|
|
|
2688
2822
|
key: "getAccessToken",
|
|
2689
2823
|
value: function getAccessToken(params, headers) {
|
|
2690
2824
|
try {
|
|
2691
|
-
var
|
|
2825
|
+
var _this14 = this;
|
|
2692
2826
|
var _a, _b;
|
|
2693
2827
|
var endpointName = "Your auth API endpoint";
|
|
2694
|
-
var requiredContentType =
|
|
2828
|
+
var requiredContentType = _this14.contentTypeText;
|
|
2695
2829
|
return AuthManagerBrowser_await(BaseAPI.fetch(params.authUrl, {
|
|
2696
2830
|
method: "GET",
|
|
2697
2831
|
headers: headers
|
|
@@ -2699,10 +2833,10 @@ var AuthManagerImpl = /*#__PURE__*/function () {
|
|
|
2699
2833
|
isBytescaleApi: false,
|
|
2700
2834
|
fetchApi: (_a = params.options) === null || _a === void 0 ? void 0 : _a.fetchApi
|
|
2701
2835
|
}), function (result) {
|
|
2702
|
-
var actualContentType = (_b = result.headers.get(
|
|
2836
|
+
var actualContentType = (_b = result.headers.get(_this14.contentType)) !== null && _b !== void 0 ? _b : "";
|
|
2703
2837
|
// Support content types like "text/plain; charset=utf-8" and "text/plain"
|
|
2704
2838
|
if (actualContentType.split(";")[0] !== requiredContentType) {
|
|
2705
|
-
throw new Error("".concat(endpointName, " returned \"").concat(actualContentType, "\" for the ").concat(
|
|
2839
|
+
throw new Error("".concat(endpointName, " returned \"").concat(actualContentType, "\" for the ").concat(_this14.contentType, " response header, but the Bytescale SDK requires \"").concat(requiredContentType, "\"."));
|
|
2706
2840
|
}
|
|
2707
2841
|
return AuthManagerBrowser_await(result.text(), function (jwt) {
|
|
2708
2842
|
if (jwt.length === 0) {
|
|
@@ -2725,7 +2859,7 @@ var AuthManagerImpl = /*#__PURE__*/function () {
|
|
|
2725
2859
|
/**
|
|
2726
2860
|
* 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).
|
|
2727
2861
|
*/
|
|
2728
|
-
var AuthManager = new AuthManagerImpl();
|
|
2862
|
+
var AuthManager = new AuthManagerImpl(new ServiceWorkerUtils());
|
|
2729
2863
|
;// CONCATENATED MODULE: ./src/public/browser/index.ts
|
|
2730
2864
|
|
|
2731
2865
|
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ServiceWorkerConfig } from "./model/ServiceWorkerConfig";
|
|
2
|
+
export declare class ServiceWorkerUtils {
|
|
3
|
+
/**
|
|
4
|
+
* Idempotent.
|
|
5
|
+
*
|
|
6
|
+
* Only returns once the service worker has been activated.
|
|
7
|
+
*
|
|
8
|
+
* We don't need to unregister it: we just need to clear the config when auth ends.
|
|
9
|
+
*/
|
|
10
|
+
registerServiceWorkerIfSupported(serviceWorkerScript: string | undefined, configFieldName: string, fallbackMessage: string): Promise<ServiceWorkerConfig | undefined>;
|
|
11
|
+
getActiveServiceWorkerElseRegister({ serviceWorkerScope, serviceWorkerScript }: ServiceWorkerConfig): Promise<ServiceWorker>;
|
|
12
|
+
/**
|
|
13
|
+
* Idempotent.
|
|
14
|
+
*
|
|
15
|
+
* Only returns once the service worker has been activated.
|
|
16
|
+
*
|
|
17
|
+
* We don't need to unregister it: we just need to clear the config when auth ends.
|
|
18
|
+
*/
|
|
19
|
+
private registerAuthServiceWorker;
|
|
20
|
+
private getActiveServiceWorker;
|
|
21
|
+
}
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { AuthSwConfigDto } from "./AuthSwConfigDto";
|
|
2
2
|
export interface AuthSwSetConfigDto {
|
|
3
3
|
config: AuthSwConfigDto;
|
|
4
|
-
|
|
4
|
+
/**
|
|
5
|
+
* We use a specific name for this type, since you can only register one service worker per scope, meaning it's
|
|
6
|
+
* possible the user will want to use their own service worker, which means we'll need to support having the Bytescale
|
|
7
|
+
* Auth Service Worker being a component of the user's service worker. Thus, we use a specific name to avoid conflict
|
|
8
|
+
* with the user's events.
|
|
9
|
+
*/
|
|
10
|
+
type: "SET_BYTESCALE_AUTH_CONFIG";
|
|
5
11
|
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { BeginAuthSessionParams } from "./AuthManagerInterface";
|
|
2
|
+
import { ServiceWorkerConfig } from "./ServiceWorkerConfig";
|
|
2
3
|
export interface AuthSession {
|
|
3
4
|
accessToken: string | undefined;
|
|
4
5
|
accessTokenRefreshHandle: number | undefined;
|
|
5
|
-
authServiceWorker:
|
|
6
|
+
authServiceWorker: ServiceWorkerConfig | undefined;
|
|
6
7
|
isActive: boolean;
|
|
7
8
|
params: BeginAuthSessionParams;
|
|
8
9
|
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { AuthManagerInterface, BeginAuthSessionParams } from "../../private/model/AuthManagerInterface";
|
|
2
|
+
import { ServiceWorkerUtils } from "../../private/ServiceWorkerUtils";
|
|
2
3
|
declare class AuthManagerImpl implements AuthManagerInterface {
|
|
4
|
+
private readonly serviceWorkerUtils;
|
|
3
5
|
private readonly authSessionMutex;
|
|
4
6
|
private readonly contentType;
|
|
5
7
|
private readonly contentTypeJson;
|
|
@@ -8,19 +10,12 @@ declare class AuthManagerImpl implements AuthManagerInterface {
|
|
|
8
10
|
private readonly maxJwtTtlSeconds;
|
|
9
11
|
private readonly retryAuthAfterErrorSeconds;
|
|
10
12
|
private readonly refreshBeforeExpirySeconds;
|
|
11
|
-
constructor();
|
|
13
|
+
constructor(serviceWorkerUtils: ServiceWorkerUtils);
|
|
12
14
|
isAuthSessionActive(): boolean;
|
|
13
15
|
beginAuthSession(params: BeginAuthSessionParams): Promise<void>;
|
|
14
16
|
endAuthSession(): Promise<void>;
|
|
15
|
-
/**
|
|
16
|
-
* Idempotent.
|
|
17
|
-
*
|
|
18
|
-
* Only returns once the service worker has been activated.
|
|
19
|
-
*
|
|
20
|
-
* We don't need to unregister it: we just need to clear the config when auth ends.
|
|
21
|
-
*/
|
|
22
|
-
private registerAuthServiceWorker;
|
|
23
17
|
private refreshAccessToken;
|
|
18
|
+
private isUsingServiceWorker;
|
|
24
19
|
private setServiceWorkerConfig;
|
|
25
20
|
private getAccessTokenUrl;
|
|
26
21
|
private getCdnUrl;
|