@nibssplc/cams-sdk-react 0.0.1-beta.91 → 0.0.1-beta.93

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
@@ -6,7 +6,7 @@ import { useMsal, useAccount, MsalProvider } from '@azure/msal-react';
6
6
  import { InteractionStatus, PublicClientApplication } from '@azure/msal-browser';
7
7
  import z$1, { z } from 'zod';
8
8
  import { OTPInput, OTPInputContext, REGEXP_ONLY_DIGITS } from 'input-otp';
9
- import { RectangleEllipsis, XIcon, CheckCircle, Mail, Shield, ShieldCheck, ShieldClose, KeyIcon, Loader2 } from 'lucide-react';
9
+ import { RectangleEllipsis, XIcon, CheckCircle, Mail, Shield, KeyIcon, ShieldCheck, ShieldClose, Loader2 } from 'lucide-react';
10
10
  import { appendErrors, FormProvider, Controller, useFormContext, useFormState, useForm } from 'react-hook-form';
11
11
  import { validateFieldsNatively, toNestErrors } from '@hookform/resolvers';
12
12
  import { clsx } from 'clsx';
@@ -1828,26 +1828,61 @@ var useOTPHandler = function (_a) {
1828
1828
  };
1829
1829
 
1830
1830
  var MFAOptions = function (_a) {
1831
- var _b = _a === void 0 ? {} : _a, onComplete = _b.onComplete, onAuthFailed = _b.onAuthFailed, MFAEndpoint = _b.MFAEndpoint;
1832
- var _c = useState(""), value = _c[0], setValue = _c[1];
1833
- var _d = useState(false), otpVisible = _d[0], setOtpVisible = _d[1];
1834
- var _e = useState(false), showSuccessAnimation = _e[0], setShowSuccessAnimation = _e[1];
1835
- var _f = useState(null), authType = _f[0], setAuthType = _f[1];
1831
+ var onComplete = _a.onComplete, onAuthFailed = _a.onAuthFailed, MFAEndpoints = _a.MFAEndpoints, usePassKey = _a.usePassKey;
1832
+ var _b = useState(""), value = _b[0], setValue = _b[1];
1833
+ var _c = useState(false), otpVisible = _c[0], setOtpVisible = _c[1];
1834
+ var _d = useState(false), showSuccessAnimation = _d[0], setShowSuccessAnimation = _d[1];
1835
+ var _e = useState(null), authType = _e[0], setAuthType = _e[1];
1836
1836
  var context = useCAMSContext();
1837
- var _g = context.authMode === "MSAL" && "sendEmailOTP" in context
1837
+ var _f = context.authMode === "MSAL" && "sendEmailOTP" in context
1838
1838
  ? context
1839
1839
  : { sendEmailOTP: null, completeMFA: null, logout: function () { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) {
1840
1840
  return [2 /*return*/];
1841
- }); }); } }, sendEmailOTP = _g.sendEmailOTP, completeMFA = _g.completeMFA, logout = _g.logout;
1841
+ }); }); } }, sendEmailOTP = _f.sendEmailOTP, completeMFA = _f.completeMFA, logout = _f.logout;
1842
1842
  var accessToken = context.authMode === "MSAL" ? context.accessToken : "";
1843
1843
  var idToken = context.authMode === "MSAL" ? context.idToken : "";
1844
- var _h = useOTPHandler({
1844
+ var authenticate = useWebAuthn().authenticate;
1845
+ var handleFIDOLogin = function () { return __awaiter(void 0, void 0, void 0, function () {
1846
+ var options, assertionResponse, error_1;
1847
+ return __generator(this, function (_a) {
1848
+ switch (_a.label) {
1849
+ case 0:
1850
+ _a.trys.push([0, 4, , 5]);
1851
+ // 1. Fetch authentication challenge from your server
1852
+ console.log("Requesting authentication challenge from server...");
1853
+ return [4 /*yield*/, axios.post(MFAEndpoints.RetrieveAuthChallenge)];
1854
+ case 1:
1855
+ options = (_a.sent()).data;
1856
+ console.log("Received challenge:", options);
1857
+ // 2. Call the SDK to trigger the browser's passkey authentication UI
1858
+ console.log("Calling SDK authenticate function...");
1859
+ return [4 /*yield*/, authenticate(options)];
1860
+ case 2:
1861
+ assertionResponse = _a.sent();
1862
+ console.log("Authentication assertion received from client:", assertionResponse);
1863
+ // 3. Send the assertion back to the server for verification
1864
+ console.log("Sending assertion to server for verification...");
1865
+ return [4 /*yield*/, axios.post(MFAEndpoints.AuthChallengeVerify, assertionResponse)];
1866
+ case 3:
1867
+ _a.sent();
1868
+ toast.success("🔑 Sign-in successful!");
1869
+ return [3 /*break*/, 5];
1870
+ case 4:
1871
+ error_1 = _a.sent();
1872
+ console.error("Authentication failed:", error_1);
1873
+ toast.error("❌ Could not sign in.");
1874
+ return [3 /*break*/, 5];
1875
+ case 5: return [2 /*return*/];
1876
+ }
1877
+ });
1878
+ }); };
1879
+ var _g = useOTPHandler({
1845
1880
  accessToken: accessToken || "",
1846
1881
  idToken: idToken || "",
1847
1882
  provider: "MSAL",
1848
1883
  appCode: context.appCode || "",
1849
1884
  authenticationType: authType,
1850
- MFAEndpoint: MFAEndpoint,
1885
+ MFAEndpoint: MFAEndpoints.ValidateMFA,
1851
1886
  onAuthComplete: function (state, data) {
1852
1887
  console.log("Completed Auth. Handling MFA", state);
1853
1888
  if (state) {
@@ -1874,7 +1909,7 @@ var MFAOptions = function (_a) {
1874
1909
  }
1875
1910
  }
1876
1911
  },
1877
- }), handleSubmitOTP = _h.handleSubmitOTP, loading = _h.loading, setLoading = _h.setLoading, attemptCount = _h.attemptCount, remainingAttempts = _h.remainingAttempts, isMaxAttemptsReached = _h.isMaxAttemptsReached, resetAttempts = _h.resetAttempts;
1912
+ }), handleSubmitOTP = _g.handleSubmitOTP, loading = _g.loading, setLoading = _g.setLoading, attemptCount = _g.attemptCount, remainingAttempts = _g.remainingAttempts, isMaxAttemptsReached = _g.isMaxAttemptsReached, resetAttempts = _g.resetAttempts;
1878
1913
  var handleGoBack = function () {
1879
1914
  setAuthType(null);
1880
1915
  setOtpVisible(false);
@@ -1914,7 +1949,13 @@ var MFAOptions = function (_a) {
1914
1949
  resetAttempts();
1915
1950
  setAuthType("AuthenticatorCode");
1916
1951
  setOtpVisible(true);
1917
- }, children: [jsxRuntimeExports.jsx("img", { src: MicrosoftAuthenticatorImg, alt: "Authenticator", className: "rounded-full", width: 24, height: 24, onError: function () { return jsxRuntimeExports.jsx(Shield, {}); } }), jsxRuntimeExports.jsxs("div", { className: "text-left", children: [jsxRuntimeExports.jsx("div", { className: "font-medium", children: "Authenticator App" }), jsxRuntimeExports.jsx("div", { className: "text-sm text-gray-500", children: "Use Authenticator App" })] })] })] })] }));
1952
+ }, children: [jsxRuntimeExports.jsx("img", { src: MicrosoftAuthenticatorImg, alt: "Authenticator", className: "rounded-full", width: 24, height: 24, onError: function () { return jsxRuntimeExports.jsx(Shield, {}); } }), jsxRuntimeExports.jsxs("div", { className: "text-left", children: [jsxRuntimeExports.jsx("div", { className: "font-medium", children: "Authenticator App" }), jsxRuntimeExports.jsx("div", { className: "text-sm text-gray-500", children: "Use Authenticator App" })] })] }), usePassKey && (jsxRuntimeExports.jsxs(Button, { variant: "outline", className: "w-full flex items-center justify-start gap-3 p-4 h-auto border-2 hover:border-[#506f4a] hover:bg-[#506f4a]/5 transition-all",
1953
+ // onClick={() => {
1954
+ // resetAttempts();
1955
+ // setAuthType("AuthenticatorCode");
1956
+ // setOtpVisible(true);
1957
+ // }}
1958
+ onClick: handleFIDOLogin, disabled: context.isLoading, children: [jsxRuntimeExports.jsx(Button, { 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", children: jsxRuntimeExports.jsx("span", { children: "Sign In " }) }), jsxRuntimeExports.jsx(KeyIcon, { className: "w-16 h-16 text-[#506f4a]" }), jsxRuntimeExports.jsxs("div", { className: "text-left", children: [jsxRuntimeExports.jsx("div", { className: "font-medium", children: "Continue with Passkey" }), jsxRuntimeExports.jsx("div", { className: "text-sm text-gray-500", children: "Passkey" })] })] }))] })] }));
1918
1959
  }
1919
1960
  else if (authType === "EmailOTP") {
1920
1961
  content = (jsxRuntimeExports.jsx(Dialog, { open: otpVisible, onOpenChange: function () {
@@ -2012,11 +2053,12 @@ var ADLoginModal = function (_a) {
2012
2053
  } }), jsxRuntimeExports.jsx(Button, { type: "submit", className: "w-full bg-[#506f4a] hover:bg-[#506f4a]/90", children: "Continue" })] }) }))) : (jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [jsxRuntimeExports.jsx(GenericOTPVerifier, { value: mfaCode, setValue: setMfaCode, setLoading: setIsLoading, isDisabled: isLoading, onChangeOTP: handleMFASubmit, fieldName: "AuthenticatorCode" }), isLoading && (jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-center gap-2 text-sm text-muted-foreground", children: [jsxRuntimeExports.jsx(Loader2, { className: "w-4 h-4 animate-spin" }), jsxRuntimeExports.jsx("span", { children: "Verifying..." })] }))] }))] }) }));
2013
2054
  };
2014
2055
 
2015
- var DefaultLoginPage = function () {
2056
+ var DefaultLoginPage = function (_a) {
2057
+ var usePassKey = _a.usePassKey, MFAEndpoints = _a.MFAEndpoints, PassKeysRegisterProps = _a.PassKeysRegisterProps;
2016
2058
  var context = useCAMSContext();
2017
2059
  var login = context.login, isLoading = context.isLoading, authMode = context.authMode;
2018
- var _a = useState(false), showADModal = _a[0], setShowADModal = _a[1];
2019
- var _b = useWebAuthn(), register = _b.register, authenticate = _b.authenticate;
2060
+ var _b = useState(false), showADModal = _b[0], setShowADModal = _b[1];
2061
+ var register = useWebAuthn().register;
2020
2062
  var handleMSALLogin = function () {
2021
2063
  if (authMode === "MSAL") {
2022
2064
  login();
@@ -2036,85 +2078,40 @@ var DefaultLoginPage = function () {
2036
2078
  },
2037
2079
  exit: { opacity: 0, scale: 0.8, y: -50, transition: { duration: 0.3 } },
2038
2080
  };
2039
- var handleRegister = function () { return __awaiter(void 0, void 0, void 0, function () {
2040
- var res, options, attestationResponse, error_1;
2081
+ var handleRegister = function (data) { return __awaiter(void 0, void 0, void 0, function () {
2082
+ var options, attestationResponse, error_1;
2041
2083
  return __generator(this, function (_a) {
2042
2084
  switch (_a.label) {
2043
2085
  case 0:
2044
- _a.trys.push([0, 5, , 6]);
2086
+ _a.trys.push([0, 4, , 5]);
2045
2087
  // 1. Fetch challenge from your server
2046
2088
  console.log("Requesting registration challenge from server...");
2047
- return [4 /*yield*/, fetch("/api/webauthn/register-challenge")];
2089
+ return [4 /*yield*/, axios.post(MFAEndpoints.RegisterNewChallenge, __assign({}, data))];
2048
2090
  case 1:
2049
- res = _a.sent();
2050
- return [4 /*yield*/, res.json()];
2051
- case 2:
2052
- options = _a.sent();
2091
+ options = (_a.sent()).data;
2053
2092
  console.log("Received challenge:", options);
2054
2093
  // 2. Call the SDK to trigger the browser's passkey creation UI
2055
2094
  console.log("Calling SDK register function...");
2056
2095
  return [4 /*yield*/, register(options)];
2057
- case 3:
2096
+ case 2:
2058
2097
  attestationResponse = _a.sent();
2059
2098
  console.log("Passkey created on client:", attestationResponse);
2060
2099
  // 3. Send the response back to the server for verification
2061
2100
  console.log("Sending attestation to server for verification...");
2062
- return [4 /*yield*/, fetch("/api/webauthn/register-verify", {
2063
- method: "POST",
2101
+ return [4 /*yield*/, axios.post(MFAEndpoints.RegisterVerify, attestationResponse, {
2064
2102
  headers: { "Content-Type": "application/json" },
2065
- body: JSON.stringify(attestationResponse),
2103
+ withCredentials: true, // credentials: 'include'
2066
2104
  })];
2067
- case 4:
2105
+ case 3:
2068
2106
  _a.sent();
2069
- alert("✅ Registration successful! Passkey created.");
2070
- return [3 /*break*/, 6];
2071
- case 5:
2107
+ toast.success("✅ Registration successful! Passkey created.");
2108
+ return [3 /*break*/, 5];
2109
+ case 4:
2072
2110
  error_1 = _a.sent();
2073
2111
  console.error("Registration failed:", error_1);
2074
- alert("❌ Could not create passkey.");
2075
- return [3 /*break*/, 6];
2076
- case 6: return [2 /*return*/];
2077
- }
2078
- });
2079
- }); };
2080
- var handleFIDOLogin = function () { return __awaiter(void 0, void 0, void 0, function () {
2081
- var res, options, assertionResponse, error_2;
2082
- return __generator(this, function (_a) {
2083
- switch (_a.label) {
2084
- case 0:
2085
- _a.trys.push([0, 5, , 6]);
2086
- // 1. Fetch authentication challenge from your server
2087
- console.log("Requesting authentication challenge from server...");
2088
- return [4 /*yield*/, fetch("/api/webauthn/auth-challenge")];
2089
- case 1:
2090
- res = _a.sent();
2091
- return [4 /*yield*/, res.json()];
2092
- case 2:
2093
- options = _a.sent();
2094
- console.log("Received challenge:", options);
2095
- // 2. Call the SDK to trigger the browser's passkey authentication UI
2096
- console.log("Calling SDK authenticate function...");
2097
- return [4 /*yield*/, authenticate(options)];
2098
- case 3:
2099
- assertionResponse = _a.sent();
2100
- console.log("Authentication assertion received from client:", assertionResponse);
2101
- // 3. Send the assertion back to the server for verification
2102
- console.log("Sending assertion to server for verification...");
2103
- return [4 /*yield*/, fetch("/api/webauthn/auth-verify", {
2104
- method: "POST",
2105
- headers: { "Content-Type": "application/json" },
2106
- body: JSON.stringify(assertionResponse),
2107
- })];
2108
- case 4:
2109
- _a.sent();
2110
- alert("🔑 Sign-in successful!");
2111
- return [3 /*break*/, 6];
2112
- case 5:
2113
- error_2 = _a.sent();
2114
- console.error("Authentication failed:", error_2);
2115
- alert("❌ Could not sign in.");
2116
- return [3 /*break*/, 6];
2117
- case 6: return [2 /*return*/];
2112
+ toast.error("❌ Could not create passkey.");
2113
+ return [3 /*break*/, 5];
2114
+ case 5: return [2 /*return*/];
2118
2115
  }
2119
2116
  });
2120
2117
  }); };
@@ -2122,19 +2119,7 @@ var DefaultLoginPage = function () {
2122
2119
  // variant="outline"
2123
2120
  , {
2124
2121
  // variant="outline"
2125
- 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: handleMSALLogin, 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(Button
2126
- // variant="outline"
2127
- , {
2128
- // variant="outline"
2129
- 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: function () { return setShowADModal(true); }, disabled: isLoading, children: [jsxRuntimeExports.jsx(KeyIcon, { className: "w-8 h-8 text-[#506f4a]" }), jsxRuntimeExports.jsx("span", { children: isLoading ? "Logging in..." : "Sign in with ActiveDirectory" })] }), jsxRuntimeExports.jsxs(Button
2130
- // variant="outline"
2131
- , {
2132
- // variant="outline"
2133
- 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: handleRegister, disabled: isLoading, children: [jsxRuntimeExports.jsx(KeyIcon, { className: "w-8 h-8 text-[#506f4a]" }), jsxRuntimeExports.jsx("span", { children: "Create a Passkey" })] }), jsxRuntimeExports.jsxs(Button
2134
- // variant="outline"
2135
- , {
2136
- // variant="outline"
2137
- 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: handleFIDOLogin, disabled: isLoading, children: [jsxRuntimeExports.jsx(KeyIcon, { className: "w-8 h-8 text-[#506f4a]" }), jsxRuntimeExports.jsx("span", { children: "Sign In with Passkey" })] })] }), 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" })] })] }) }) }, "landing"), jsxRuntimeExports.jsx(ADLoginModal, { open: showADModal, onOpenChange: setShowADModal, onLogin: function (_a) { return __awaiter(void 0, [_a], void 0, function (_b) {
2122
+ 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: handleMSALLogin, disabled: isLoading, children: [jsxRuntimeExports.jsx("img", { src: MicrosoftLogo, alt: "Microsoft Logo", width: 35, height: 35 }), jsxRuntimeExports.jsx("span", { className: "ml-2", children: isLoading ? "Logging in..." : "Sign in with Microsoft" })] }), jsxRuntimeExports.jsxs(Button, { 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: function () { return setShowADModal(true); }, disabled: isLoading, children: [jsxRuntimeExports.jsx(KeyIcon, { className: "w-8 h-8 text-[#506f4a]" }), jsxRuntimeExports.jsx("span", { children: isLoading ? "Logging in..." : "Sign in with ActiveDirectory" })] }), usePassKey && (jsxRuntimeExports.jsxs(Button, { 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: function () { return handleRegister(PassKeysRegisterProps); }, disabled: isLoading, children: [jsxRuntimeExports.jsx(KeyIcon, { className: "w-12 h-12 text-[#506f4a]" }), jsxRuntimeExports.jsx("span", { children: "Create a Passkey" })] }))] }), 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" })] })] }) }) }, "landing"), jsxRuntimeExports.jsx(ADLoginModal, { open: showADModal, onOpenChange: setShowADModal, onLogin: function (_a) { return __awaiter(void 0, [_a], void 0, function (_b) {
2138
2123
  var username = _b.username, password = _b.password, MFACode = _b.MFACode;
2139
2124
  return __generator(this, function (_c) {
2140
2125
  // Implement your AD login logic here
@@ -2151,11 +2136,17 @@ var ErrorFallback = function (_a) {
2151
2136
 
2152
2137
  var MFAEndpointsSchema = z$1.object({
2153
2138
  ValidateMFA: z$1.url("MFAEndpoint must be a valid URL"),
2139
+ RegisterNewChallenge: z$1.url("MFA RegisterNewChallenge must be a valid URL"),
2140
+ RegisterVerify: z$1.url("MFA RegisterVerify must be a valid URL"),
2141
+ RetrieveAuthChallenge: z$1.url("MFA RetrieveAuthChallenge must be a valid URL"),
2142
+ AuthChallengeVerify: z$1.url("MFA AuthChallengeVerify must be a valid URL"),
2154
2143
  });
2155
2144
  var MFAGate = function (_a) {
2156
2145
  var children = _a.children, _b = _a.fallback, fallback = _b === void 0 ? jsxRuntimeExports.jsx(LoadingSpinner, {}) : _b,
2157
2146
  // loginComponent: LoginComponent = DefaultLoginPage,
2158
- MFAEndpoints = _a.MFAEndpoints;
2147
+ _c = _a.usePassKey,
2148
+ // loginComponent: LoginComponent = DefaultLoginPage,
2149
+ usePassKey = _c === void 0 ? false : _c, MFAEndpoints = _a.MFAEndpoints;
2159
2150
  var context = useCAMSContext();
2160
2151
  var validatedMFAEndpoints = useMemo(function () {
2161
2152
  var parsed = MFAEndpointsSchema.safeParse(MFAEndpoints);
@@ -2187,10 +2178,10 @@ var MFAGate = function (_a) {
2187
2178
  if (context.isLoading)
2188
2179
  return fallback;
2189
2180
  if (context.requiresMFA) {
2190
- return (jsxRuntimeExports.jsx(MFAOptions, { MFAEndpoint: validatedMFAEndpoints.ValidateMFA, onComplete: handleComplete, onAuthFailed: handleAuthFailed }));
2181
+ return (jsxRuntimeExports.jsx(MFAOptions, { MFAEndpoints: validatedMFAEndpoints, usePassKey: usePassKey, onComplete: handleComplete, onAuthFailed: handleAuthFailed }));
2191
2182
  }
2192
2183
  if (!context.isAuthenticated) {
2193
- return jsxRuntimeExports.jsx(DefaultLoginPage, {});
2184
+ return jsxRuntimeExports.jsx(DefaultLoginPage, { usePassKey: usePassKey, MFAEndpoints: MFAEndpoints });
2194
2185
  }
2195
2186
  return jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children: children });
2196
2187
  };