@digitaldefiance/express-suite-react-components 2.5.7 → 2.5.9

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
@@ -362,6 +362,20 @@ MIT © Digital Defiance
362
362
 
363
363
  ## ChangeLog
364
364
 
365
+ ### Version 2.5.9
366
+
367
+ - Fix /user/verify loop
368
+
369
+ ### Version 2.5.8
370
+
371
+ #### Changed
372
+
373
+ - **User Settings Storage** - Removed localStorage for userSettings (never read, server is source of truth)
374
+ - User settings are now only stored in-memory and persisted to the server via API
375
+ - Settings are loaded from the server on login/token verification
376
+ - Eliminates risk of stale data from localStorage
377
+ - Reduces unnecessary localStorage operations
378
+
365
379
  ### Version 2.5.7
366
380
 
367
381
  - Relax isRestricted check to default false if no roles available
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@digitaldefiance/express-suite-react-components",
3
- "version": "2.5.7",
3
+ "version": "2.5.9",
4
4
  "description": "React MUI components for Digital Defiance Express Suite",
5
5
  "main": "src/index.js",
6
6
  "types": "src/index.d.ts",
@@ -25,8 +25,8 @@
25
25
  "react-router-dom": "6.29.0"
26
26
  },
27
27
  "dependencies": {
28
- "@digitaldefiance/i18n-lib": "3.6.3",
29
- "@digitaldefiance/suite-core-lib": "^2.2.20",
28
+ "@digitaldefiance/i18n-lib": "3.6.4",
29
+ "@digitaldefiance/suite-core-lib": "^2.2.22",
30
30
  "@emotion/react": "^11.14.0",
31
31
  "@emotion/styled": "^11.14.0",
32
32
  "@mui/icons-material": "^7.0.2",
@@ -1 +1 @@
1
- {"version":3,"file":"UserLanguageSelector.d.ts","sourceRoot":"","sources":["../../../../../packages/digitaldefiance-express-suite-react-components/src/components/UserLanguageSelector.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,EAAE,EAAwB,MAAM,OAAO,CAAC;AAIjD,eAAO,MAAM,oBAAoB,EAAE,EA+BlC,CAAC;AAEF,eAAe,oBAAoB,CAAC"}
1
+ {"version":3,"file":"UserLanguageSelector.d.ts","sourceRoot":"","sources":["../../../../../packages/digitaldefiance-express-suite-react-components/src/components/UserLanguageSelector.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,EAAE,EAAiC,MAAM,OAAO,CAAC;AAM1D,eAAO,MAAM,oBAAoB,EAAE,EAiClC,CAAC;AAEF,eAAe,oBAAoB,CAAC"}
@@ -5,10 +5,14 @@ const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const i18n_lib_1 = require("@digitaldefiance/i18n-lib");
6
6
  const material_1 = require("@mui/material");
7
7
  const react_1 = require("react");
8
- const AuthProvider_1 = require("../contexts/AuthProvider");
9
8
  const Flag_1 = require("./Flag");
9
+ const hooks_1 = require("../hooks");
10
+ const services_1 = require("../services");
11
+ const contexts_1 = require("../contexts");
10
12
  const UserLanguageSelector = () => {
11
- const { language, setLanguage } = (0, AuthProvider_1.useAuth)();
13
+ const { baseUrl } = (0, contexts_1.useSuiteConfig)();
14
+ const authenticatedApi = (0, react_1.useMemo)(() => (0, services_1.createAuthenticatedApiClient)(baseUrl), [baseUrl]);
15
+ const { currentLanguage, changeLanguage } = (0, hooks_1.useUserSettings)({ authenticatedApi });
12
16
  const [anchorEl, setAnchorEl] = (0, react_1.useState)(null);
13
17
  const handleClick = (event) => {
14
18
  setAnchorEl(event.currentTarget);
@@ -17,10 +21,10 @@ const UserLanguageSelector = () => {
17
21
  setAnchorEl(null);
18
22
  };
19
23
  const handleLanguageChange = (newLanguage) => {
20
- setLanguage(newLanguage);
24
+ changeLanguage(newLanguage);
21
25
  handleClose();
22
26
  };
23
- return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(material_1.Button, { onClick: handleClick, children: (0, jsx_runtime_1.jsx)(Flag_1.Flag, { language: language }) }), (0, jsx_runtime_1.jsx)(material_1.Menu, { anchorEl: anchorEl, open: Boolean(anchorEl), onClose: handleClose, children: Object.values(i18n_lib_1.LanguageRegistry.getAllLanguages()).map((lang) => ((0, jsx_runtime_1.jsxs)(material_1.MenuItem, { onClick: () => handleLanguageChange(lang.code), children: [(0, jsx_runtime_1.jsx)(Flag_1.Flag, { language: lang.code, sx: { mr: 1 } }), " ", lang.name] }, lang.code))) })] }));
27
+ return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(material_1.Button, { onClick: handleClick, children: (0, jsx_runtime_1.jsx)(Flag_1.Flag, { language: currentLanguage }) }), (0, jsx_runtime_1.jsx)(material_1.Menu, { anchorEl: anchorEl, open: Boolean(anchorEl), onClose: handleClose, children: Object.values(i18n_lib_1.LanguageRegistry.getAllLanguages()).map((lang) => ((0, jsx_runtime_1.jsxs)(material_1.MenuItem, { onClick: () => handleLanguageChange(lang.code), children: [(0, jsx_runtime_1.jsx)(Flag_1.Flag, { language: lang.code, sx: { mr: 1 } }), " ", lang.name] }, lang.code))) })] }));
24
28
  };
25
29
  exports.UserLanguageSelector = UserLanguageSelector;
26
30
  exports.default = exports.UserLanguageSelector;
@@ -1,8 +1,8 @@
1
1
  import { Member as FrontendMember, EmailString, IECIESConfig, SecureString } from '@digitaldefiance/ecies-lib';
2
- import { CurrencyCode, Timezone } from '@digitaldefiance/i18n-lib';
2
+ import { CurrencyCode } from '@digitaldefiance/i18n-lib';
3
3
  import { Wallet } from '@ethereumjs/wallet';
4
4
  import { ReactNode } from 'react';
5
- import { ISuccessMessage, IRequestUserDTO, IConstants } from '@digitaldefiance/suite-core-lib';
5
+ import { ISuccessMessage, IRequestUserDTO, IConstants, IUserSettings } from '@digitaldefiance/suite-core-lib';
6
6
  import { PaletteMode } from '@mui/material';
7
7
  export interface AuthContextData {
8
8
  /**
@@ -69,8 +69,7 @@ export interface AuthContextData {
69
69
  }>;
70
70
  isAuthenticated: boolean;
71
71
  isCheckingAuth: boolean;
72
- isPasswordLoginAvailable?: () => boolean;
73
- language: string;
72
+ isBrowserPasswordLoginAvailable?: () => boolean;
74
73
  loading: boolean;
75
74
  logout: () => void;
76
75
  mnemonic?: SecureString;
@@ -105,8 +104,6 @@ export interface AuthContextData {
105
104
  }>;
106
105
  }>;
107
106
  serverPublicKey: string | null;
108
- setColorMode: (mode?: PaletteMode) => Promise<void>;
109
- setCurrencyCode: (code?: CurrencyCode) => Promise<void>;
110
107
  /**
111
108
  * Gets the remaining time in seconds for the mnemonic expiration
112
109
  * @returns Number of seconds remaining, or 0 if no mnemonic is set
@@ -117,12 +114,10 @@ export interface AuthContextData {
117
114
  * @returns Number of seconds remaining, or 0 if no wallet is set
118
115
  */
119
116
  getWalletRemainingTime: () => number;
120
- setLanguage: (lang: string) => Promise<void>;
121
117
  setMnemonic: (mnemonic: SecureString, durationSeconds?: number) => void;
122
118
  setMnemonicExpirationSeconds: (seconds: number) => void;
123
- setTimezone: (timezone?: Timezone) => Promise<void>;
124
119
  setWalletExpirationSeconds: (seconds: number) => void;
125
- setUpPasswordLogin: (mnemonic: SecureString, password: SecureString, username?: string, email?: EmailString) => Promise<{
120
+ setUpBrowserPasswordLogin: (mnemonic: SecureString, password: SecureString, username?: string, email?: EmailString) => Promise<{
126
121
  success: boolean;
127
122
  message: string;
128
123
  } | {
@@ -130,11 +125,11 @@ export interface AuthContextData {
130
125
  errorType?: string;
131
126
  }>;
132
127
  setUser: (user: IRequestUserDTO | null) => Promise<void>;
128
+ setUserSetting: (setting?: Partial<IUserSettings>) => Promise<void>;
133
129
  setWallet: (wallet: Wallet, durationSeconds?: number) => void;
134
- toggleColorMode: () => Promise<void>;
135
130
  user: FrontendMember | null;
136
131
  userData: IRequestUserDTO | null;
137
- timezone?: Timezone;
132
+ userSettings: IUserSettings | undefined;
138
133
  token: string | null;
139
134
  wallet?: Wallet;
140
135
  walletExpirationSeconds: number;
@@ -1 +1 @@
1
- {"version":3,"file":"AuthProvider.d.ts","sourceRoot":"","sources":["../../../../../packages/digitaldefiance-express-suite-react-components/src/contexts/AuthProvider.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"AuthProvider.d.ts","sourceRoot":"","sources":["../../../../../packages/digitaldefiance-express-suite-react-components/src/contexts/AuthProvider.tsx"],"names":[],"mappings":"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"}
@@ -11,10 +11,11 @@ const authService_1 = require("../services/authService");
11
11
  const authenticatedApi_1 = require("../services/authenticatedApi");
12
12
  const useExpiringValue_1 = require("../hooks/useExpiringValue");
13
13
  const useLocalStorage_1 = require("../hooks/useLocalStorage");
14
+ const useUserSettings_1 = require("../hooks/useUserSettings");
14
15
  const suite_core_lib_1 = require("@digitaldefiance/suite-core-lib");
15
16
  exports.AuthContext = (0, react_1.createContext)({});
16
17
  const AuthProviderInner = ({ children, baseUrl, constants, eciesConfig, onLogout }) => {
17
- const { changeLanguage, currentLanguage, t, tComponent } = (0, I18nProvider_1.useI18n)();
18
+ const { t, tComponent } = (0, I18nProvider_1.useI18n)();
18
19
  const { setColorMode: themeSetPaletteMode } = (0, ThemeProvider_1.useTheme)();
19
20
  const authService = (0, react_1.useMemo)(() => (0, authService_1.createAuthService)(constants, baseUrl, eciesConfig), [constants, baseUrl, eciesConfig]);
20
21
  const authenticatedApi = (0, react_1.useMemo)(() => (0, authenticatedApi_1.createAuthenticatedApiClient)(baseUrl), [baseUrl]);
@@ -34,44 +35,10 @@ const AuthProviderInner = ({ children, baseUrl, constants, eciesConfig, onLogout
34
35
  const [isCheckingAuth, setIsCheckingAuth] = (0, react_1.useState)(true);
35
36
  const [token, setToken] = (0, react_1.useState)(null);
36
37
  const [authState, setAuthState] = (0, react_1.useState)(0);
37
- const [colorMode, setColorMode] = (0, react_1.useState)(() => {
38
- return localStorage.getItem('colorMode') ?? 'light';
39
- });
40
- const [currencyCode, setCurrencyCode] = (0, react_1.useState)(() => {
41
- return new i18n_lib_1.CurrencyCode(localStorage.getItem('currencyCode') ?? i18n_lib_1.DefaultCurrencyCode);
42
- });
43
- const [timezone, setTimezone] = (0, react_1.useState)(() => {
44
- return new i18n_lib_1.Timezone(localStorage.getItem('timezone') ?? 'UTC');
38
+ // Use the user settings hook for settings management
39
+ const { userSettings, setUserSettingAndUpdateSettings } = (0, useUserSettings_1.useUserSettings)({
40
+ authenticatedApi,
45
41
  });
46
- const setColorModeAndUpdateStorage = (0, react_1.useCallback)(async (mode) => {
47
- themeSetPaletteMode(mode ?? 'light');
48
- setColorMode(mode ?? 'light');
49
- if (!mode) {
50
- localStorage.removeItem('colorMode');
51
- return;
52
- }
53
- localStorage.setItem('colorMode', mode);
54
- }, [themeSetPaletteMode]);
55
- const setCurrencyCodeAndUpdateStorage = (0, react_1.useCallback)(async (code) => {
56
- setCurrencyCode(code);
57
- if (!code) {
58
- localStorage.removeItem('currencyCode');
59
- return;
60
- }
61
- localStorage.setItem('currencyCode', code.value);
62
- }, []);
63
- const setTimezoneAndUpdateStorage = (0, react_1.useCallback)(async (code) => {
64
- setTimezone(code);
65
- if (!code) {
66
- localStorage.removeItem('timezone');
67
- return;
68
- }
69
- localStorage.setItem('timezone', code.value);
70
- }, []);
71
- const toggleColorMode = (0, react_1.useCallback)(async () => {
72
- const newMode = colorMode === 'light' ? 'dark' : 'light';
73
- await setColorModeAndUpdateStorage(newMode);
74
- }, [colorMode, setColorModeAndUpdateStorage]);
75
42
  // Helper functions to calculate remaining time (now provided by the hooks)
76
43
  const getMnemonicRemainingTime = mnemonicManager.getRemainingTime;
77
44
  const getWalletRemainingTime = walletManager.getRemainingTime;
@@ -83,8 +50,10 @@ const AuthProviderInner = ({ children, baseUrl, constants, eciesConfig, onLogout
83
50
  // language changes and inadvertently revert to the older user.siteLanguage,
84
51
  // causing a second update request with English US.
85
52
  (0, react_1.useEffect)(() => {
86
- if (user?.siteLanguage && user.siteLanguage !== currentLanguage) {
87
- void changeLanguage(user.siteLanguage);
53
+ if (user?.siteLanguage) {
54
+ (async () => {
55
+ await setUserSettingAndUpdateSettings({ siteLanguage: user.siteLanguage });
56
+ })();
88
57
  }
89
58
  // We intentionally only react to changes in the user's saved language.
90
59
  // eslint-disable-next-line react-hooks/exhaustive-deps
@@ -119,8 +88,7 @@ const AuthProviderInner = ({ children, baseUrl, constants, eciesConfig, onLogout
119
88
  setToken(null);
120
89
  setFrontendUser(null);
121
90
  setServerPublicKey(null);
122
- setTimezone(undefined);
123
- setCurrencyCode(undefined);
91
+ await setUserSettingAndUpdateSettings(undefined);
124
92
  themeSetPaletteMode('light');
125
93
  clearMnemonic();
126
94
  clearWallet();
@@ -132,28 +100,34 @@ const AuthProviderInner = ({ children, baseUrl, constants, eciesConfig, onLogout
132
100
  setIsAuthenticated(false);
133
101
  setToken(null);
134
102
  }
135
- else {
136
- setUser(userData);
137
- setIsGlobalAdmin(userData.roles.some((r) => r.admin));
103
+ else if ('id' in userData && 'email' in userData) {
104
+ const userDataDTO = userData;
105
+ setUser(userDataDTO);
106
+ setIsGlobalAdmin((userDataDTO).roles.some((r) => r.admin));
138
107
  setIsAuthenticated(true);
139
108
  setToken(token);
140
- // Set theme based on user's darkMode preference
141
- setColorModeAndUpdateStorage(userData.darkMode ? 'dark' : 'light');
142
- setCurrencyCodeAndUpdateStorage(new i18n_lib_1.CurrencyCode(userData.currency));
143
- setTimezoneAndUpdateStorage(new i18n_lib_1.Timezone(userData.timezone));
109
+ await setUserSettingAndUpdateSettings({
110
+ darkMode: userDataDTO.darkMode,
111
+ currency: new i18n_lib_1.CurrencyCode(userDataDTO.currency),
112
+ timezone: new i18n_lib_1.Timezone(userDataDTO.timezone),
113
+ siteLanguage: userDataDTO.siteLanguage,
114
+ email: new ecies_lib_1.EmailString(userDataDTO.email),
115
+ directChallenge: userDataDTO.directChallenge,
116
+ });
144
117
  }
145
118
  }
146
119
  catch (error) {
147
120
  console.error('Token verification failed:', error);
148
121
  setUser(null);
149
122
  setIsAuthenticated(false);
123
+ await setUserSettingAndUpdateSettings(undefined);
150
124
  localStorage.removeItem('authToken');
151
125
  }
152
126
  finally {
153
127
  setLoading(false);
154
128
  setIsCheckingAuth(false);
155
129
  }
156
- }, [authService, clearMnemonic, clearWallet, setColorModeAndUpdateStorage, setCurrencyCodeAndUpdateStorage, setTimezoneAndUpdateStorage]);
130
+ }, [authService, clearMnemonic, clearWallet, setUserSettingAndUpdateSettings, themeSetPaletteMode]);
157
131
  (0, react_1.useEffect)(() => {
158
132
  const token = localStorage.getItem('authToken');
159
133
  if (token) {
@@ -165,7 +139,8 @@ const AuthProviderInner = ({ children, baseUrl, constants, eciesConfig, onLogout
165
139
  setLoading(false);
166
140
  setIsCheckingAuth(false);
167
141
  }
168
- }, [checkAuth, authState]);
142
+ // eslint-disable-next-line react-hooks/exhaustive-deps
143
+ }, [authState]); // Only run when authState changes (login/logout), not when checkAuth is recreated
169
144
  const directLogin = (0, react_1.useCallback)(async (mnemonic, username, email, expireMnemonicSeconds, expireWalletSeconds) => {
170
145
  setLoading(true);
171
146
  const loginResult = await authService.directLogin(mnemonic, username, email);
@@ -181,14 +156,18 @@ const AuthProviderInner = ({ children, baseUrl, constants, eciesConfig, onLogout
181
156
  setAuthState((prev) => prev + 1);
182
157
  localStorage.setItem('authToken', loginResult.token);
183
158
  localStorage.setItem('user', JSON.stringify(loginResult.user));
184
- // Set theme based on user's darkMode preference
185
- setColorModeAndUpdateStorage(loginResult.user.darkMode ? 'dark' : 'light');
186
- setCurrencyCodeAndUpdateStorage(new i18n_lib_1.CurrencyCode(loginResult.user.currency));
187
- setTimezoneAndUpdateStorage(new i18n_lib_1.Timezone(loginResult.user.timezone));
159
+ await setUserSettingAndUpdateSettings({
160
+ darkMode: loginResult.user.darkMode,
161
+ currency: new i18n_lib_1.CurrencyCode(loginResult.user.currency),
162
+ timezone: new i18n_lib_1.Timezone(loginResult.user.timezone),
163
+ siteLanguage: loginResult.user.siteLanguage,
164
+ email: new ecies_lib_1.EmailString(loginResult.user.email),
165
+ directChallenge: loginResult.user.directChallenge,
166
+ });
188
167
  return loginResult;
189
168
  }
190
169
  return loginResult;
191
- }, [authService, setMnemonic, setWallet, setColorModeAndUpdateStorage, setCurrencyCodeAndUpdateStorage, setTimezoneAndUpdateStorage]);
170
+ }, [authService, setMnemonic, setWallet, setUserSettingAndUpdateSettings]);
192
171
  const emailChallengeLogin = (0, react_1.useCallback)(async (mnemonic, token, username, email, expireMnemonicSeconds, expireWalletSeconds) => {
193
172
  setLoading(true);
194
173
  const loginResult = await authService.emailChallengeLogin(mnemonic, token, username, email);
@@ -204,24 +183,28 @@ const AuthProviderInner = ({ children, baseUrl, constants, eciesConfig, onLogout
204
183
  setAuthState((prev) => prev + 1);
205
184
  localStorage.setItem('authToken', loginResult.token);
206
185
  localStorage.setItem('user', JSON.stringify(loginResult.user));
207
- // Set theme based on user's darkMode preference
208
- setColorModeAndUpdateStorage(loginResult.user.darkMode ? 'dark' : 'light');
209
- setCurrencyCodeAndUpdateStorage(new i18n_lib_1.CurrencyCode(loginResult.user.currency));
210
- setTimezoneAndUpdateStorage(new i18n_lib_1.Timezone(loginResult.user.timezone));
186
+ await setUserSettingAndUpdateSettings({
187
+ darkMode: loginResult.user.darkMode,
188
+ currency: new i18n_lib_1.CurrencyCode(loginResult.user.currency),
189
+ timezone: new i18n_lib_1.Timezone(loginResult.user.timezone),
190
+ siteLanguage: loginResult.user.siteLanguage,
191
+ email: new ecies_lib_1.EmailString(loginResult.user.email),
192
+ directChallenge: loginResult.user.directChallenge,
193
+ });
211
194
  return loginResult;
212
195
  }
213
196
  return loginResult;
214
- }, [authService, setMnemonic, setWallet, setColorModeAndUpdateStorage, setCurrencyCodeAndUpdateStorage, setTimezoneAndUpdateStorage]);
197
+ }, [authService, setMnemonic, setWallet, setUserSettingAndUpdateSettings]);
215
198
  const getPasswordLoginService = (0, react_1.useCallback)(() => {
216
199
  const eciesService = new ecies_lib_1.ECIESService(eciesConfig);
217
200
  return new ecies_lib_1.PasswordLoginService(eciesService, new ecies_lib_1.Pbkdf2Service(ecies_lib_1.Constants.PBKDF2_PROFILES, ecies_lib_1.Constants.ECIES, ecies_lib_1.Constants.PBKDF2));
218
201
  }, [eciesConfig]);
219
- const isPasswordLoginAvailable = (0, react_1.useCallback)(() => {
202
+ const isBrowserPasswordLoginAvailable = (0, react_1.useCallback)(() => {
220
203
  const storedEncryptedPassword = localStorage.getItem('encryptedPassword');
221
204
  return !!storedEncryptedPassword;
222
205
  }, []);
223
206
  const passwordLogin = (0, react_1.useCallback)(async (password, username, email) => {
224
- if (!isPasswordLoginAvailable()) {
207
+ if (!isBrowserPasswordLoginAvailable()) {
225
208
  return { error: tComponent(suite_core_lib_1.SuiteCoreComponentId, suite_core_lib_1.SuiteCoreStringKey.Error_Login_PasswordLoginNotSetup), errorType: 'PasswordLoginNotSetup' };
226
209
  }
227
210
  setLoading(true);
@@ -233,12 +216,17 @@ const AuthProviderInner = ({ children, baseUrl, constants, eciesConfig, onLogout
233
216
  setMnemonic(mnemonic);
234
217
  // Set theme based on user's darkMode preference if login succeeded
235
218
  if ('user' in loginResult) {
236
- setColorModeAndUpdateStorage(loginResult.user.darkMode ? 'dark' : 'light');
237
- setCurrencyCodeAndUpdateStorage(new i18n_lib_1.CurrencyCode(loginResult.user.currency));
238
- setTimezoneAndUpdateStorage(new i18n_lib_1.Timezone(loginResult.user.timezone));
219
+ await setUserSettingAndUpdateSettings({
220
+ darkMode: loginResult.user.darkMode,
221
+ currency: new i18n_lib_1.CurrencyCode(loginResult.user.currency),
222
+ timezone: new i18n_lib_1.Timezone(loginResult.user.timezone),
223
+ siteLanguage: loginResult.user.siteLanguage,
224
+ email: new ecies_lib_1.EmailString(loginResult.user.email),
225
+ directChallenge: loginResult.user.directChallenge,
226
+ });
239
227
  }
240
228
  return loginResult;
241
- }, [authService, getPasswordLoginService, setMnemonic, setWallet, t, tComponent, isPasswordLoginAvailable, setColorModeAndUpdateStorage, setCurrencyCodeAndUpdateStorage, setTimezoneAndUpdateStorage]);
229
+ }, [authService, getPasswordLoginService, setMnemonic, setWallet, t, tComponent, isBrowserPasswordLoginAvailable, setUserSettingAndUpdateSettings]);
242
230
  const refreshToken = (0, react_1.useCallback)(async () => {
243
231
  try {
244
232
  const result = await authService.refreshToken();
@@ -266,7 +254,7 @@ const AuthProviderInner = ({ children, baseUrl, constants, eciesConfig, onLogout
266
254
  setLoading(false);
267
255
  return result;
268
256
  }, [baseUrl]);
269
- const setUpPasswordLogin = (0, react_1.useCallback)(async (mnemonic, password, username, email) => {
257
+ const setUpBrowserPasswordLogin = (0, react_1.useCallback)(async (mnemonic, password, username, email) => {
270
258
  setLoading(true);
271
259
  const passwordLoginService = getPasswordLoginService();
272
260
  try {
@@ -290,10 +278,14 @@ const AuthProviderInner = ({ children, baseUrl, constants, eciesConfig, onLogout
290
278
  if (loginResult.user) {
291
279
  setUser(loginResult.user);
292
280
  setIsAuthenticated(true);
293
- // Set theme based on user's darkMode preference
294
- setColorModeAndUpdateStorage(loginResult.user.darkMode ? 'dark' : 'light');
295
- setCurrencyCodeAndUpdateStorage(new i18n_lib_1.CurrencyCode(loginResult.user.currency));
296
- setTimezoneAndUpdateStorage(new i18n_lib_1.Timezone(loginResult.user.timezone));
281
+ await setUserSettingAndUpdateSettings({
282
+ darkMode: loginResult.user.darkMode,
283
+ currency: new i18n_lib_1.CurrencyCode(loginResult.user.currency),
284
+ timezone: new i18n_lib_1.Timezone(loginResult.user.timezone),
285
+ siteLanguage: loginResult.user.siteLanguage,
286
+ email: new ecies_lib_1.EmailString(loginResult.user.email),
287
+ directChallenge: loginResult.user.directChallenge,
288
+ });
297
289
  }
298
290
  setAuthState((prev) => prev + 1);
299
291
  return {
@@ -304,7 +296,7 @@ const AuthProviderInner = ({ children, baseUrl, constants, eciesConfig, onLogout
304
296
  };
305
297
  }
306
298
  return loginResult;
307
- }, [baseUrl, setColorModeAndUpdateStorage, setCurrencyCodeAndUpdateStorage, setTimezoneAndUpdateStorage]);
299
+ }, [authService, setUserSettingAndUpdateSettings]);
308
300
  const logout = (0, react_1.useCallback)(async () => {
309
301
  localStorage.removeItem('user');
310
302
  localStorage.removeItem('authToken');
@@ -312,22 +304,18 @@ const AuthProviderInner = ({ children, baseUrl, constants, eciesConfig, onLogout
312
304
  setUser(null);
313
305
  clearWallet();
314
306
  setIsAuthenticated(false);
315
- setColorMode('light');
316
- setTimezone(undefined);
317
- setCurrencyCode(undefined);
307
+ await setUserSettingAndUpdateSettings(undefined);
318
308
  setAuthState((prev) => prev + 1);
319
309
  // Call the optional navigation callback if provided
320
310
  if (onLogout) {
321
311
  onLogout();
322
312
  }
323
- }, [onLogout, clearMnemonic, clearWallet]);
313
+ }, [onLogout, clearMnemonic, clearWallet, setUserSettingAndUpdateSettings]);
324
314
  const verifyToken = (0, react_1.useCallback)(async (token) => {
325
315
  const requestUser = await authService.verifyToken(token);
326
316
  if (typeof requestUser === 'object' && 'error' in requestUser) {
327
317
  setIsAuthenticated(false);
328
- setColorMode('light');
329
- setTimezone(undefined);
330
- setCurrencyCode(undefined);
318
+ await setUserSettingAndUpdateSettings(undefined);
331
319
  return false;
332
320
  }
333
321
  else {
@@ -335,9 +323,9 @@ const AuthProviderInner = ({ children, baseUrl, constants, eciesConfig, onLogout
335
323
  setIsAuthenticated(true);
336
324
  return true;
337
325
  }
338
- }, [baseUrl]);
326
+ }, [authService, setUserSettingAndUpdateSettings]);
339
327
  const changePassword = (0, react_1.useCallback)(async (currentPassword, newPassword) => {
340
- if (!isPasswordLoginAvailable()) {
328
+ if (!isBrowserPasswordLoginAvailable()) {
341
329
  return { error: tComponent(suite_core_lib_1.SuiteCoreComponentId, suite_core_lib_1.SuiteCoreStringKey.Error_Login_PasswordLoginNotSetup), errorType: 'PasswordLoginNotSetup' };
342
330
  }
343
331
  setLoading(true);
@@ -358,26 +346,12 @@ const AuthProviderInner = ({ children, baseUrl, constants, eciesConfig, onLogout
358
346
  setLoading(false);
359
347
  return { error: 'Password change failed' };
360
348
  }
361
- }, [setMnemonic, setWallet, t, tComponent, isPasswordLoginAvailable]);
349
+ }, [setMnemonic, setWallet, t, tComponent, isBrowserPasswordLoginAvailable]);
362
350
  const contextValue = (0, react_1.useMemo)(() => {
363
- const setUserAndLanguage = async (newUser) => {
351
+ const setUserAndIsAuthenticated = async (newUser) => {
364
352
  setUser(newUser);
365
353
  setIsAuthenticated(!!newUser);
366
354
  };
367
- const setLanguageAndUpdateUser = async (newLanguage) => {
368
- // Change the language in the i18n context
369
- changeLanguage(newLanguage);
370
- // Update the user's language preference on the server if authenticated
371
- const token = localStorage.getItem('authToken');
372
- if (token) {
373
- try {
374
- await authenticatedApi.post('/user/language', { language: newLanguage });
375
- }
376
- catch (error) {
377
- console.error('Failed to update user language:', error);
378
- }
379
- }
380
- };
381
355
  return {
382
356
  admin: isGlobalAdmin,
383
357
  authState,
@@ -386,16 +360,13 @@ const AuthProviderInner = ({ children, baseUrl, constants, eciesConfig, onLogout
386
360
  checkAuth,
387
361
  clearMnemonic,
388
362
  clearWallet,
389
- colorMode,
390
- currencyCode,
391
363
  directLogin,
392
364
  emailChallengeLogin,
393
365
  getMnemonicRemainingTime,
394
366
  getWalletRemainingTime,
395
367
  isAuthenticated,
396
368
  isCheckingAuth,
397
- isPasswordLoginAvailable,
398
- language: currentLanguage,
369
+ isBrowserPasswordLoginAvailable,
399
370
  loading,
400
371
  logout,
401
372
  mnemonic: mnemonicManager.value,
@@ -405,21 +376,17 @@ const AuthProviderInner = ({ children, baseUrl, constants, eciesConfig, onLogout
405
376
  register,
406
377
  requestEmailLogin,
407
378
  serverPublicKey,
408
- setColorMode: setColorModeAndUpdateStorage,
409
- setCurrencyCode: setCurrencyCodeAndUpdateStorage,
410
- setLanguage: setLanguageAndUpdateUser,
411
379
  setMnemonic,
412
380
  setMnemonicExpirationSeconds,
413
- setUpPasswordLogin,
414
- setUser: setUserAndLanguage,
415
- setTimezone: setTimezoneAndUpdateStorage,
381
+ setUpBrowserPasswordLogin,
382
+ setUser: setUserAndIsAuthenticated,
383
+ setUserSetting: setUserSettingAndUpdateSettings,
416
384
  setWallet,
417
385
  setWalletExpirationSeconds,
418
- timezone,
419
- toggleColorMode,
420
386
  token,
421
387
  user: frontendUser,
422
388
  userData: user,
389
+ userSettings,
423
390
  verifyToken,
424
391
  wallet: walletManager.value,
425
392
  walletExpirationSeconds,
@@ -428,14 +395,10 @@ const AuthProviderInner = ({ children, baseUrl, constants, eciesConfig, onLogout
428
395
  authenticatedApi,
429
396
  authState,
430
397
  backupCodeLogin,
431
- changeLanguage,
432
398
  changePassword,
433
399
  checkAuth,
434
400
  clearMnemonic,
435
401
  clearWallet,
436
- colorMode,
437
- currencyCode,
438
- currentLanguage,
439
402
  directLogin,
440
403
  emailChallengeLogin,
441
404
  frontendUser,
@@ -444,7 +407,7 @@ const AuthProviderInner = ({ children, baseUrl, constants, eciesConfig, onLogout
444
407
  isAuthenticated,
445
408
  isCheckingAuth,
446
409
  isGlobalAdmin,
447
- isPasswordLoginAvailable,
410
+ isBrowserPasswordLoginAvailable,
448
411
  loading,
449
412
  logout,
450
413
  mnemonicManager.value,
@@ -454,18 +417,15 @@ const AuthProviderInner = ({ children, baseUrl, constants, eciesConfig, onLogout
454
417
  register,
455
418
  requestEmailLogin,
456
419
  serverPublicKey,
457
- setColorModeAndUpdateStorage,
458
- setCurrencyCodeAndUpdateStorage,
459
420
  setMnemonic,
460
421
  setMnemonicExpirationSeconds,
461
- setUpPasswordLogin,
462
- setTimezoneAndUpdateStorage,
422
+ setUpBrowserPasswordLogin,
423
+ setUserSettingAndUpdateSettings,
463
424
  setWallet,
464
425
  setWalletExpirationSeconds,
465
- timezone,
466
- toggleColorMode,
467
426
  token,
468
427
  user,
428
+ userSettings,
469
429
  verifyToken,
470
430
  walletManager.value,
471
431
  walletExpirationSeconds,
@@ -1 +1 @@
1
- {"version":3,"file":"MenuContext.d.ts","sourceRoot":"","sources":["../../../../../packages/digitaldefiance-express-suite-react-components/src/contexts/MenuContext.tsx"],"names":[],"mappings":"AAiBA,OAAO,EACL,EAAE,EACF,SAAS,EAQV,MAAM,OAAO,CAAC;AAEf,OAAO,EAAE,QAAQ,EAAa,MAAM,mBAAmB,CAAC;AAExD,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAGxD,UAAU,iBAAiB;IACzB,QAAQ,EAAE,SAAS,CAAC;IACpB,WAAW,CAAC,EAAE,WAAW,EAAE,CAAC;IAC5B,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,UAAU,eAAe;IACvB,WAAW,EAAE,WAAW,EAAE,CAAC;IAC3B,cAAc,EAAE,CACd,QAAQ,EAAE,QAAQ,EAClB,eAAe,EAAE,OAAO,KACrB,WAAW,EAAE,CAAC;IACnB,kBAAkB,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,MAAM,IAAI,CAAC;IACxD,mBAAmB,EAAE,CAAC,OAAO,EAAE,WAAW,EAAE,KAAK,MAAM,IAAI,CAAC;IAC5D,WAAW,EAAE,MAAM,KAAK,CAAC,WAAW,CAAC,CAAC;CACvC;AAID,eAAO,MAAM,YAAY,EAAE,EAAE,CAAC,iBAAiB,CAgP9C,CAAC;AAEF,eAAO,MAAM,OAAO,QAAO,eAM1B,CAAC"}
1
+ {"version":3,"file":"MenuContext.d.ts","sourceRoot":"","sources":["../../../../../packages/digitaldefiance-express-suite-react-components/src/contexts/MenuContext.tsx"],"names":[],"mappings":"AAiBA,OAAO,EACL,EAAE,EACF,SAAS,EAQV,MAAM,OAAO,CAAC;AAEf,OAAO,EAAE,QAAQ,EAAa,MAAM,mBAAmB,CAAC;AAExD,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAKxD,UAAU,iBAAiB;IACzB,QAAQ,EAAE,SAAS,CAAC;IACpB,WAAW,CAAC,EAAE,WAAW,EAAE,CAAC;IAC5B,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,UAAU,eAAe;IACvB,WAAW,EAAE,WAAW,EAAE,CAAC;IAC3B,cAAc,EAAE,CACd,QAAQ,EAAE,QAAQ,EAClB,eAAe,EAAE,OAAO,KACrB,WAAW,EAAE,CAAC;IACnB,kBAAkB,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,MAAM,IAAI,CAAC;IACxD,mBAAmB,EAAE,CAAC,OAAO,EAAE,WAAW,EAAE,KAAK,MAAM,IAAI,CAAC;IAC5D,WAAW,EAAE,MAAM,KAAK,CAAC,WAAW,CAAC,CAAC;CACvC;AAID,eAAO,MAAM,YAAY,EAAE,EAAE,CAAC,iBAAiB,CAmP9C,CAAC;AAEF,eAAO,MAAM,OAAO,QAAO,eAM1B,CAAC"}
@@ -10,12 +10,18 @@ const react_1 = require("react");
10
10
  const AuthProvider_1 = require("./AuthProvider");
11
11
  const MenuType_1 = require("../types/MenuType");
12
12
  const I18nProvider_1 = require("./I18nProvider");
13
+ const hooks_1 = require("../hooks");
14
+ const SuiteConfigProvider_1 = require("./SuiteConfigProvider");
15
+ const services_1 = require("../services");
13
16
  const MenuContext = (0, react_1.createContext)(undefined);
14
17
  const MenuProvider = ({ children, menuConfigs = [], enableBackupCodes = true }) => {
15
- const { userData: user, isAuthenticated, mnemonic, clearMnemonic, wallet, clearWallet, colorMode, toggleColorMode } = (0, AuthProvider_1.useAuth)();
18
+ const { userData: user, isAuthenticated, mnemonic, clearMnemonic, wallet, clearWallet, colorMode } = (0, AuthProvider_1.useAuth)();
16
19
  const registeredMenuOptions = (0, react_1.useRef)(new Set());
17
20
  const [registeredOptions, setRegisteredOptions] = (0, react_1.useState)(new Map());
18
21
  const { tComponent } = (0, I18nProvider_1.useI18n)();
22
+ const { baseUrl } = (0, SuiteConfigProvider_1.useSuiteConfig)();
23
+ const authenticatedApi = (0, react_1.useMemo)(() => (0, services_1.createAuthenticatedApiClient)(baseUrl), [baseUrl]);
24
+ const { toggleColorMode } = (0, hooks_1.useUserSettings)({ authenticatedApi });
19
25
  const registerMenuOption = (0, react_1.useCallback)((option) => {
20
26
  const unregister = () => {
21
27
  setRegisteredOptions((prev) => {
@@ -1,13 +1,25 @@
1
- export interface UserSettingsValues {
2
- email: string;
3
- timezone: string;
4
- siteLanguage: string;
5
- currency: string;
6
- darkMode: boolean;
7
- directChallenge: boolean;
8
- [key: string]: any;
1
+ import { IUserSettings, IUserSettingsDTO } from '@digitaldefiance/suite-core-lib';
2
+ export interface UseUserSettingsOptions {
3
+ authenticatedApi: {
4
+ post: (url: string, data: any) => Promise<any>;
5
+ };
9
6
  }
10
7
  export interface UseUserSettingsResult {
8
+ currentLanguage: string;
9
+ changeLanguage: (languageCode: string) => Promise<void>;
10
+ userSettings: IUserSettings | undefined;
11
+ setUserSettingAndUpdateSettings: (setting?: Partial<IUserSettings>) => Promise<void>;
12
+ toggleColorMode: () => Promise<void>;
13
+ }
14
+ /**
15
+ * Hook for managing user settings state and synchronization.
16
+ * Used by AuthProvider to handle user settings logic.
17
+ */
18
+ export declare const useUserSettings: ({ authenticatedApi, }: UseUserSettingsOptions) => UseUserSettingsResult;
19
+ export interface UserSettingsValues extends IUserSettingsDTO {
20
+ [key: string]: any;
21
+ }
22
+ export interface UseUserSettingsPublicResult {
11
23
  settings: UserSettingsValues | null;
12
24
  isLoading: boolean;
13
25
  error: Error | null;
@@ -25,5 +37,9 @@ export interface UseUserSettingsResult {
25
37
  }>;
26
38
  refreshSettings: () => Promise<void>;
27
39
  }
28
- export declare const useUserSettings: () => UseUserSettingsResult;
40
+ /**
41
+ * Public hook for components to manage user settings.
42
+ * Provides a simpler API for fetching and updating settings.
43
+ */
44
+ export declare const useUserSettingsPublic: () => UseUserSettingsPublicResult;
29
45
  //# sourceMappingURL=useUserSettings.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useUserSettings.d.ts","sourceRoot":"","sources":["../../../../../packages/digitaldefiance-express-suite-react-components/src/hooks/useUserSettings.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;IAClB,eAAe,EAAE,OAAO,CAAC;IACzB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,kBAAkB,GAAG,IAAI,CAAC;IACpC,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,cAAc,EAAE,CAAC,MAAM,EAAE,kBAAkB,KAAK,OAAO,CAAC;QACtD,OAAO,EAAE,OAAO,CAAC;QACjB,OAAO,EAAE,MAAM,CAAC;KACjB,GAAG;QACF,KAAK,EAAE,MAAM,CAAC;QACd,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,GAAG,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;KAC/C,CAAC,CAAC;IACH,eAAe,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACtC;AAED,eAAO,MAAM,eAAe,QAAO,qBA+FlC,CAAC"}
1
+ {"version":3,"file":"useUserSettings.d.ts","sourceRoot":"","sources":["../../../../../packages/digitaldefiance-express-suite-react-components/src/hooks/useUserSettings.ts"],"names":[],"mappings":"AASA,OAAO,EACL,aAAa,EAGb,gBAAgB,EAIjB,MAAM,iCAAiC,CAAC;AAYzC,MAAM,WAAW,sBAAsB;IACrC,gBAAgB,EAAE;QAChB,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;KAChD,CAAC;CACH;AAED,MAAM,WAAW,qBAAqB;IACpC,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACxD,YAAY,EAAE,aAAa,GAAG,SAAS,CAAC;IACxC,+BAA+B,EAAE,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACrF,eAAe,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACtC;AAED;;;GAGG;AACH,eAAO,MAAM,eAAe,GAAI,uBAE7B,sBAAsB,KAAG,qBAoD3B,CAAC;AAGF,MAAM,WAAW,kBAAmB,SAAQ,gBAAgB;IAC1D,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAED,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,EAAE,kBAAkB,GAAG,IAAI,CAAC;IACpC,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,cAAc,EAAE,CAAC,MAAM,EAAE,kBAAkB,KAAK,OAAO,CAAC;QACtD,OAAO,EAAE,OAAO,CAAC;QACjB,OAAO,EAAE,MAAM,CAAC;KACjB,GAAG;QACF,KAAK,EAAE,MAAM,CAAC;QACd,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,GAAG,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;KAC/C,CAAC,CAAC;IACH,eAAe,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACtC;AAED;;;GAGG;AACH,eAAO,MAAM,qBAAqB,QAAO,2BA2ExC,CAAC"}
@@ -1,17 +1,74 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.useUserSettings = void 0;
3
+ exports.useUserSettingsPublic = exports.useUserSettings = void 0;
4
4
  const react_1 = require("react");
5
- const services_1 = require("../services");
6
- const contexts_1 = require("../contexts");
7
- const contexts_2 = require("../contexts");
8
5
  const i18n_lib_1 = require("@digitaldefiance/i18n-lib");
6
+ const ecies_lib_1 = require("@digitaldefiance/ecies-lib");
9
7
  const suite_core_lib_1 = require("@digitaldefiance/suite-core-lib");
10
- const useUserSettings = () => {
11
- const { baseUrl } = (0, contexts_1.useSuiteConfig)();
12
- const { userData, setCurrencyCode, setLanguage } = (0, contexts_2.useAuth)();
13
- const { setColorMode } = (0, contexts_2.useTheme)();
14
- const api = (0, react_1.useMemo)(() => (0, services_1.createAuthenticatedApiClient)(baseUrl), [baseUrl]);
8
+ const contexts_1 = require("../contexts");
9
+ const defaultUserSettings = {
10
+ darkMode: false,
11
+ currency: new i18n_lib_1.CurrencyCode(i18n_lib_1.DefaultCurrencyCode),
12
+ timezone: new i18n_lib_1.Timezone(i18n_lib_1.DefaultTimezone),
13
+ siteLanguage: i18n_lib_1.DefaultLanguageCode,
14
+ email: new ecies_lib_1.EmailString('bob@example.com'),
15
+ directChallenge: false,
16
+ };
17
+ /**
18
+ * Hook for managing user settings state and synchronization.
19
+ * Used by AuthProvider to handle user settings logic.
20
+ */
21
+ const useUserSettings = ({ authenticatedApi, }) => {
22
+ const { isAuthenticated } = (0, contexts_1.useAuth)();
23
+ const { setColorMode: themeSetPaletteMode } = (0, contexts_1.useTheme)();
24
+ const { currentLanguage, changeLanguage } = (0, contexts_1.useI18n)();
25
+ const [userSettings, setUserSettings] = (0, react_1.useState)(undefined);
26
+ const setUserSettingAndUpdateSettings = (0, react_1.useCallback)(async (setting) => {
27
+ if (setting) {
28
+ const newUserSettings = {
29
+ ...defaultUserSettings,
30
+ ...(userSettings ? userSettings : {}),
31
+ ...setting,
32
+ };
33
+ setUserSettings(newUserSettings);
34
+ if (setting.darkMode !== undefined) {
35
+ themeSetPaletteMode(setting.darkMode ? 'dark' : 'light');
36
+ }
37
+ if (setting.siteLanguage !== undefined && setting.siteLanguage !== currentLanguage) {
38
+ changeLanguage(setting.siteLanguage);
39
+ }
40
+ const dehydratedSettings = (0, suite_core_lib_1.dehydrateUserSettings)(newUserSettings);
41
+ if (isAuthenticated) {
42
+ await authenticatedApi.post('/user/settings', dehydratedSettings);
43
+ }
44
+ }
45
+ else {
46
+ setUserSettings(undefined);
47
+ themeSetPaletteMode('light');
48
+ }
49
+ }, [isAuthenticated, userSettings, currentLanguage, changeLanguage, themeSetPaletteMode, authenticatedApi]);
50
+ const changeLanguageSetting = (0, react_1.useCallback)(async (languageCode) => {
51
+ await setUserSettingAndUpdateSettings({ siteLanguage: languageCode });
52
+ }, [setUserSettingAndUpdateSettings]);
53
+ const toggleColorMode = async () => {
54
+ const currentSetting = { ...({ darkMode: userSettings?.darkMode ? userSettings.darkMode : true }) };
55
+ await setUserSettingAndUpdateSettings({ ...currentSetting, darkMode: !currentSetting.darkMode });
56
+ };
57
+ return {
58
+ changeLanguage: changeLanguageSetting,
59
+ currentLanguage,
60
+ userSettings,
61
+ setUserSettingAndUpdateSettings,
62
+ toggleColorMode,
63
+ };
64
+ };
65
+ exports.useUserSettings = useUserSettings;
66
+ /**
67
+ * Public hook for components to manage user settings.
68
+ * Provides a simpler API for fetching and updating settings.
69
+ */
70
+ const useUserSettingsPublic = () => {
71
+ const { userData, setUserSetting, userSettings } = (0, contexts_1.useAuth)();
15
72
  const [settings, setSettings] = (0, react_1.useState)(null);
16
73
  const [isLoading, setIsLoading] = (0, react_1.useState)(true);
17
74
  const [error, setError] = (0, react_1.useState)(null);
@@ -19,64 +76,48 @@ const useUserSettings = () => {
19
76
  setIsLoading(true);
20
77
  setError(null);
21
78
  try {
22
- const result = await api.get('/user/settings');
23
- if (result?.data?.settings) {
24
- setSettings(result.data.settings);
79
+ if (userSettings) {
80
+ const dehydratedSettings = (0, suite_core_lib_1.dehydrateUserSettings)(userSettings);
81
+ setSettings(dehydratedSettings);
25
82
  }
26
- else {
27
- // Fallback to userData - use current value without dependency
83
+ else if (userData) {
28
84
  const fallback = {
29
- email: userData?.email || '',
30
- timezone: userData?.timezone || 'UTC',
31
- siteLanguage: userData?.siteLanguage || 'en-US',
32
- currency: userData?.currency || 'USD',
33
- darkMode: userData?.darkMode || false,
34
- directChallenge: userData?.directChallenge || false,
85
+ email: userData.email || '',
86
+ timezone: userData.timezone || 'UTC',
87
+ siteLanguage: userData.siteLanguage || 'en-US',
88
+ currency: userData.currency || 'USD',
89
+ darkMode: userData.darkMode || false,
90
+ directChallenge: userData.directChallenge || false,
35
91
  };
36
92
  setSettings(fallback);
37
93
  }
38
94
  }
39
95
  catch (err) {
40
96
  setError(err instanceof Error ? err : new suite_core_lib_1.TranslatableSuiteError(suite_core_lib_1.SuiteCoreStringKey.Settings_RetrieveFailure));
41
- // Use fallback from userData
42
- const fallback = {
43
- email: userData?.email || '',
44
- timezone: userData?.timezone || 'UTC',
45
- siteLanguage: userData?.siteLanguage || 'en-US',
46
- currency: userData?.currency || 'USD',
47
- darkMode: userData?.darkMode || false,
48
- directChallenge: userData?.directChallenge || false,
49
- };
50
- setSettings(fallback);
51
97
  }
52
98
  finally {
53
99
  setIsLoading(false);
54
100
  }
55
- // eslint-disable-next-line react-hooks/exhaustive-deps
56
- }, [api]); // userData intentionally omitted to prevent infinite loops
101
+ }, [userSettings, userData]);
57
102
  (0, react_1.useEffect)(() => {
58
103
  refreshSettings();
59
104
  }, [refreshSettings]);
60
- const updateSettings = async (values) => {
105
+ const updateSettings = (0, react_1.useCallback)(async (values) => {
61
106
  setIsLoading(true);
62
107
  setError(null);
63
108
  try {
64
- const result = await api.post('/user/settings', values);
65
- // Update context values
66
- if (values.currency) {
67
- await setCurrencyCode(new i18n_lib_1.CurrencyCode(values.currency));
68
- }
69
- if (values.siteLanguage) {
70
- await setLanguage(values.siteLanguage);
71
- }
72
- if (values.darkMode !== userData?.darkMode) {
73
- setColorMode(values.darkMode ? 'dark' : 'light');
74
- }
75
- // Update local state
109
+ await setUserSetting({
110
+ darkMode: values.darkMode,
111
+ currency: new i18n_lib_1.CurrencyCode(values.currency),
112
+ timezone: new i18n_lib_1.Timezone(values.timezone),
113
+ siteLanguage: values.siteLanguage,
114
+ email: new ecies_lib_1.EmailString(values.email),
115
+ directChallenge: values.directChallenge,
116
+ });
76
117
  setSettings(values);
77
118
  return {
78
119
  success: true,
79
- message: result.data.message || (0, suite_core_lib_1.getSuiteCoreTranslation)(suite_core_lib_1.SuiteCoreStringKey.Settings_SaveSuccess)
120
+ message: (0, suite_core_lib_1.getSuiteCoreTranslation)(suite_core_lib_1.SuiteCoreStringKey.Settings_SaveSuccess)
80
121
  };
81
122
  }
82
123
  catch (err) {
@@ -92,7 +133,7 @@ const useUserSettings = () => {
92
133
  finally {
93
134
  setIsLoading(false);
94
135
  }
95
- };
136
+ }, [setUserSetting]);
96
137
  return {
97
138
  settings,
98
139
  isLoading,
@@ -101,4 +142,4 @@ const useUserSettings = () => {
101
142
  refreshSettings,
102
143
  };
103
144
  };
104
- exports.useUserSettings = useUserSettings;
145
+ exports.useUserSettingsPublic = useUserSettingsPublic;
@@ -7,7 +7,7 @@ const contexts_1 = require("../contexts");
7
7
  const hooks_1 = require("../hooks");
8
8
  const suite_core_lib_1 = require("@digitaldefiance/suite-core-lib");
9
9
  const UserSettingsFormWrapper = ({ onSuccess, componentProps = {}, }) => {
10
- const { settings, isLoading, updateSettings } = (0, hooks_1.useUserSettings)();
10
+ const { settings, isLoading, updateSettings } = (0, hooks_1.useUserSettingsPublic)();
11
11
  const { languages } = (0, contexts_1.useSuiteConfig)();
12
12
  const handleSubmit = async (values) => {
13
13
  const result = await updateSettings(values);