@nibssplc/cams-sdk-react 0.0.1-beta.75 → 0.0.1-beta.76

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.
@@ -0,0 +1,5 @@
1
+ interface ErrorFallbackProps {
2
+ message: string;
3
+ }
4
+ declare const ErrorFallback: ({ message }: ErrorFallbackProps) => import("react/jsx-runtime").JSX.Element;
5
+ export default ErrorFallback;
@@ -4,5 +4,5 @@ interface MFAGateProps {
4
4
  loginComponent?: React.ComponentType;
5
5
  MFAEndpoint?: string;
6
6
  }
7
- declare const MFAGate: ({ children, fallback, loginComponent: LoginComponent, MFAEndpoint, }: MFAGateProps) => string | number | bigint | true | Iterable<import("react").ReactNode> | Promise<string | number | bigint | boolean | import("react").ReactPortal | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<import("react").ReactNode> | null | undefined> | import("react/jsx-runtime").JSX.Element;
7
+ declare const MFAGate: ({ children, fallback, loginComponent: LoginComponent, MFAEndpoint, }: MFAGateProps) => string | number | bigint | boolean | Iterable<import("react").ReactNode> | Promise<string | number | bigint | boolean | import("react").ReactPortal | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<import("react").ReactNode> | null | undefined> | import("react/jsx-runtime").JSX.Element | null;
8
8
  export default MFAGate;
@@ -23,7 +23,8 @@ export interface UseCAMSMSALAuthReturn {
23
23
  appCode: string;
24
24
  mfaAuthenticator: CAMSMFAAuthenticator | null;
25
25
  requiresMFA: boolean;
26
- completeMFA: (code: string, type: "EmailOTP" | "AuthenticatorCode") => Promise<MFAResponse>;
26
+ completeMFA: (data: UserValidatedResponse) => Promise<MFAResponse>;
27
+ setRequiresMFA: React.Dispatch<React.SetStateAction<boolean>>;
27
28
  sendEmailOTP: () => Promise<boolean>;
28
29
  }
29
30
  export declare function useCAMSMSALAuth(options: UseCAMSMSALAuthOptions): UseCAMSMSALAuthReturn;
package/dist/index.cjs.js CHANGED
@@ -256,11 +256,21 @@ function useCAMSAuth(options) {
256
256
  };
257
257
  }
258
258
 
259
+ var CAMSContext$1 = React.createContext(null);
260
+ function useCAMSContext$1() {
261
+ var context = React.useContext(CAMSContext$1);
262
+ if (!context) {
263
+ throw new Error("useCAMSContext must be used within a UnifiedCAMSProvider");
264
+ }
265
+ return context;
266
+ }
267
+
259
268
  function useCAMSMSALAuth(options) {
260
269
  var _this = this;
261
270
  var storageKey = options.storageKey || "CAMS-MSAL-AUTH-SDK";
262
271
  var _a = msalReact.useMsal(), instance = _a.instance, inProgress = _a.inProgress, accounts = _a.accounts;
263
272
  var account = msalReact.useAccount(accounts[0] || {});
273
+ var setUserProfile = useCAMSContext$1().setUserProfile;
264
274
  var _b = React.useState(null), error = _b[0], setError = _b[1];
265
275
  var _c = React.useState(""), idToken = _c[0], setIdToken = _c[1];
266
276
  var _d = React.useState(""), accessToken = _d[0], setAccessToken = _d[1];
@@ -409,50 +419,41 @@ function useCAMSMSALAuth(options) {
409
419
  }
410
420
  });
411
421
  }); }, [instance, scopes, options]);
412
- var completeMFA = React.useCallback(function (code, type) { return __awaiter(_this, void 0, void 0, function () {
413
- var mfaResponse, error_1;
422
+ var completeMFA = React.useCallback(function (data) { return __awaiter(_this, void 0, void 0, function () {
414
423
  return __generator(this, function (_a) {
415
- switch (_a.label) {
416
- case 0:
417
- if (!mfaAuthenticator) {
418
- throw new camsSdk.CAMSError(camsSdk.CAMSErrorType.API_VALIDATION_ERROR, "MFA Authenticator not initialized");
419
- }
420
- _a.label = 1;
421
- case 1:
422
- _a.trys.push([1, 3, , 4]);
423
- return [4 /*yield*/, mfaAuthenticator.verifyOTP(code, type)];
424
- case 2:
425
- mfaResponse = _a.sent();
426
- if (mfaResponse.isAuthenticated) {
427
- // Update storage with complete authentication BEFORE setting state
428
- if (typeof window !== "undefined") {
429
- localStorage.setItem(storageKey, JSON.stringify({
430
- isAuthenticated: true,
431
- requiresMFA: false,
432
- accessToken: accessToken,
433
- idToken: idToken,
434
- userProfile: mfaResponse,
435
- }));
436
- camsSdk.Logger.info("MFA completed successfully, storage updated", {
437
- accessToken: accessToken,
438
- idToken: idToken,
439
- isAuthenticated: isAuthenticated,
440
- requiresMFA: requiresMFA,
441
- });
442
- }
443
- // Set requiresMFA to false after storage update
444
- setRequiresMFA(false);
445
- camsSdk.Logger.debug("MFA completed successfully, requiresMFA set to false");
446
- }
447
- return [2 /*return*/, mfaResponse];
448
- case 3:
449
- error_1 = _a.sent();
450
- setError(error_1);
451
- throw error_1;
452
- case 4: return [2 /*return*/];
424
+ if (!mfaAuthenticator) {
425
+ throw new camsSdk.CAMSError(camsSdk.CAMSErrorType.API_VALIDATION_ERROR, "MFA Authenticator not initialized");
426
+ }
427
+ camsSdk.Logger.info("Completed MFA.. Setting State");
428
+ try {
429
+ // Update storage with complete authentication BEFORE setting state
430
+ if (typeof window !== "undefined") {
431
+ localStorage.setItem(storageKey, JSON.stringify({
432
+ isAuthenticated: true,
433
+ requiresMFA: false,
434
+ accessToken: accessToken,
435
+ idToken: idToken,
436
+ }));
437
+ setUserProfile({ type: "AUTH_SUCCESS", userProfile: __assign({}, data) });
438
+ setRequiresMFA(false);
439
+ // Set requiresMFA to false after storage update
440
+ camsSdk.Logger.debug("MFA completed successfully, storage updated", {
441
+ accessToken: accessToken,
442
+ idToken: idToken,
443
+ isAuthenticated: true,
444
+ requiresMFA: false,
445
+ });
446
+ }
447
+ camsSdk.Logger.debug("MFA completed successfully, requiresMFA set to false");
448
+ return [2 /*return*/, data];
449
+ }
450
+ catch (error) {
451
+ setError(error);
452
+ throw error;
453
453
  }
454
+ return [2 /*return*/];
454
455
  });
455
- }); }, [mfaAuthenticator, accessToken, idToken, storageKey, requiresMFA]);
456
+ }); }, [mfaAuthenticator, accessToken, idToken, storageKey]);
456
457
  var sendEmailOTP = React.useCallback(function () { return __awaiter(_this, void 0, void 0, function () {
457
458
  return __generator(this, function (_a) {
458
459
  switch (_a.label) {
@@ -507,6 +508,7 @@ function useCAMSMSALAuth(options) {
507
508
  requiresMFA: requiresMFA,
508
509
  completeMFA: completeMFA,
509
510
  sendEmailOTP: sendEmailOTP,
511
+ setRequiresMFA: setRequiresMFA,
510
512
  };
511
513
  }
512
514
 
@@ -979,9 +981,9 @@ if (process.env.NODE_ENV === 'production') {
979
981
 
980
982
  var jsxRuntimeExports = jsxRuntime.exports;
981
983
 
982
- var CAMSContext$1 = React.createContext(null);
983
- function useCAMSContext$1() {
984
- var context = React.useContext(CAMSContext$1);
984
+ var CAMSContext = React.createContext(null);
985
+ function useCAMSContext() {
986
+ var context = React.useContext(CAMSContext);
985
987
  if (!context) {
986
988
  throw new Error('useCAMSContext must be used within a CAMSProvider');
987
989
  }
@@ -990,7 +992,7 @@ function useCAMSContext$1() {
990
992
 
991
993
  function ProtectedRoute(_a) {
992
994
  var children = _a.children, fallback = _a.fallback, redirectTo = _a.redirectTo;
993
- var _b = useCAMSContext$1(), isAuthenticated = _b.isAuthenticated, isLoading = _b.isLoading;
995
+ var _b = useCAMSContext(), isAuthenticated = _b.isAuthenticated, isLoading = _b.isLoading;
994
996
  if (isLoading) {
995
997
  return fallback || jsxRuntimeExports.jsx("div", { children: "Loading..." });
996
998
  }
@@ -1129,15 +1131,6 @@ var ClientOnly = function (_a) {
1129
1131
  return jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children: children });
1130
1132
  };
1131
1133
 
1132
- var CAMSContext = React.createContext(null);
1133
- function useCAMSContext() {
1134
- var context = React.useContext(CAMSContext);
1135
- if (!context) {
1136
- throw new Error("useCAMSContext must be used within a UnifiedCAMSProvider");
1137
- }
1138
- return context;
1139
- }
1140
-
1141
1134
  var GuidSchema = z.z.uuid("appCode must be a valid GUID");
1142
1135
  var setCookie = function (name, value, days) {
1143
1136
  var expires = new Date(Date.now() + days * 24 * 60 * 60 * 1000).toUTCString();
@@ -1249,7 +1242,7 @@ function CAMSProviderCore(props) {
1249
1242
  var value = React.useMemo(function () {
1250
1243
  return (__assign(__assign({}, auth), { logout: enhancedLogout, userProfile: userProfile, setUserProfile: setUserProfile, authMode: mode }));
1251
1244
  }, [auth, userProfile, mode]);
1252
- return jsxRuntimeExports.jsx(CAMSContext.Provider, { value: value, children: children });
1245
+ return jsxRuntimeExports.jsx(CAMSContext$1.Provider, { value: value, children: children });
1253
1246
  }
1254
1247
  function UnifiedCAMSProvider(props) {
1255
1248
  // Validate appCode is a valid GUID
@@ -1766,8 +1759,8 @@ var MFAOptions = function (_a) {
1766
1759
  var _d = React.useState(false), otpVisible = _d[0], setOtpVisible = _d[1];
1767
1760
  var _e = React.useState(false), showSuccessAnimation = _e[0], setShowSuccessAnimation = _e[1];
1768
1761
  var _f = React.useState(null), authType = _f[0], setAuthType = _f[1];
1769
- var _g = React.useState(""), lastOTPCode = _g[0], setLastOTPCode = _g[1];
1770
- var context = useCAMSContext();
1762
+ var _g = React.useState(""); _g[0]; var setLastOTPCode = _g[1];
1763
+ var context = useCAMSContext$1();
1771
1764
  var _h = context.authMode === "MSAL" && "sendEmailOTP" in context
1772
1765
  ? context
1773
1766
  : { sendEmailOTP: null, completeMFA: null, logout: function () { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) {
@@ -1783,10 +1776,12 @@ var MFAOptions = function (_a) {
1783
1776
  authenticationType: authType,
1784
1777
  MFAEndpoint: MFAEndpoint,
1785
1778
  onAuthComplete: function (state, data) {
1779
+ console.log("Completed Auth. Handling MFA", state);
1786
1780
  if (state) {
1787
1781
  // Call completeMFA to update context state
1788
- if (completeMFA && authType && lastOTPCode) {
1789
- completeMFA(lastOTPCode, authType).catch(function (error) {
1782
+ if (completeMFA && data) {
1783
+ console.log("IN Complete MFA Block. Handling MFA", data);
1784
+ completeMFA(data).catch(function (error) {
1790
1785
  console.error("Failed to complete MFA:", error);
1791
1786
  });
1792
1787
  }
@@ -1802,7 +1797,7 @@ var MFAOptions = function (_a) {
1802
1797
  onAuthFailed === null || onAuthFailed === void 0 ? void 0 : onAuthFailed();
1803
1798
  onComplete === null || onComplete === void 0 ? void 0 : onComplete(false);
1804
1799
  });
1805
- }, 1000);
1800
+ }, 3000);
1806
1801
  }
1807
1802
  }
1808
1803
  },
@@ -1874,7 +1869,7 @@ var AuthLogo = "data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2
1874
1869
  var MicrosoftLogo = "data:image/svg+xml,%3Csvg%20width%3D%2225%22%20height%3D%2225%22%20viewBox%3D%220%200%2025%2025%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cg%20id%3D%22microsoft_svgrepo.com%22%3E%3Cpath%20id%3D%22Vector%22%20d%3D%22M20.75%2013.25H13.25V20.75H20.75V13.25Z%22%20fill%3D%22%23FEBA08%22%2F%3E%3Cpath%20id%3D%22Vector_2%22%20d%3D%22M11.75%2013.25H4.25V20.75H11.75V13.25Z%22%20fill%3D%22%2305A6F0%22%2F%3E%3Cpath%20id%3D%22Vector_3%22%20d%3D%22M20.75%204.25H13.25V11.75H20.75V4.25Z%22%20fill%3D%22%2380BC06%22%2F%3E%3Cpath%20id%3D%22Vector_4%22%20d%3D%22M11.75%204.25H4.25V11.75H11.75V4.25Z%22%20fill%3D%22%23F25325%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E";
1875
1870
 
1876
1871
  var DefaultLoginPage = function () {
1877
- var context = useCAMSContext();
1872
+ var context = useCAMSContext$1();
1878
1873
  var login = context.login, isLoading = context.isLoading, authMode = context.authMode;
1879
1874
  var handleLogin = function () {
1880
1875
  if (authMode === "MSAL") {
@@ -1902,41 +1897,49 @@ var DefaultLoginPage = function () {
1902
1897
  className: "w-full flex items-center justify-center cursor-pointer bg-[#506f4a] hover:bg-[#506f4a] rounded-lg border border-transparent px-5 py-8 text-base font-medium transition-colors duration-250", onClick: handleLogin, disabled: isLoading, children: [jsxRuntimeExports.jsx("img", { src: MicrosoftLogo, alt: "Microsoft Logo", width: 35, height: 35 }), jsxRuntimeExports.jsx("span", { children: isLoading ? 'Logging in...' : "Sign in with Microsoft" })] }) }), jsxRuntimeExports.jsxs(CardFooter, { className: "flex items-center justify-center mt-6 space-x-2 text-gray-400 text-sm", children: [jsxRuntimeExports.jsx(lucideReact.ShieldCheck, { className: "w-4 h-4 text-[#506f4a] pulse-glow" }), jsxRuntimeExports.jsx("span", { children: "Powered By NIBSS" })] })] }) }) }, "landing") }));
1903
1898
  };
1904
1899
 
1900
+ var ErrorFallback = function (_a) {
1901
+ var message = _a.message;
1902
+ return (jsxRuntimeExports.jsx("div", { className: "flex items-center justify-center min-h-screen bg-gray-50", children: jsxRuntimeExports.jsxs("div", { className: "bg-white p-6 rounded-lg shadow-lg border border-red-200 max-w-md", children: [jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3 mb-2", children: [jsxRuntimeExports.jsx("svg", { className: "w-6 h-6 text-red-500", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: jsxRuntimeExports.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" }) }), jsxRuntimeExports.jsx("h2", { className: "text-lg font-semibold text-gray-900", children: "Configuration Error" })] }), jsxRuntimeExports.jsx("p", { className: "text-red-600", children: message })] }) }));
1903
+ };
1904
+
1905
1905
  var MFAEndpointUrlSchema = z.url("MFAEndpoint must be a valid URL");
1906
1906
  var MFAGate = function (_a) {
1907
- var children = _a.children, fallback = _a.fallback, LoginComponent = _a.loginComponent, MFAEndpoint = _a.MFAEndpoint;
1908
- var context = useCAMSContext();
1909
- var urlValidation = MFAEndpointUrlSchema.safeParse(MFAEndpoint);
1910
- if (!urlValidation.success) {
1911
- throw new Error("Invalid MFAEndpoint: ".concat(urlValidation.error.issues[0].message));
1912
- }
1907
+ var children = _a.children, _b = _a.fallback, fallback = _b === void 0 ? jsxRuntimeExports.jsx(LoadingSpinner, {}) : _b, _c = _a.loginComponent, LoginComponent = _c === void 0 ? DefaultLoginPage : _c, MFAEndpoint = _a.MFAEndpoint;
1908
+ var context = useCAMSContext$1();
1909
+ var validatedMFAEndpoint = React.useMemo(function () {
1910
+ var parsed = MFAEndpointUrlSchema.safeParse(MFAEndpoint);
1911
+ if (!parsed.success) {
1912
+ camsSdk.Logger.error("Invalid MFAEndpoint", parsed.error);
1913
+ return null;
1914
+ }
1915
+ return parsed.data;
1916
+ }, [MFAEndpoint]);
1917
+ var handleComplete = React.useCallback(function (success) {
1918
+ if (!success)
1919
+ camsSdk.Logger.error("MFA authentication failed");
1920
+ }, []);
1921
+ var handleAuthFailed = React.useCallback(function () { return __awaiter(void 0, void 0, void 0, function () {
1922
+ return __generator(this, function (_a) {
1923
+ switch (_a.label) {
1924
+ case 0: return [4 /*yield*/, context.logout()];
1925
+ case 1:
1926
+ _a.sent();
1927
+ return [2 /*return*/];
1928
+ }
1929
+ });
1930
+ }); }, [context.logout]);
1913
1931
  camsSdk.Logger.debug("MFA Endpoint >>>", { MFAEndpoint: MFAEndpoint });
1914
- // Only apply MFA gate for MSAL mode
1915
- if (context.authMode !== "MSAL") {
1932
+ if (!validatedMFAEndpoint)
1933
+ return jsxRuntimeExports.jsx(ErrorFallback, { message: "Invalid MFA configuration." });
1934
+ if (context.authMode !== "MSAL")
1916
1935
  return jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children: children });
1936
+ if (context.isLoading)
1937
+ return fallback;
1938
+ if (context.requiresMFA) {
1939
+ return (jsxRuntimeExports.jsx(MFAOptions, { MFAEndpoint: validatedMFAEndpoint, onComplete: handleComplete, onAuthFailed: handleAuthFailed }));
1917
1940
  }
1918
- var requiresMFA = context.requiresMFA, isAuthenticated = context.isAuthenticated, isLoading = context.isLoading;
1919
- if (isLoading) {
1920
- return fallback || jsxRuntimeExports.jsx("div", { className: "flex h-dvh items-center justify-center", children: "Loading..." });
1921
- }
1922
- if (requiresMFA) {
1923
- return (jsxRuntimeExports.jsx(MFAOptions, { MFAEndpoint: MFAEndpoint, onComplete: function (success) {
1924
- if (!success) {
1925
- console.error("MFA authentication failed");
1926
- }
1927
- }, onAuthFailed: function () { return __awaiter(void 0, void 0, void 0, function () {
1928
- return __generator(this, function (_a) {
1929
- switch (_a.label) {
1930
- case 0: return [4 /*yield*/, context.logout()];
1931
- case 1:
1932
- _a.sent();
1933
- return [2 /*return*/];
1934
- }
1935
- });
1936
- }); } }));
1937
- }
1938
- if (!isAuthenticated) {
1939
- return LoginComponent ? jsxRuntimeExports.jsx(LoginComponent, {}) : jsxRuntimeExports.jsx(DefaultLoginPage, {});
1941
+ if (!context.isAuthenticated) {
1942
+ return jsxRuntimeExports.jsx(LoginComponent, {});
1940
1943
  }
1941
1944
  return jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children: children });
1942
1945
  };
@@ -1950,7 +1953,7 @@ exports.MFAOptions = MFAOptions;
1950
1953
  exports.ProtectedRoute = ProtectedRoute;
1951
1954
  exports.UnifiedCAMSProvider = UnifiedCAMSProvider;
1952
1955
  exports.useCAMSAuth = useCAMSAuth;
1953
- exports.useCAMSContext = useCAMSContext;
1956
+ exports.useCAMSContext = useCAMSContext$1;
1954
1957
  exports.useCAMSMSALAuth = useCAMSMSALAuth;
1955
1958
  exports.useCAMSMSALContext = useCAMSMSALContext;
1956
1959
  exports.useCAMSPopupAuth = useCAMSPopupAuth;