@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 +18 -4
- package/dist/components/MFAGate.d.ts +2 -1
- package/dist/components/UnifiedCAMSProvider.d.ts +5 -0
- package/dist/context/CAMSContext.d.ts +5 -0
- package/dist/hooks/useCAMSMSALAuth.d.ts +0 -5
- package/dist/index.cjs.js +26 -50
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.esm.js +26 -50
- package/dist/index.esm.js.map +1 -1
- package/dist/styles.css +3 -0
- package/package.json +7 -3
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
|
-
|
|
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
|
-
```
|
|
279
|
-
|
|
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,
|
|
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
|
-
|
|
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
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
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
|
-
|
|
2445
|
+
_b.sent();
|
|
2471
2446
|
return [2 /*return*/];
|
|
2472
2447
|
}
|
|
2473
2448
|
});
|
|
2474
|
-
}); }, [context
|
|
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
|
-
|
|
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) {
|