@nibssplc/cams-sdk-react 1.0.0-rc.46 → 1.0.0-rc.48

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/README.md CHANGED
@@ -13,6 +13,19 @@ For MSAL mode, also install:
13
13
  npm install @azure/msal-browser @azure/msal-react
14
14
  ```
15
15
 
16
+ ### Importing Styles
17
+
18
+ The SDK includes bundled Tailwind CSS. Import it in your app entry point:
19
+
20
+ ```tsx
21
+ import '@nibssplc/cams-sdk-react/dist/styles.css';
22
+ ```
23
+
24
+ For Next.js, add to `app/layout.tsx` or `pages/_app.tsx`:
25
+ ```tsx
26
+ import '@nibssplc/cams-sdk-react/dist/styles.css';
27
+ ```
28
+
16
29
  ## Features
17
30
 
18
31
  - ⚛️ React hooks for authentication
@@ -273,13 +286,14 @@ export default function RootLayout({ children }) {
273
286
 
274
287
  ## Styling
275
288
 
276
- Components use Tailwind CSS. Ensure Tailwind is configured in your project:
289
+ The SDK bundles all required Tailwind CSS, so you don't need to configure Tailwind in your project. Simply import the styles:
277
290
 
278
- ```bash
279
- npm install -D tailwindcss
280
- npx tailwindcss init
291
+ ```tsx
292
+ import '@nibssplc/cams-sdk-react/dist/styles.css';
281
293
  ```
282
294
 
295
+ If your project already uses Tailwind, the SDK styles will work alongside your existing configuration.
296
+
283
297
  ## Examples
284
298
 
285
299
  See the [examples](../../examples) directory for complete implementations:
@@ -15,6 +15,7 @@ interface MFAGateProps {
15
15
  CredentialsAuthEndpoint?: string;
16
16
  PassKeysRegisterProps?: Record<string, unknown>;
17
17
  MFAEndpoints?: MFAEndpoints;
18
+ requiresMFA?: boolean;
18
19
  }
19
- declare const MFAGate: ({ children, fallback, usePassKey, useADLogin, CredentialsAuthEndpoint, PassKeysRegisterProps, MFAEndpoints, }: 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;
20
+ declare const MFAGate: ({ children, fallback, usePassKey, useADLogin, CredentialsAuthEndpoint, PassKeysRegisterProps, MFAEndpoints, requiresMFA, }: 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;
20
21
  export default MFAGate;
@@ -14,6 +14,11 @@ interface MSALProviderProps extends BaseProviderProps, Omit<UseCAMSMSALAuthOptio
14
14
  mode: "MSAL";
15
15
  msalConfig: Configuration;
16
16
  msalInstance?: PublicClientApplication;
17
+ onAuthSuccess?: (tokens: {
18
+ accessToken: string;
19
+ idToken: string;
20
+ }) => void;
21
+ onAuthError?: (error: any) => void;
17
22
  }
18
23
  type UnifiedCAMSProviderProps = RegularProviderProps | MSALProviderProps;
19
24
  export declare function UnifiedCAMSProvider(props: UnifiedCAMSProviderProps): import("react/jsx-runtime").JSX.Element;
@@ -12,6 +12,11 @@ interface RegularCAMSContextValue extends BaseCAMSContextValue, UseCAMSAuthRetur
12
12
  }
13
13
  interface MSALCAMSContextValue extends BaseCAMSContextValue, UseCAMSMSALAuthReturn {
14
14
  authMode: "MSAL";
15
+ onAuthSuccess?: (tokens: {
16
+ accessToken: string;
17
+ idToken: string;
18
+ }) => void;
19
+ onAuthError?: (error: any) => void;
15
20
  }
16
21
  export type CAMSContextValue = RegularCAMSContextValue | MSALCAMSContextValue;
17
22
  export declare const CAMSContext: import("react").Context<CAMSContextValue | null>;
@@ -1,11 +1,6 @@
1
1
  import "../utils/crypto-polyfill";
2
2
  import { CAMSError, CAMSMFAAuthenticator, MFAResponse } from "@nibssplc/cams-sdk";
3
3
  export interface UseCAMSMSALAuthOptions {
4
- onAuthSuccess?: (tokens: {
5
- accessToken: string;
6
- idToken: string;
7
- }) => void;
8
- onAuthError?: (error: CAMSError) => void;
9
4
  onTokenExpired?: () => void;
10
5
  scopes?: string[];
11
6
  storageKey?: string;
package/dist/index.cjs.js CHANGED
@@ -434,7 +434,7 @@ var deleteCookie = function (name) {
434
434
 
435
435
  function useCAMSMSALAuth(options) {
436
436
  var _this = this;
437
- var optStorageKey = options.storageKey, optScopes = options.scopes, prompt = options.prompt, appCode = options.appCode, MFAEndpoint = options.MFAEndpoint, onAuthSuccess = options.onAuthSuccess, onAuthError = options.onAuthError, _a = options.activeCookiePeriod, activeCookiePeriod = _a === void 0 ? 1 : _a;
437
+ var optStorageKey = options.storageKey, optScopes = options.scopes, prompt = options.prompt, appCode = options.appCode, MFAEndpoint = options.MFAEndpoint, _a = options.activeCookiePeriod, activeCookiePeriod = _a === void 0 ? 1 : _a;
438
438
  var storageKey = optStorageKey || "CAMS-MSAL-AUTH-SDK";
439
439
  var _b = msalReact.useMsal(), instance = _b.instance, inProgress = _b.inProgress, accounts = _b.accounts;
440
440
  var account = msalReact.useAccount(accounts[0] || {});
@@ -563,10 +563,6 @@ function useCAMSMSALAuth(options) {
563
563
  idToken: response.idToken,
564
564
  }));
565
565
  }
566
- onAuthSuccess === null || onAuthSuccess === void 0 ? void 0 : onAuthSuccess({
567
- accessToken: response.accessToken,
568
- idToken: response.idToken,
569
- });
570
566
  return [3 /*break*/, 4];
571
567
  case 3:
572
568
  err_1 = _b.sent();
@@ -586,12 +582,10 @@ function useCAMSMSALAuth(options) {
586
582
  ((_a = err_1.message) === null || _a === void 0 ? void 0 : _a.includes("popup"))) {
587
583
  camsError_1 = new camsSdk.CAMSError(camsSdk.CAMSErrorType.POPUP_BLOCKED, "Popup blocked by browser. Please allow popups and try again.");
588
584
  setError(camsError_1);
589
- onAuthError === null || onAuthError === void 0 ? void 0 : onAuthError(camsError_1);
590
585
  return [2 /*return*/];
591
586
  }
592
587
  camsError = new camsSdk.CAMSError(camsSdk.CAMSErrorType.API_VALIDATION_ERROR, "Login failed: " + err_1.message || err_1);
593
588
  setError(camsError);
594
- onAuthError === null || onAuthError === void 0 ? void 0 : onAuthError(camsError);
595
589
  return [3 /*break*/, 4];
596
590
  case 4: return [2 /*return*/];
597
591
  }
@@ -602,8 +596,6 @@ function useCAMSMSALAuth(options) {
602
596
  prompt,
603
597
  appCode,
604
598
  MFAEndpoint,
605
- onAuthSuccess,
606
- onAuthError,
607
599
  storageKey,
608
600
  inProgress,
609
601
  ]);
@@ -1496,8 +1488,8 @@ function CAMSProviderCore(props) {
1496
1488
  ]);
1497
1489
  var value = React.useMemo(function () {
1498
1490
  auth.logout; var authRest = __rest(auth, ["logout"]);
1499
- return __assign(__assign({}, authRest), { logout: enhancedLogout, userProfile: userProfile, setUserProfile: setUserProfile, authMode: mode });
1500
- }, [auth, userProfile, mode]);
1491
+ return __assign(__assign({}, authRest), { logout: enhancedLogout, userProfile: userProfile, setUserProfile: setUserProfile, authMode: mode, onAuthSuccess: mode === "MSAL" ? props.onAuthSuccess : undefined, onAuthError: mode === "MSAL" ? props.onAuthError : undefined });
1492
+ }, [auth, userProfile, mode, props]);
1501
1493
  return jsxRuntimeExports.jsx(CAMSContext.Provider, { value: value, children: children });
1502
1494
  }
1503
1495
  function UnifiedCAMSProvider(props) {
@@ -1844,36 +1836,6 @@ function DialogTitle(_a) {
1844
1836
 
1845
1837
  var a="container_f782f4",i="inner_37f4c9",c="bar_409d0f";const r=({size:r=35,color:l="black",speed:d=1,stroke:o=3.5})=>jsxRuntimeExports.jsx("div",{className:a,style:{"--uib-size":r+"px","--uib-color":l,"--uib-speed":d+"s","--uib-stroke":o+"px"},children:jsxRuntimeExports.jsxs("div",{className:i,children:[jsxRuntimeExports.jsx("div",{className:c}),jsxRuntimeExports.jsx("div",{className:c}),jsxRuntimeExports.jsx("div",{className:c}),jsxRuntimeExports.jsx("div",{className:c})]})});
1846
1838
 
1847
- function styleInject(css, ref) {
1848
- if ( ref === void 0 ) ref = {};
1849
- var insertAt = ref.insertAt;
1850
-
1851
- if (typeof document === 'undefined') { return; }
1852
-
1853
- var head = document.head || document.getElementsByTagName('head')[0];
1854
- var style = document.createElement('style');
1855
- style.type = 'text/css';
1856
-
1857
- if (insertAt === 'top') {
1858
- if (head.firstChild) {
1859
- head.insertBefore(style, head.firstChild);
1860
- } else {
1861
- head.appendChild(style);
1862
- }
1863
- } else {
1864
- head.appendChild(style);
1865
- }
1866
-
1867
- if (style.styleSheet) {
1868
- style.styleSheet.cssText = css;
1869
- } else {
1870
- style.appendChild(document.createTextNode(css));
1871
- }
1872
- }
1873
-
1874
- var css_248z = ".container_f782f4 {\n flex-shrink: 0;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n height: calc(var(--uib-size) * 0.9);\n width: var(--uib-size);\n}\n\n.inner_37f4c9 {\n display: flex;\n align-items: center;\n justify-content: space-between;\n width: var(--uib-size);\n height: calc(var(--uib-size) * 0.9);\n}\n\n.bar_409d0f {\n width: var(--uib-stroke);\n height: 100%;\n background-color: var(--uib-color);\n transition: background-color 0.3s ease;\n}\n\n.bar_409d0f:nth-child(1) {\n animation: grow_ca6a4e var(--uib-speed) ease-in-out calc(var(--uib-speed) * -0.45) infinite;\n}\n\n.bar_409d0f:nth-child(2) {\n animation: grow_ca6a4e var(--uib-speed) ease-in-out calc(var(--uib-speed) * -0.3) infinite;\n}\n\n.bar_409d0f:nth-child(3) {\n animation: grow_ca6a4e var(--uib-speed) ease-in-out calc(var(--uib-speed) * -0.15) infinite;\n}\n\n.bar_409d0f:nth-child(4) {\n animation: grow_ca6a4e var(--uib-speed) ease-in-out infinite;\n}\n\n@keyframes grow_ca6a4e {\n 0%, 100% {\n transform: scaleY(0.3);\n }\n 50% {\n transform: scaleY(1);\n }\n}";
1875
- styleInject(css_248z);
1876
-
1877
1839
  var LoadingSpinner = function (_a) {
1878
1840
  var loadingText = _a.loadingText;
1879
1841
  return (jsxRuntimeExports.jsxs("div", { className: "flex flex-col justify-center items-center h-full w-full py-10", children: [jsxRuntimeExports.jsx("script", { type: "module", defer: true, src: "https://cdn.jsdelivr.net/npm/ldrs/dist/auto/waveform.js" }), jsxRuntimeExports.jsx(r, { size: "35", stroke: "3.5", speed: "1", color: "green" }), loadingText && (jsxRuntimeExports.jsx("p", { className: "text-center font-semibold mt-3", children: "Loading..." }))] }));
@@ -2448,7 +2410,7 @@ var MFAGate = function (_a) {
2448
2410
  // loginComponent: LoginComponent = DefaultLoginPage,
2449
2411
  _c = _a.usePassKey,
2450
2412
  // loginComponent: LoginComponent = DefaultLoginPage,
2451
- usePassKey = _c === void 0 ? false : _c, _d = _a.useADLogin, useADLogin = _d === void 0 ? false : _d, CredentialsAuthEndpoint = _a.CredentialsAuthEndpoint, PassKeysRegisterProps = _a.PassKeysRegisterProps, MFAEndpoints = _a.MFAEndpoints;
2413
+ usePassKey = _c === void 0 ? false : _c, _d = _a.useADLogin, useADLogin = _d === void 0 ? false : _d, CredentialsAuthEndpoint = _a.CredentialsAuthEndpoint, PassKeysRegisterProps = _a.PassKeysRegisterProps, MFAEndpoints = _a.MFAEndpoints, requiresMFA = _a.requiresMFA;
2452
2414
  var context = useCAMSContext();
2453
2415
  var validatedMFAEndpoints = React.useMemo(function () {
2454
2416
  var parsed = MFAEndpointsSchema.safeParse(MFAEndpoints);
@@ -2459,19 +2421,32 @@ var MFAGate = function (_a) {
2459
2421
  return parsed.data;
2460
2422
  }, [MFAEndpoints]);
2461
2423
  var handleComplete = React.useCallback(function (success) {
2462
- if (!success)
2424
+ var _a;
2425
+ if (success && context.authMode === "MSAL") {
2426
+ (_a = context.onAuthSuccess) === null || _a === void 0 ? void 0 : _a.call(context, {
2427
+ accessToken: context.accessToken,
2428
+ idToken: context.idToken,
2429
+ });
2430
+ }
2431
+ else if (!success) {
2463
2432
  camsSdk.Logger.error("MFA authentication failed");
2464
- }, []);
2433
+ }
2434
+ }, [context]);
2465
2435
  var handleAuthFailed = React.useCallback(function () { return __awaiter$1(void 0, void 0, void 0, function () {
2466
- return __generator$1(this, function (_a) {
2467
- switch (_a.label) {
2468
- case 0: return [4 /*yield*/, context.logout()];
2436
+ var _a;
2437
+ return __generator$1(this, function (_b) {
2438
+ switch (_b.label) {
2439
+ case 0:
2440
+ if (context.authMode === "MSAL" && context.error) {
2441
+ (_a = context.onAuthError) === null || _a === void 0 ? void 0 : _a.call(context, context.error);
2442
+ }
2443
+ return [4 /*yield*/, context.logout()];
2469
2444
  case 1:
2470
- _a.sent();
2445
+ _b.sent();
2471
2446
  return [2 /*return*/];
2472
2447
  }
2473
2448
  });
2474
- }); }, [context.logout]);
2449
+ }); }, [context]);
2475
2450
  if (useADLogin && !CredentialsAuthEndpoint)
2476
2451
  return jsxRuntimeExports.jsx(ErrorFallback, { message: "Invalid AD Login Configuration." });
2477
2452
  if (!validatedMFAEndpoints)
@@ -2480,7 +2455,8 @@ var MFAGate = function (_a) {
2480
2455
  return jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children: children });
2481
2456
  if (context.isLoading)
2482
2457
  return fallback;
2483
- if (context.requiresMFA) {
2458
+ var shouldRequireMFA = requiresMFA !== null && requiresMFA !== void 0 ? requiresMFA : context.requiresMFA;
2459
+ if (shouldRequireMFA) {
2484
2460
  return (jsxRuntimeExports.jsx(MFAOptions, { MFAEndpoints: validatedMFAEndpoints, usePassKey: usePassKey, onComplete: handleComplete, onAuthFailed: handleAuthFailed }));
2485
2461
  }
2486
2462
  if (!context.isAuthenticated) {