@djangocfg/api 2.1.46 → 2.1.47

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/auth.cjs CHANGED
@@ -62,7 +62,7 @@ module.exports = __toCommonJS(auth_exports);
62
62
 
63
63
  // src/auth/context/AuthContext.tsx
64
64
  var import_navigation = require("next/navigation");
65
- var import_react2 = require("react");
65
+ var import_react3 = require("react");
66
66
  var import_hooks2 = require("@djangocfg/ui-nextjs/hooks");
67
67
 
68
68
  // src/generated/cfg_accounts/accounts__auth/client.ts
@@ -3717,6 +3717,185 @@ function getCacheMetadata() {
3717
3717
  }
3718
3718
  __name(getCacheMetadata, "getCacheMetadata");
3719
3719
 
3720
+ // src/auth/hooks/useSessionStorage.ts
3721
+ var import_react = require("react");
3722
+ function useSessionStorage(key, initialValue) {
3723
+ const [storedValue, setStoredValue] = (0, import_react.useState)(() => {
3724
+ if (typeof window === "undefined") {
3725
+ return initialValue;
3726
+ }
3727
+ try {
3728
+ const item = window.sessionStorage.getItem(key);
3729
+ return item ? JSON.parse(item) : initialValue;
3730
+ } catch (error) {
3731
+ authLogger.error(`Error reading sessionStorage key "${key}":`, error);
3732
+ return initialValue;
3733
+ }
3734
+ });
3735
+ const checkDataSize = /* @__PURE__ */ __name((data) => {
3736
+ try {
3737
+ const jsonString = JSON.stringify(data);
3738
+ const sizeInBytes = new Blob([jsonString]).size;
3739
+ const sizeInKB = sizeInBytes / 1024;
3740
+ if (sizeInKB > 1024) {
3741
+ authLogger.warn(`Data size (${sizeInKB.toFixed(2)}KB) exceeds 1MB limit for key "${key}"`);
3742
+ return false;
3743
+ }
3744
+ return true;
3745
+ } catch (error) {
3746
+ authLogger.error(`Error checking data size for key "${key}":`, error);
3747
+ return false;
3748
+ }
3749
+ }, "checkDataSize");
3750
+ const clearOldData = /* @__PURE__ */ __name(() => {
3751
+ try {
3752
+ const keys = Object.keys(sessionStorage).filter((key2) => key2 && typeof key2 === "string");
3753
+ if (keys.length > 50) {
3754
+ const itemsToRemove = Math.ceil(keys.length * 0.2);
3755
+ for (let i = 0; i < itemsToRemove; i++) {
3756
+ try {
3757
+ const key2 = keys[i];
3758
+ if (key2) {
3759
+ sessionStorage.removeItem(key2);
3760
+ sessionStorage.removeItem(`${key2}_timestamp`);
3761
+ }
3762
+ } catch {
3763
+ }
3764
+ }
3765
+ }
3766
+ } catch (error) {
3767
+ authLogger.error("Error clearing old sessionStorage data:", error);
3768
+ }
3769
+ }, "clearOldData");
3770
+ const forceClearAll = /* @__PURE__ */ __name(() => {
3771
+ try {
3772
+ const keys = Object.keys(sessionStorage);
3773
+ for (const key2 of keys) {
3774
+ try {
3775
+ sessionStorage.removeItem(key2);
3776
+ } catch {
3777
+ }
3778
+ }
3779
+ } catch (error) {
3780
+ authLogger.error("Error force clearing sessionStorage:", error);
3781
+ }
3782
+ }, "forceClearAll");
3783
+ const setValue = /* @__PURE__ */ __name((value) => {
3784
+ try {
3785
+ const valueToStore = value instanceof Function ? value(storedValue) : value;
3786
+ if (!checkDataSize(valueToStore)) {
3787
+ authLogger.warn(`Data size too large for key "${key}", removing key`);
3788
+ try {
3789
+ window.sessionStorage.removeItem(key);
3790
+ window.sessionStorage.removeItem(`${key}_timestamp`);
3791
+ } catch {
3792
+ }
3793
+ setStoredValue(valueToStore);
3794
+ return;
3795
+ }
3796
+ setStoredValue(valueToStore);
3797
+ if (typeof window !== "undefined") {
3798
+ try {
3799
+ window.sessionStorage.setItem(key, JSON.stringify(valueToStore));
3800
+ window.sessionStorage.setItem(`${key}_timestamp`, Date.now().toString());
3801
+ } catch (storageError) {
3802
+ if (storageError.name === "QuotaExceededError" || storageError.code === 22 || storageError.message?.includes("quota")) {
3803
+ authLogger.warn("sessionStorage quota exceeded, clearing old data...");
3804
+ clearOldData();
3805
+ try {
3806
+ window.sessionStorage.setItem(key, JSON.stringify(valueToStore));
3807
+ window.sessionStorage.setItem(`${key}_timestamp`, Date.now().toString());
3808
+ } catch (retryError) {
3809
+ authLogger.error(`Failed to set sessionStorage key "${key}" after clearing old data:`, retryError);
3810
+ try {
3811
+ forceClearAll();
3812
+ window.sessionStorage.setItem(key, JSON.stringify(valueToStore));
3813
+ window.sessionStorage.setItem(`${key}_timestamp`, Date.now().toString());
3814
+ } catch (finalError) {
3815
+ authLogger.error(`Failed to set sessionStorage key "${key}" after force clearing:`, finalError);
3816
+ setStoredValue(valueToStore);
3817
+ }
3818
+ }
3819
+ } else {
3820
+ throw storageError;
3821
+ }
3822
+ }
3823
+ }
3824
+ } catch (error) {
3825
+ authLogger.error(`Error setting sessionStorage key "${key}":`, error);
3826
+ const valueToStore = value instanceof Function ? value(storedValue) : value;
3827
+ setStoredValue(valueToStore);
3828
+ }
3829
+ }, "setValue");
3830
+ const removeValue = /* @__PURE__ */ __name(() => {
3831
+ try {
3832
+ setStoredValue(initialValue);
3833
+ if (typeof window !== "undefined") {
3834
+ try {
3835
+ window.sessionStorage.removeItem(key);
3836
+ window.sessionStorage.removeItem(`${key}_timestamp`);
3837
+ } catch (removeError) {
3838
+ if (removeError.name === "QuotaExceededError" || removeError.code === 22 || removeError.message?.includes("quota")) {
3839
+ authLogger.warn("sessionStorage quota exceeded during removal, clearing old data...");
3840
+ clearOldData();
3841
+ try {
3842
+ window.sessionStorage.removeItem(key);
3843
+ window.sessionStorage.removeItem(`${key}_timestamp`);
3844
+ } catch (retryError) {
3845
+ authLogger.error(`Failed to remove sessionStorage key "${key}" after clearing:`, retryError);
3846
+ forceClearAll();
3847
+ }
3848
+ } else {
3849
+ throw removeError;
3850
+ }
3851
+ }
3852
+ }
3853
+ } catch (error) {
3854
+ authLogger.error(`Error removing sessionStorage key "${key}":`, error);
3855
+ }
3856
+ }, "removeValue");
3857
+ return [storedValue, setValue, removeValue];
3858
+ }
3859
+ __name(useSessionStorage, "useSessionStorage");
3860
+
3861
+ // src/auth/hooks/useAuthRedirect.ts
3862
+ var AUTH_REDIRECT_KEY = "auth_redirect_url";
3863
+ var useAuthRedirectManager = /* @__PURE__ */ __name((options = {}) => {
3864
+ const { fallbackUrl = "/dashboard", clearOnUse = true } = options;
3865
+ const [redirectUrl, setRedirectUrl, removeRedirectUrl] = useSessionStorage(AUTH_REDIRECT_KEY, "");
3866
+ const setRedirect = /* @__PURE__ */ __name((url) => {
3867
+ setRedirectUrl(url);
3868
+ }, "setRedirect");
3869
+ const getRedirect = /* @__PURE__ */ __name(() => {
3870
+ return redirectUrl;
3871
+ }, "getRedirect");
3872
+ const clearRedirect = /* @__PURE__ */ __name(() => {
3873
+ removeRedirectUrl();
3874
+ }, "clearRedirect");
3875
+ const hasRedirect = /* @__PURE__ */ __name(() => {
3876
+ return redirectUrl.length > 0;
3877
+ }, "hasRedirect");
3878
+ const getFinalRedirectUrl = /* @__PURE__ */ __name(() => {
3879
+ return redirectUrl || fallbackUrl;
3880
+ }, "getFinalRedirectUrl");
3881
+ const useAndClearRedirect = /* @__PURE__ */ __name(() => {
3882
+ const finalUrl = getFinalRedirectUrl();
3883
+ if (clearOnUse) {
3884
+ clearRedirect();
3885
+ }
3886
+ return finalUrl;
3887
+ }, "useAndClearRedirect");
3888
+ return {
3889
+ redirectUrl,
3890
+ setRedirect,
3891
+ getRedirect,
3892
+ clearRedirect,
3893
+ hasRedirect,
3894
+ getFinalRedirectUrl,
3895
+ useAndClearRedirect
3896
+ };
3897
+ }, "useAuthRedirectManager");
3898
+
3720
3899
  // src/auth/utils/analytics.ts
3721
3900
  var AnalyticsEvent = /* @__PURE__ */ ((AnalyticsEvent2) => {
3722
3901
  AnalyticsEvent2["AUTH_OTP_REQUEST"] = "auth_otp_request";
@@ -3754,7 +3933,7 @@ var Analytics = {
3754
3933
  };
3755
3934
 
3756
3935
  // src/auth/context/AccountsContext.tsx
3757
- var import_react = require("react");
3936
+ var import_react2 = require("react");
3758
3937
 
3759
3938
  // src/generated/cfg_accounts/_utils/hooks/accounts__auth.ts
3760
3939
  var import_swr = require("swr");
@@ -3826,20 +4005,20 @@ __name(useCreateAccountsOtpVerifyCreate, "useCreateAccountsOtpVerifyCreate");
3826
4005
 
3827
4006
  // src/auth/context/AccountsContext.tsx
3828
4007
  var import_jsx_runtime = require("react/jsx-runtime");
3829
- var AccountsContext = (0, import_react.createContext)(void 0);
4008
+ var AccountsContext = (0, import_react2.createContext)(void 0);
3830
4009
  function AccountsProvider({ children }) {
3831
- const [profile, setProfile] = (0, import_react.useState)(() => {
4010
+ const [profile, setProfile] = (0, import_react2.useState)(() => {
3832
4011
  const cached = getCachedProfile();
3833
4012
  return cached || void 0;
3834
4013
  });
3835
- const [isLoadingProfile, setIsLoadingProfile] = (0, import_react.useState)(false);
3836
- const [profileError, setProfileError] = (0, import_react.useState)(null);
3837
- const profileRef = (0, import_react.useRef)(profile);
3838
- const isLoadingRef = (0, import_react.useRef)(false);
3839
- (0, import_react.useEffect)(() => {
4014
+ const [isLoadingProfile, setIsLoadingProfile] = (0, import_react2.useState)(false);
4015
+ const [profileError, setProfileError] = (0, import_react2.useState)(null);
4016
+ const profileRef = (0, import_react2.useRef)(profile);
4017
+ const isLoadingRef = (0, import_react2.useRef)(false);
4018
+ (0, import_react2.useEffect)(() => {
3840
4019
  profileRef.current = profile;
3841
4020
  }, [profile]);
3842
- (0, import_react.useEffect)(() => {
4021
+ (0, import_react2.useEffect)(() => {
3843
4022
  isLoadingRef.current = isLoadingProfile;
3844
4023
  }, [isLoadingProfile]);
3845
4024
  const updateMutation = useUpdateAccountsProfileUpdateUpdate();
@@ -3848,7 +4027,7 @@ function AccountsProvider({ children }) {
3848
4027
  const otpRequestMutation = useCreateAccountsOtpRequestCreate();
3849
4028
  const otpVerifyMutation = useCreateAccountsOtpVerifyCreate();
3850
4029
  const tokenRefreshMutation = useCreateAccountsTokenRefreshCreate();
3851
- const refreshProfile = (0, import_react.useCallback)(async (callerId) => {
4030
+ const refreshProfile = (0, import_react2.useCallback)(async (callerId) => {
3852
4031
  const currentProfile = profileRef.current;
3853
4032
  const currentLoading = isLoadingRef.current;
3854
4033
  if (currentProfile && !currentLoading) {
@@ -3910,7 +4089,7 @@ function AccountsProvider({ children }) {
3910
4089
  }
3911
4090
  return result;
3912
4091
  }, "refreshToken");
3913
- const logout = (0, import_react.useCallback)(() => {
4092
+ const logout = (0, import_react2.useCallback)(() => {
3914
4093
  api.clearTokens();
3915
4094
  setProfile(void 0);
3916
4095
  setProfileError(null);
@@ -3933,7 +4112,7 @@ function AccountsProvider({ children }) {
3933
4112
  }
3934
4113
  __name(AccountsProvider, "AccountsProvider");
3935
4114
  function useAccountsContext() {
3936
- const context = (0, import_react.useContext)(AccountsContext);
4115
+ const context = (0, import_react2.useContext)(AccountsContext);
3937
4116
  if (!context) {
3938
4117
  throw new Error("useAccountsContext must be used within AccountsProvider");
3939
4118
  }
@@ -3948,7 +4127,7 @@ var defaultRoutes = {
3948
4127
  defaultCallback: "/dashboard",
3949
4128
  defaultAuthCallback: "/auth"
3950
4129
  };
3951
- var AuthContext = (0, import_react2.createContext)(void 0);
4130
+ var AuthContext = (0, import_react3.createContext)(void 0);
3952
4131
  var EMAIL_STORAGE_KEY = "auth_email";
3953
4132
  var PHONE_STORAGE_KEY = "auth_phone";
3954
4133
  var hasValidTokens = /* @__PURE__ */ __name(() => {
@@ -3957,37 +4136,41 @@ var hasValidTokens = /* @__PURE__ */ __name(() => {
3957
4136
  }, "hasValidTokens");
3958
4137
  var AuthProviderInternal = /* @__PURE__ */ __name(({ children, config }) => {
3959
4138
  const accounts = useAccountsContext();
3960
- const [isLoading, setIsLoading] = (0, import_react2.useState)(() => {
4139
+ const redirectManager = useAuthRedirectManager({
4140
+ fallbackUrl: config?.routes?.defaultCallback || defaultRoutes.defaultCallback,
4141
+ clearOnUse: true
4142
+ });
4143
+ const [isLoading, setIsLoading] = (0, import_react3.useState)(() => {
3961
4144
  if (typeof window !== "undefined") {
3962
4145
  const hasTokens = hasValidTokens();
3963
4146
  return !hasTokens;
3964
4147
  }
3965
4148
  return true;
3966
4149
  });
3967
- const [initialized, setInitialized] = (0, import_react2.useState)(false);
4150
+ const [initialized, setInitialized] = (0, import_react3.useState)(false);
3968
4151
  const router = (0, import_hooks2.useCfgRouter)();
3969
4152
  const pathname = (0, import_navigation.usePathname)();
3970
4153
  const queryParams = (0, import_hooks2.useQueryParams)();
3971
4154
  const [storedEmail, setStoredEmail, clearStoredEmail] = (0, import_hooks2.useLocalStorage)(EMAIL_STORAGE_KEY, null);
3972
4155
  const [storedPhone, setStoredPhone, clearStoredPhone] = (0, import_hooks2.useLocalStorage)(PHONE_STORAGE_KEY, null);
3973
4156
  const user = accounts.profile;
3974
- const userRef = (0, import_react2.useRef)(user);
3975
- const configRef = (0, import_react2.useRef)(config);
3976
- const isLoadingProfileRef = (0, import_react2.useRef)(false);
3977
- (0, import_react2.useEffect)(() => {
4157
+ const userRef = (0, import_react3.useRef)(user);
4158
+ const configRef = (0, import_react3.useRef)(config);
4159
+ const isLoadingProfileRef = (0, import_react3.useRef)(false);
4160
+ (0, import_react3.useEffect)(() => {
3978
4161
  userRef.current = user;
3979
4162
  }, [user]);
3980
- (0, import_react2.useEffect)(() => {
4163
+ (0, import_react3.useEffect)(() => {
3981
4164
  configRef.current = config;
3982
4165
  }, [config]);
3983
- const clearAuthState = (0, import_react2.useCallback)((caller) => {
4166
+ const clearAuthState = (0, import_react3.useCallback)((caller) => {
3984
4167
  authLogger.info("clearAuthState >> caller", caller);
3985
4168
  api.clearTokens();
3986
4169
  clearProfileCache();
3987
4170
  setInitialized(true);
3988
4171
  setIsLoading(false);
3989
4172
  }, []);
3990
- const handleGlobalAuthError = (0, import_react2.useCallback)((error, context = "API Request") => {
4173
+ const handleGlobalAuthError = (0, import_react3.useCallback)((error, context = "API Request") => {
3991
4174
  if (error?.success === false) {
3992
4175
  authLogger.warn(`Error detected in ${context}, clearing tokens`);
3993
4176
  clearAuthState(`globalAuthError:${context}`);
@@ -3995,7 +4178,7 @@ var AuthProviderInternal = /* @__PURE__ */ __name(({ children, config }) => {
3995
4178
  }
3996
4179
  return false;
3997
4180
  }, [clearAuthState]);
3998
- const loadCurrentProfile = (0, import_react2.useCallback)(async (callerId) => {
4181
+ const loadCurrentProfile = (0, import_react3.useCallback)(async (callerId) => {
3999
4182
  const finalCallerId = callerId || "AuthContext.loadCurrentProfile";
4000
4183
  if (isLoadingProfileRef.current) {
4001
4184
  authLogger.debug(`Profile loading already in progress, skipping duplicate call from: ${finalCallerId}`);
@@ -4031,7 +4214,7 @@ var AuthProviderInternal = /* @__PURE__ */ __name(({ children, config }) => {
4031
4214
  isLoadingProfileRef.current = false;
4032
4215
  }
4033
4216
  }, [clearAuthState, handleGlobalAuthError, accounts]);
4034
- (0, import_react2.useEffect)(() => {
4217
+ (0, import_react3.useEffect)(() => {
4035
4218
  if (initialized) return;
4036
4219
  const initializeAuth = /* @__PURE__ */ __name(async () => {
4037
4220
  authLogger.info("Initializing auth...");
@@ -4081,7 +4264,7 @@ var AuthProviderInternal = /* @__PURE__ */ __name(({ children, config }) => {
4081
4264
  }, "initializeAuth");
4082
4265
  initializeAuth();
4083
4266
  }, [initialized]);
4084
- (0, import_react2.useEffect)(() => {
4267
+ (0, import_react3.useEffect)(() => {
4085
4268
  if (!initialized) return;
4086
4269
  const isAuthenticated = api.isAuthenticated();
4087
4270
  const authRoute = config?.routes?.auth || defaultRoutes.auth;
@@ -4092,15 +4275,15 @@ var AuthProviderInternal = /* @__PURE__ */ __name(({ children, config }) => {
4092
4275
  router.push(callbackUrl);
4093
4276
  }
4094
4277
  }, [initialized, pathname, queryParams, config?.routes]);
4095
- const pushToDefaultCallbackUrl = (0, import_react2.useCallback)(() => {
4278
+ const pushToDefaultCallbackUrl = (0, import_react3.useCallback)(() => {
4096
4279
  const callbackUrl = config?.routes?.defaultCallback || defaultRoutes.defaultCallback;
4097
4280
  router.push(callbackUrl);
4098
4281
  }, [config?.routes, router]);
4099
- const pushToDefaultAuthCallbackUrl = (0, import_react2.useCallback)(() => {
4282
+ const pushToDefaultAuthCallbackUrl = (0, import_react3.useCallback)(() => {
4100
4283
  const authCallbackUrl = config?.routes?.defaultAuthCallback || defaultRoutes.defaultAuthCallback;
4101
4284
  router.push(authCallbackUrl);
4102
4285
  }, [config?.routes, router]);
4103
- const checkAuthAndRedirect = (0, import_react2.useCallback)(async () => {
4286
+ const checkAuthAndRedirect = (0, import_react3.useCallback)(async () => {
4104
4287
  try {
4105
4288
  setIsLoading(true);
4106
4289
  const isAuthenticated = api.isAuthenticated();
@@ -4122,7 +4305,7 @@ var AuthProviderInternal = /* @__PURE__ */ __name(({ children, config }) => {
4122
4305
  setIsLoading(false);
4123
4306
  }
4124
4307
  }, [loadCurrentProfile, clearAuthState, pushToDefaultCallbackUrl, pushToDefaultAuthCallbackUrl, handleGlobalAuthError]);
4125
- const requestOTP = (0, import_react2.useCallback)(
4308
+ const requestOTP = (0, import_react3.useCallback)(
4126
4309
  async (identifier, channel, sourceUrl) => {
4127
4310
  api.clearTokens();
4128
4311
  try {
@@ -4150,7 +4333,7 @@ var AuthProviderInternal = /* @__PURE__ */ __name(({ children, config }) => {
4150
4333
  },
4151
4334
  [accounts]
4152
4335
  );
4153
- const verifyOTP = (0, import_react2.useCallback)(
4336
+ const verifyOTP = (0, import_react3.useCallback)(
4154
4337
  async (identifier, otpCode, channel, sourceUrl, redirectUrl) => {
4155
4338
  try {
4156
4339
  const channelValue = channel === "phone" ? enums_exports.OTPVerifyRequestChannel.PHONE : enums_exports.OTPVerifyRequestChannel.EMAIL;
@@ -4181,7 +4364,9 @@ var AuthProviderInternal = /* @__PURE__ */ __name(({ children, config }) => {
4181
4364
  if (result.user?.id) {
4182
4365
  Analytics.setUser(String(result.user.id));
4183
4366
  }
4184
- const finalRedirectUrl = redirectUrl || config?.routes?.defaultCallback || defaultRoutes.defaultCallback;
4367
+ const savedRedirect = redirectManager.useAndClearRedirect();
4368
+ const finalRedirectUrl = redirectUrl || savedRedirect || config?.routes?.defaultCallback || defaultRoutes.defaultCallback;
4369
+ authLogger.info("Redirecting after auth to:", finalRedirectUrl);
4185
4370
  router.hardPush(finalRedirectUrl);
4186
4371
  return {
4187
4372
  success: true,
@@ -4202,7 +4387,7 @@ var AuthProviderInternal = /* @__PURE__ */ __name(({ children, config }) => {
4202
4387
  },
4203
4388
  [setStoredEmail, setStoredPhone, clearStoredEmail, clearStoredPhone, config?.routes?.defaultCallback, accounts, router]
4204
4389
  );
4205
- const refreshToken = (0, import_react2.useCallback)(async () => {
4390
+ const refreshToken = (0, import_react3.useCallback)(async () => {
4206
4391
  try {
4207
4392
  const refreshTokenValue = api.getRefreshToken();
4208
4393
  if (!refreshTokenValue) {
@@ -4235,7 +4420,7 @@ var AuthProviderInternal = /* @__PURE__ */ __name(({ children, config }) => {
4235
4420
  };
4236
4421
  }
4237
4422
  }, [clearAuthState, accounts]);
4238
- const logout = (0, import_react2.useCallback)(async () => {
4423
+ const logout = (0, import_react3.useCallback)(async () => {
4239
4424
  const performLogout = /* @__PURE__ */ __name(() => {
4240
4425
  Analytics.event("auth_logout" /* AUTH_LOGOUT */, {
4241
4426
  category: "auth" /* AUTH */
@@ -4264,10 +4449,10 @@ var AuthProviderInternal = /* @__PURE__ */ __name(({ children, config }) => {
4264
4449
  }
4265
4450
  }
4266
4451
  }, [accounts, config?.routes?.defaultAuthCallback, router]);
4267
- const isAdminUser = (0, import_react2.useMemo)(() => {
4452
+ const isAdminUser = (0, import_react3.useMemo)(() => {
4268
4453
  return Boolean(user?.is_staff || user?.is_superuser);
4269
4454
  }, [user]);
4270
- const value = (0, import_react2.useMemo)(
4455
+ const value = (0, import_react3.useMemo)(
4271
4456
  () => ({
4272
4457
  user,
4273
4458
  isLoading,
@@ -4287,7 +4472,12 @@ var AuthProviderInternal = /* @__PURE__ */ __name(({ children, config }) => {
4287
4472
  requestOTP,
4288
4473
  verifyOTP,
4289
4474
  refreshToken,
4290
- logout
4475
+ logout,
4476
+ // Redirect URL methods
4477
+ saveRedirectUrl: redirectManager.setRedirect,
4478
+ getRedirectUrl: redirectManager.getFinalRedirectUrl,
4479
+ clearRedirectUrl: redirectManager.clearRedirect,
4480
+ hasRedirectUrl: redirectManager.hasRedirect
4291
4481
  }),
4292
4482
  [
4293
4483
  user,
@@ -4304,7 +4494,8 @@ var AuthProviderInternal = /* @__PURE__ */ __name(({ children, config }) => {
4304
4494
  requestOTP,
4305
4495
  verifyOTP,
4306
4496
  refreshToken,
4307
- logout
4497
+ logout,
4498
+ redirectManager
4308
4499
  ]
4309
4500
  );
4310
4501
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(AuthContext.Provider, { value, children });
@@ -4313,205 +4504,32 @@ var AuthProvider = /* @__PURE__ */ __name(({ children, config }) => {
4313
4504
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(AccountsProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(AuthProviderInternal, { config, children }) });
4314
4505
  }, "AuthProvider");
4315
4506
  var useAuth = /* @__PURE__ */ __name(() => {
4316
- const context = (0, import_react2.useContext)(AuthContext);
4507
+ const context = (0, import_react3.useContext)(AuthContext);
4317
4508
  if (context === void 0) {
4318
4509
  throw new Error("useAuth must be used within an AuthProvider");
4319
4510
  }
4320
4511
  return context;
4321
4512
  }, "useAuth");
4322
4513
 
4323
- // src/auth/hooks/useSessionStorage.ts
4324
- var import_react3 = require("react");
4325
- function useSessionStorage(key, initialValue) {
4326
- const [storedValue, setStoredValue] = (0, import_react3.useState)(() => {
4327
- if (typeof window === "undefined") {
4328
- return initialValue;
4329
- }
4330
- try {
4331
- const item = window.sessionStorage.getItem(key);
4332
- return item ? JSON.parse(item) : initialValue;
4333
- } catch (error) {
4334
- authLogger.error(`Error reading sessionStorage key "${key}":`, error);
4335
- return initialValue;
4336
- }
4337
- });
4338
- const checkDataSize = /* @__PURE__ */ __name((data) => {
4339
- try {
4340
- const jsonString = JSON.stringify(data);
4341
- const sizeInBytes = new Blob([jsonString]).size;
4342
- const sizeInKB = sizeInBytes / 1024;
4343
- if (sizeInKB > 1024) {
4344
- authLogger.warn(`Data size (${sizeInKB.toFixed(2)}KB) exceeds 1MB limit for key "${key}"`);
4345
- return false;
4346
- }
4347
- return true;
4348
- } catch (error) {
4349
- authLogger.error(`Error checking data size for key "${key}":`, error);
4350
- return false;
4351
- }
4352
- }, "checkDataSize");
4353
- const clearOldData = /* @__PURE__ */ __name(() => {
4354
- try {
4355
- const keys = Object.keys(sessionStorage).filter((key2) => key2 && typeof key2 === "string");
4356
- if (keys.length > 50) {
4357
- const itemsToRemove = Math.ceil(keys.length * 0.2);
4358
- for (let i = 0; i < itemsToRemove; i++) {
4359
- try {
4360
- const key2 = keys[i];
4361
- if (key2) {
4362
- sessionStorage.removeItem(key2);
4363
- sessionStorage.removeItem(`${key2}_timestamp`);
4364
- }
4365
- } catch {
4366
- }
4367
- }
4368
- }
4369
- } catch (error) {
4370
- authLogger.error("Error clearing old sessionStorage data:", error);
4371
- }
4372
- }, "clearOldData");
4373
- const forceClearAll = /* @__PURE__ */ __name(() => {
4374
- try {
4375
- const keys = Object.keys(sessionStorage);
4376
- for (const key2 of keys) {
4377
- try {
4378
- sessionStorage.removeItem(key2);
4379
- } catch {
4380
- }
4381
- }
4382
- } catch (error) {
4383
- authLogger.error("Error force clearing sessionStorage:", error);
4384
- }
4385
- }, "forceClearAll");
4386
- const setValue = /* @__PURE__ */ __name((value) => {
4387
- try {
4388
- const valueToStore = value instanceof Function ? value(storedValue) : value;
4389
- if (!checkDataSize(valueToStore)) {
4390
- authLogger.warn(`Data size too large for key "${key}", removing key`);
4391
- try {
4392
- window.sessionStorage.removeItem(key);
4393
- window.sessionStorage.removeItem(`${key}_timestamp`);
4394
- } catch {
4395
- }
4396
- setStoredValue(valueToStore);
4397
- return;
4398
- }
4399
- setStoredValue(valueToStore);
4400
- if (typeof window !== "undefined") {
4401
- try {
4402
- window.sessionStorage.setItem(key, JSON.stringify(valueToStore));
4403
- window.sessionStorage.setItem(`${key}_timestamp`, Date.now().toString());
4404
- } catch (storageError) {
4405
- if (storageError.name === "QuotaExceededError" || storageError.code === 22 || storageError.message?.includes("quota")) {
4406
- authLogger.warn("sessionStorage quota exceeded, clearing old data...");
4407
- clearOldData();
4408
- try {
4409
- window.sessionStorage.setItem(key, JSON.stringify(valueToStore));
4410
- window.sessionStorage.setItem(`${key}_timestamp`, Date.now().toString());
4411
- } catch (retryError) {
4412
- authLogger.error(`Failed to set sessionStorage key "${key}" after clearing old data:`, retryError);
4413
- try {
4414
- forceClearAll();
4415
- window.sessionStorage.setItem(key, JSON.stringify(valueToStore));
4416
- window.sessionStorage.setItem(`${key}_timestamp`, Date.now().toString());
4417
- } catch (finalError) {
4418
- authLogger.error(`Failed to set sessionStorage key "${key}" after force clearing:`, finalError);
4419
- setStoredValue(valueToStore);
4420
- }
4421
- }
4422
- } else {
4423
- throw storageError;
4424
- }
4425
- }
4426
- }
4427
- } catch (error) {
4428
- authLogger.error(`Error setting sessionStorage key "${key}":`, error);
4429
- const valueToStore = value instanceof Function ? value(storedValue) : value;
4430
- setStoredValue(valueToStore);
4431
- }
4432
- }, "setValue");
4433
- const removeValue = /* @__PURE__ */ __name(() => {
4434
- try {
4435
- setStoredValue(initialValue);
4436
- if (typeof window !== "undefined") {
4437
- try {
4438
- window.sessionStorage.removeItem(key);
4439
- window.sessionStorage.removeItem(`${key}_timestamp`);
4440
- } catch (removeError) {
4441
- if (removeError.name === "QuotaExceededError" || removeError.code === 22 || removeError.message?.includes("quota")) {
4442
- authLogger.warn("sessionStorage quota exceeded during removal, clearing old data...");
4443
- clearOldData();
4444
- try {
4445
- window.sessionStorage.removeItem(key);
4446
- window.sessionStorage.removeItem(`${key}_timestamp`);
4447
- } catch (retryError) {
4448
- authLogger.error(`Failed to remove sessionStorage key "${key}" after clearing:`, retryError);
4449
- forceClearAll();
4450
- }
4451
- } else {
4452
- throw removeError;
4453
- }
4454
- }
4455
- }
4456
- } catch (error) {
4457
- authLogger.error(`Error removing sessionStorage key "${key}":`, error);
4458
- }
4459
- }, "removeValue");
4460
- return [storedValue, setValue, removeValue];
4461
- }
4462
- __name(useSessionStorage, "useSessionStorage");
4463
-
4464
- // src/auth/hooks/useAuthRedirect.ts
4465
- var AUTH_REDIRECT_KEY = "auth_redirect_url";
4466
- var useAuthRedirectManager = /* @__PURE__ */ __name((options = {}) => {
4467
- const { fallbackUrl = "/dashboard", clearOnUse = true } = options;
4468
- const [redirectUrl, setRedirectUrl, removeRedirectUrl] = useSessionStorage(AUTH_REDIRECT_KEY, "");
4469
- const setRedirect = /* @__PURE__ */ __name((url) => {
4470
- setRedirectUrl(url);
4471
- }, "setRedirect");
4472
- const getRedirect = /* @__PURE__ */ __name(() => {
4473
- return redirectUrl;
4474
- }, "getRedirect");
4475
- const clearRedirect = /* @__PURE__ */ __name(() => {
4476
- removeRedirectUrl();
4477
- }, "clearRedirect");
4478
- const hasRedirect = /* @__PURE__ */ __name(() => {
4479
- return redirectUrl.length > 0;
4480
- }, "hasRedirect");
4481
- const getFinalRedirectUrl = /* @__PURE__ */ __name(() => {
4482
- return redirectUrl || fallbackUrl;
4483
- }, "getFinalRedirectUrl");
4484
- const useAndClearRedirect = /* @__PURE__ */ __name(() => {
4485
- const finalUrl = getFinalRedirectUrl();
4486
- if (clearOnUse) {
4487
- clearRedirect();
4488
- }
4489
- return finalUrl;
4490
- }, "useAndClearRedirect");
4491
- return {
4492
- redirectUrl,
4493
- setRedirect,
4494
- getRedirect,
4495
- clearRedirect,
4496
- hasRedirect,
4497
- getFinalRedirectUrl,
4498
- useAndClearRedirect
4499
- };
4500
- }, "useAuthRedirectManager");
4501
-
4502
4514
  // src/auth/hooks/useAuthGuard.ts
4503
4515
  var import_react4 = require("react");
4504
4516
  var import_hooks3 = require("@djangocfg/ui-nextjs/hooks");
4505
4517
  var useAuthGuard = /* @__PURE__ */ __name((options = {}) => {
4506
- const { redirectTo = "/auth", requireAuth = true } = options;
4507
- const { isAuthenticated, isLoading } = useAuth();
4518
+ const { redirectTo = "/auth", requireAuth = true, saveRedirectUrl: shouldSaveUrl = true } = options;
4519
+ const { isAuthenticated, isLoading, saveRedirectUrl } = useAuth();
4508
4520
  const router = (0, import_hooks3.useCfgRouter)();
4521
+ const [isRedirecting, setIsRedirecting] = (0, import_react4.useState)(false);
4509
4522
  (0, import_react4.useEffect)(() => {
4510
- if (!isLoading && requireAuth && !isAuthenticated) {
4523
+ if (!isLoading && requireAuth && !isAuthenticated && !isRedirecting) {
4524
+ if (shouldSaveUrl && typeof window !== "undefined") {
4525
+ const currentUrl = window.location.pathname + window.location.search;
4526
+ saveRedirectUrl(currentUrl);
4527
+ }
4528
+ setIsRedirecting(true);
4511
4529
  router.push(redirectTo);
4512
4530
  }
4513
- }, [isAuthenticated, isLoading, router, redirectTo, requireAuth]);
4514
- return { isAuthenticated, isLoading };
4531
+ }, [isAuthenticated, isLoading, router, redirectTo, requireAuth, isRedirecting, shouldSaveUrl, saveRedirectUrl]);
4532
+ return { isAuthenticated, isLoading, isRedirecting };
4515
4533
  }, "useAuthGuard");
4516
4534
 
4517
4535
  // src/auth/hooks/useLocalStorage.ts