@nibssplc/cams-sdk-react 0.0.1-beta.63 → 0.0.1-beta.65

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.esm.js CHANGED
@@ -1210,7 +1210,7 @@ function CAMSProviderCore(props) {
1210
1210
  }, [mode, auth, userProfile]);
1211
1211
  var value = useMemo(function () {
1212
1212
  return (__assign(__assign({}, auth), { logout: enhancedLogout, userProfile: userProfile, setUserProfile: setUserProfile, authMode: mode }));
1213
- }, [auth, userProfile, mode]);
1213
+ }, [auth, userProfile, mode, mode === "MSAL" && "requiresMFA" in auth ? auth.requiresMFA : null]);
1214
1214
  return jsxRuntimeExports.jsx(CAMSContext.Provider, { value: value, children: children });
1215
1215
  }
1216
1216
  function UnifiedCAMSProvider(props) {
@@ -1572,8 +1572,48 @@ var AuthSuccessAnimation = function (_a) {
1572
1572
  return (jsxRuntimeExports.jsxs(motion.div, { initial: { opacity: 0, scale: 0.8 }, animate: { opacity: 1, scale: 1 }, transition: { duration: 0.5, ease: "easeOut" }, className: "flex flex-col items-center justify-center space-y-6 p-8", onAnimationComplete: onComplete, children: [jsxRuntimeExports.jsx(motion.div, { initial: { scale: 0 }, animate: { scale: 1 }, transition: { delay: 0.2, duration: 0.6, type: "spring", stiffness: 200 }, children: jsxRuntimeExports.jsx(CheckCircle, { className: "w-20 h-20 text-green-500" }) }), jsxRuntimeExports.jsxs(motion.div, { initial: { y: 20, opacity: 0 }, animate: { y: 0, opacity: 1 }, transition: { delay: 0.4, duration: 0.5 }, className: "text-center space-y-2", children: [jsxRuntimeExports.jsx("h2", { className: "text-2xl font-bold text-green-600", children: "Authentication Successful!" }), jsxRuntimeExports.jsx("p", { className: "text-gray-600", children: "Redirecting you to the application..." })] }), jsxRuntimeExports.jsx(motion.div, { initial: { width: 0 }, animate: { width: "100%" }, transition: { delay: 0.8, duration: 2 }, className: "h-1 bg-green-500 rounded-full max-w-xs" })] }));
1573
1573
  };
1574
1574
 
1575
+ // Function to parse userAgent and generate a device ID
1576
+ var GenerateDeviceId = function () {
1577
+ var _a;
1578
+ if (typeof window === "undefined" || !window.navigator) {
1579
+ return "unknown-device";
1580
+ }
1581
+ var userAgent = window.navigator.userAgent;
1582
+ var deviceId = "";
1583
+ // Parse browser, version, OS, and device type
1584
+ var browserMatch = Array.from(userAgent.matchAll(/(Chrome|Firefox|Safari|Edge|Opera)\/([\d.]+)/ig));
1585
+ var osMatch = Array.from(userAgent.matchAll(/\(([^)]+)\)/g));
1586
+ var isMobile = /Mobile|Android|iPhone|iPad/i.test(userAgent);
1587
+ // Browser info
1588
+ if (browserMatch.length > 0) {
1589
+ var _b = browserMatch[0], browserName = _b[1], browserVersion = _b[2];
1590
+ var majorVersion = browserVersion.split(".")[0];
1591
+ deviceId += "".concat(browserName, "-").concat(majorVersion);
1592
+ }
1593
+ else {
1594
+ deviceId += "UnknownBrowser";
1595
+ }
1596
+ // OS info
1597
+ if (osMatch.length > 0) {
1598
+ var osInfo = osMatch[0][1]
1599
+ .split(";")[0]
1600
+ .trim()
1601
+ .replace(/[\s/()]/g, "_");
1602
+ deviceId += "_".concat(osInfo);
1603
+ }
1604
+ else {
1605
+ deviceId += "_UnknownOS";
1606
+ }
1607
+ // Device type
1608
+ deviceId += isMobile ? "_Mobile" : "_Desktop";
1609
+ // Add a simple hash of userAgent for uniqueness
1610
+ var hash = btoa(userAgent).slice(0, 8);
1611
+ deviceId += "_".concat(hash);
1612
+ return (_a = deviceId.replace(/[^a-zA-Z0-9-_]/g, "_")) !== null && _a !== void 0 ? _a : "unknown-device";
1613
+ };
1614
+
1575
1615
  var useOTPHandler = function (_a) {
1576
- var provider = _a.provider, accessToken = _a.accessToken, idToken = _a.idToken, appCode = _a.appCode, authenticationType = _a.authenticationType, apiEndpoint = _a.apiEndpoint, onAuthComplete = _a.onAuthComplete;
1616
+ var provider = _a.provider, accessToken = _a.accessToken, idToken = _a.idToken, appCode = _a.appCode, authenticationType = _a.authenticationType, MFAEndpoint = _a.MFAEndpoint, onAuthComplete = _a.onAuthComplete;
1577
1617
  var _b = useState(false), loading = _b[0], setLoading = _b[1];
1578
1618
  var _c = useState(0), attemptCount = _c[0], setAttemptCount = _c[1];
1579
1619
  var _d = useState(false), isMaxAttemptsReached = _d[0], setIsMaxAttemptsReached = _d[1];
@@ -1597,13 +1637,18 @@ var useOTPHandler = function (_a) {
1597
1637
  setAttemptCount(currentAttempt);
1598
1638
  if (authenticationType === null)
1599
1639
  return [2 /*return*/, false];
1600
- return [4 /*yield*/, axios.post(apiEndpoint || '/api/auth/verify-mfa', {
1640
+ return [4 /*yield*/, axios.post(MFAEndpoint || "/api/auth/verify-mfa", {
1601
1641
  provider: provider,
1602
1642
  accessToken: accessToken,
1603
1643
  idToken: idToken,
1604
1644
  authenticationType: authenticationType,
1605
1645
  MFACode: authenticationValue,
1606
1646
  appCode: appCode,
1647
+ }, {
1648
+ headers: {
1649
+ "X-Device-ID": GenerateDeviceId(),
1650
+ },
1651
+ timeout: 605000,
1607
1652
  })];
1608
1653
  case 2:
1609
1654
  response = (_a.sent()).data;
@@ -1647,7 +1692,7 @@ var useOTPHandler = function (_a) {
1647
1692
  idToken,
1648
1693
  authenticationType,
1649
1694
  onAuthComplete,
1650
- apiEndpoint,
1695
+ MFAEndpoint,
1651
1696
  attemptCount,
1652
1697
  isMaxAttemptsReached,
1653
1698
  ]);
@@ -1672,33 +1717,54 @@ var MFAOptions = function (_a) {
1672
1717
  var _d = useState(false), otpVisible = _d[0], setOtpVisible = _d[1];
1673
1718
  var _e = useState(false), showSuccessAnimation = _e[0], setShowSuccessAnimation = _e[1];
1674
1719
  var _f = useState(null), authType = _f[0], setAuthType = _f[1];
1720
+ var _g = useState(""), lastOTPCode = _g[0], setLastOTPCode = _g[1];
1675
1721
  var context = useCAMSContext();
1676
- var sendEmailOTP = (context.authMode === "MSAL" && "sendEmailOTP" in context
1722
+ var _h = context.authMode === "MSAL" && "sendEmailOTP" in context
1677
1723
  ? context
1678
- : { sendEmailOTP: null }).sendEmailOTP;
1724
+ : { sendEmailOTP: null, completeMFA: null }, sendEmailOTP = _h.sendEmailOTP, completeMFA = _h.completeMFA;
1679
1725
  var accessToken = context.authMode === "MSAL" ? context.accessToken : "";
1680
1726
  var idToken = context.authMode === "MSAL" ? context.idToken : "";
1681
- var _g = useOTPHandler({
1727
+ var _j = useOTPHandler({
1682
1728
  accessToken: accessToken || "",
1683
1729
  idToken: idToken || "",
1684
1730
  provider: "MSAL",
1685
1731
  appCode: context.appCode || "",
1686
1732
  authenticationType: authType,
1687
- apiEndpoint: MFAEndpoint,
1688
- onAuthComplete: function (state, data) {
1689
- if (state) {
1690
- setShowSuccessAnimation(true);
1691
- toast.success(jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 text-sm text-green-600 bg-green-50 p-3 rounded-lg", children: [jsxRuntimeExports.jsx(ShieldCheck, { className: "w-4 h-4" }), jsxRuntimeExports.jsx("span", { children: "Multi-Factor Authentication Successful" })] }));
1692
- setTimeout(function () { return onComplete === null || onComplete === void 0 ? void 0 : onComplete(true); }, 2000);
1693
- }
1694
- else {
1695
- toast.error(jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 text-sm text-red-600 bg-red-50 p-3 rounded-lg", children: [jsxRuntimeExports.jsx(ShieldClose, { className: "w-4 h-4" }), jsxRuntimeExports.jsx("span", { children: (data === null || data === void 0 ? void 0 : data.message) || "Invalid code. Please try again." })] }));
1696
- if (isMaxAttemptsReached) {
1697
- setTimeout(function () { return onComplete === null || onComplete === void 0 ? void 0 : onComplete(false); }, 1000);
1733
+ MFAEndpoint: MFAEndpoint,
1734
+ onAuthComplete: function (state, data) { return __awaiter(void 0, void 0, void 0, function () {
1735
+ var error_1;
1736
+ return __generator(this, function (_a) {
1737
+ switch (_a.label) {
1738
+ case 0:
1739
+ if (!state) return [3 /*break*/, 5];
1740
+ if (!(completeMFA && authType && lastOTPCode)) return [3 /*break*/, 4];
1741
+ _a.label = 1;
1742
+ case 1:
1743
+ _a.trys.push([1, 3, , 4]);
1744
+ return [4 /*yield*/, completeMFA(lastOTPCode, authType)];
1745
+ case 2:
1746
+ _a.sent();
1747
+ return [3 /*break*/, 4];
1748
+ case 3:
1749
+ error_1 = _a.sent();
1750
+ console.error("Failed to complete MFA:", error_1);
1751
+ return [3 /*break*/, 4];
1752
+ case 4:
1753
+ setShowSuccessAnimation(true);
1754
+ toast.success(jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 text-sm text-green-600 bg-green-50 p-3 rounded-lg", children: [jsxRuntimeExports.jsx(ShieldCheck, { className: "w-4 h-4" }), jsxRuntimeExports.jsx("span", { children: "Multi-Factor Authentication Successful" })] }));
1755
+ setTimeout(function () { return onComplete === null || onComplete === void 0 ? void 0 : onComplete(true); }, 2000);
1756
+ return [3 /*break*/, 6];
1757
+ case 5:
1758
+ toast.error(jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 text-sm text-red-600 bg-red-50 p-3 rounded-lg", children: [jsxRuntimeExports.jsx(ShieldClose, { className: "w-4 h-4" }), jsxRuntimeExports.jsx("span", { children: (data === null || data === void 0 ? void 0 : data.message) || "Invalid code. Please try again." })] }));
1759
+ if (isMaxAttemptsReached) {
1760
+ setTimeout(function () { return onComplete === null || onComplete === void 0 ? void 0 : onComplete(false); }, 1000);
1761
+ }
1762
+ _a.label = 6;
1763
+ case 6: return [2 /*return*/];
1698
1764
  }
1699
- }
1700
- },
1701
- }), handleSubmitOTP = _g.handleSubmitOTP, loading = _g.loading, setLoading = _g.setLoading, attemptCount = _g.attemptCount, remainingAttempts = _g.remainingAttempts, isMaxAttemptsReached = _g.isMaxAttemptsReached, resetAttempts = _g.resetAttempts;
1765
+ });
1766
+ }); },
1767
+ }), handleSubmitOTP = _j.handleSubmitOTP, loading = _j.loading, setLoading = _j.setLoading, attemptCount = _j.attemptCount, remainingAttempts = _j.remainingAttempts, isMaxAttemptsReached = _j.isMaxAttemptsReached, resetAttempts = _j.resetAttempts;
1702
1768
  var handleGoBack = function () {
1703
1769
  setAuthType(null);
1704
1770
  setOtpVisible(false);
@@ -1707,9 +1773,9 @@ var MFAOptions = function (_a) {
1707
1773
  };
1708
1774
  // Show success animation if authentication is successful
1709
1775
  if (showSuccessAnimation) {
1710
- return (jsxRuntimeExports.jsx(Card, { className: "mx-auto space-y-6 p-6 bg-white rounded-lg shadow-md", children: jsxRuntimeExports.jsx(AuthSuccessAnimation, { onComplete: function () {
1711
- // Animation completed, can add additional logic here if needed
1712
- } }) }));
1776
+ return (jsxRuntimeExports.jsx("div", { className: "flex justify-center items-center h-dvh", children: jsxRuntimeExports.jsx(Card, { className: "mx-auto space-y-6 p-6 bg-white rounded-lg shadow-md", children: jsxRuntimeExports.jsx(AuthSuccessAnimation, { onComplete: function () {
1777
+ // Animation completed, can add additional logic here if needed
1778
+ } }) }) }));
1713
1779
  }
1714
1780
  var content = jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, {});
1715
1781
  if (!authType) {
@@ -1745,12 +1811,18 @@ var MFAOptions = function (_a) {
1745
1811
  setAuthType(null);
1746
1812
  setOtpVisible(false);
1747
1813
  setValue("");
1748
- }, children: [jsxRuntimeExports.jsx(DialogHeader, { children: jsxRuntimeExports.jsx(DialogTitle, { children: "Email OTP" }) }), jsxRuntimeExports.jsx(DialogContent, { className: "sm:max-w-[425px]", children: jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [jsxRuntimeExports.jsx(GenericOTPVerifier, { value: value, setValue: setValue, isDisabled: loading || isMaxAttemptsReached, onChangeOTP: handleSubmitOTP, fieldName: "EmailOTP", attemptCount: attemptCount, remainingAttempts: remainingAttempts, isMaxAttemptsReached: isMaxAttemptsReached }), jsxRuntimeExports.jsx(Button, { variant: "ghost", className: "w-full text-sm", onClick: handleGoBack, children: "\u2190 Choose different method" })] }) })] }));
1814
+ }, children: [jsxRuntimeExports.jsx(DialogHeader, { children: jsxRuntimeExports.jsx(DialogTitle, { children: "Email OTP" }) }), jsxRuntimeExports.jsx(DialogContent, { className: "sm:max-w-[425px]", children: jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [jsxRuntimeExports.jsx(GenericOTPVerifier, { value: value, setValue: setValue, isDisabled: loading || isMaxAttemptsReached, onChangeOTP: function (code) {
1815
+ setLastOTPCode(code);
1816
+ return handleSubmitOTP(code);
1817
+ }, fieldName: "EmailOTP", attemptCount: attemptCount, remainingAttempts: remainingAttempts, isMaxAttemptsReached: isMaxAttemptsReached }), jsxRuntimeExports.jsx(Button, { variant: "ghost", className: "w-full text-sm", onClick: handleGoBack, children: "\u2190 Choose different method" })] }) })] }));
1749
1818
  }
1750
1819
  else if (authType === "AuthenticatorCode") {
1751
- content = (jsxRuntimeExports.jsxs(Dialog, { open: otpVisible, onOpenChange: handleGoBack, children: [jsxRuntimeExports.jsx(DialogHeader, { children: jsxRuntimeExports.jsx(DialogTitle, { children: "Authenticator App" }) }), jsxRuntimeExports.jsx(DialogContent, { className: "sm:max-w-[425px]", children: loading ? (jsxRuntimeExports.jsx("div", { className: "p-3 flex justify-center items-center", children: jsxRuntimeExports.jsx(LoadingSpinner, {}) })) : (jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [jsxRuntimeExports.jsx("p", { className: "text-sm text-gray-600 text-center", children: "Enter the 6-digit Code from your Authenticator app" }), jsxRuntimeExports.jsx(GenericOTPVerifier, { value: value, setValue: setValue, isDisabled: loading || isMaxAttemptsReached, onChangeOTP: handleSubmitOTP, fieldName: "AuthenticatorCode", attemptCount: attemptCount, remainingAttempts: remainingAttempts, isMaxAttemptsReached: isMaxAttemptsReached })] })) })] }));
1820
+ content = (jsxRuntimeExports.jsxs(Dialog, { open: otpVisible, onOpenChange: handleGoBack, children: [jsxRuntimeExports.jsx(DialogHeader, { children: jsxRuntimeExports.jsx(DialogTitle, { children: "Authenticator App" }) }), jsxRuntimeExports.jsx(DialogContent, { className: "sm:max-w-[425px]", children: loading ? (jsxRuntimeExports.jsx("div", { className: "p-3 flex justify-center items-center", children: jsxRuntimeExports.jsx(LoadingSpinner, {}) })) : (jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [jsxRuntimeExports.jsx("p", { className: "text-sm text-gray-600 text-center", children: "Enter the 6-digit Code from your Authenticator app" }), jsxRuntimeExports.jsx(GenericOTPVerifier, { value: value, setValue: setValue, isDisabled: loading || isMaxAttemptsReached, onChangeOTP: function (code) {
1821
+ setLastOTPCode(code);
1822
+ return handleSubmitOTP(code);
1823
+ }, fieldName: "AuthenticatorCode", attemptCount: attemptCount, remainingAttempts: remainingAttempts, isMaxAttemptsReached: isMaxAttemptsReached })] })) })] }));
1752
1824
  }
1753
- return (jsxRuntimeExports.jsx("div", { className: "flex justify-center items-center h-dvh", children: jsxRuntimeExports.jsxs(Card, { className: "mx-auto space-y-6 p-6 bg-white rounded-lg shadow-md", children: [jsxRuntimeExports.jsxs(CardHeader, { children: [jsxRuntimeExports.jsx("div", { className: "flex justify-center items", children: jsxRuntimeExports.jsx("img", { src: OTPAuthenticationImg, alt: "NIBSS Logo", width: 365, height: 365 }) }), jsxRuntimeExports.jsx(CardTitle, { className: "text-3xl font-bold mb-6 text-center", children: "Two-Factor Authentication" }), jsxRuntimeExports.jsx(CardTitle, { className: "text-gray-300 text-base -tracking-wide text-center", children: "Your Microsoft account has been validated. Please complete two-factor authentication to continue." })] }), jsxRuntimeExports.jsx(CardContent, { children: content }), jsxRuntimeExports.jsxs(CardFooter, { className: "flex items-center justify-center mt-6 space-x-2 text-gray-400 text-sm", children: [jsxRuntimeExports.jsx(ShieldCheck, { className: "w-4 h-4 text-[#506f4a] pulse-glow" }), jsxRuntimeExports.jsx("span", { children: "Powered By NIBSS" })] })] }) }));
1825
+ return (jsxRuntimeExports.jsx("div", { className: "flex justify-center items-center h-dvh", children: jsxRuntimeExports.jsxs(Card, { className: "mx-auto space-y-6 p-6 bg-white rounded-lg shadow-md", children: [jsxRuntimeExports.jsxs(CardHeader, { children: [jsxRuntimeExports.jsx("div", { className: "flex justify-center items", children: jsxRuntimeExports.jsx("img", { src: OTPAuthenticationImg, alt: "NIBSS Logo", width: 365, height: 365 }) }), jsxRuntimeExports.jsx(CardTitle, { className: "text-3xl font-bold mb-6 text-center", children: "Two-Factor Authentication" }), jsxRuntimeExports.jsx(CardTitle, { className: "text-gray-300 text-base -tracking-wide text-center", children: "Your Microsoft account has been validated. Please complete two-factor authentication to continue." })] }), jsxRuntimeExports.jsx(CardContent, { className: "max-w-[80%]", children: content }), jsxRuntimeExports.jsxs(CardFooter, { className: "flex items-center justify-center mt-6 space-x-2 text-gray-400 text-sm", children: [jsxRuntimeExports.jsx(ShieldCheck, { className: "w-4 h-4 text-[#506f4a] pulse-glow" }), jsxRuntimeExports.jsx("span", { children: "Powered By NIBSS" })] })] }) }));
1754
1826
  };
1755
1827
 
1756
1828
  var LoginButton = function () {