@nibssplc/cams-sdk-react 0.0.1-beta.49 → 0.0.1-beta.50

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
@@ -1,13 +1,13 @@
1
1
  # NIBSS CAMS SDK - React
2
2
 
3
- React hooks and components for NIBSS CAMS SDK with support for both popup and redirect authentication flows.
3
+ React hooks and components for NIBSS CAMS SDK with support for popup authentication and Azure AD MSAL integration.
4
4
 
5
5
  ## Installation
6
6
 
7
7
  ```bash
8
8
  npm install @nibssplc/cams-sdk-react
9
9
 
10
- # For MSAL redirect support (optional)
10
+ # For Azure AD MSAL support (optional)
11
11
  npm install @azure/msal-browser @azure/msal-react
12
12
  ```
13
13
 
@@ -16,30 +16,43 @@ npm install @azure/msal-browser @azure/msal-react
16
16
  ### Popup Authentication (Default)
17
17
 
18
18
  ```tsx
19
- import { CAMSProvider, useCAMSAuth } from '@nibssplc/cams-sdk-react';
19
+ import { CAMSProvider, useCAMSContext } from '@nibssplc/cams-sdk-react';
20
20
 
21
21
  function App() {
22
22
  return (
23
- <CAMSProvider>
23
+ <CAMSProvider appCode="your-app-code" storageKey="CAMS-AUTH-SDK">
24
24
  <LoginComponent />
25
25
  </CAMSProvider>
26
26
  );
27
27
  }
28
28
 
29
29
  function LoginComponent() {
30
- const { login, logout, isAuthenticated, isLoading } = useCAMSAuth();
30
+ const { login, logout, isAuthenticated, isLoading, userProfile, error } = useCAMSContext();
31
31
 
32
- const handleLogin = () => {
33
- login({
34
- camsUrl: 'https://your-cams-instance.com/auth',
35
- messageOrigin: 'your-cams-instance.com',
36
- windowWidth: 500,
37
- windowHeight: 600,
38
- });
32
+ const handleLogin = async () => {
33
+ try {
34
+ await login({
35
+ camsUrl: 'https://your-cams-instance.com/auth',
36
+ messageOrigin: 'your-cams-instance.com',
37
+ windowWidth: 500,
38
+ windowHeight: 600,
39
+ });
40
+ } catch (err) {
41
+ console.error('Login failed:', err);
42
+ }
39
43
  };
40
44
 
45
+ if (error) {
46
+ return <div>Error: {error.message}</div>;
47
+ }
48
+
41
49
  if (isAuthenticated) {
42
- return <button onClick={logout}>Logout</button>;
50
+ return (
51
+ <div>
52
+ <p>Welcome, {userProfile?.name}!</p>
53
+ <button onClick={logout}>Logout</button>
54
+ </div>
55
+ );
43
56
  }
44
57
 
45
58
  return (
@@ -50,12 +63,62 @@ function LoginComponent() {
50
63
  }
51
64
  ```
52
65
 
53
- ### MSAL Redirect Authentication with MFA
66
+ ### Direct Hook Usage
67
+
68
+ ```tsx
69
+ import { useCAMSAuth } from '@nibssplc/cams-sdk-react';
70
+
71
+ function LoginComponent() {
72
+ const {
73
+ login,
74
+ logout,
75
+ isAuthenticated,
76
+ isLoading,
77
+ error,
78
+ token,
79
+ profile
80
+ } = useCAMSAuth({
81
+ appCode: 'your-app-code',
82
+ storageKey: 'CAMS-AUTH-SDK',
83
+ onAuthSuccess: (token) => console.log('Login successful'),
84
+ onAuthError: (error) => console.error('Login failed:', error),
85
+ });
86
+
87
+ const handleLogin = async () => {
88
+ await login({
89
+ camsUrl: 'https://your-cams-instance.com/auth',
90
+ messageOrigin: 'your-cams-instance.com',
91
+ windowWidth: 500,
92
+ windowHeight: 600,
93
+ });
94
+ };
95
+
96
+ return (
97
+ <div>
98
+ {isAuthenticated ? (
99
+ <div>
100
+ <p>Welcome, {profile?.name}!</p>
101
+ <p>Token: {token}</p>
102
+ <button onClick={logout}>Logout</button>
103
+ </div>
104
+ ) : (
105
+ <button onClick={handleLogin} disabled={isLoading}>
106
+ {isLoading ? 'Logging in...' : 'Login'}
107
+ </button>
108
+ )}
109
+ {error && <div>Error: {error.message}</div>}
110
+ </div>
111
+ );
112
+ }
113
+ ```
114
+
115
+ ### Azure AD MSAL Integration with MFA
54
116
 
55
117
  ```tsx
56
- import { CAMSMSALProvider, useCAMSMSALAuth } from '@nibssplc/cams-sdk-react';
118
+ import { CAMSMSALProvider, useCAMSMSALContext } from '@nibssplc/cams-sdk-react';
119
+ import { Configuration } from '@azure/msal-browser';
57
120
 
58
- const msalConfig = {
121
+ const msalConfig: Configuration = {
59
122
  auth: {
60
123
  clientId: 'your-client-id',
61
124
  authority: 'https://login.microsoftonline.com/your-tenant-id',
@@ -65,7 +128,14 @@ const msalConfig = {
65
128
 
66
129
  function App() {
67
130
  return (
68
- <CAMSMSALProvider msalConfig={msalConfig}>
131
+ <CAMSMSALProvider
132
+ msalConfig={msalConfig}
133
+ mfaUrl="/auth/multi-factor"
134
+ storageKey="CAMS-MSAL-AUTH-SDK"
135
+ scopes={['openid', 'profile', 'email']}
136
+ onAuthSuccess={(token) => console.log('Auth complete:', token)}
137
+ onAuthError={(error) => console.error('Auth failed:', error)}
138
+ >
69
139
  <LoginComponent />
70
140
  </CAMSMSALProvider>
71
141
  );
@@ -75,86 +145,253 @@ function LoginComponent() {
75
145
  const {
76
146
  login,
77
147
  logout,
78
- completeMFA,
79
148
  isAuthenticated,
80
149
  isLoading,
81
- isMFAPending,
82
- account
83
- } = useCAMSMSALAuth({
84
- scopes: ['openid', 'profile', 'email'],
85
- mfaUrl: 'https://your-mfa-page.com/verify',
86
- onAuthSuccess: (token) => console.log('Auth complete:', token),
87
- onMFARequired: (msalToken, account) => console.log('MFA required for:', account.name),
88
- });
150
+ error,
151
+ userProfile,
152
+ accessToken,
153
+ idToken
154
+ } = useCAMSMSALContext();
89
155
 
90
- // Handle MFA completion (call this after MFA verification)
91
- const handleMFAComplete = (mfaToken: string) => {
92
- completeMFA(mfaToken);
93
- };
156
+ if (error) {
157
+ return <div>Error: {error.message}</div>;
158
+ }
94
159
 
95
160
  if (isAuthenticated) {
96
161
  return (
97
162
  <div>
98
- <p>Welcome, {account?.name}</p>
163
+ <p>Welcome, {userProfile?.name}!</p>
164
+ <p>Access Token: {accessToken}</p>
99
165
  <button onClick={logout}>Logout</button>
100
166
  </div>
101
167
  );
102
168
  }
103
169
 
104
- if (isMFAPending) {
105
- return <div>Completing MFA verification...</div>;
106
- }
107
-
108
170
  return (
109
171
  <button onClick={login} disabled={isLoading}>
110
- {isLoading ? 'Redirecting...' : 'Login with Azure AD'}
172
+ {isLoading ? 'Logging in...' : 'Login with Azure AD'}
111
173
  </button>
112
174
  );
113
175
  }
114
176
  ```
115
177
 
178
+ ### Direct MSAL Hook Usage
179
+
180
+ ```tsx
181
+ import { useCAMSMSALAuth } from '@nibssplc/cams-sdk-react';
182
+ import { useMsal } from '@azure/msal-react';
183
+
184
+ function LoginComponent() {
185
+ const {
186
+ login,
187
+ logout,
188
+ isAuthenticated,
189
+ isLoading,
190
+ error,
191
+ accessToken,
192
+ idToken,
193
+ appCode
194
+ } = useCAMSMSALAuth({
195
+ mfaUrl: '/auth/multi-factor',
196
+ storageKey: 'CAMS-MSAL-AUTH-SDK',
197
+ scopes: ['openid', 'profile', 'email'],
198
+ onAuthSuccess: (token) => console.log('Login successful'),
199
+ onAuthError: (error) => console.error('Login failed:', error),
200
+ });
201
+
202
+ return (
203
+ <div>
204
+ {isAuthenticated ? (
205
+ <div>
206
+ <p>Access Token: {accessToken}</p>
207
+ <p>ID Token: {idToken}</p>
208
+ <button onClick={logout}>Logout</button>
209
+ </div>
210
+ ) : (
211
+ <button onClick={login} disabled={isLoading}>
212
+ {isLoading ? 'Logging in...' : 'Login with Azure AD'}
213
+ </button>
214
+ )}
215
+ {error && <div>Error: {error.message}</div>}
216
+ </div>
217
+ );
218
+ }
219
+ ```
220
+
116
221
  ## API Reference
117
222
 
223
+ ### useCAMSAuth
224
+
225
+ Hook for popup-based CAMS authentication.
226
+
227
+ ```tsx
228
+ const {
229
+ login, // (config: CAMSConfig) => Promise<void>
230
+ logout, // () => Promise<void>
231
+ isAuthenticated, // boolean
232
+ isLoading, // boolean
233
+ error, // CAMSError | null
234
+ token, // string | null
235
+ profile, // Profile | null
236
+ appCode, // string
237
+ storageKey, // string
238
+ } = useCAMSAuth(options);
239
+ ```
240
+
241
+ **Options:**
242
+ - `appCode: string` - Application code (required)
243
+ - `storageKey?: string` - Storage key (default: "CAMS-AUTH-SDK")
244
+ - `onAuthSuccess?: (token: string) => void` - Success callback
245
+ - `onAuthError?: (error: CAMSError) => void` - Error callback
246
+ - `onTokenExpired?: () => void` - Token expiration callback
247
+
118
248
  ### useCAMSMSALAuth
119
249
 
120
- Hook for MSAL redirect authentication.
250
+ Hook for Azure AD MSAL authentication with MFA support.
121
251
 
122
252
  ```tsx
123
253
  const {
124
- login,
125
- logout,
126
- isAuthenticated,
127
- isLoading,
128
- error,
129
- token,
130
- profile,
131
- account
254
+ login, // () => Promise<void>
255
+ logout, // () => Promise<void>
256
+ isAuthenticated, // boolean
257
+ isLoading, // boolean
258
+ error, // CAMSError | null
259
+ idToken, // string
260
+ accessToken, // string
261
+ appCode, // string
262
+ storageKey, // string
132
263
  } = useCAMSMSALAuth(options);
133
264
  ```
134
265
 
135
266
  **Options:**
136
- - `scopes?: string[]` - OAuth scopes (default: `['openid', 'profile', 'email']`)
137
- - `mfaUrl?: string` - Custom MFA page URL for redirect after MSAL login
138
- - `onAuthSuccess?: (token: string) => void` - Success callback (after MFA completion)
267
+ - `mfaUrl?: string` - MFA URL (default: "/auth/multi-factor")
268
+ - `storageKey?: string` - Storage key (default: "CAMS-MSAL-AUTH-SDK")
269
+ - `scopes?: string[]` - MSAL scopes (default: ["openid", "profile", "email"])
270
+ - `prompt?: string` - MSAL prompt (default: "login")
271
+ - `allowedOrigins?: string[]` - Allowed message origins
272
+ - `messageOrigin?: string` - Expected message origin
273
+ - `onAuthSuccess?: (token: string) => void` - Success callback
139
274
  - `onAuthError?: (error: CAMSError) => void` - Error callback
140
- - `onTokenExpired?: () => void` - Token expiration callback
141
- - `onMFARequired?: (msalToken: string, account: AccountInfo) => void` - MFA required callback
142
275
 
143
- **Returns:**
144
- - `completeMFA: (mfaToken: string) => void` - Complete MFA verification
145
- - `isMFAPending: boolean` - Whether MFA verification is pending
276
+ ### CAMSProvider
277
+
278
+ Provider component for popup-based authentication.
279
+
280
+ ```tsx
281
+ <CAMSProvider
282
+ appCode="your-app-code"
283
+ storageKey="CAMS-AUTH-SDK"
284
+ onAuthSuccess={(token) => console.log('Success')}
285
+ onAuthError={(error) => console.error('Error:', error)}
286
+ onTokenExpired={() => console.log('Token expired')}
287
+ >
288
+ {children}
289
+ </CAMSProvider>
290
+ ```
146
291
 
147
292
  ### CAMSMSALProvider
148
293
 
149
- Provider component for MSAL integration.
294
+ Provider component for Azure AD MSAL integration.
150
295
 
151
296
  ```tsx
152
- <CAMSMSALProvider msalConfig={config} msalInstance={instance}>
297
+ <CAMSMSALProvider
298
+ msalConfig={config}
299
+ msalInstance={instance}
300
+ mfaUrl="/auth/multi-factor"
301
+ storageKey="CAMS-MSAL-AUTH-SDK"
302
+ scopes={['openid', 'profile', 'email']}
303
+ onAuthSuccess={(token) => console.log('Success')}
304
+ onAuthError={(error) => console.error('Error:', error)}
305
+ >
153
306
  {children}
154
307
  </CAMSMSALProvider>
155
308
  ```
156
309
 
157
310
  **Props:**
158
- - `msalConfig: Configuration` - MSAL configuration object
311
+ - `msalConfig: Configuration` - MSAL configuration object (required)
159
312
  - `msalInstance?: PublicClientApplication` - Optional pre-configured MSAL instance
160
- - `children: ReactNode` - Child components
313
+ - `children: ReactNode` - Child components
314
+ - All `UseCAMSMSALAuthOptions` are also supported as props
315
+
316
+ ### Context Hooks
317
+
318
+ #### useCAMSContext
319
+
320
+ Access CAMS authentication context (must be used within `CAMSProvider`).
321
+
322
+ ```tsx
323
+ const {
324
+ login, logout, isAuthenticated, isLoading, error, token, profile,
325
+ userProfile, setUserProfile, appCode, storageKey
326
+ } = useCAMSContext();
327
+ ```
328
+
329
+ #### useCAMSMSALContext
330
+
331
+ Access CAMS MSAL authentication context (must be used within `CAMSMSALProvider`).
332
+
333
+ ```tsx
334
+ const {
335
+ login, logout, isAuthenticated, isLoading, error,
336
+ idToken, accessToken, appCode, storageKey,
337
+ userProfile, setUserProfile
338
+ } = useCAMSMSALContext();
339
+ ```
340
+
341
+ ### Components
342
+
343
+ #### ProtectedRoute
344
+
345
+ Route component that requires authentication.
346
+
347
+ ```tsx
348
+ <ProtectedRoute fallback={<LoginPage />}>
349
+ <Dashboard />
350
+ </ProtectedRoute>
351
+ ```
352
+
353
+ #### ClientOnly
354
+
355
+ Wrapper component for client-side only rendering (useful for SSR).
356
+
357
+ ```tsx
358
+ <ClientOnly fallback={<div>Loading...</div>}>
359
+ <CAMSProvider>
360
+ <App />
361
+ </CAMSProvider>
362
+ </ClientOnly>
363
+ ```
364
+
365
+ ## Types
366
+
367
+ ### Profile
368
+
369
+ ```typescript
370
+ interface Profile {
371
+ userProfile: {
372
+ name: string;
373
+ image?: string | null;
374
+ tokens: {
375
+ Bearer: string;
376
+ };
377
+ };
378
+ }
379
+ ```
380
+
381
+ ### CAMSError
382
+
383
+ ```typescript
384
+ class CAMSError extends Error {
385
+ constructor(public type: CAMSErrorType, message: string);
386
+ }
387
+
388
+ enum CAMSErrorType {
389
+ POPUP_BLOCKED = "POPUP_BLOCKED",
390
+ TIMEOUT = "TIMEOUT",
391
+ INVALID_ORIGIN = "INVALID_ORIGIN",
392
+ USER_CANCELLED = "USER_CANCELLED",
393
+ INVALID_URL = "INVALID_URL",
394
+ MAX_RETRIES_EXCEEDED = "MAX_RETRIES_EXCEEDED",
395
+ API_VALIDATION_ERROR = "VALIDATION_ERROR",
396
+ }
397
+ ```
@@ -1,18 +1,13 @@
1
- import { ReactNode } from 'react';
2
- import { CAMSConfig } from '@nibssplc/cams-sdk';
1
+ import React from "react";
2
+ import { Profile } from '@nibssplc/cams-sdk';
3
3
  import { UseCAMSAuthReturn, UseCAMSAuthOptions } from '../hooks/useCAMSAuth';
4
- import { UseCAMSMSALAuthOptions } from '../hooks/useCAMSMSALAuth';
5
4
  interface CAMSContextValue extends UseCAMSAuthReturn {
6
- defaultConfig?: Partial<CAMSConfig>;
7
- isAuthenticated: boolean;
8
- idToken: string | null;
9
- accessToken: string | null;
5
+ userProfile: Profile | null;
6
+ setUserProfile: (profile: Profile | null) => void;
10
7
  }
11
8
  export interface CAMSProviderProps extends UseCAMSAuthOptions {
12
- children: ReactNode;
13
- defaultConfig?: Partial<CAMSConfig>;
14
- msalOptions?: UseCAMSMSALAuthOptions;
9
+ children: React.ReactNode;
15
10
  }
16
- export declare function CAMSProvider({ children, defaultConfig, msalOptions, ...authOptions }: CAMSProviderProps): import("react/jsx-runtime").JSX.Element;
11
+ export declare function CAMSProvider({ children, ...authOptions }: Readonly<CAMSProviderProps>): import("react/jsx-runtime").JSX.Element;
17
12
  export declare function useCAMSContext(): CAMSContextValue;
18
13
  export {};
@@ -1,5 +1,6 @@
1
- import { CAMSConfig, CAMSError, Profile } from '@nibssplc/cams-sdk';
1
+ import { CAMSConfig, CAMSError, Profile } from "@nibssplc/cams-sdk";
2
2
  export interface UseCAMSAuthOptions {
3
+ appCode: string;
3
4
  storageKey?: string;
4
5
  onAuthSuccess?: (token: string) => void;
5
6
  onAuthError?: (error: CAMSError) => void;
@@ -13,5 +14,7 @@ export interface UseCAMSAuthReturn {
13
14
  error: CAMSError | null;
14
15
  token: string | null;
15
16
  profile: Profile | null;
17
+ appCode: string;
18
+ storageKey: string;
16
19
  }
17
20
  export declare function useCAMSAuth(options?: UseCAMSAuthOptions): UseCAMSAuthReturn;
@@ -4,6 +4,7 @@ export interface UseCAMSMSALAuthOptions {
4
4
  onAuthError?: (error: CAMSError) => void;
5
5
  onTokenExpired?: () => void;
6
6
  scopes?: string[];
7
+ storageKey?: string;
7
8
  mfaUrl?: string;
8
9
  prompt?: string;
9
10
  messageOrigin?: string;