@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.
@@ -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
- return AuthManagerBrowser_await(_this2.registerAuthServiceWorker(params), function (_this2$registerAuthSe) {
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$registerAuthSe
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
- return AuthManagerBrowser_await(_this6.setAccessToken(session.params, jwt), function (setTokenResult) {
2601
- _this6.setServiceWorkerConfig(session, [{
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
- var desiredTtl = setTokenResult.ttlSeconds - _this6.refreshBeforeExpirySeconds;
2610
- timeout = Math.max(desiredTtl, _this6.minJwtTtlSeconds);
2611
- if (desiredTtl !== timeout) {
2612
- ConsoleUtils.warn("JWT expiration is too short: waiting for ".concat(timeout, " seconds before refreshing."));
2613
- }
2614
- // 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!
2615
- timeout = Math.min(timeout, _this6.maxJwtTtlSeconds);
2616
- session.accessToken = setTokenResult.accessToken;
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, _result3) {
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, _result3);
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
- var _a;
2643
- var message = {
2644
- type: "SET_CONFIG",
2645
- config: config
2646
- };
2647
- (_a = session.authServiceWorker) === null || _a === void 0 ? void 0 : _a.postMessage(message);
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 _this8 = this;
2798
+ var _this10 = this;
2665
2799
  var _a;
2666
- return AuthManagerBrowser_awaitIgnored(BaseAPI.fetch(_this8.getAccessTokenUrl(params), {
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 _this10 = this;
2816
+ var _this12 = this;
2683
2817
  var _a;
2684
2818
  var request = {
2685
2819
  accessToken: jwt
2686
2820
  };
2687
- return AuthManagerBrowser_await(BaseAPI.fetch(_this10.getAccessTokenUrl(params), {
2821
+ return AuthManagerBrowser_await(BaseAPI.fetch(_this12.getAccessTokenUrl(params, setCookie), {
2688
2822
  method: "PUT",
2689
2823
  credentials: "include",
2690
- headers: AuthManagerBrowser_defineProperty({}, _this10.contentType, _this10.contentTypeJson),
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 _this12 = this;
2840
+ var _this14 = this;
2707
2841
  var _a, _b;
2708
2842
  var endpointName = "Your auth API endpoint";
2709
- var requiredContentType = _this12.contentTypeText;
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(_this12.contentType)) !== null && _b !== void 0 ? _b : "";
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(_this12.contentType, " response header, but the Bytescale SDK requires \"").concat(requiredContentType, "\"."));
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
- return AuthManagerBrowser_await(_this2.registerAuthServiceWorker(params), function (_this2$registerAuthSe) {
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$registerAuthSe
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
- return AuthManagerBrowser_await(_this6.setAccessToken(session.params, jwt), function (setTokenResult) {
2586
- _this6.setServiceWorkerConfig(session, [{
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
- var desiredTtl = setTokenResult.ttlSeconds - _this6.refreshBeforeExpirySeconds;
2595
- timeout = Math.max(desiredTtl, _this6.minJwtTtlSeconds);
2596
- if (desiredTtl !== timeout) {
2597
- ConsoleUtils.warn("JWT expiration is too short: waiting for ".concat(timeout, " seconds before refreshing."));
2598
- }
2599
- // 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!
2600
- timeout = Math.min(timeout, _this6.maxJwtTtlSeconds);
2601
- session.accessToken = setTokenResult.accessToken;
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, _result3) {
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, _result3);
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
- var _a;
2628
- var message = {
2629
- type: "SET_CONFIG",
2630
- config: config
2631
- };
2632
- (_a = session.authServiceWorker) === null || _a === void 0 ? void 0 : _a.postMessage(message);
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 _this8 = this;
2783
+ var _this10 = this;
2650
2784
  var _a;
2651
- return AuthManagerBrowser_awaitIgnored(BaseAPI.fetch(_this8.getAccessTokenUrl(params), {
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 _this10 = this;
2801
+ var _this12 = this;
2668
2802
  var _a;
2669
2803
  var request = {
2670
2804
  accessToken: jwt
2671
2805
  };
2672
- return AuthManagerBrowser_await(BaseAPI.fetch(_this10.getAccessTokenUrl(params), {
2806
+ return AuthManagerBrowser_await(BaseAPI.fetch(_this12.getAccessTokenUrl(params, setCookie), {
2673
2807
  method: "PUT",
2674
2808
  credentials: "include",
2675
- headers: AuthManagerBrowser_defineProperty({}, _this10.contentType, _this10.contentTypeJson),
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 _this12 = this;
2825
+ var _this14 = this;
2692
2826
  var _a, _b;
2693
2827
  var endpointName = "Your auth API endpoint";
2694
- var requiredContentType = _this12.contentTypeText;
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(_this12.contentType)) !== null && _b !== void 0 ? _b : "";
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(_this12.contentType, " response header, but the Bytescale SDK requires \"").concat(requiredContentType, "\"."));
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
- type: "SET_CONFIG";
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: ServiceWorker | undefined;
6
+ authServiceWorker: ServiceWorkerConfig | undefined;
6
7
  isActive: boolean;
7
8
  params: BeginAuthSessionParams;
8
9
  }
@@ -0,0 +1,4 @@
1
+ export interface ServiceWorkerConfig {
2
+ serviceWorkerScope: string;
3
+ serviceWorkerScript: string;
4
+ }
@@ -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;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bytescale/sdk",
3
- "version": "3.16.0",
3
+ "version": "3.18.0",
4
4
  "description": "Bytescale JavaScript SDK",
5
5
  "author": "Bytescale <hello@bytescale.com> (https://www.bytescale.com)",
6
6
  "license": "MIT",