@nibssplc/cams-sdk-react 1.0.0-rc.132 → 1.0.0-rc.134

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/index.cjs.js CHANGED
@@ -415,15 +415,42 @@ function useCAMSMSALAuth(options) {
415
415
  var optStorageKey = options.storageKey, optScopes = options.scopes, prompt = options.prompt, appCode = options.appCode, ValidateUserEndpoint = options.ValidateUserEndpoint, _a = options.activeCookiePeriod, activeCookiePeriod = _a === void 0 ? 1 : _a, _b = options.DisableCAMSUserProfileValidation, DisableCAMSUserProfileValidation = _b === void 0 ? false : _b;
416
416
  var storageKey = optStorageKey || "CAMS-MSAL-AUTH-SDK";
417
417
  var _c = msalReact.useMsal(), instance = _c.instance, inProgress = _c.inProgress, accounts = _c.accounts;
418
- var account = msalReact.useAccount(accounts[0] || {});
418
+ msalReact.useAccount(accounts[0] || {});
419
+ var isTokenValid = function (token) {
420
+ try {
421
+ var payload = JSON.parse(atob(token.split(".")[1]));
422
+ return payload.exp * 1000 > Date.now();
423
+ }
424
+ catch (_a) {
425
+ return false;
426
+ }
427
+ };
428
+ var readFromStorage = function () {
429
+ var _a, _b, _c;
430
+ if (typeof window === "undefined")
431
+ return { accessToken: "", idToken: "", email: "" };
432
+ try {
433
+ var raw = localStorage.getItem(storageKey);
434
+ if (!raw)
435
+ return { accessToken: "", idToken: "", email: "" };
436
+ var parsed = JSON.parse(raw);
437
+ var token = (_a = parsed.accessToken) !== null && _a !== void 0 ? _a : "";
438
+ return isTokenValid(token)
439
+ ? { accessToken: token, idToken: (_b = parsed.idToken) !== null && _b !== void 0 ? _b : "", email: (_c = parsed.email) !== null && _c !== void 0 ? _c : "" }
440
+ : { accessToken: "", idToken: "", email: "" };
441
+ }
442
+ catch (_d) {
443
+ return { accessToken: "", idToken: "", email: "" };
444
+ }
445
+ };
419
446
  var _d = React.useState(null), error = _d[0], setError = _d[1];
420
- var _e = React.useState(""), idToken = _e[0], setIdToken = _e[1];
421
- var _f = React.useState(""), accessToken = _f[0], setAccessToken = _f[1];
422
- var _g = React.useState(""), email = _g[0], setEmail = _g[1];
447
+ var _e = React.useState(function () { return readFromStorage().idToken; }), idToken = _e[0], setIdToken = _e[1];
448
+ var _f = React.useState(function () { return readFromStorage().accessToken; }), accessToken = _f[0], setAccessToken = _f[1];
449
+ var _g = React.useState(function () { return readFromStorage().email; }), email = _g[0], setEmail = _g[1];
423
450
  var _h = React.useState(false), requiresMFA = _h[0], setRequiresMFA = _h[1];
424
451
  var _j = React.useState(false), isFetchingMFAConfig = _j[0], setIsFetchingMFAConfig = _j[1];
425
452
  var isLoading = inProgress !== msalBrowser.InteractionStatus.None || isFetchingMFAConfig;
426
- var isAuthenticated = !!account && !!accessToken && !requiresMFA;
453
+ var isAuthenticated = !!accessToken && !requiresMFA;
427
454
  var scopes = optScopes || ["openid", "profile", "email"];
428
455
  var login = React.useCallback(function () { return __awaiter$1(_this, void 0, void 0, function () {
429
456
  var response, authenticator, email_1, userConfig, camsError, error_1, err_1, camsError_1, camsError;
@@ -452,6 +479,7 @@ function useCAMSMSALAuth(options) {
452
479
  setIdToken(response.idToken);
453
480
  setEmail(email_1);
454
481
  setRequiresMFA(false);
482
+ localStorage.setItem(storageKey, JSON.stringify({ accessToken: response.accessToken, idToken: response.idToken, email: email_1, appCode: appCode }));
455
483
  camsSdk.Logger.info("CAMS User Profile Validation Disabled. Skipping MFA config fetch.");
456
484
  return [3 /*break*/, 7];
457
485
  case 3:
@@ -478,6 +506,7 @@ function useCAMSMSALAuth(options) {
478
506
  setIdToken(response.idToken);
479
507
  setEmail(userConfig.userInfo.email);
480
508
  setRequiresMFA(userConfig.userInfo.isMFAEnabled);
509
+ localStorage.setItem(storageKey, JSON.stringify({ accessToken: response.accessToken, idToken: response.idToken, email: userConfig.userInfo.email, appCode: appCode }));
481
510
  }
482
511
  else {
483
512
  camsError = new camsSdk.CAMSError(camsSdk.CAMSErrorType.API_VALIDATION_ERROR, "Login failed: " + userConfig.message);
@@ -575,6 +604,8 @@ function useCAMSMSALAuth(options) {
575
604
  setEmail("");
576
605
  setError(null);
577
606
  setRequiresMFA(false);
607
+ if (typeof window !== "undefined")
608
+ localStorage.removeItem(storageKey);
578
609
  }
579
610
  catch (err) {
580
611
  camsError = new camsSdk.CAMSError(camsSdk.CAMSErrorType.API_VALIDATION_ERROR, "Logout failed: " + err);
@@ -1777,45 +1808,44 @@ var MFAGate = function (_a) {
1777
1808
  }
1778
1809
  return parsed.data;
1779
1810
  }, [MFAEndpoints]);
1780
- // Extract the specific values we need from context for dependencies
1811
+ // Extract primitives from context to avoid object reference churn in deps
1781
1812
  var contextRequiresMFA = "requiresMFA" in context ? context.requiresMFA : false;
1782
1813
  var contextAccessToken = "accessToken" in context ? context.accessToken : "";
1814
+ var contextIdToken = "idToken" in context ? context.idToken : "";
1815
+ var contextHasUser = !!context.user;
1816
+ var contextIsLoading = context.isLoading;
1817
+ // Use refs so callbacks never cause effect/useCallback to re-run
1818
+ var onAuthSuccessRef = React.useRef(onAuthSuccess);
1819
+ var contextOnAuthSuccessRef = React.useRef("onAuthSuccess" in context ? context.onAuthSuccess : undefined);
1820
+ React.useEffect(function () { onAuthSuccessRef.current = onAuthSuccess; }, [onAuthSuccess]);
1821
+ React.useEffect(function () { contextOnAuthSuccessRef.current = "onAuthSuccess" in context ? context.onAuthSuccess : undefined; });
1783
1822
  var fireOnAuthSuccess = React.useCallback(function (tokens) { return __awaiter$1(void 0, void 0, void 0, function () {
1784
- var _a;
1785
- return __generator$1(this, function (_b) {
1786
- switch (_b.label) {
1823
+ var _a, _b;
1824
+ return __generator$1(this, function (_c) {
1825
+ switch (_c.label) {
1787
1826
  case 0: return [4 /*yield*/, Promise.all([
1788
- onAuthSuccess === null || onAuthSuccess === void 0 ? void 0 : onAuthSuccess(tokens),
1789
- "onAuthSuccess" in context ? (_a = context.onAuthSuccess) === null || _a === void 0 ? void 0 : _a.call(context, tokens) : undefined,
1827
+ (_a = onAuthSuccessRef.current) === null || _a === void 0 ? void 0 : _a.call(onAuthSuccessRef, tokens),
1828
+ (_b = contextOnAuthSuccessRef.current) === null || _b === void 0 ? void 0 : _b.call(contextOnAuthSuccessRef, tokens),
1790
1829
  ])];
1791
1830
  case 1:
1792
- _b.sent();
1831
+ _c.sent();
1793
1832
  return [2 /*return*/];
1794
1833
  }
1795
1834
  });
1796
- }); }, [context, onAuthSuccess]);
1835
+ }); }, [] // stable — reads from refs
1836
+ );
1797
1837
  var handleComplete = React.useCallback(function (success) { return __awaiter$1(void 0, void 0, void 0, function () {
1798
- var accessToken, idToken;
1799
1838
  return __generator$1(this, function (_a) {
1800
- switch (_a.label) {
1801
- case 0:
1802
- if (!success) return [3 /*break*/, 2];
1803
- accessToken = "accessToken" in context ? context.accessToken : "";
1804
- idToken = "idToken" in context ? context.idToken : "";
1805
- camsSdk.Logger.info("MFA Authentication Successful");
1806
- setAuthState("Completing");
1807
- return [4 /*yield*/, fireOnAuthSuccess({ accessToken: accessToken, idToken: idToken })];
1808
- case 1:
1809
- _a.sent();
1810
- setAuthState("Authenticated");
1811
- return [3 /*break*/, 3];
1812
- case 2:
1813
- camsSdk.Logger.error("MFA Authentication Failed");
1814
- _a.label = 3;
1815
- case 3: return [2 /*return*/];
1839
+ if (success) {
1840
+ camsSdk.Logger.info("MFA Authentication Successful");
1841
+ setAuthState("Completing");
1842
+ }
1843
+ else {
1844
+ camsSdk.Logger.error("MFA Authentication Failed");
1816
1845
  }
1846
+ return [2 /*return*/];
1817
1847
  });
1818
- }); }, [context, fireOnAuthSuccess]);
1848
+ }); }, []);
1819
1849
  var handleAuthFailed = React.useCallback(function () { return __awaiter$1(void 0, void 0, void 0, function () {
1820
1850
  var _a;
1821
1851
  return __generator$1(this, function (_b) {
@@ -1835,11 +1865,11 @@ var MFAGate = function (_a) {
1835
1865
  });
1836
1866
  }); }, [context, onAuthError]);
1837
1867
  React.useEffect(function () {
1838
- if (context.isLoading) {
1868
+ if (contextIsLoading) {
1839
1869
  setAuthState("Loading");
1840
1870
  return;
1841
1871
  }
1842
- if (context.user) {
1872
+ if (contextHasUser) {
1843
1873
  setAuthState("Authenticated");
1844
1874
  return;
1845
1875
  }
@@ -1850,21 +1880,32 @@ var MFAGate = function (_a) {
1850
1880
  var shouldRequireMFA = requiresMFA !== null && requiresMFA !== void 0 ? requiresMFA : contextRequiresMFA;
1851
1881
  if (shouldRequireMFA) {
1852
1882
  setAuthState("MFA_Required");
1883
+ return;
1853
1884
  }
1854
- else {
1855
- var accessToken = "accessToken" in context ? context.accessToken : "";
1856
- var idToken = "idToken" in context ? context.idToken : "";
1857
- setAuthState("Completing");
1858
- fireOnAuthSuccess({ accessToken: accessToken, idToken: idToken }).then(function () { return setAuthState("Authenticated"); });
1859
- }
1885
+ // Only fire once — guard against re-running while already completing/authenticated
1886
+ setAuthState(function (prev) {
1887
+ if (prev === "Completing" || prev === "Authenticated")
1888
+ return prev;
1889
+ return "Completing";
1890
+ });
1860
1891
  }, [
1861
- context.isLoading,
1862
- context.user,
1892
+ contextIsLoading,
1893
+ contextHasUser,
1863
1894
  contextRequiresMFA,
1864
1895
  contextAccessToken,
1865
1896
  requiresMFA,
1866
- fireOnAuthSuccess,
1867
1897
  ]);
1898
+ // Separate effect: fire callback and advance to Authenticated only when Completing
1899
+ React.useEffect(function () {
1900
+ if (authState !== "Completing")
1901
+ return;
1902
+ var cancelled = false;
1903
+ fireOnAuthSuccess({ accessToken: contextAccessToken, idToken: contextIdToken }).then(function () {
1904
+ if (!cancelled)
1905
+ setAuthState("Authenticated");
1906
+ });
1907
+ return function () { cancelled = true; };
1908
+ }, [authState, contextAccessToken, contextIdToken, fireOnAuthSuccess]);
1868
1909
  if (useADLogin && !CredentialsAuthEndpoint)
1869
1910
  return jsxRuntime.jsx(ErrorFallback, { message: "Invalid AD Login Configuration." });
1870
1911
  if (!ValidatedMFAEndpoints)