@nibssplc/cams-sdk-react 0.0.1-beta.76 → 0.0.1-beta.77

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.cjs.js CHANGED
@@ -256,315 +256,9 @@ function useCAMSAuth(options) {
256
256
  };
257
257
  }
258
258
 
259
- var CAMSContext$1 = React.createContext(null);
260
- function useCAMSContext$1() {
261
- var context = React.useContext(CAMSContext$1);
262
- if (!context) {
263
- throw new Error("useCAMSContext must be used within a UnifiedCAMSProvider");
264
- }
265
- return context;
266
- }
259
+ var jsxRuntime = {exports: {}};
267
260
 
268
- function useCAMSMSALAuth(options) {
269
- var _this = this;
270
- var storageKey = options.storageKey || "CAMS-MSAL-AUTH-SDK";
271
- var _a = msalReact.useMsal(), instance = _a.instance, inProgress = _a.inProgress, accounts = _a.accounts;
272
- var account = msalReact.useAccount(accounts[0] || {});
273
- var setUserProfile = useCAMSContext$1().setUserProfile;
274
- var _b = React.useState(null), error = _b[0], setError = _b[1];
275
- var _c = React.useState(""), idToken = _c[0], setIdToken = _c[1];
276
- var _d = React.useState(""), accessToken = _d[0], setAccessToken = _d[1];
277
- var _e = React.useState(null), mfaAuthenticator = _e[0], setMfaAuthenticator = _e[1];
278
- var _f = React.useState(false), requiresMFA = _f[0], setRequiresMFA = _f[1];
279
- var isLoading = inProgress !== msalBrowser.InteractionStatus.None;
280
- var isAuthenticated = !!account && !!accessToken && !requiresMFA;
281
- var scopes = options.scopes || ["openid", "profile", "email"];
282
- var isTokenValid = function (token) {
283
- try {
284
- var payload = JSON.parse(atob(token.split(".")[1]));
285
- return payload.exp * 1000 > Date.now();
286
- }
287
- catch (_a) {
288
- return false;
289
- }
290
- };
291
- React.useEffect(function () {
292
- if (typeof window !== "undefined" && !accessToken) {
293
- var stored = localStorage.getItem(storageKey);
294
- if (stored) {
295
- try {
296
- var _a = JSON.parse(stored), accessToken_1 = _a.accessToken, idToken_1 = _a.idToken, storedRequiresMFA = _a.requiresMFA, storedIsAuthenticated = _a.isAuthenticated;
297
- if (accessToken_1 && isTokenValid(accessToken_1)) {
298
- setAccessToken(accessToken_1);
299
- setIdToken(idToken_1);
300
- // Restore MFA state
301
- if (storedRequiresMFA && !storedIsAuthenticated) {
302
- var mfaConfig = {
303
- accessToken: accessToken_1,
304
- idToken: idToken_1,
305
- appCode: options.appCode,
306
- provider: "MSAL",
307
- apiEndpoint: options.MFAEndpoint,
308
- };
309
- var authenticator = new camsSdk.CAMSMFAAuthenticator(mfaConfig);
310
- setMfaAuthenticator(authenticator);
311
- setRequiresMFA(true);
312
- }
313
- camsSdk.Logger.debug("App Code", { ">>>": options.appCode });
314
- }
315
- else {
316
- localStorage.removeItem(storageKey);
317
- }
318
- }
319
- catch (_b) { }
320
- }
321
- else if (account) {
322
- // Storage cleared but MSAL account exists - clear MSAL state
323
- instance.logoutRedirect().catch(function () { });
324
- }
325
- }
326
- }, [accessToken, account, instance, options.storageKey]);
327
- // useEffect(() => {
328
- // const handleRedirect = async () => {
329
- // try {
330
- // const response = await instance.handleRedirectPromise();
331
- // if (response) {
332
- // const account = response.account;
333
- // instance.setActiveA ccount(account);
334
- // const tokenResponse = await instance.acq uireTokenSilent({
335
- // scopes,
336
- // account,
337
- // });
338
- // setToken(tokenResponse.accessToken);
339
- // setAccessToken(tokenResponse.accessToken);
340
- // setIdToken(tokenResponse.idTo ken);
341
- // options.onAuthSuccess?.(tokenR esponse.accessToken);
342
- // if (
343
- // typeof window !== "undefined" &&
344
- // process.env.NODE_ENV !== "test"
345
- // ) {
346
- // window.location.href = options.mfaUrl!;
347
- // }
348
- // }
349
- // } catch (err) {
350
- // console.error("Redirect handling failed:", err);
351
- // }
352
- // };
353
- // handleRedirect();
354
- // }, []);
355
- var login = React.useCallback(function () { return __awaiter(_this, void 0, void 0, function () {
356
- var response, mfaConfig, authenticator, err_1, camsError_1, camsError;
357
- var _a, _b, _c, _d;
358
- return __generator(this, function (_e) {
359
- switch (_e.label) {
360
- case 0:
361
- setError(null);
362
- _e.label = 1;
363
- case 1:
364
- _e.trys.push([1, 3, , 4]);
365
- return [4 /*yield*/, instance.loginPopup({
366
- scopes: scopes,
367
- prompt: options.prompt || "login",
368
- })];
369
- case 2:
370
- response = _e.sent();
371
- console.log("Login Token response:", {
372
- accessToken: response.accessToken,
373
- idToken: response.idToken,
374
- });
375
- setAccessToken(response.accessToken);
376
- setIdToken(response.idToken);
377
- mfaConfig = {
378
- accessToken: response.accessToken,
379
- idToken: response.idToken,
380
- appCode: options.appCode,
381
- provider: "MSAL",
382
- apiEndpoint: options.MFAEndpoint,
383
- };
384
- authenticator = new camsSdk.CAMSMFAAuthenticator(mfaConfig);
385
- setMfaAuthenticator(authenticator);
386
- setRequiresMFA(true);
387
- // Don't persist as authenticated until MFA is complete
388
- if (typeof window !== "undefined") {
389
- localStorage.setItem(storageKey, JSON.stringify({
390
- isAuthenticated: false,
391
- requiresMFA: true,
392
- accessToken: response.accessToken,
393
- idToken: response.idToken,
394
- }));
395
- }
396
- (_a = options.onAuthSuccess) === null || _a === void 0 ? void 0 : _a.call(options, response.accessToken);
397
- return [3 /*break*/, 4];
398
- case 3:
399
- err_1 = _e.sent();
400
- // Handle user cancellation gracefully
401
- if (err_1.errorCode === "user_cancelled") {
402
- camsSdk.Logger.error("User cancelled login");
403
- setError(null); // Don't treat cancellation as an error
404
- return [2 /*return*/];
405
- }
406
- // If popup is blocked
407
- if (err_1.errorCode === "popup_window_error" ||
408
- ((_b = err_1.message) === null || _b === void 0 ? void 0 : _b.includes("popup"))) {
409
- camsError_1 = new camsSdk.CAMSError(camsSdk.CAMSErrorType.POPUP_BLOCKED, "Popup blocked by browser. Please allow popups and try again.");
410
- setError(camsError_1);
411
- (_c = options.onAuthError) === null || _c === void 0 ? void 0 : _c.call(options, camsError_1);
412
- return [2 /*return*/];
413
- }
414
- camsError = new camsSdk.CAMSError(camsSdk.CAMSErrorType.API_VALIDATION_ERROR, "Login failed: " + err_1.message || err_1);
415
- setError(camsError);
416
- (_d = options.onAuthError) === null || _d === void 0 ? void 0 : _d.call(options, camsError);
417
- return [3 /*break*/, 4];
418
- case 4: return [2 /*return*/];
419
- }
420
- });
421
- }); }, [instance, scopes, options]);
422
- var completeMFA = React.useCallback(function (data) { return __awaiter(_this, void 0, void 0, function () {
423
- return __generator(this, function (_a) {
424
- if (!mfaAuthenticator) {
425
- throw new camsSdk.CAMSError(camsSdk.CAMSErrorType.API_VALIDATION_ERROR, "MFA Authenticator not initialized");
426
- }
427
- camsSdk.Logger.info("Completed MFA.. Setting State");
428
- try {
429
- // Update storage with complete authentication BEFORE setting state
430
- if (typeof window !== "undefined") {
431
- localStorage.setItem(storageKey, JSON.stringify({
432
- isAuthenticated: true,
433
- requiresMFA: false,
434
- accessToken: accessToken,
435
- idToken: idToken,
436
- }));
437
- setUserProfile({ type: "AUTH_SUCCESS", userProfile: __assign({}, data) });
438
- setRequiresMFA(false);
439
- // Set requiresMFA to false after storage update
440
- camsSdk.Logger.debug("MFA completed successfully, storage updated", {
441
- accessToken: accessToken,
442
- idToken: idToken,
443
- isAuthenticated: true,
444
- requiresMFA: false,
445
- });
446
- }
447
- camsSdk.Logger.debug("MFA completed successfully, requiresMFA set to false");
448
- return [2 /*return*/, data];
449
- }
450
- catch (error) {
451
- setError(error);
452
- throw error;
453
- }
454
- return [2 /*return*/];
455
- });
456
- }); }, [mfaAuthenticator, accessToken, idToken, storageKey]);
457
- var sendEmailOTP = React.useCallback(function () { return __awaiter(_this, void 0, void 0, function () {
458
- return __generator(this, function (_a) {
459
- switch (_a.label) {
460
- case 0:
461
- if (!mfaAuthenticator) {
462
- return [2 /*return*/, false];
463
- }
464
- return [4 /*yield*/, mfaAuthenticator.sendEmailOTP()];
465
- case 1: return [2 /*return*/, _a.sent()];
466
- }
467
- });
468
- }); }, [mfaAuthenticator]);
469
- var logout = React.useCallback(function () { return __awaiter(_this, void 0, void 0, function () {
470
- var err_2, camsError;
471
- return __generator(this, function (_a) {
472
- switch (_a.label) {
473
- case 0:
474
- _a.trys.push([0, 2, , 3]);
475
- camsSdk.Logger.info("Logging User Out");
476
- return [4 /*yield*/, instance.logoutRedirect()];
477
- case 1:
478
- _a.sent();
479
- setAccessToken("");
480
- setIdToken("");
481
- setError(null);
482
- setMfaAuthenticator(null);
483
- setRequiresMFA(false);
484
- if (typeof window !== "undefined") {
485
- localStorage.removeItem(storageKey);
486
- }
487
- return [3 /*break*/, 3];
488
- case 2:
489
- err_2 = _a.sent();
490
- camsError = new camsSdk.CAMSError(camsSdk.CAMSErrorType.API_VALIDATION_ERROR, "Logout failed: " + err_2);
491
- setError(camsError);
492
- return [3 /*break*/, 3];
493
- case 3: return [2 /*return*/];
494
- }
495
- });
496
- }); }, [instance, storageKey]);
497
- return {
498
- login: login,
499
- logout: logout,
500
- storageKey: storageKey,
501
- isAuthenticated: isAuthenticated,
502
- isLoading: isLoading,
503
- error: error,
504
- idToken: idToken,
505
- accessToken: accessToken,
506
- appCode: options.appCode,
507
- mfaAuthenticator: mfaAuthenticator,
508
- requiresMFA: requiresMFA,
509
- completeMFA: completeMFA,
510
- sendEmailOTP: sendEmailOTP,
511
- setRequiresMFA: setRequiresMFA,
512
- };
513
- }
514
-
515
- /**
516
- * Hook for handling authentication in popup windows
517
- * This should be used by the popup app to complete authentication
518
- */
519
- function useCAMSPopupAuth(options) {
520
- if (options === void 0) { options = {}; }
521
- var _a = options.storageKey, storageKey = _a === void 0 ? "CAMS-SDK" : _a, targetOrigin = options.targetOrigin, onAuthComplete = options.onAuthComplete, onAuthError = options.onAuthError;
522
- React.useEffect(function () {
523
- if (typeof window === "undefined" || !camsSdk.isPopupWindow())
524
- return;
525
- // Initialize popup auth handler
526
- camsSdk.initializePopupAuth(targetOrigin);
527
- // Set up global handlers for the popup app
528
- var globalHandlers = window.__CAMS_POPUP_AUTH__;
529
- if (globalHandlers) {
530
- var originalCompleteAuth_1 = globalHandlers.completeAuth;
531
- var originalErrorAuth_1 = globalHandlers.errorAuth;
532
- globalHandlers.completeAuth = function (profile) {
533
- onAuthComplete === null || onAuthComplete === void 0 ? void 0 : onAuthComplete(profile);
534
- originalCompleteAuth_1(profile);
535
- };
536
- globalHandlers.errorAuth = function (error) {
537
- onAuthError === null || onAuthError === void 0 ? void 0 : onAuthError(error);
538
- originalErrorAuth_1(error);
539
- };
540
- }
541
- }, [targetOrigin, onAuthComplete, onAuthError]);
542
- var completeAuth = React.useCallback(function (profile) {
543
- if (!camsSdk.isPopupWindow()) {
544
- console.warn("completeAuth called outside of popup window");
545
- return;
546
- }
547
- var sessionManager = new camsSdk.CAMSSessionManager(localStorage, storageKey);
548
- sessionManager.completePopupAuth(profile, targetOrigin);
549
- }, [storageKey, targetOrigin]);
550
- var errorAuth = React.useCallback(function (error) {
551
- if (!camsSdk.isPopupWindow()) {
552
- console.warn("errorAuth called outside of popup window");
553
- return;
554
- }
555
- var sessionManager = new camsSdk.CAMSSessionManager(localStorage, storageKey);
556
- sessionManager.errorPopupAuth(error, targetOrigin);
557
- }, [storageKey, targetOrigin]);
558
- return {
559
- completeAuth: completeAuth,
560
- errorAuth: errorAuth,
561
- isPopup: camsSdk.isPopupWindow(),
562
- };
563
- }
564
-
565
- var jsxRuntime = {exports: {}};
566
-
567
- var reactJsxRuntime_production = {};
261
+ var reactJsxRuntime_production = {};
568
262
 
569
263
  /**
570
264
  * @license React
@@ -973,14 +667,461 @@ function requireReactJsxRuntime_development () {
973
667
  return reactJsxRuntime_development;
974
668
  }
975
669
 
976
- if (process.env.NODE_ENV === 'production') {
977
- jsxRuntime.exports = requireReactJsxRuntime_production();
978
- } else {
979
- jsxRuntime.exports = requireReactJsxRuntime_development();
670
+ if (process.env.NODE_ENV === 'production') {
671
+ jsxRuntime.exports = requireReactJsxRuntime_production();
672
+ } else {
673
+ jsxRuntime.exports = requireReactJsxRuntime_development();
674
+ }
675
+
676
+ var jsxRuntimeExports = jsxRuntime.exports;
677
+
678
+ var CAMSContext$1 = React.createContext(null);
679
+ function useCAMSContext$1() {
680
+ var context = React.useContext(CAMSContext$1);
681
+ if (!context) {
682
+ throw new Error("useCAMSContext must be used within a UnifiedCAMSProvider");
683
+ }
684
+ return context;
685
+ }
686
+
687
+ var ClientOnly = function (_a) {
688
+ var children = _a.children, _b = _a.fallback, fallback = _b === void 0 ? null : _b;
689
+ var _c = React.useState(false), hasMounted = _c[0], setHasMounted = _c[1];
690
+ React.useEffect(function () {
691
+ setHasMounted(true);
692
+ }, []);
693
+ if (!hasMounted) {
694
+ return jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children: fallback });
695
+ }
696
+ return jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children: children });
697
+ };
698
+
699
+ var GuidSchema = z.z.uuid("appCode must be a valid GUID");
700
+ var setCookie$1 = function (name, value, days) {
701
+ if (days === void 0) { days = 1; }
702
+ var expires = new Date(Date.now() + days * 24 * 60 * 60 * 1000).toUTCString();
703
+ document.cookie = "".concat(name, "=").concat(encodeURIComponent(value), "; expires=").concat(expires, "; path=/; samesite=Lax");
704
+ };
705
+ var getCookie$1 = function (name) {
706
+ var _a;
707
+ return ((_a = document.cookie
708
+ .split("; ")
709
+ .find(function (row) { return row.startsWith(name + "="); })) === null || _a === void 0 ? void 0 : _a.split("=")[1])
710
+ ? decodeURIComponent(document.cookie
711
+ .split("; ")
712
+ .find(function (row) { return row.startsWith(name + "="); })
713
+ .split("=")[1])
714
+ : null;
715
+ };
716
+ var deleteCookie$1 = function (name) {
717
+ document.cookie = name + "=; Max-Age=-99999999; path=/";
718
+ };
719
+ function CAMSProviderCore(props) {
720
+ var _this = this;
721
+ var children = props.children, mode = props.mode, appCode = props.appCode;
722
+ // Always call both hooks to satisfy Rules of Hooks
723
+ var regularAuth = useCAMSAuth(mode === "REGULAR"
724
+ ? __assign(__assign({}, props), { appCode: appCode })
725
+ : { appCode: "" });
726
+ var msalAuth = useCAMSMSALAuth(mode === "MSAL"
727
+ ? __assign(__assign({}, props), { appCode: appCode })
728
+ : { appCode: "" });
729
+ var auth = mode === "REGULAR" ? regularAuth : msalAuth;
730
+ var profileStorageKey = "".concat(auth.storageKey, "-PROFILE");
731
+ var getInitialProfile = function () {
732
+ if (typeof window === "undefined")
733
+ return null;
734
+ try {
735
+ var storedProfile = getCookie$1(profileStorageKey);
736
+ return storedProfile ? JSON.parse(storedProfile) : null;
737
+ }
738
+ catch (_a) {
739
+ return null;
740
+ }
741
+ };
742
+ var _a = React.useState(getInitialProfile), userProfile = _a[0], setUserProfile = _a[1];
743
+ React.useEffect(function () {
744
+ if (typeof window !== "undefined") {
745
+ var storedProfile = getCookie$1(profileStorageKey);
746
+ if (storedProfile) {
747
+ try {
748
+ setUserProfile(JSON.parse(storedProfile));
749
+ }
750
+ catch (_a) { }
751
+ }
752
+ }
753
+ }, [profileStorageKey]);
754
+ React.useEffect(function () {
755
+ if (typeof window !== "undefined") {
756
+ if (userProfile) {
757
+ setCookie$1(profileStorageKey, JSON.stringify(userProfile), 1);
758
+ }
759
+ else {
760
+ deleteCookie$1(profileStorageKey);
761
+ }
762
+ }
763
+ }, [userProfile, profileStorageKey]);
764
+ var enhancedLogout = function () { return __awaiter(_this, void 0, void 0, function () {
765
+ return __generator(this, function (_a) {
766
+ switch (_a.label) {
767
+ case 0: return [4 /*yield*/, auth.logout()];
768
+ case 1:
769
+ _a.sent();
770
+ setUserProfile(null);
771
+ if (typeof window !== "undefined") {
772
+ deleteCookie$1(profileStorageKey);
773
+ }
774
+ return [2 /*return*/];
775
+ }
776
+ });
777
+ }); };
778
+ // Handle MFA completion for MSAL mode
779
+ React.useEffect(function () {
780
+ if (mode === "MSAL" &&
781
+ "requiresMFA" in auth &&
782
+ !auth.requiresMFA &&
783
+ auth.isAuthenticated) {
784
+ // MFA completed, extract profile from localStorage
785
+ var storedData = localStorage.getItem(auth.storageKey);
786
+ console.log("MFA Complete - Checking for profile:", storedData);
787
+ if (storedData) {
788
+ try {
789
+ var parsed = JSON.parse(storedData);
790
+ console.log("Parsed storage data:", parsed);
791
+ if (parsed.userProfile) {
792
+ console.log("Setting user profile:", parsed.userProfile);
793
+ setUserProfile(parsed.userProfile);
794
+ }
795
+ }
796
+ catch (e) {
797
+ console.error("Error parsing stored data:", e);
798
+ }
799
+ }
800
+ }
801
+ }, [
802
+ mode,
803
+ "requiresMFA" in auth ? auth.requiresMFA : false,
804
+ auth.isAuthenticated,
805
+ auth.storageKey,
806
+ userProfile,
807
+ ]);
808
+ var value = React.useMemo(function () {
809
+ return (__assign(__assign({}, auth), { logout: enhancedLogout, userProfile: userProfile, setUserProfile: setUserProfile, authMode: mode }));
810
+ }, [auth, userProfile, mode]);
811
+ return jsxRuntimeExports.jsx(CAMSContext$1.Provider, { value: value, children: children });
812
+ }
813
+ function UnifiedCAMSProvider(props) {
814
+ // Validate appCode is a valid GUID
815
+ var appCodeValidation = GuidSchema.safeParse(props.appCode);
816
+ if (!appCodeValidation.success) {
817
+ throw new Error("Invalid appCode: ".concat(appCodeValidation.error.issues[0].message));
818
+ }
819
+ if (props.mode === "MSAL") {
820
+ var msalConfig = props.msalConfig, msalInstance = props.msalInstance;
821
+ var instance = msalInstance || new msalBrowser.PublicClientApplication(msalConfig);
822
+ return (jsxRuntimeExports.jsx(msalReact.MsalProvider, { instance: instance, children: jsxRuntimeExports.jsx(CAMSProviderCore, __assign({}, props)) }));
823
+ }
824
+ return (jsxRuntimeExports.jsx(ClientOnly, { fallback: jsxRuntimeExports.jsx("div", { children: "Loading..." }), children: jsxRuntimeExports.jsx(CAMSProviderCore, __assign({}, props)) }));
825
+ }
826
+ // Backward compatibility exports
827
+ var CAMSProvider = function (props) { return (jsxRuntimeExports.jsx(UnifiedCAMSProvider, __assign({}, props, { mode: "REGULAR" }))); };
828
+
829
+ function useCAMSMSALAuth(options) {
830
+ var _this = this;
831
+ var storageKey = options.storageKey || "CAMS-MSAL-AUTH-SDK";
832
+ var _a = msalReact.useMsal(), instance = _a.instance, inProgress = _a.inProgress, accounts = _a.accounts;
833
+ var account = msalReact.useAccount(accounts[0] || {});
834
+ var _b = React.useState(null), error = _b[0], setError = _b[1];
835
+ var _c = React.useState(""), idToken = _c[0], setIdToken = _c[1];
836
+ var _d = React.useState(""), accessToken = _d[0], setAccessToken = _d[1];
837
+ var _e = React.useState(null), mfaAuthenticator = _e[0], setMfaAuthenticator = _e[1];
838
+ var _f = React.useState(false), requiresMFA = _f[0], setRequiresMFA = _f[1];
839
+ var isLoading = inProgress !== msalBrowser.InteractionStatus.None;
840
+ var isAuthenticated = !!account && !!accessToken && !requiresMFA;
841
+ var scopes = options.scopes || ["openid", "profile", "email"];
842
+ var isTokenValid = function (token) {
843
+ try {
844
+ var payload = JSON.parse(atob(token.split(".")[1]));
845
+ return payload.exp * 1000 > Date.now();
846
+ }
847
+ catch (_a) {
848
+ return false;
849
+ }
850
+ };
851
+ React.useEffect(function () {
852
+ if (typeof window !== "undefined" && !accessToken) {
853
+ var stored = localStorage.getItem(storageKey);
854
+ if (stored) {
855
+ try {
856
+ var _a = JSON.parse(stored), accessToken_1 = _a.accessToken, idToken_1 = _a.idToken, storedRequiresMFA = _a.requiresMFA, storedIsAuthenticated = _a.isAuthenticated;
857
+ if (accessToken_1 && isTokenValid(accessToken_1)) {
858
+ setAccessToken(accessToken_1);
859
+ setIdToken(idToken_1);
860
+ // Restore MFA state
861
+ if (storedRequiresMFA && !storedIsAuthenticated) {
862
+ var mfaConfig = {
863
+ accessToken: accessToken_1,
864
+ idToken: idToken_1,
865
+ appCode: options.appCode,
866
+ provider: "MSAL",
867
+ apiEndpoint: options.MFAEndpoint,
868
+ };
869
+ var authenticator = new camsSdk.CAMSMFAAuthenticator(mfaConfig);
870
+ setMfaAuthenticator(authenticator);
871
+ setRequiresMFA(true);
872
+ }
873
+ camsSdk.Logger.debug("App Code", { ">>>": options.appCode });
874
+ }
875
+ else {
876
+ localStorage.removeItem(storageKey);
877
+ }
878
+ }
879
+ catch (_b) { }
880
+ }
881
+ else if (account) {
882
+ // Storage cleared but MSAL account exists - clear MSAL state
883
+ instance.logoutRedirect().catch(function () { });
884
+ }
885
+ }
886
+ }, [accessToken, account, instance, options.storageKey]);
887
+ // useEffect(() => {
888
+ // const handleRedirect = async () => {
889
+ // try {
890
+ // const response = await instance.handleRedirectPromise();
891
+ // if (response) {
892
+ // const account = response.account;
893
+ // instance.setActiveA ccount(account);
894
+ // const tokenResponse = await instance.acq uireTokenSilent({
895
+ // scopes,
896
+ // account,
897
+ // });
898
+ // setToken(tokenResponse.accessToken);
899
+ // setAccessToken(tokenResponse.accessToken);
900
+ // setIdToken(tokenResponse.idTo ken);
901
+ // options.onAuthSuccess?.(tokenR esponse.accessToken);
902
+ // if (
903
+ // typeof window !== "undefined" &&
904
+ // process.env.NODE_ENV !== "test"
905
+ // ) {
906
+ // window.location.href = options.mfaUrl!;
907
+ // }
908
+ // }
909
+ // } catch (err) {
910
+ // console.error("Redirect handling failed:", err);
911
+ // }
912
+ // };
913
+ // handleRedirect();
914
+ // }, []);
915
+ var login = React.useCallback(function () { return __awaiter(_this, void 0, void 0, function () {
916
+ var response, mfaConfig, authenticator, err_1, camsError_1, camsError;
917
+ var _a, _b, _c, _d;
918
+ return __generator(this, function (_e) {
919
+ switch (_e.label) {
920
+ case 0:
921
+ setError(null);
922
+ _e.label = 1;
923
+ case 1:
924
+ _e.trys.push([1, 3, , 4]);
925
+ return [4 /*yield*/, instance.loginPopup({
926
+ scopes: scopes,
927
+ prompt: options.prompt || "login",
928
+ })];
929
+ case 2:
930
+ response = _e.sent();
931
+ console.log("Login Token response:", {
932
+ accessToken: response.accessToken,
933
+ idToken: response.idToken,
934
+ });
935
+ setAccessToken(response.accessToken);
936
+ setIdToken(response.idToken);
937
+ mfaConfig = {
938
+ accessToken: response.accessToken,
939
+ idToken: response.idToken,
940
+ appCode: options.appCode,
941
+ provider: "MSAL",
942
+ apiEndpoint: options.MFAEndpoint,
943
+ };
944
+ authenticator = new camsSdk.CAMSMFAAuthenticator(mfaConfig);
945
+ setMfaAuthenticator(authenticator);
946
+ setRequiresMFA(true);
947
+ // Don't persist as authenticated until MFA is complete
948
+ if (typeof window !== "undefined") {
949
+ localStorage.setItem(storageKey, JSON.stringify({
950
+ isAuthenticated: false,
951
+ requiresMFA: true,
952
+ accessToken: response.accessToken,
953
+ idToken: response.idToken,
954
+ }));
955
+ }
956
+ (_a = options.onAuthSuccess) === null || _a === void 0 ? void 0 : _a.call(options, response.accessToken);
957
+ return [3 /*break*/, 4];
958
+ case 3:
959
+ err_1 = _e.sent();
960
+ // Handle user cancellation gracefully
961
+ if (err_1.errorCode === "user_cancelled") {
962
+ camsSdk.Logger.error("User cancelled login");
963
+ setError(null); // Don't treat cancellation as an error
964
+ return [2 /*return*/];
965
+ }
966
+ // If popup is blocked
967
+ if (err_1.errorCode === "popup_window_error" ||
968
+ ((_b = err_1.message) === null || _b === void 0 ? void 0 : _b.includes("popup"))) {
969
+ camsError_1 = new camsSdk.CAMSError(camsSdk.CAMSErrorType.POPUP_BLOCKED, "Popup blocked by browser. Please allow popups and try again.");
970
+ setError(camsError_1);
971
+ (_c = options.onAuthError) === null || _c === void 0 ? void 0 : _c.call(options, camsError_1);
972
+ return [2 /*return*/];
973
+ }
974
+ camsError = new camsSdk.CAMSError(camsSdk.CAMSErrorType.API_VALIDATION_ERROR, "Login failed: " + err_1.message || err_1);
975
+ setError(camsError);
976
+ (_d = options.onAuthError) === null || _d === void 0 ? void 0 : _d.call(options, camsError);
977
+ return [3 /*break*/, 4];
978
+ case 4: return [2 /*return*/];
979
+ }
980
+ });
981
+ }); }, [instance, scopes, options]);
982
+ var completeMFA = React.useCallback(function (data) { return __awaiter(_this, void 0, void 0, function () {
983
+ return __generator(this, function (_a) {
984
+ if (!mfaAuthenticator) {
985
+ throw new camsSdk.CAMSError(camsSdk.CAMSErrorType.API_VALIDATION_ERROR, "MFA Authenticator not initialized");
986
+ }
987
+ camsSdk.Logger.info("Completed MFA.. Setting State");
988
+ try {
989
+ // Update storage with complete authentication BEFORE setting state
990
+ if (typeof window !== "undefined") {
991
+ localStorage.setItem(storageKey, JSON.stringify({
992
+ isAuthenticated: true,
993
+ requiresMFA: false,
994
+ accessToken: accessToken,
995
+ idToken: idToken,
996
+ }));
997
+ setCookie$1("CAMS-MSAL-AUTH-SDK-PROFILE", JSON.stringify({ type: "AUTH_SUCCESS", userProfile: __assign({}, data) }), 1);
998
+ setRequiresMFA(false);
999
+ // Set requiresMFA to false after storage update
1000
+ camsSdk.Logger.debug("MFA completed successfully, storage updated", {
1001
+ accessToken: accessToken,
1002
+ idToken: idToken,
1003
+ isAuthenticated: true,
1004
+ requiresMFA: false,
1005
+ });
1006
+ }
1007
+ camsSdk.Logger.debug("MFA completed successfully, requiresMFA set to false");
1008
+ return [2 /*return*/, data];
1009
+ }
1010
+ catch (error) {
1011
+ setError(error);
1012
+ throw error;
1013
+ }
1014
+ return [2 /*return*/];
1015
+ });
1016
+ }); }, [mfaAuthenticator, accessToken, idToken, storageKey]);
1017
+ var sendEmailOTP = React.useCallback(function () { return __awaiter(_this, void 0, void 0, function () {
1018
+ return __generator(this, function (_a) {
1019
+ switch (_a.label) {
1020
+ case 0:
1021
+ if (!mfaAuthenticator) {
1022
+ return [2 /*return*/, false];
1023
+ }
1024
+ return [4 /*yield*/, mfaAuthenticator.sendEmailOTP()];
1025
+ case 1: return [2 /*return*/, _a.sent()];
1026
+ }
1027
+ });
1028
+ }); }, [mfaAuthenticator]);
1029
+ var logout = React.useCallback(function () { return __awaiter(_this, void 0, void 0, function () {
1030
+ var err_2, camsError;
1031
+ return __generator(this, function (_a) {
1032
+ switch (_a.label) {
1033
+ case 0:
1034
+ _a.trys.push([0, 2, , 3]);
1035
+ camsSdk.Logger.info("Logging User Out");
1036
+ return [4 /*yield*/, instance.logoutRedirect()];
1037
+ case 1:
1038
+ _a.sent();
1039
+ setAccessToken("");
1040
+ setIdToken("");
1041
+ setError(null);
1042
+ setMfaAuthenticator(null);
1043
+ setRequiresMFA(false);
1044
+ if (typeof window !== "undefined") {
1045
+ localStorage.removeItem(storageKey);
1046
+ }
1047
+ return [3 /*break*/, 3];
1048
+ case 2:
1049
+ err_2 = _a.sent();
1050
+ camsError = new camsSdk.CAMSError(camsSdk.CAMSErrorType.API_VALIDATION_ERROR, "Logout failed: " + err_2);
1051
+ setError(camsError);
1052
+ return [3 /*break*/, 3];
1053
+ case 3: return [2 /*return*/];
1054
+ }
1055
+ });
1056
+ }); }, [instance, storageKey]);
1057
+ return {
1058
+ login: login,
1059
+ logout: logout,
1060
+ storageKey: storageKey,
1061
+ isAuthenticated: isAuthenticated,
1062
+ isLoading: isLoading,
1063
+ error: error,
1064
+ idToken: idToken,
1065
+ accessToken: accessToken,
1066
+ appCode: options.appCode,
1067
+ mfaAuthenticator: mfaAuthenticator,
1068
+ requiresMFA: requiresMFA,
1069
+ completeMFA: completeMFA,
1070
+ sendEmailOTP: sendEmailOTP,
1071
+ setRequiresMFA: setRequiresMFA,
1072
+ };
1073
+ }
1074
+
1075
+ /**
1076
+ * Hook for handling authentication in popup windows
1077
+ * This should be used by the popup app to complete authentication
1078
+ */
1079
+ function useCAMSPopupAuth(options) {
1080
+ if (options === void 0) { options = {}; }
1081
+ var _a = options.storageKey, storageKey = _a === void 0 ? "CAMS-SDK" : _a, targetOrigin = options.targetOrigin, onAuthComplete = options.onAuthComplete, onAuthError = options.onAuthError;
1082
+ React.useEffect(function () {
1083
+ if (typeof window === "undefined" || !camsSdk.isPopupWindow())
1084
+ return;
1085
+ // Initialize popup auth handler
1086
+ camsSdk.initializePopupAuth(targetOrigin);
1087
+ // Set up global handlers for the popup app
1088
+ var globalHandlers = window.__CAMS_POPUP_AUTH__;
1089
+ if (globalHandlers) {
1090
+ var originalCompleteAuth_1 = globalHandlers.completeAuth;
1091
+ var originalErrorAuth_1 = globalHandlers.errorAuth;
1092
+ globalHandlers.completeAuth = function (profile) {
1093
+ onAuthComplete === null || onAuthComplete === void 0 ? void 0 : onAuthComplete(profile);
1094
+ originalCompleteAuth_1(profile);
1095
+ };
1096
+ globalHandlers.errorAuth = function (error) {
1097
+ onAuthError === null || onAuthError === void 0 ? void 0 : onAuthError(error);
1098
+ originalErrorAuth_1(error);
1099
+ };
1100
+ }
1101
+ }, [targetOrigin, onAuthComplete, onAuthError]);
1102
+ var completeAuth = React.useCallback(function (profile) {
1103
+ if (!camsSdk.isPopupWindow()) {
1104
+ console.warn("completeAuth called outside of popup window");
1105
+ return;
1106
+ }
1107
+ var sessionManager = new camsSdk.CAMSSessionManager(localStorage, storageKey);
1108
+ sessionManager.completePopupAuth(profile, targetOrigin);
1109
+ }, [storageKey, targetOrigin]);
1110
+ var errorAuth = React.useCallback(function (error) {
1111
+ if (!camsSdk.isPopupWindow()) {
1112
+ console.warn("errorAuth called outside of popup window");
1113
+ return;
1114
+ }
1115
+ var sessionManager = new camsSdk.CAMSSessionManager(localStorage, storageKey);
1116
+ sessionManager.errorPopupAuth(error, targetOrigin);
1117
+ }, [storageKey, targetOrigin]);
1118
+ return {
1119
+ completeAuth: completeAuth,
1120
+ errorAuth: errorAuth,
1121
+ isPopup: camsSdk.isPopupWindow(),
1122
+ };
980
1123
  }
981
1124
 
982
- var jsxRuntimeExports = jsxRuntime.exports;
983
-
984
1125
  var CAMSContext = React.createContext(null);
985
1126
  function useCAMSContext() {
986
1127
  var context = React.useContext(CAMSContext);
@@ -1007,11 +1148,11 @@ function ProtectedRoute(_a) {
1007
1148
  }
1008
1149
 
1009
1150
  var CAMSMSALContext = React.createContext(null);
1010
- var setCookie$1 = function (name, value, days) {
1151
+ var setCookie = function (name, value, days) {
1011
1152
  var expires = new Date(Date.now() + days * 864e5).toUTCString();
1012
1153
  document.cookie = "".concat(name, "=").concat(encodeURIComponent(value), "; expires=").concat(expires, "; path=/; samesite=Lax");
1013
1154
  };
1014
- var getCookie$1 = function (name) {
1155
+ var getCookie = function (name) {
1015
1156
  var _a;
1016
1157
  return ((_a = document.cookie
1017
1158
  .split("; ")
@@ -1022,7 +1163,7 @@ var getCookie$1 = function (name) {
1022
1163
  .split("=")[1])
1023
1164
  : null;
1024
1165
  };
1025
- var deleteCookie$1 = function (name) {
1166
+ var deleteCookie = function (name) {
1026
1167
  document.cookie = name + "=; Max-Age=-99999999; path=/";
1027
1168
  };
1028
1169
  var isTokenValid = function (token) {
@@ -1044,7 +1185,7 @@ function CAMSMSALProviderInner(_a) {
1044
1185
  return null;
1045
1186
  }
1046
1187
  try {
1047
- var storedProfile = getCookie$1(profileStorageKey);
1188
+ var storedProfile = getCookie(profileStorageKey);
1048
1189
  return storedProfile ? JSON.parse(storedProfile) : null;
1049
1190
  }
1050
1191
  catch (_a) {
@@ -1056,7 +1197,7 @@ function CAMSMSALProviderInner(_a) {
1056
1197
  React.useEffect(function () {
1057
1198
  if (typeof window !== "undefined") {
1058
1199
  // const storedProfile = localStorage.get Item(profileStorageKey);
1059
- var storedProfile = getCookie$1(profileStorageKey);
1200
+ var storedProfile = getCookie(profileStorageKey);
1060
1201
  if (storedProfile) {
1061
1202
  try {
1062
1203
  setUserProfile(JSON.parse(storedProfile));
@@ -1081,10 +1222,10 @@ function CAMSMSALProviderInner(_a) {
1081
1222
  React.useEffect(function () {
1082
1223
  if (typeof window !== "undefined") {
1083
1224
  if (userProfile) {
1084
- setCookie$1(profileStorageKey, JSON.stringify(userProfile), 1); // Store for 1 day
1225
+ setCookie(profileStorageKey, JSON.stringify(userProfile), 1); // Store for 1 day
1085
1226
  }
1086
1227
  else {
1087
- deleteCookie$1(profileStorageKey);
1228
+ deleteCookie(profileStorageKey);
1088
1229
  }
1089
1230
  }
1090
1231
  }, [userProfile, profileStorageKey]);
@@ -1097,7 +1238,7 @@ function CAMSMSALProviderInner(_a) {
1097
1238
  _a.sent();
1098
1239
  setUserProfile(null);
1099
1240
  if (typeof window !== "undefined") {
1100
- deleteCookie$1(profileStorageKey);
1241
+ deleteCookie(profileStorageKey);
1101
1242
  }
1102
1243
  return [2 /*return*/];
1103
1244
  }
@@ -1119,147 +1260,6 @@ function useCAMSMSALContext() {
1119
1260
  return context;
1120
1261
  }
1121
1262
 
1122
- var ClientOnly = function (_a) {
1123
- var children = _a.children, _b = _a.fallback, fallback = _b === void 0 ? null : _b;
1124
- var _c = React.useState(false), hasMounted = _c[0], setHasMounted = _c[1];
1125
- React.useEffect(function () {
1126
- setHasMounted(true);
1127
- }, []);
1128
- if (!hasMounted) {
1129
- return jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children: fallback });
1130
- }
1131
- return jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children: children });
1132
- };
1133
-
1134
- var GuidSchema = z.z.uuid("appCode must be a valid GUID");
1135
- var setCookie = function (name, value, days) {
1136
- var expires = new Date(Date.now() + days * 24 * 60 * 60 * 1000).toUTCString();
1137
- document.cookie = "".concat(name, "=").concat(encodeURIComponent(value), "; expires=").concat(expires, "; path=/; samesite=Lax");
1138
- };
1139
- var getCookie = function (name) {
1140
- var _a;
1141
- return ((_a = document.cookie
1142
- .split("; ")
1143
- .find(function (row) { return row.startsWith(name + "="); })) === null || _a === void 0 ? void 0 : _a.split("=")[1])
1144
- ? decodeURIComponent(document.cookie
1145
- .split("; ")
1146
- .find(function (row) { return row.startsWith(name + "="); })
1147
- .split("=")[1])
1148
- : null;
1149
- };
1150
- var deleteCookie = function (name) {
1151
- document.cookie = name + "=; Max-Age=-99999999; path=/";
1152
- };
1153
- function CAMSProviderCore(props) {
1154
- var _this = this;
1155
- var children = props.children, mode = props.mode, appCode = props.appCode;
1156
- // Always call both hooks to satisfy Rules of Hooks
1157
- var regularAuth = useCAMSAuth(mode === "REGULAR"
1158
- ? __assign(__assign({}, props), { appCode: appCode })
1159
- : { appCode: "" });
1160
- var msalAuth = useCAMSMSALAuth(mode === "MSAL"
1161
- ? __assign(__assign({}, props), { appCode: appCode })
1162
- : { appCode: "" });
1163
- var auth = mode === "REGULAR" ? regularAuth : msalAuth;
1164
- var profileStorageKey = "".concat(auth.storageKey, "-PROFILE");
1165
- var getInitialProfile = function () {
1166
- if (typeof window === "undefined")
1167
- return null;
1168
- try {
1169
- var storedProfile = getCookie(profileStorageKey);
1170
- return storedProfile ? JSON.parse(storedProfile) : null;
1171
- }
1172
- catch (_a) {
1173
- return null;
1174
- }
1175
- };
1176
- var _a = React.useState(getInitialProfile), userProfile = _a[0], setUserProfile = _a[1];
1177
- React.useEffect(function () {
1178
- if (typeof window !== "undefined") {
1179
- var storedProfile = getCookie(profileStorageKey);
1180
- if (storedProfile) {
1181
- try {
1182
- setUserProfile(JSON.parse(storedProfile));
1183
- }
1184
- catch (_a) { }
1185
- }
1186
- }
1187
- }, [profileStorageKey]);
1188
- React.useEffect(function () {
1189
- if (typeof window !== "undefined") {
1190
- if (userProfile) {
1191
- setCookie(profileStorageKey, JSON.stringify(userProfile), 1);
1192
- }
1193
- else {
1194
- deleteCookie(profileStorageKey);
1195
- }
1196
- }
1197
- }, [userProfile, profileStorageKey]);
1198
- var enhancedLogout = function () { return __awaiter(_this, void 0, void 0, function () {
1199
- return __generator(this, function (_a) {
1200
- switch (_a.label) {
1201
- case 0: return [4 /*yield*/, auth.logout()];
1202
- case 1:
1203
- _a.sent();
1204
- setUserProfile(null);
1205
- if (typeof window !== "undefined") {
1206
- deleteCookie(profileStorageKey);
1207
- }
1208
- return [2 /*return*/];
1209
- }
1210
- });
1211
- }); };
1212
- // Handle MFA completion for MSAL mode
1213
- React.useEffect(function () {
1214
- if (mode === "MSAL" &&
1215
- "requiresMFA" in auth &&
1216
- !auth.requiresMFA &&
1217
- auth.isAuthenticated) {
1218
- // MFA completed, extract profile from localStorage
1219
- var storedData = localStorage.getItem(auth.storageKey);
1220
- console.log("MFA Complete - Checking for profile:", storedData);
1221
- if (storedData) {
1222
- try {
1223
- var parsed = JSON.parse(storedData);
1224
- console.log("Parsed storage data:", parsed);
1225
- if (parsed.userProfile) {
1226
- console.log("Setting user profile:", parsed.userProfile);
1227
- setUserProfile(parsed.userProfile);
1228
- }
1229
- }
1230
- catch (e) {
1231
- console.error("Error parsing stored data:", e);
1232
- }
1233
- }
1234
- }
1235
- }, [
1236
- mode,
1237
- "requiresMFA" in auth ? auth.requiresMFA : false,
1238
- auth.isAuthenticated,
1239
- auth.storageKey,
1240
- userProfile,
1241
- ]);
1242
- var value = React.useMemo(function () {
1243
- return (__assign(__assign({}, auth), { logout: enhancedLogout, userProfile: userProfile, setUserProfile: setUserProfile, authMode: mode }));
1244
- }, [auth, userProfile, mode]);
1245
- return jsxRuntimeExports.jsx(CAMSContext$1.Provider, { value: value, children: children });
1246
- }
1247
- function UnifiedCAMSProvider(props) {
1248
- // Validate appCode is a valid GUID
1249
- var appCodeValidation = GuidSchema.safeParse(props.appCode);
1250
- if (!appCodeValidation.success) {
1251
- throw new Error("Invalid appCode: ".concat(appCodeValidation.error.issues[0].message));
1252
- }
1253
- if (props.mode === "MSAL") {
1254
- var msalConfig = props.msalConfig, msalInstance = props.msalInstance;
1255
- var instance = msalInstance || new msalBrowser.PublicClientApplication(msalConfig);
1256
- return (jsxRuntimeExports.jsx(msalReact.MsalProvider, { instance: instance, children: jsxRuntimeExports.jsx(CAMSProviderCore, __assign({}, props)) }));
1257
- }
1258
- return (jsxRuntimeExports.jsx(ClientOnly, { fallback: jsxRuntimeExports.jsx("div", { children: "Loading..." }), children: jsxRuntimeExports.jsx(CAMSProviderCore, __assign({}, props)) }));
1259
- }
1260
- // Backward compatibility exports
1261
- var CAMSProvider = function (props) { return (jsxRuntimeExports.jsx(UnifiedCAMSProvider, __assign({}, props, { mode: "REGULAR" }))); };
1262
-
1263
1263
  /** A special constant with type `never` */
1264
1264
  function $constructor(name, initializer, params) {
1265
1265
  function init(inst, def) {
@@ -1952,6 +1952,7 @@ exports.MFAGate = MFAGate;
1952
1952
  exports.MFAOptions = MFAOptions;
1953
1953
  exports.ProtectedRoute = ProtectedRoute;
1954
1954
  exports.UnifiedCAMSProvider = UnifiedCAMSProvider;
1955
+ exports.setCookie = setCookie$1;
1955
1956
  exports.useCAMSAuth = useCAMSAuth;
1956
1957
  exports.useCAMSContext = useCAMSContext$1;
1957
1958
  exports.useCAMSMSALAuth = useCAMSMSALAuth;