authscape 1.0.764 → 1.0.768
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/index.js +104 -81
- package/package.json +1 -1
- package/src/components/AuthScapeApp.js +46 -21
- package/src/services/apiService.js +55 -53
- package/src/services/authService.js +3 -3
package/index.js
CHANGED
|
@@ -76,19 +76,30 @@ function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
|
|
|
76
76
|
function asyncGeneratorStep(n, t, e, r, o, a, c) { try { var i = n[a](c), u = i.value; } catch (n) { return void e(n); } i.done ? t(u) : Promise.resolve(u).then(r, o); }
|
|
77
77
|
function _asyncToGenerator(n) { return function () { var t = this, e = arguments; return new Promise(function (r, o) { var a = n.apply(t, e); function _next(n) { asyncGeneratorStep(a, r, o, _next, _throw, "next", n); } function _throw(n) { asyncGeneratorStep(a, r, o, _next, _throw, "throw", n); } _next(void 0); }); }; } // Re-export toast and transitions so pages can import from authscape
|
|
78
78
|
// ============================================================================
|
|
79
|
-
//
|
|
79
|
+
// Auth Redirect Circuit Breaker
|
|
80
80
|
// ============================================================================
|
|
81
|
-
var
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
81
|
+
var AUTH_REDIRECT_KEY = 'authscape_redirect_count';
|
|
82
|
+
var AUTH_REDIRECT_TS_KEY = 'authscape_redirect_ts';
|
|
83
|
+
var AUTH_MAX_REDIRECTS = 3;
|
|
84
|
+
var AUTH_REDIRECT_WINDOW_MS = 30000; // 30 seconds
|
|
85
|
+
|
|
86
|
+
var checkAndIncrementRedirect = function checkAndIncrementRedirect() {
|
|
87
|
+
if (typeof window === 'undefined') return false;
|
|
88
|
+
var now = Date.now();
|
|
89
|
+
var storedTs = parseInt(sessionStorage.getItem(AUTH_REDIRECT_TS_KEY) || '0', 10);
|
|
90
|
+
var count = parseInt(sessionStorage.getItem(AUTH_REDIRECT_KEY) || '0', 10);
|
|
91
|
+
if (now - storedTs > AUTH_REDIRECT_WINDOW_MS) {
|
|
92
|
+
count = 0;
|
|
93
|
+
sessionStorage.setItem(AUTH_REDIRECT_TS_KEY, String(now));
|
|
94
|
+
}
|
|
95
|
+
count += 1;
|
|
96
|
+
sessionStorage.setItem(AUTH_REDIRECT_KEY, String(count));
|
|
97
|
+
return count <= AUTH_MAX_REDIRECTS;
|
|
98
|
+
};
|
|
99
|
+
var resetRedirectCounter = function resetRedirectCounter() {
|
|
100
|
+
if (typeof window === 'undefined') return;
|
|
101
|
+
sessionStorage.removeItem(AUTH_REDIRECT_KEY);
|
|
102
|
+
sessionStorage.removeItem(AUTH_REDIRECT_TS_KEY);
|
|
92
103
|
};
|
|
93
104
|
|
|
94
105
|
// ============================================================================
|
|
@@ -715,6 +726,7 @@ function ensureUserHelpers(u) {
|
|
|
715
726
|
// AuthScapeApp Component
|
|
716
727
|
// ============================================================================
|
|
717
728
|
function AuthScapeApp(_ref10) {
|
|
729
|
+
var _searchParams$get;
|
|
718
730
|
var Component = _ref10.Component,
|
|
719
731
|
layout = _ref10.layout,
|
|
720
732
|
loadingLayout = _ref10.loadingLayout,
|
|
@@ -757,8 +769,9 @@ function AuthScapeApp(_ref10) {
|
|
|
757
769
|
var queryCodeUsed = (0, _react.useRef)(null);
|
|
758
770
|
var ga4React = (0, _react.useRef)(null);
|
|
759
771
|
var errorTrackingInitializedRef = (0, _react.useRef)(false);
|
|
772
|
+
var loginRedirectPending = (0, _react.useRef)(false);
|
|
760
773
|
var searchParams = (0, _navigation.useSearchParams)();
|
|
761
|
-
var queryCode = searchParams.get("code");
|
|
774
|
+
var queryCode = (_searchParams$get = searchParams === null || searchParams === void 0 ? void 0 : searchParams.get("code")) !== null && _searchParams$get !== void 0 ? _searchParams$get : null;
|
|
762
775
|
var pathname = (0, _navigation.usePathname)();
|
|
763
776
|
var signInValidator = /*#__PURE__*/function () {
|
|
764
777
|
var _ref11 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee8(codeFromQuery) {
|
|
@@ -782,13 +795,14 @@ function AuthScapeApp(_ref10) {
|
|
|
782
795
|
setIsSigningIn(true);
|
|
783
796
|
codeVerifier = window.localStorage.getItem("verifier");
|
|
784
797
|
if (!(!codeFromQuery || !codeVerifier)) {
|
|
785
|
-
_context8.next =
|
|
798
|
+
_context8.next = 12;
|
|
786
799
|
break;
|
|
787
800
|
}
|
|
788
801
|
window.localStorage.clear();
|
|
789
|
-
|
|
802
|
+
setIsSigningIn(false);
|
|
803
|
+
setFrontEndLoadedState(true);
|
|
790
804
|
return _context8.abrupt("return");
|
|
791
|
-
case
|
|
805
|
+
case 12:
|
|
792
806
|
headers = {
|
|
793
807
|
"Content-Type": "application/x-www-form-urlencoded"
|
|
794
808
|
};
|
|
@@ -800,56 +814,51 @@ function AuthScapeApp(_ref10) {
|
|
|
800
814
|
client_secret: process.env.client_secret,
|
|
801
815
|
code_verifier: codeVerifier
|
|
802
816
|
});
|
|
803
|
-
_context8.prev =
|
|
804
|
-
_context8.next =
|
|
817
|
+
_context8.prev = 14;
|
|
818
|
+
_context8.next = 17;
|
|
805
819
|
return _axios["default"].post(process.env.authorityUri + "/connect/token", body, {
|
|
806
820
|
headers: headers
|
|
807
821
|
});
|
|
808
|
-
case
|
|
822
|
+
case 17:
|
|
809
823
|
response = _context8.sent;
|
|
810
824
|
domainHost = window.location.hostname.split(".").slice(-2).join(".");
|
|
811
825
|
window.localStorage.removeItem("verifier");
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
maxAge: 60 * 60 * 24 * 365,
|
|
826
|
+
_jsCookie["default"].set("access_token", response.data.access_token, {
|
|
827
|
+
expires: 365,
|
|
815
828
|
path: "/",
|
|
816
829
|
domain: domainHost,
|
|
817
830
|
secure: true
|
|
818
831
|
});
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
return setCookie("expires_in", response.data.expires_in, {
|
|
822
|
-
maxAge: 60 * 60 * 24 * 365,
|
|
832
|
+
_jsCookie["default"].set("expires_in", String(response.data.expires_in), {
|
|
833
|
+
expires: 365,
|
|
823
834
|
path: "/",
|
|
824
835
|
domain: domainHost,
|
|
825
836
|
secure: true
|
|
826
837
|
});
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
return setCookie("refresh_token", response.data.refresh_token, {
|
|
830
|
-
maxAge: 60 * 60 * 24 * 365,
|
|
838
|
+
_jsCookie["default"].set("refresh_token", response.data.refresh_token, {
|
|
839
|
+
expires: 365,
|
|
831
840
|
path: "/",
|
|
832
841
|
domain: domainHost,
|
|
833
842
|
secure: true
|
|
834
843
|
});
|
|
835
|
-
|
|
844
|
+
resetRedirectCounter();
|
|
836
845
|
redirectUri = window.localStorage.getItem("redirectUri") || "/";
|
|
837
846
|
window.localStorage.clear();
|
|
838
847
|
window.location.href = redirectUri;
|
|
839
|
-
_context8.next =
|
|
848
|
+
_context8.next = 35;
|
|
840
849
|
break;
|
|
841
|
-
case
|
|
842
|
-
_context8.prev =
|
|
843
|
-
_context8.t0 = _context8["catch"](
|
|
850
|
+
case 29:
|
|
851
|
+
_context8.prev = 29;
|
|
852
|
+
_context8.t0 = _context8["catch"](14);
|
|
844
853
|
console.error("PKCE sign-in failed", _context8.t0);
|
|
845
854
|
window.localStorage.clear();
|
|
846
855
|
setIsSigningIn(false);
|
|
847
|
-
|
|
848
|
-
case
|
|
856
|
+
setFrontEndLoadedState(true);
|
|
857
|
+
case 35:
|
|
849
858
|
case "end":
|
|
850
859
|
return _context8.stop();
|
|
851
860
|
}
|
|
852
|
-
}, _callee8, null, [[
|
|
861
|
+
}, _callee8, null, [[14, 29]]);
|
|
853
862
|
}));
|
|
854
863
|
return function signInValidator(_x4) {
|
|
855
864
|
return _ref11.apply(this, arguments);
|
|
@@ -960,7 +969,12 @@ function AuthScapeApp(_ref10) {
|
|
|
960
969
|
};
|
|
961
970
|
}, [frontEndLoadedState, pageProps.googleAnalytics4Code, pageProps.microsoftClarityCode]);
|
|
962
971
|
(0, _react.useEffect)(function () {
|
|
963
|
-
if (enforceLoggedIn && pathname !== "/signin-oidc" && frontEndLoadedState && !signedInUserState) {
|
|
972
|
+
if (enforceLoggedIn && pathname !== "/signin-oidc" && frontEndLoadedState && !signedInUserState && !loginRedirectPending.current) {
|
|
973
|
+
if (!checkAndIncrementRedirect()) {
|
|
974
|
+
console.warn('[AuthScape] Auth redirect loop detected — halting redirects.');
|
|
975
|
+
return;
|
|
976
|
+
}
|
|
977
|
+
loginRedirectPending.current = true;
|
|
964
978
|
module.exports.authService().login();
|
|
965
979
|
}
|
|
966
980
|
}, [signedInUserState, enforceLoggedIn, frontEndLoadedState, pathname]);
|
|
@@ -9598,19 +9612,6 @@ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e
|
|
|
9598
9612
|
function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return e; }; var t, e = {}, r = Object.prototype, n = r.hasOwnProperty, o = Object.defineProperty || function (t, e, r) { t[e] = r.value; }, i = "function" == typeof Symbol ? Symbol : {}, a = i.iterator || "@@iterator", c = i.asyncIterator || "@@asyncIterator", u = i.toStringTag || "@@toStringTag"; function define(t, e, r) { return Object.defineProperty(t, e, { value: r, enumerable: !0, configurable: !0, writable: !0 }), t[e]; } try { define({}, ""); } catch (t) { define = function define(t, e, r) { return t[e] = r; }; } function wrap(t, e, r, n) { var i = e && e.prototype instanceof Generator ? e : Generator, a = Object.create(i.prototype), c = new Context(n || []); return o(a, "_invoke", { value: makeInvokeMethod(t, r, c) }), a; } function tryCatch(t, e, r) { try { return { type: "normal", arg: t.call(e, r) }; } catch (t) { return { type: "throw", arg: t }; } } e.wrap = wrap; var h = "suspendedStart", l = "suspendedYield", f = "executing", s = "completed", y = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var p = {}; define(p, a, function () { return this; }); var d = Object.getPrototypeOf, v = d && d(d(values([]))); v && v !== r && n.call(v, a) && (p = v); var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p); function defineIteratorMethods(t) { ["next", "throw", "return"].forEach(function (e) { define(t, e, function (t) { return this._invoke(e, t); }); }); } function AsyncIterator(t, e) { function invoke(r, o, i, a) { var c = tryCatch(t[r], t, o); if ("throw" !== c.type) { var u = c.arg, h = u.value; return h && "object" == _typeof(h) && n.call(h, "__await") ? e.resolve(h.__await).then(function (t) { invoke("next", t, i, a); }, function (t) { invoke("throw", t, i, a); }) : e.resolve(h).then(function (t) { u.value = t, i(u); }, function (t) { return invoke("throw", t, i, a); }); } a(c.arg); } var r; o(this, "_invoke", { value: function value(t, n) { function callInvokeWithMethodAndArg() { return new e(function (e, r) { invoke(t, n, e, r); }); } return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } }); } function makeInvokeMethod(e, r, n) { var o = h; return function (i, a) { if (o === f) throw Error("Generator is already running"); if (o === s) { if ("throw" === i) throw a; return { value: t, done: !0 }; } for (n.method = i, n.arg = a;;) { var c = n.delegate; if (c) { var u = maybeInvokeDelegate(c, n); if (u) { if (u === y) continue; return u; } } if ("next" === n.method) n.sent = n._sent = n.arg;else if ("throw" === n.method) { if (o === h) throw o = s, n.arg; n.dispatchException(n.arg); } else "return" === n.method && n.abrupt("return", n.arg); o = f; var p = tryCatch(e, r, n); if ("normal" === p.type) { if (o = n.done ? s : l, p.arg === y) continue; return { value: p.arg, done: n.done }; } "throw" === p.type && (o = s, n.method = "throw", n.arg = p.arg); } }; } function maybeInvokeDelegate(e, r) { var n = r.method, o = e.iterator[n]; if (o === t) return r.delegate = null, "throw" === n && e.iterator["return"] && (r.method = "return", r.arg = t, maybeInvokeDelegate(e, r), "throw" === r.method) || "return" !== n && (r.method = "throw", r.arg = new TypeError("The iterator does not provide a '" + n + "' method")), y; var i = tryCatch(o, e.iterator, r.arg); if ("throw" === i.type) return r.method = "throw", r.arg = i.arg, r.delegate = null, y; var a = i.arg; return a ? a.done ? (r[e.resultName] = a.value, r.next = e.nextLoc, "return" !== r.method && (r.method = "next", r.arg = t), r.delegate = null, y) : a : (r.method = "throw", r.arg = new TypeError("iterator result is not an object"), r.delegate = null, y); } function pushTryEntry(t) { var e = { tryLoc: t[0] }; 1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e); } function resetTryEntry(t) { var e = t.completion || {}; e.type = "normal", delete e.arg, t.completion = e; } function Context(t) { this.tryEntries = [{ tryLoc: "root" }], t.forEach(pushTryEntry, this), this.reset(!0); } function values(e) { if (e || "" === e) { var r = e[a]; if (r) return r.call(e); if ("function" == typeof e.next) return e; if (!isNaN(e.length)) { var o = -1, i = function next() { for (; ++o < e.length;) if (n.call(e, o)) return next.value = e[o], next.done = !1, next; return next.value = t, next.done = !0, next; }; return i.next = i; } } throw new TypeError(_typeof(e) + " is not iterable"); } return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, "constructor", { value: GeneratorFunctionPrototype, configurable: !0 }), o(GeneratorFunctionPrototype, "constructor", { value: GeneratorFunction, configurable: !0 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, "GeneratorFunction"), e.isGeneratorFunction = function (t) { var e = "function" == typeof t && t.constructor; return !!e && (e === GeneratorFunction || "GeneratorFunction" === (e.displayName || e.name)); }, e.mark = function (t) { return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, "GeneratorFunction")), t.prototype = Object.create(g), t; }, e.awrap = function (t) { return { __await: t }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () { return this; }), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) { void 0 === i && (i = Promise); var a = new AsyncIterator(wrap(t, r, n, o), i); return e.isGeneratorFunction(r) ? a : a.next().then(function (t) { return t.done ? t.value : a.next(); }); }, defineIteratorMethods(g), define(g, u, "Generator"), define(g, a, function () { return this; }), define(g, "toString", function () { return "[object Generator]"; }), e.keys = function (t) { var e = Object(t), r = []; for (var n in e) r.push(n); return r.reverse(), function next() { for (; r.length;) { var t = r.pop(); if (t in e) return next.value = t, next.done = !1, next; } return next.done = !0, next; }; }, e.values = values, Context.prototype = { constructor: Context, reset: function reset(e) { if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(resetTryEntry), !e) for (var r in this) "t" === r.charAt(0) && n.call(this, r) && !isNaN(+r.slice(1)) && (this[r] = t); }, stop: function stop() { this.done = !0; var t = this.tryEntries[0].completion; if ("throw" === t.type) throw t.arg; return this.rval; }, dispatchException: function dispatchException(e) { if (this.done) throw e; var r = this; function handle(n, o) { return a.type = "throw", a.arg = e, r.next = n, o && (r.method = "next", r.arg = t), !!o; } for (var o = this.tryEntries.length - 1; o >= 0; --o) { var i = this.tryEntries[o], a = i.completion; if ("root" === i.tryLoc) return handle("end"); if (i.tryLoc <= this.prev) { var c = n.call(i, "catchLoc"), u = n.call(i, "finallyLoc"); if (c && u) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } else if (c) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); } else { if (!u) throw Error("try statement without catch or finally"); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } } } }, abrupt: function abrupt(t, e) { for (var r = this.tryEntries.length - 1; r >= 0; --r) { var o = this.tryEntries[r]; if (o.tryLoc <= this.prev && n.call(o, "finallyLoc") && this.prev < o.finallyLoc) { var i = o; break; } } i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null); var a = i ? i.completion : {}; return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, y) : this.complete(a); }, complete: function complete(t, e) { if ("throw" === t.type) throw t.arg; return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && e && (this.next = e), y; }, finish: function finish(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y; } }, "catch": function _catch(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.tryLoc === t) { var n = r.completion; if ("throw" === n.type) { var o = n.arg; resetTryEntry(r); } return o; } } throw Error("illegal catch attempt"); }, delegateYield: function delegateYield(e, r, n) { return this.delegate = { iterator: values(e), resultName: r, nextLoc: n }, "next" === this.method && (this.arg = t), y; } }, e; }
|
|
9599
9613
|
function asyncGeneratorStep(n, t, e, r, o, a, c) { try { var i = n[a](c), u = i.value; } catch (n) { return void e(n); } i.done ? t(u) : Promise.resolve(u).then(r, o); }
|
|
9600
9614
|
function _asyncToGenerator(n) { return function () { var t = this, e = arguments; return new Promise(function (r, o) { var a = n.apply(t, e); function _next(n) { asyncGeneratorStep(a, r, o, _next, _throw, "next", n); } function _throw(n) { asyncGeneratorStep(a, r, o, _next, _throw, "throw", n); } _next(void 0); }); }; }
|
|
9601
|
-
// Cookie utility function
|
|
9602
|
-
var setCookie = function setCookie(name, value) {
|
|
9603
|
-
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
9604
|
-
return new Promise(function (resolve) {
|
|
9605
|
-
var cookieString = "".concat(name, "=").concat(value, ";");
|
|
9606
|
-
if (options.maxAge) cookieString += "max-age=".concat(options.maxAge, ";");
|
|
9607
|
-
if (options.path) cookieString += "path=".concat(options.path, ";");
|
|
9608
|
-
if (options.domain) cookieString += "domain=".concat(options.domain, ";");
|
|
9609
|
-
if (options.secure) cookieString += "secure;";
|
|
9610
|
-
document.cookie = cookieString;
|
|
9611
|
-
resolve();
|
|
9612
|
-
});
|
|
9613
|
-
};
|
|
9614
9615
|
var setupDefaultOptions = /*#__PURE__*/function () {
|
|
9615
9616
|
var _ref = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
|
|
9616
9617
|
var ctx,
|
|
@@ -9657,9 +9658,16 @@ var RefreshToken = /*#__PURE__*/function () {
|
|
|
9657
9658
|
return _regeneratorRuntime().wrap(function _callee2$(_context2) {
|
|
9658
9659
|
while (1) switch (_context2.prev = _context2.next) {
|
|
9659
9660
|
case 0:
|
|
9661
|
+
_context2.prev = 0;
|
|
9660
9662
|
accessToken = _jsCookie["default"].get('access_token') || '';
|
|
9661
9663
|
refreshToken = _jsCookie["default"].get('refresh_token') || '';
|
|
9662
|
-
|
|
9664
|
+
if (refreshToken) {
|
|
9665
|
+
_context2.next = 5;
|
|
9666
|
+
break;
|
|
9667
|
+
}
|
|
9668
|
+
return _context2.abrupt("return", false);
|
|
9669
|
+
case 5:
|
|
9670
|
+
_context2.next = 7;
|
|
9663
9671
|
return instance.post(process.env.authorityUri + "/connect/token", _queryString["default"].stringify({
|
|
9664
9672
|
grant_type: 'refresh_token',
|
|
9665
9673
|
client_id: process.env.client_id,
|
|
@@ -9671,42 +9679,44 @@ var RefreshToken = /*#__PURE__*/function () {
|
|
|
9671
9679
|
"Authorization": "Bearer " + accessToken
|
|
9672
9680
|
}
|
|
9673
9681
|
});
|
|
9674
|
-
case
|
|
9682
|
+
case 7:
|
|
9675
9683
|
response = _context2.sent;
|
|
9676
9684
|
if (!(response != null && response.status == 200)) {
|
|
9677
|
-
_context2.next =
|
|
9685
|
+
_context2.next = 15;
|
|
9678
9686
|
break;
|
|
9679
9687
|
}
|
|
9680
9688
|
domainHost = window.location.hostname.split('.').slice(-2).join('.');
|
|
9681
9689
|
originalRequest.headers['Authorization'] = 'Bearer ' + response.data.access_token;
|
|
9682
|
-
|
|
9683
|
-
|
|
9684
|
-
maxAge: 60 * 60 * 24 * 365,
|
|
9690
|
+
_jsCookie["default"].set('access_token', response.data.access_token, {
|
|
9691
|
+
expires: 365,
|
|
9685
9692
|
path: '/',
|
|
9686
9693
|
domain: domainHost,
|
|
9687
9694
|
secure: true
|
|
9688
9695
|
});
|
|
9689
|
-
|
|
9690
|
-
|
|
9691
|
-
return setCookie('expires_in', response.data.expires_in, {
|
|
9692
|
-
maxAge: 60 * 60 * 24 * 365,
|
|
9696
|
+
_jsCookie["default"].set('expires_in', String(response.data.expires_in), {
|
|
9697
|
+
expires: 365,
|
|
9693
9698
|
path: '/',
|
|
9694
9699
|
domain: domainHost,
|
|
9695
9700
|
secure: true
|
|
9696
9701
|
});
|
|
9697
|
-
|
|
9698
|
-
|
|
9699
|
-
return setCookie('refresh_token', response.data.refresh_token, {
|
|
9700
|
-
maxAge: 60 * 60 * 24 * 365,
|
|
9702
|
+
_jsCookie["default"].set('refresh_token', response.data.refresh_token, {
|
|
9703
|
+
expires: 365,
|
|
9701
9704
|
path: '/',
|
|
9702
9705
|
domain: domainHost,
|
|
9703
9706
|
secure: true
|
|
9704
9707
|
});
|
|
9705
|
-
|
|
9708
|
+
return _context2.abrupt("return", true);
|
|
9709
|
+
case 15:
|
|
9710
|
+
return _context2.abrupt("return", false);
|
|
9711
|
+
case 18:
|
|
9712
|
+
_context2.prev = 18;
|
|
9713
|
+
_context2.t0 = _context2["catch"](0);
|
|
9714
|
+
return _context2.abrupt("return", false);
|
|
9715
|
+
case 21:
|
|
9706
9716
|
case "end":
|
|
9707
9717
|
return _context2.stop();
|
|
9708
9718
|
}
|
|
9709
|
-
}, _callee2);
|
|
9719
|
+
}, _callee2, null, [[0, 18]]);
|
|
9710
9720
|
}));
|
|
9711
9721
|
return function RefreshToken(_x, _x2) {
|
|
9712
9722
|
return _ref2.apply(this, arguments);
|
|
@@ -9727,48 +9737,58 @@ var apiService = exports.apiService = function apiService() {
|
|
|
9727
9737
|
return response;
|
|
9728
9738
|
}, /*#__PURE__*/function () {
|
|
9729
9739
|
var _ref3 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee3(error) {
|
|
9730
|
-
var originalConfig, domainHost;
|
|
9740
|
+
var originalConfig, refreshed, domainHost;
|
|
9731
9741
|
return _regeneratorRuntime().wrap(function _callee3$(_context3) {
|
|
9732
9742
|
while (1) switch (_context3.prev = _context3.next) {
|
|
9733
9743
|
case 0:
|
|
9734
9744
|
originalConfig = error.config;
|
|
9735
9745
|
if (!error.response) {
|
|
9736
|
-
_context3.next =
|
|
9746
|
+
_context3.next = 13;
|
|
9737
9747
|
break;
|
|
9738
9748
|
}
|
|
9739
9749
|
if (!(error.response.status === 401 && !originalConfig._retry)) {
|
|
9740
|
-
_context3.next =
|
|
9750
|
+
_context3.next = 10;
|
|
9741
9751
|
break;
|
|
9742
9752
|
}
|
|
9743
9753
|
originalConfig._retry = true;
|
|
9744
9754
|
_context3.next = 6;
|
|
9745
9755
|
return RefreshToken(originalConfig, instance);
|
|
9746
9756
|
case 6:
|
|
9757
|
+
refreshed = _context3.sent;
|
|
9758
|
+
if (!refreshed) {
|
|
9759
|
+
_context3.next = 9;
|
|
9760
|
+
break;
|
|
9761
|
+
}
|
|
9747
9762
|
return _context3.abrupt("return", instance.request(originalConfig));
|
|
9748
|
-
case
|
|
9763
|
+
case 9:
|
|
9764
|
+
return _context3.abrupt("return", Promise.reject(error));
|
|
9765
|
+
case 10:
|
|
9749
9766
|
if (!(error.response.status === 400)) {
|
|
9750
|
-
_context3.next =
|
|
9767
|
+
_context3.next = 13;
|
|
9751
9768
|
break;
|
|
9752
9769
|
}
|
|
9753
9770
|
if (error.response.config.url.includes("/connect/token")) {
|
|
9754
9771
|
domainHost = window.location.hostname.split('.').slice(-2).join('.');
|
|
9755
9772
|
_jsCookie["default"].remove('access_token', {
|
|
9756
9773
|
path: '/',
|
|
9757
|
-
domain: domainHost
|
|
9774
|
+
domain: domainHost,
|
|
9775
|
+
secure: true
|
|
9758
9776
|
});
|
|
9759
9777
|
_jsCookie["default"].remove('refresh_token', {
|
|
9760
9778
|
path: '/',
|
|
9761
|
-
domain: domainHost
|
|
9779
|
+
domain: domainHost,
|
|
9780
|
+
secure: true
|
|
9762
9781
|
});
|
|
9763
9782
|
_jsCookie["default"].remove('expires_in', {
|
|
9764
9783
|
path: '/',
|
|
9765
|
-
domain: domainHost
|
|
9784
|
+
domain: domainHost,
|
|
9785
|
+
secure: true
|
|
9766
9786
|
});
|
|
9767
9787
|
}
|
|
9768
9788
|
return _context3.abrupt("return", Promise.reject(error));
|
|
9769
|
-
case
|
|
9789
|
+
case 13:
|
|
9770
9790
|
return _context3.abrupt("return", Promise.reject(error));
|
|
9771
|
-
case
|
|
9791
|
+
case 14:
|
|
9772
9792
|
case "end":
|
|
9773
9793
|
return _context3.stop();
|
|
9774
9794
|
}
|
|
@@ -10317,15 +10337,18 @@ var _authService = exports.authService = function authService() {
|
|
|
10317
10337
|
AuthUri = process.env.authorityUri;
|
|
10318
10338
|
_jsCookie["default"].remove('access_token', {
|
|
10319
10339
|
path: '/',
|
|
10320
|
-
domain: domainHost
|
|
10340
|
+
domain: domainHost,
|
|
10341
|
+
secure: true
|
|
10321
10342
|
});
|
|
10322
10343
|
_jsCookie["default"].remove('refresh_token', {
|
|
10323
10344
|
path: '/',
|
|
10324
|
-
domain: domainHost
|
|
10345
|
+
domain: domainHost,
|
|
10346
|
+
secure: true
|
|
10325
10347
|
});
|
|
10326
10348
|
_jsCookie["default"].remove('expires_in', {
|
|
10327
10349
|
path: '/',
|
|
10328
|
-
domain: domainHost
|
|
10350
|
+
domain: domainHost,
|
|
10351
|
+
secure: true
|
|
10329
10352
|
});
|
|
10330
10353
|
|
|
10331
10354
|
// destroyCookie({}, "access_token", {
|
package/package.json
CHANGED
|
@@ -17,18 +17,33 @@ import { HubConnectionBuilder, LogLevel, HttpTransportType } from '@microsoft/si
|
|
|
17
17
|
import Cookies from 'js-cookie';
|
|
18
18
|
|
|
19
19
|
// ============================================================================
|
|
20
|
-
//
|
|
20
|
+
// Auth Redirect Circuit Breaker
|
|
21
21
|
// ============================================================================
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
22
|
+
const AUTH_REDIRECT_KEY = 'authscape_redirect_count';
|
|
23
|
+
const AUTH_REDIRECT_TS_KEY = 'authscape_redirect_ts';
|
|
24
|
+
const AUTH_MAX_REDIRECTS = 3;
|
|
25
|
+
const AUTH_REDIRECT_WINDOW_MS = 30000; // 30 seconds
|
|
26
|
+
|
|
27
|
+
const checkAndIncrementRedirect = () => {
|
|
28
|
+
if (typeof window === 'undefined') return false;
|
|
29
|
+
const now = Date.now();
|
|
30
|
+
const storedTs = parseInt(sessionStorage.getItem(AUTH_REDIRECT_TS_KEY) || '0', 10);
|
|
31
|
+
let count = parseInt(sessionStorage.getItem(AUTH_REDIRECT_KEY) || '0', 10);
|
|
32
|
+
|
|
33
|
+
if (now - storedTs > AUTH_REDIRECT_WINDOW_MS) {
|
|
34
|
+
count = 0;
|
|
35
|
+
sessionStorage.setItem(AUTH_REDIRECT_TS_KEY, String(now));
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
count += 1;
|
|
39
|
+
sessionStorage.setItem(AUTH_REDIRECT_KEY, String(count));
|
|
40
|
+
return count <= AUTH_MAX_REDIRECTS;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const resetRedirectCounter = () => {
|
|
44
|
+
if (typeof window === 'undefined') return;
|
|
45
|
+
sessionStorage.removeItem(AUTH_REDIRECT_KEY);
|
|
46
|
+
sessionStorage.removeItem(AUTH_REDIRECT_TS_KEY);
|
|
32
47
|
};
|
|
33
48
|
|
|
34
49
|
// ============================================================================
|
|
@@ -484,9 +499,10 @@ export function AuthScapeApp({
|
|
|
484
499
|
const queryCodeUsed = useRef(null);
|
|
485
500
|
const ga4React = useRef(null);
|
|
486
501
|
const errorTrackingInitializedRef = useRef(false);
|
|
502
|
+
const loginRedirectPending = useRef(false);
|
|
487
503
|
|
|
488
504
|
const searchParams = useSearchParams();
|
|
489
|
-
const queryCode = searchParams
|
|
505
|
+
const queryCode = searchParams?.get("code") ?? null;
|
|
490
506
|
const pathname = usePathname();
|
|
491
507
|
|
|
492
508
|
const signInValidator = async (codeFromQuery) => {
|
|
@@ -500,7 +516,8 @@ export function AuthScapeApp({
|
|
|
500
516
|
const codeVerifier = window.localStorage.getItem("verifier");
|
|
501
517
|
if (!codeFromQuery || !codeVerifier) {
|
|
502
518
|
window.localStorage.clear();
|
|
503
|
-
|
|
519
|
+
setIsSigningIn(false);
|
|
520
|
+
setFrontEndLoadedState(true);
|
|
504
521
|
return;
|
|
505
522
|
}
|
|
506
523
|
|
|
@@ -526,25 +543,27 @@ export function AuthScapeApp({
|
|
|
526
543
|
|
|
527
544
|
window.localStorage.removeItem("verifier");
|
|
528
545
|
|
|
529
|
-
|
|
530
|
-
|
|
546
|
+
Cookies.set("access_token", response.data.access_token, {
|
|
547
|
+
expires: 365,
|
|
531
548
|
path: "/",
|
|
532
549
|
domain: domainHost,
|
|
533
550
|
secure: true,
|
|
534
551
|
});
|
|
535
|
-
|
|
536
|
-
|
|
552
|
+
Cookies.set("expires_in", String(response.data.expires_in), {
|
|
553
|
+
expires: 365,
|
|
537
554
|
path: "/",
|
|
538
555
|
domain: domainHost,
|
|
539
556
|
secure: true,
|
|
540
557
|
});
|
|
541
|
-
|
|
542
|
-
|
|
558
|
+
Cookies.set("refresh_token", response.data.refresh_token, {
|
|
559
|
+
expires: 365,
|
|
543
560
|
path: "/",
|
|
544
561
|
domain: domainHost,
|
|
545
562
|
secure: true,
|
|
546
563
|
});
|
|
547
564
|
|
|
565
|
+
resetRedirectCounter();
|
|
566
|
+
|
|
548
567
|
const redirectUri = window.localStorage.getItem("redirectUri") || "/";
|
|
549
568
|
window.localStorage.clear();
|
|
550
569
|
|
|
@@ -553,7 +572,7 @@ export function AuthScapeApp({
|
|
|
553
572
|
console.error("PKCE sign-in failed", exp);
|
|
554
573
|
window.localStorage.clear();
|
|
555
574
|
setIsSigningIn(false);
|
|
556
|
-
|
|
575
|
+
setFrontEndLoadedState(true);
|
|
557
576
|
}
|
|
558
577
|
};
|
|
559
578
|
|
|
@@ -653,8 +672,14 @@ export function AuthScapeApp({
|
|
|
653
672
|
enforceLoggedIn &&
|
|
654
673
|
pathname !== "/signin-oidc" &&
|
|
655
674
|
frontEndLoadedState &&
|
|
656
|
-
!signedInUserState
|
|
675
|
+
!signedInUserState &&
|
|
676
|
+
!loginRedirectPending.current
|
|
657
677
|
) {
|
|
678
|
+
if (!checkAndIncrementRedirect()) {
|
|
679
|
+
console.warn('[AuthScape] Auth redirect loop detected — halting redirects.');
|
|
680
|
+
return;
|
|
681
|
+
}
|
|
682
|
+
loginRedirectPending.current = true;
|
|
658
683
|
module.exports.authService().login();
|
|
659
684
|
}
|
|
660
685
|
}, [signedInUserState, enforceLoggedIn, frontEndLoadedState, pathname]);
|
|
@@ -3,19 +3,6 @@ import querystring from 'query-string';
|
|
|
3
3
|
import fileDownload from 'js-file-download';
|
|
4
4
|
import Cookies from 'js-cookie';
|
|
5
5
|
|
|
6
|
-
// Cookie utility function
|
|
7
|
-
const setCookie = (name, value, options = {}) => {
|
|
8
|
-
return new Promise((resolve) => {
|
|
9
|
-
let cookieString = `${name}=${value};`;
|
|
10
|
-
if (options.maxAge) cookieString += `max-age=${options.maxAge};`;
|
|
11
|
-
if (options.path) cookieString += `path=${options.path};`;
|
|
12
|
-
if (options.domain) cookieString += `domain=${options.domain};`;
|
|
13
|
-
if (options.secure) cookieString += `secure;`;
|
|
14
|
-
document.cookie = cookieString;
|
|
15
|
-
resolve();
|
|
16
|
-
});
|
|
17
|
-
};
|
|
18
|
-
|
|
19
6
|
const setupDefaultOptions = async (ctx = null) => {
|
|
20
7
|
let defaultOptions = {};
|
|
21
8
|
if (ctx == null) {
|
|
@@ -42,46 +29,58 @@ const setupDefaultOptions = async (ctx = null) => {
|
|
|
42
29
|
}
|
|
43
30
|
|
|
44
31
|
const RefreshToken = async (originalRequest, instance) => {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
let response = await instance.post(process.env.authorityUri + "/connect/token",
|
|
49
|
-
querystring.stringify({
|
|
50
|
-
grant_type: 'refresh_token',
|
|
51
|
-
client_id: process.env.client_id,
|
|
52
|
-
client_secret: process.env.client_secret,
|
|
53
|
-
refresh_token: refreshToken
|
|
54
|
-
}), {
|
|
55
|
-
headers: {
|
|
56
|
-
"Content-Type": "application/x-www-form-urlencoded",
|
|
57
|
-
"Authorization": "Bearer " + accessToken
|
|
58
|
-
}
|
|
59
|
-
});
|
|
32
|
+
try {
|
|
33
|
+
let accessToken = Cookies.get('access_token') || '';
|
|
34
|
+
let refreshToken = Cookies.get('refresh_token') || '';
|
|
60
35
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
36
|
+
if (!refreshToken) {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
64
39
|
|
|
65
|
-
await
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
40
|
+
let response = await instance.post(process.env.authorityUri + "/connect/token",
|
|
41
|
+
querystring.stringify({
|
|
42
|
+
grant_type: 'refresh_token',
|
|
43
|
+
client_id: process.env.client_id,
|
|
44
|
+
client_secret: process.env.client_secret,
|
|
45
|
+
refresh_token: refreshToken
|
|
46
|
+
}), {
|
|
47
|
+
headers: {
|
|
48
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
49
|
+
"Authorization": "Bearer " + accessToken
|
|
50
|
+
}
|
|
70
51
|
});
|
|
71
52
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
53
|
+
if (response != null && response.status == 200) {
|
|
54
|
+
let domainHost = window.location.hostname.split('.').slice(-2).join('.');
|
|
55
|
+
originalRequest.headers['Authorization'] = 'Bearer ' + response.data.access_token;
|
|
56
|
+
|
|
57
|
+
Cookies.set('access_token', response.data.access_token, {
|
|
58
|
+
expires: 365,
|
|
59
|
+
path: '/',
|
|
60
|
+
domain: domainHost,
|
|
61
|
+
secure: true
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
Cookies.set('expires_in', String(response.data.expires_in), {
|
|
65
|
+
expires: 365,
|
|
66
|
+
path: '/',
|
|
67
|
+
domain: domainHost,
|
|
68
|
+
secure: true
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
Cookies.set('refresh_token', response.data.refresh_token, {
|
|
72
|
+
expires: 365,
|
|
73
|
+
path: '/',
|
|
74
|
+
domain: domainHost,
|
|
75
|
+
secure: true
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
return true;
|
|
79
|
+
}
|
|
78
80
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
domain: domainHost,
|
|
83
|
-
secure: true
|
|
84
|
-
});
|
|
81
|
+
return false;
|
|
82
|
+
} catch (err) {
|
|
83
|
+
return false;
|
|
85
84
|
}
|
|
86
85
|
}
|
|
87
86
|
|
|
@@ -107,16 +106,19 @@ export const apiService = (ctx = null) => {
|
|
|
107
106
|
if (error.response) {
|
|
108
107
|
if (error.response.status === 401 && !originalConfig._retry) {
|
|
109
108
|
originalConfig._retry = true;
|
|
110
|
-
await RefreshToken(originalConfig, instance);
|
|
111
|
-
|
|
109
|
+
const refreshed = await RefreshToken(originalConfig, instance);
|
|
110
|
+
if (refreshed) {
|
|
111
|
+
return instance.request(originalConfig);
|
|
112
|
+
}
|
|
113
|
+
return Promise.reject(error);
|
|
112
114
|
}
|
|
113
115
|
|
|
114
116
|
if (error.response.status === 400) {
|
|
115
117
|
if (error.response.config.url.includes("/connect/token")) {
|
|
116
118
|
let domainHost = window.location.hostname.split('.').slice(-2).join('.');
|
|
117
|
-
Cookies.remove('access_token', { path: '/', domain: domainHost });
|
|
118
|
-
Cookies.remove('refresh_token', { path: '/', domain: domainHost });
|
|
119
|
-
Cookies.remove('expires_in', { path: '/', domain: domainHost });
|
|
119
|
+
Cookies.remove('access_token', { path: '/', domain: domainHost, secure: true });
|
|
120
|
+
Cookies.remove('refresh_token', { path: '/', domain: domainHost, secure: true });
|
|
121
|
+
Cookies.remove('expires_in', { path: '/', domain: domainHost, secure: true });
|
|
120
122
|
}
|
|
121
123
|
return Promise.reject(error);
|
|
122
124
|
}
|
|
@@ -127,9 +127,9 @@ export const authService = () => {
|
|
|
127
127
|
let AuthUri = process.env.authorityUri;
|
|
128
128
|
|
|
129
129
|
|
|
130
|
-
Cookies.remove('access_token', { path: '/', domain: domainHost });
|
|
131
|
-
Cookies.remove('refresh_token', { path: '/', domain: domainHost });
|
|
132
|
-
Cookies.remove('expires_in', { path: '/', domain: domainHost });
|
|
130
|
+
Cookies.remove('access_token', { path: '/', domain: domainHost, secure: true });
|
|
131
|
+
Cookies.remove('refresh_token', { path: '/', domain: domainHost, secure: true });
|
|
132
|
+
Cookies.remove('expires_in', { path: '/', domain: domainHost, secure: true });
|
|
133
133
|
|
|
134
134
|
|
|
135
135
|
// destroyCookie({}, "access_token", {
|