@nibssplc/cams-sdk-react 1.0.0-rc.134 → 1.0.0-rc.136
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 +99 -6
- package/dist/index.cjs.js +5 -5
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +5 -5
- package/dist/index.esm.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -293,6 +293,105 @@ export default function RootLayout({ children }) {
|
|
|
293
293
|
}
|
|
294
294
|
```
|
|
295
295
|
|
|
296
|
+
## Sample Implementation - MSAL Mode with MFA
|
|
297
|
+
|
|
298
|
+
### Environment Variables
|
|
299
|
+
|
|
300
|
+
```bash
|
|
301
|
+
# .env.local
|
|
302
|
+
NEXT_PUBLIC_AZURE_MSAL_CLIENT_ID=your-client-id
|
|
303
|
+
NEXT_PUBLIC_AZURE_MSAL_ALLOWED_TENANT_GROUP=your-tenant-id
|
|
304
|
+
NEXTAUTH_URL=http://localhost:3000
|
|
305
|
+
NEXT_PUBLIC_CAMS_APP_ID=your-app-guid
|
|
306
|
+
NEXT_PUBLIC_CAMS_SDK_BASE_URL=https://your-cams-api-endpoint.com
|
|
307
|
+
AUTH_MAX_TIMEOUT=60000
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
### Configuration Setup
|
|
311
|
+
|
|
312
|
+
```tsx
|
|
313
|
+
// lib/msalConfig.ts
|
|
314
|
+
import { Configuration } from '@azure/msal-browser';
|
|
315
|
+
|
|
316
|
+
export const msalConfig: Configuration = {
|
|
317
|
+
auth: {
|
|
318
|
+
clientId: process.env.NEXT_PUBLIC_AZURE_MSAL_CLIENT_ID ?? "",
|
|
319
|
+
authority: `https://login.microsoftonline.com/${process.env.NEXT_PUBLIC_AZURE_MSAL_ALLOWED_TENANT_GROUP}`,
|
|
320
|
+
redirectUri: process.env.NEXTAUTH_URL || (typeof window !== "undefined" ? window.location.origin : ""),
|
|
321
|
+
},
|
|
322
|
+
system: {
|
|
323
|
+
loadFrameTimeout: Number(process.env.AUTH_MAX_TIMEOUT) || 60000,
|
|
324
|
+
allowNativeBroker: false,
|
|
325
|
+
},
|
|
326
|
+
};
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
### Provider Setup with MFA
|
|
330
|
+
|
|
331
|
+
```tsx
|
|
332
|
+
// app/providers.tsx
|
|
333
|
+
'use client';
|
|
334
|
+
|
|
335
|
+
import { UnifiedCAMSProvider, MFAGate } from '@nibssplc/cams-sdk-react';
|
|
336
|
+
import { msalConfig } from '@/lib/msalConfig';
|
|
337
|
+
import { toast } from 'sonner'; // or your preferred toast library
|
|
338
|
+
|
|
339
|
+
export function Providers({ children }: { children: React.ReactNode }) {
|
|
340
|
+
return (
|
|
341
|
+
<UnifiedCAMSProvider
|
|
342
|
+
mode="MSAL"
|
|
343
|
+
appCode={process.env.NEXT_PUBLIC_CAMS_APP_ID!}
|
|
344
|
+
ValidateUserEndpoint={`${process.env.NEXT_PUBLIC_CAMS_SDK_BASE_URL}/api/Auth/AuthenticateUserMFA`}
|
|
345
|
+
msalConfig={msalConfig}
|
|
346
|
+
DisableCAMSUserProfileValidation={true}
|
|
347
|
+
>
|
|
348
|
+
<MFAGate
|
|
349
|
+
requiresMFA={false}
|
|
350
|
+
DisableCAMSUserProfileValidation={true}
|
|
351
|
+
MFAEndpoints={{
|
|
352
|
+
ValidateUserMFA: `${process.env.NEXT_PUBLIC_CAMS_SDK_BASE_URL}/api/Auth/AuthenticateUserMFA`,
|
|
353
|
+
RetrieveAuthChallenge: `${process.env.NEXT_PUBLIC_CAMS_SDK_BASE_URL}/api/Auth/RetrieveAuthChallenge`,
|
|
354
|
+
AuthChallengeVerify: `${process.env.NEXT_PUBLIC_CAMS_SDK_BASE_URL}/api/Auth/AuthChallengeVerification`,
|
|
355
|
+
}}
|
|
356
|
+
onAuthError={(err) =>
|
|
357
|
+
toast.error(`Authentication Error: ${err.message || "An Error Occurred During Authentication."}`)
|
|
358
|
+
}
|
|
359
|
+
onAuthSuccess={async (tokens) => {
|
|
360
|
+
toast.success("Authentication successful!");
|
|
361
|
+
// Handle successful authentication
|
|
362
|
+
}}
|
|
363
|
+
>
|
|
364
|
+
{children}
|
|
365
|
+
</MFAGate>
|
|
366
|
+
</UnifiedCAMSProvider>
|
|
367
|
+
);
|
|
368
|
+
}
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
### Usage in Components
|
|
372
|
+
|
|
373
|
+
```tsx
|
|
374
|
+
// app/dashboard.tsx
|
|
375
|
+
'use client';
|
|
376
|
+
|
|
377
|
+
import { useCAMSContext } from '@nibssplc/cams-sdk-react';
|
|
378
|
+
|
|
379
|
+
export default function Dashboard() {
|
|
380
|
+
const { isAuthenticated, userProfile, logout } = useCAMSContext();
|
|
381
|
+
|
|
382
|
+
if (!isAuthenticated) {
|
|
383
|
+
return <div>Loading...</div>;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
return (
|
|
387
|
+
<div>
|
|
388
|
+
<h1>Welcome, {userProfile?.name}!</h1>
|
|
389
|
+
<button onClick={logout}>Logout</button>
|
|
390
|
+
</div>
|
|
391
|
+
);
|
|
392
|
+
}
|
|
393
|
+
```
|
|
394
|
+
|
|
296
395
|
## Styling
|
|
297
396
|
|
|
298
397
|
The SDK bundles all required Tailwind CSS, so you don't need to configure Tailwind in your project. Simply import the styles:
|
|
@@ -312,12 +411,6 @@ import '@nibssplc/cams-sdk-react/dist/styles.css';
|
|
|
312
411
|
|
|
313
412
|
If your project already uses Tailwind, the SDK styles will work alongside your existing configuration.
|
|
314
413
|
|
|
315
|
-
## Examples
|
|
316
|
-
|
|
317
|
-
See the [examples](../../examples) directory for complete implementations:
|
|
318
|
-
- `integrated-mfa-example.tsx` - MSAL mode with MFA
|
|
319
|
-
- `popup-auth-example.tsx` - Regular popup authentication
|
|
320
|
-
|
|
321
414
|
## License
|
|
322
415
|
|
|
323
416
|
MIT
|
package/dist/index.cjs.js
CHANGED
|
@@ -473,13 +473,13 @@ function useCAMSMSALAuth(options) {
|
|
|
473
473
|
case 2:
|
|
474
474
|
response = _e.sent();
|
|
475
475
|
authenticator = new camsSdk.CAMSMFAAuthenticator();
|
|
476
|
-
if (!DisableCAMSUserProfileValidation) return [3 /*break*/, 3];
|
|
477
476
|
email_1 = ((_a = response.account) === null || _a === void 0 ? void 0 : _a.username) || ((_b = response.idTokenClaims) === null || _b === void 0 ? void 0 : _b.preferred_username) || "";
|
|
477
|
+
localStorage.setItem(storageKey, JSON.stringify({ accessToken: response.accessToken, idToken: response.idToken, email: email_1, appCode: appCode }));
|
|
478
|
+
if (!DisableCAMSUserProfileValidation) return [3 /*break*/, 3];
|
|
478
479
|
setAccessToken(response.accessToken);
|
|
479
480
|
setIdToken(response.idToken);
|
|
480
481
|
setEmail(email_1);
|
|
481
482
|
setRequiresMFA(false);
|
|
482
|
-
localStorage.setItem(storageKey, JSON.stringify({ accessToken: response.accessToken, idToken: response.idToken, email: email_1, appCode: appCode }));
|
|
483
483
|
camsSdk.Logger.info("CAMS User Profile Validation Disabled. Skipping MFA config fetch.");
|
|
484
484
|
return [3 /*break*/, 7];
|
|
485
485
|
case 3:
|
|
@@ -1759,13 +1759,13 @@ var DefaultLoginPage = function (_a) {
|
|
|
1759
1759
|
onADLoginSuccess === null || onADLoginSuccess === void 0 ? void 0 : onADLoginSuccess();
|
|
1760
1760
|
} }) }) }));
|
|
1761
1761
|
}
|
|
1762
|
-
return (jsxRuntime.jsxs("main", { className: "cams-sdk min-h-screen bg-gray-50", children: [jsxRuntime.jsx(framerMotion.motion.div, { initial: { opacity: 0 }, animate: { opacity: 1 }, exit: { opacity: 0 }, transition: { duration: 0.5 }, children: jsxRuntime.jsx("div", { className: "flex h-screen items-center justify-center", children: jsxRuntime.jsxs(framerMotion.motion.div, { variants: cardVariants, initial: "hidden", animate: "visible", exit: "exit", className: "w-full max-w-md p-6 space-y-
|
|
1762
|
+
return (jsxRuntime.jsxs("main", { className: "cams-sdk min-h-screen bg-gray-50", children: [jsxRuntime.jsx(framerMotion.motion.div, { initial: { opacity: 0 }, animate: { opacity: 1 }, exit: { opacity: 0 }, transition: { duration: 0.5 }, children: jsxRuntime.jsx("div", { className: "flex h-screen items-center justify-center", children: jsxRuntime.jsxs(framerMotion.motion.div, { variants: cardVariants, initial: "hidden", animate: "visible", exit: "exit", className: "w-full max-w-md p-6 space-y-6 rounded-2xl shadow-2xl", children: [jsxRuntime.jsxs(CardHeader, { className: "text-center space-y-3", children: [jsxRuntime.jsx("div", { className: "w-full flex items-center justify-center", children: jsxRuntime.jsx("img", { src: NIBSSLogo, alt: "NIBSS Logo", width: 250, height: 250 }) }), jsxRuntime.jsx(CardTitle, { className: "text-3xl font-bold", children: "NIBSS CAMS" }), jsxRuntime.jsx(CardTitle, { className: "text-gray-500 dark:text-gray-400 font-bold text-2xl", children: "Centralized Authentication" })] }), jsxRuntime.jsxs(CardAction, { className: "w-full flex flex-col items-center justify-center text-center text-gray-500 dark:text-gray-400 mb-8", children: [jsxRuntime.jsx("img", { src: AuthLogo, alt: "Auth Logo", width: 385, height: 385 }), "Use Below Identity Providers To Authenticate"] }), jsxRuntime.jsxs("div", { className: "space-y-6", children: [jsxRuntime.jsxs(Button
|
|
1763
1763
|
// variant="outline"
|
|
1764
1764
|
, {
|
|
1765
1765
|
// variant="outline"
|
|
1766
|
-
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: [jsxRuntime.jsx("img", { src: MicrosoftLogo, alt: "Microsoft Logo", width: 35, height: 35 }), jsxRuntime.jsx("span", { className: "ml-2", children: isLoading ? "Logging in..." : "Sign in with Microsoft" })] }), useADLogin && (jsxRuntime.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: [jsxRuntime.jsx(lucideReact.KeyIcon, { className: "text-[#506f4a]", size: 64 }), jsxRuntime.jsx("span", { children: isLoading
|
|
1766
|
+
className: "w-full flex items-center justify-center cursor-pointer bg-[#506f4a] hover:bg-[#506f4a] text-white rounded-lg border border-transparent px-5 py-8 text-base font-medium transition-colors duration-250", onClick: handleMSALLogin, disabled: isLoading, children: [jsxRuntime.jsx("img", { src: MicrosoftLogo, alt: "Microsoft Logo", width: 35, height: 35 }), jsxRuntime.jsx("span", { className: "ml-2", children: isLoading ? "Logging in..." : "Sign in with Microsoft" })] }), useADLogin && (jsxRuntime.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: [jsxRuntime.jsx(lucideReact.KeyIcon, { className: "text-[#506f4a]", size: 64 }), jsxRuntime.jsx("span", { children: isLoading
|
|
1767
1767
|
? "Logging in..."
|
|
1768
|
-
: "Sign in with
|
|
1768
|
+
: "Sign in with Active Directory" })] }))] }), jsxRuntime.jsxs(CardFooter, { className: "flex items-center justify-center mt-6 space-x-2 text-gray-400 text-sm", children: [jsxRuntime.jsx(lucideReact.ShieldCheck, { className: "w-6 h-6 text-[#506f4a] pulse-glow" }), jsxRuntime.jsx("span", { className: "font-semibold", children: "Powered By NIBSS" })] })] }) }) }, "landing"), jsxRuntime.jsx(ADLoginModal, { open: showADModal, onOpenChange: setShowADModal, isLoading: context.isLoading || isCredAuthLoading, setIsLoading: setIsCredAuthLoading, onLogin: function (_a) { return __awaiter$1(void 0, [_a], void 0, function (_b) {
|
|
1769
1769
|
var username = _b.username, password = _b.password, MFACode = _b.MFACode, appCode = _b.appCode;
|
|
1770
1770
|
return __generator$1(this, function (_c) {
|
|
1771
1771
|
switch (_c.label) {
|