@nibssplc/cams-sdk-react 0.0.1-beta.59 → 0.0.1-beta.61

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
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import React__default, { useState, useRef, useEffect, useCallback, createContext, useContext, useMemo } from 'react';
3
- import { isPopupWindow, initializePopupAuth, CAMSSessionManager, CAMSError, CAMSErrorType, Logger, CAMSMFAAuthenticator } from '@nibssplc/cams-sdk';
3
+ import { isPopupWindow, initializePopupAuth, CAMSSessionManager, Logger, CAMSError, CAMSErrorType, CAMSMFAAuthenticator } from '@nibssplc/cams-sdk';
4
4
  export * from '@nibssplc/cams-sdk';
5
5
  import { useMsal, useAccount, MsalProvider } from '@azure/msal-react';
6
6
  import { InteractionStatus, PublicClientApplication } from '@azure/msal-browser';
@@ -240,7 +240,7 @@ function useCAMSMSALAuth(options) {
240
240
  var _this = this;
241
241
  if (options === void 0) { options = {
242
242
  appCode: "",
243
- mfaUrl: "/auth/multi-factor",
243
+ MFAEndpoint: "/auth/multi-factor",
244
244
  storageKey: "CAMS-MSAL-AUTH-SDK",
245
245
  }; }
246
246
  var _a = useMsal(), instance = _a.instance, inProgress = _a.inProgress, accounts = _a.accounts;
@@ -310,74 +310,67 @@ function useCAMSMSALAuth(options) {
310
310
  // handleRedirect();
311
311
  // }, []);
312
312
  var login = useCallback(function () { return __awaiter(_this, void 0, void 0, function () {
313
- var err_1, camsError_1, camsError;
314
- var _a, _b, _c;
315
- return __generator(this, function (_d) {
316
- switch (_d.label) {
313
+ var response, mfaConfig, authenticator, err_1, camsError_1, camsError;
314
+ var _a, _b, _c, _d;
315
+ return __generator(this, function (_e) {
316
+ switch (_e.label) {
317
317
  case 0:
318
318
  setError(null);
319
- _d.label = 1;
319
+ _e.label = 1;
320
320
  case 1:
321
- _d.trys.push([1, 3, , 4]);
322
- // await instance.loginR edirect({
323
- // scopes,
324
- // prompt: options.prompt || "login",
325
- // });
326
- return [4 /*yield*/, instance
327
- .loginPopup({
321
+ _e.trys.push([1, 3, , 4]);
322
+ return [4 /*yield*/, instance.loginPopup({
328
323
  scopes: scopes,
329
324
  prompt: options.prompt || "login",
330
- })
331
- .then(function (response) {
332
- var _a;
333
- Logger.debug("Login Token response:", {
334
- accessToken: response.accessToken,
335
- idToken: response.idToken,
336
- });
337
- setAccessToken(response.accessToken);
338
- setIdToken(response.idToken);
339
- // Initialize MFA authenticator
340
- var mfaConfig = {
341
- accessToken: response.accessToken,
342
- idToken: response.idToken,
343
- appCode: options.appCode,
344
- provider: "MSAL",
345
- apiEndpoint: options.mfaApiEndpoint,
346
- };
347
- var authenticator = new CAMSMFAAuthenticator(mfaConfig);
348
- setMfaAuthenticator(authenticator);
349
- setRequiresMFA(true);
350
- // Don't persist as authenticated until MFA is complete
351
- if (typeof window !== "undefined") {
352
- localStorage.setItem(options.storageKey, JSON.stringify({
353
- isAuthenticated: false,
354
- requiresMFA: true,
355
- accessToken: response.accessToken,
356
- idToken: response.idToken,
357
- }));
358
- }
359
- (_a = options.onAuthSuccess) === null || _a === void 0 ? void 0 : _a.call(options, response.accessToken);
360
325
  })];
361
326
  case 2:
362
- // await instance.loginR edirect({
363
- // scopes,
364
- // prompt: options.prompt || "login",
365
- // });
366
- _d.sent();
327
+ response = _e.sent();
328
+ Logger.debug("Login Token response:", {
329
+ accessToken: response.accessToken,
330
+ idToken: response.idToken,
331
+ });
332
+ setAccessToken(response.accessToken);
333
+ setIdToken(response.idToken);
334
+ mfaConfig = {
335
+ accessToken: response.accessToken,
336
+ idToken: response.idToken,
337
+ appCode: options.appCode,
338
+ provider: "MSAL",
339
+ apiEndpoint: options.MFAEndpoint,
340
+ };
341
+ authenticator = new CAMSMFAAuthenticator(mfaConfig);
342
+ setMfaAuthenticator(authenticator);
343
+ setRequiresMFA(true);
344
+ // Don't persist as authenticated until MFA is complete
345
+ if (typeof window !== "undefined") {
346
+ localStorage.setItem(options.storageKey, JSON.stringify({
347
+ isAuthenticated: false,
348
+ requiresMFA: true,
349
+ accessToken: response.accessToken,
350
+ idToken: response.idToken,
351
+ }));
352
+ }
353
+ (_a = options.onAuthSuccess) === null || _a === void 0 ? void 0 : _a.call(options, response.accessToken);
367
354
  return [3 /*break*/, 4];
368
355
  case 3:
369
- err_1 = _d.sent();
356
+ err_1 = _e.sent();
357
+ // Handle user cancellation gracefully
358
+ if (err_1.errorCode === "user_cancelled") {
359
+ Logger.info("User cancelled login");
360
+ setError(null); // Don't treat cancellation as an error
361
+ return [2 /*return*/];
362
+ }
370
363
  // If popup is blocked
371
364
  if (err_1.errorCode === "popup_window_error" ||
372
- ((_a = err_1.message) === null || _a === void 0 ? void 0 : _a.includes("popup"))) {
373
- camsError_1 = new CAMSError(CAMSErrorType.POPUP_BLOCKED, "Both popup and redirect failed: " + err_1);
365
+ ((_b = err_1.message) === null || _b === void 0 ? void 0 : _b.includes("popup"))) {
366
+ camsError_1 = new CAMSError(CAMSErrorType.POPUP_BLOCKED, "Popup blocked by browser. Please allow popups and try again.");
374
367
  setError(camsError_1);
375
- (_b = options.onAuthError) === null || _b === void 0 ? void 0 : _b.call(options, camsError_1);
368
+ (_c = options.onAuthError) === null || _c === void 0 ? void 0 : _c.call(options, camsError_1);
376
369
  return [2 /*return*/];
377
370
  }
378
- camsError = new CAMSError(CAMSErrorType.API_VALIDATION_ERROR, "Login failed: " + err_1);
371
+ camsError = new CAMSError(CAMSErrorType.API_VALIDATION_ERROR, "Login failed: " + err_1.message || err_1);
379
372
  setError(camsError);
380
- (_c = options.onAuthError) === null || _c === void 0 ? void 0 : _c.call(options, camsError);
373
+ (_d = options.onAuthError) === null || _d === void 0 ? void 0 : _d.call(options, camsError);
381
374
  return [3 /*break*/, 4];
382
375
  case 4: return [2 /*return*/];
383
376
  }
@@ -1125,14 +1118,14 @@ var deleteCookie = function (name) {
1125
1118
  };
1126
1119
  function CAMSProviderCore(props) {
1127
1120
  var _this = this;
1128
- var _a = props, children = _a.children, mode = _a.mode, appCode = _a.appCode, validateTokenUrl = _a.validateTokenUrl;
1121
+ var children = props.children, mode = props.mode, appCode = props.appCode;
1129
1122
  // Always call both hooks to satisfy Rules of Hooks
1130
1123
  var regularAuth = useCAMSAuth(mode === "REGULAR"
1131
1124
  ? __assign(__assign({}, props), { appCode: appCode })
1132
1125
  : { appCode: "" });
1133
1126
  var msalAuth = useCAMSMSALAuth(mode === "MSAL"
1134
1127
  ? __assign(__assign({}, props), { appCode: appCode })
1135
- : { appCode: "" });
1128
+ : { appCode: "", MFAEndpoint: "/auth/multi-factor" });
1136
1129
  var auth = mode === "REGULAR" ? regularAuth : msalAuth;
1137
1130
  var profileStorageKey = "".concat(auth.storageKey, "-PROFILE");
1138
1131
  var getInitialProfile = function () {
@@ -1146,7 +1139,7 @@ function CAMSProviderCore(props) {
1146
1139
  return null;
1147
1140
  }
1148
1141
  };
1149
- var _b = useState(getInitialProfile), userProfile = _b[0], setUserProfile = _b[1];
1142
+ var _a = useState(getInitialProfile), userProfile = _a[0], setUserProfile = _a[1];
1150
1143
  useEffect(function () {
1151
1144
  if (typeof window !== "undefined") {
1152
1145
  var storedProfile = getCookie(profileStorageKey);
@@ -1184,7 +1177,11 @@ function CAMSProviderCore(props) {
1184
1177
  }); };
1185
1178
  // Handle MFA completion for MSAL mode
1186
1179
  useEffect(function () {
1187
- if (mode === "MSAL" && "requiresMFA" in auth && !auth.requiresMFA && auth.isAuthenticated && !userProfile) {
1180
+ if (mode === "MSAL" &&
1181
+ "requiresMFA" in auth &&
1182
+ !auth.requiresMFA &&
1183
+ auth.isAuthenticated &&
1184
+ !userProfile) {
1188
1185
  // MFA completed, extract profile from stored data
1189
1186
  var storedData = getCookie(auth.storageKey);
1190
1187
  if (storedData) {
@@ -1199,8 +1196,8 @@ function CAMSProviderCore(props) {
1199
1196
  }
1200
1197
  }, [mode, auth, userProfile]);
1201
1198
  var value = useMemo(function () {
1202
- return (__assign(__assign({}, auth), { logout: enhancedLogout, userProfile: userProfile, setUserProfile: setUserProfile, authMode: mode, validateTokenUrl: validateTokenUrl }));
1203
- }, [auth, userProfile, mode, validateTokenUrl]);
1199
+ return (__assign(__assign({}, auth), { logout: enhancedLogout, userProfile: userProfile, setUserProfile: setUserProfile, authMode: mode }));
1200
+ }, [auth, userProfile, mode]);
1204
1201
  return jsxRuntimeExports.jsx(CAMSContext.Provider, { value: value, children: children });
1205
1202
  }
1206
1203
  function UnifiedCAMSProvider(props) {
@@ -1209,11 +1206,11 @@ function UnifiedCAMSProvider(props) {
1209
1206
  if (!appCodeValidation.success) {
1210
1207
  throw new Error("Invalid appCode: ".concat(appCodeValidation.error.issues[0].message));
1211
1208
  }
1212
- // Validate validateTokenUrl if provided
1213
- if (props.mode === "MSAL" && props.validateTokenUrl) {
1214
- var urlValidation = UrlSchema.safeParse(props.validateTokenUrl);
1209
+ // Validate apiEndpoint if provided
1210
+ if (props.mode === "MSAL" && props.MFAEndpoint) {
1211
+ var urlValidation = UrlSchema.safeParse(props.MFAEndpoint);
1215
1212
  if (!urlValidation.success) {
1216
- throw new Error("Invalid validateTokenUrl: ".concat(urlValidation.error.issues[0].message));
1213
+ throw new Error("Invalid apiEndpoint: ".concat(urlValidation.error.issues[0].message));
1217
1214
  }
1218
1215
  }
1219
1216
  if (props.mode === "MSAL") {
@@ -1667,18 +1664,18 @@ var MFAOptions = function (_a) {
1667
1664
  var _f = useState(null), authType = _f[0], setAuthType = _f[1];
1668
1665
  var context = useCAMSContext();
1669
1666
  var isSDKMode = context.authMode === "MSAL" && "completeMFA" in context;
1670
- var _g = isSDKMode
1667
+ var sendEmailOTP = (isSDKMode
1671
1668
  ? context
1672
- : { completeMFA: null, sendEmailOTP: null }; _g.completeMFA; var sendEmailOTP = _g.sendEmailOTP;
1669
+ : { sendEmailOTP: null }).sendEmailOTP;
1673
1670
  var accessToken = context.authMode === "MSAL" ? context.accessToken : "";
1674
1671
  var idToken = context.authMode === "MSAL" ? context.idToken : "";
1675
- var _h = useOTPHandler({
1672
+ var _g = useOTPHandler({
1676
1673
  provider: "azure",
1677
1674
  accessToken: accessToken || "",
1678
1675
  idToken: idToken || "",
1679
1676
  appCode: context.appCode || "",
1680
1677
  authenticationType: authType,
1681
- validateTokenUrl: context.validateTokenUrl || "/api/validate-token",
1678
+ validateTokenUrl: ((context.authMode === "MSAL" && "MFAEndpoint" in context) ? (context.MFAEndpoint || "/api/auth/verify-mfa") : "/api/validate-token"),
1682
1679
  onAuthComplete: function (success, data) {
1683
1680
  if (success) {
1684
1681
  setShowSuccessAnimation(true);
@@ -1692,7 +1689,7 @@ var MFAOptions = function (_a) {
1692
1689
  }
1693
1690
  }
1694
1691
  },
1695
- }), handleSubmitOTP = _h.handleSubmitOTP, loading = _h.loading, attemptCount = _h.attemptCount, isMaxAttemptsReached = _h.isMaxAttemptsReached, remainingAttempts = _h.remainingAttempts, resetAttempts = _h.resetAttempts;
1692
+ }), handleSubmitOTP = _g.handleSubmitOTP, loading = _g.loading, attemptCount = _g.attemptCount, isMaxAttemptsReached = _g.isMaxAttemptsReached, remainingAttempts = _g.remainingAttempts, resetAttempts = _g.resetAttempts;
1696
1693
  var handleGoBack = function () {
1697
1694
  setAuthType(null);
1698
1695
  setOtpVisible(false);
@@ -1730,7 +1727,7 @@ var MFAOptions = function (_a) {
1730
1727
  resetAttempts();
1731
1728
  setAuthType("AuthenticatorCode");
1732
1729
  setOtpVisible(true);
1733
- }, children: [jsxRuntimeExports.jsx("img", { src: "/microsoftauthenticator.svg", alt: "Authenticator", className: "rounded-full", width: 24, height: 24 }), 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" })] })] })] })] }));
1730
+ }, children: [jsxRuntimeExports.jsx("img", { src: "/images/microsoftauthenticator.svg", alt: "Authenticator", className: "rounded-full", width: 24, height: 24 }), 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" })] })] })] })] }));
1734
1731
  }
1735
1732
  else if (authType === "EmailOTP") {
1736
1733
  content = (jsxRuntimeExports.jsxs(Dialog, { open: otpVisible, onOpenChange: function () {
@@ -1742,7 +1739,7 @@ var MFAOptions = function (_a) {
1742
1739
  else if (authType === "AuthenticatorCode") {
1743
1740
  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 })] })) })] }));
1744
1741
  }
1745
- return (jsxRuntimeExports.jsxs(Card, { className: "mx-auto space-y-6 p-6 bg-white rounded-lg shadow-md", children: [jsxRuntimeExports.jsxs(CardHeader, { children: [jsxRuntimeExports.jsx("img", { src: "/OTPAuthentication1.svg", 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-sm -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" })] })] }));
1742
+ return (jsxRuntimeExports.jsx("div", { className: "flex justify-center items-center", 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("img", { src: "/images/OTPAuthentication.svg", 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-sm -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" })] })] }) }));
1746
1743
  };
1747
1744
 
1748
1745
  var LoginButton = function () {