@oxyhq/services 5.15.9 → 5.16.1

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.
Files changed (159) hide show
  1. package/lib/commonjs/core/OxyServices.js +0 -1
  2. package/lib/commonjs/core/OxyServices.js.map +1 -1
  3. package/lib/commonjs/core/mixins/OxyServices.assets.js +15 -0
  4. package/lib/commonjs/core/mixins/OxyServices.assets.js.map +1 -1
  5. package/lib/commonjs/core/mixins/OxyServices.auth.js +3 -6
  6. package/lib/commonjs/core/mixins/OxyServices.auth.js.map +1 -1
  7. package/lib/commonjs/core/mixins/OxyServices.devices.js +1 -1
  8. package/lib/commonjs/core/mixins/OxyServices.devices.js.map +1 -1
  9. package/lib/commonjs/core/mixins/index.js +11 -12
  10. package/lib/commonjs/core/mixins/index.js.map +1 -1
  11. package/lib/commonjs/crypto/signatureService.js +3 -2
  12. package/lib/commonjs/crypto/signatureService.js.map +1 -1
  13. package/lib/commonjs/i18n/locales/ar-SA.json +1 -9
  14. package/lib/commonjs/i18n/locales/ca-ES.json +1 -9
  15. package/lib/commonjs/i18n/locales/de-DE.json +1 -9
  16. package/lib/commonjs/i18n/locales/en-US.json +3 -21
  17. package/lib/commonjs/i18n/locales/es-ES.json +3 -21
  18. package/lib/commonjs/i18n/locales/fr-FR.json +1 -9
  19. package/lib/commonjs/i18n/locales/it-IT.json +1 -9
  20. package/lib/commonjs/i18n/locales/ja-JP.json +1 -9
  21. package/lib/commonjs/i18n/locales/ko-KR.json +1 -9
  22. package/lib/commonjs/i18n/locales/pt-PT.json +1 -9
  23. package/lib/commonjs/i18n/locales/zh-CN.json +1 -9
  24. package/lib/commonjs/index.js.map +1 -1
  25. package/lib/commonjs/ui/context/OxyContext.js +24 -4
  26. package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
  27. package/lib/commonjs/ui/context/hooks/useAuthOperations.js +217 -100
  28. package/lib/commonjs/ui/context/hooks/useAuthOperations.js.map +1 -1
  29. package/lib/commonjs/ui/screens/AccountSettingsScreen.js +2 -319
  30. package/lib/commonjs/ui/screens/AccountSettingsScreen.js.map +1 -1
  31. package/lib/commonjs/ui/screens/OxyAuthScreen.js +16 -7
  32. package/lib/commonjs/ui/screens/OxyAuthScreen.js.map +1 -1
  33. package/lib/commonjs/ui/screens/PrivacySettingsScreen.js +0 -1
  34. package/lib/commonjs/ui/screens/PrivacySettingsScreen.js.map +1 -1
  35. package/lib/commonjs/ui/screens/SessionManagementScreen.js +43 -29
  36. package/lib/commonjs/ui/screens/SessionManagementScreen.js.map +1 -1
  37. package/lib/commonjs/ui/stores/authStore.js +14 -1
  38. package/lib/commonjs/ui/stores/authStore.js.map +1 -1
  39. package/lib/module/core/OxyServices.js +0 -1
  40. package/lib/module/core/OxyServices.js.map +1 -1
  41. package/lib/module/core/mixins/OxyServices.assets.js +15 -0
  42. package/lib/module/core/mixins/OxyServices.assets.js.map +1 -1
  43. package/lib/module/core/mixins/OxyServices.auth.js +3 -6
  44. package/lib/module/core/mixins/OxyServices.auth.js.map +1 -1
  45. package/lib/module/core/mixins/OxyServices.devices.js +1 -1
  46. package/lib/module/core/mixins/OxyServices.devices.js.map +1 -1
  47. package/lib/module/core/mixins/index.js +1 -2
  48. package/lib/module/core/mixins/index.js.map +1 -1
  49. package/lib/module/crypto/signatureService.js +3 -2
  50. package/lib/module/crypto/signatureService.js.map +1 -1
  51. package/lib/module/i18n/locales/ar-SA.json +1 -9
  52. package/lib/module/i18n/locales/ca-ES.json +1 -9
  53. package/lib/module/i18n/locales/de-DE.json +1 -9
  54. package/lib/module/i18n/locales/en-US.json +3 -21
  55. package/lib/module/i18n/locales/es-ES.json +3 -21
  56. package/lib/module/i18n/locales/fr-FR.json +1 -9
  57. package/lib/module/i18n/locales/it-IT.json +1 -9
  58. package/lib/module/i18n/locales/ja-JP.json +1 -9
  59. package/lib/module/i18n/locales/ko-KR.json +1 -9
  60. package/lib/module/i18n/locales/pt-PT.json +1 -9
  61. package/lib/module/i18n/locales/zh-CN.json +1 -9
  62. package/lib/module/index.js.map +1 -1
  63. package/lib/module/ui/context/OxyContext.js +24 -4
  64. package/lib/module/ui/context/OxyContext.js.map +1 -1
  65. package/lib/module/ui/context/hooks/useAuthOperations.js +217 -100
  66. package/lib/module/ui/context/hooks/useAuthOperations.js.map +1 -1
  67. package/lib/module/ui/screens/AccountSettingsScreen.js +2 -319
  68. package/lib/module/ui/screens/AccountSettingsScreen.js.map +1 -1
  69. package/lib/module/ui/screens/OxyAuthScreen.js +16 -7
  70. package/lib/module/ui/screens/OxyAuthScreen.js.map +1 -1
  71. package/lib/module/ui/screens/PrivacySettingsScreen.js +0 -1
  72. package/lib/module/ui/screens/PrivacySettingsScreen.js.map +1 -1
  73. package/lib/module/ui/screens/SessionManagementScreen.js +44 -29
  74. package/lib/module/ui/screens/SessionManagementScreen.js.map +1 -1
  75. package/lib/module/ui/stores/authStore.js +14 -1
  76. package/lib/module/ui/stores/authStore.js.map +1 -1
  77. package/lib/typescript/core/OxyServices.d.ts +0 -1
  78. package/lib/typescript/core/OxyServices.d.ts.map +1 -1
  79. package/lib/typescript/core/mixins/OxyServices.assets.d.ts +7 -1
  80. package/lib/typescript/core/mixins/OxyServices.assets.d.ts.map +1 -1
  81. package/lib/typescript/core/mixins/OxyServices.auth.d.ts +3 -4
  82. package/lib/typescript/core/mixins/OxyServices.auth.d.ts.map +1 -1
  83. package/lib/typescript/core/mixins/OxyServices.devices.d.ts +1 -4
  84. package/lib/typescript/core/mixins/OxyServices.devices.d.ts.map +1 -1
  85. package/lib/typescript/core/mixins/index.d.ts +2 -64
  86. package/lib/typescript/core/mixins/index.d.ts.map +1 -1
  87. package/lib/typescript/crypto/signatureService.d.ts +2 -1
  88. package/lib/typescript/crypto/signatureService.d.ts.map +1 -1
  89. package/lib/typescript/index.d.ts +1 -1
  90. package/lib/typescript/index.d.ts.map +1 -1
  91. package/lib/typescript/models/interfaces.d.ts +22 -1
  92. package/lib/typescript/models/interfaces.d.ts.map +1 -1
  93. package/lib/typescript/types/bip39.d.ts +1 -0
  94. package/lib/typescript/types/buffer.d.ts +1 -0
  95. package/lib/typescript/types/color.d.ts +1 -0
  96. package/lib/typescript/types/elliptic.d.ts +1 -0
  97. package/lib/typescript/types/expo-crypto.d.ts +1 -0
  98. package/lib/typescript/types/expo-secure-store.d.ts +1 -0
  99. package/lib/typescript/ui/context/OxyContext.d.ts +11 -3
  100. package/lib/typescript/ui/context/OxyContext.d.ts.map +1 -1
  101. package/lib/typescript/ui/context/hooks/useAuthOperations.d.ts +13 -5
  102. package/lib/typescript/ui/context/hooks/useAuthOperations.d.ts.map +1 -1
  103. package/lib/typescript/ui/screens/AccountSettingsScreen.d.ts.map +1 -1
  104. package/lib/typescript/ui/screens/OxyAuthScreen.d.ts.map +1 -1
  105. package/lib/typescript/ui/screens/PrivacySettingsScreen.d.ts.map +1 -1
  106. package/lib/typescript/ui/screens/SessionManagementScreen.d.ts.map +1 -1
  107. package/lib/typescript/ui/stores/authStore.d.ts +4 -0
  108. package/lib/typescript/ui/stores/authStore.d.ts.map +1 -1
  109. package/package.json +5 -4
  110. package/src/core/OxyServices.ts +0 -1
  111. package/src/core/mixins/OxyServices.assets.ts +16 -1
  112. package/src/core/mixins/OxyServices.auth.ts +3 -8
  113. package/src/core/mixins/OxyServices.devices.ts +1 -4
  114. package/src/core/mixins/index.ts +2 -5
  115. package/src/crypto/index.ts +1 -0
  116. package/src/crypto/keyManager.ts +1 -0
  117. package/src/crypto/polyfill.ts +1 -0
  118. package/src/crypto/recoveryPhrase.ts +1 -0
  119. package/src/crypto/signatureService.ts +4 -5
  120. package/src/i18n/locales/ar-SA.json +1 -9
  121. package/src/i18n/locales/ca-ES.json +1 -9
  122. package/src/i18n/locales/de-DE.json +1 -9
  123. package/src/i18n/locales/en-US.json +3 -21
  124. package/src/i18n/locales/es-ES.json +3 -21
  125. package/src/i18n/locales/fr-FR.json +1 -9
  126. package/src/i18n/locales/it-IT.json +1 -9
  127. package/src/i18n/locales/ja-JP.json +1 -9
  128. package/src/i18n/locales/ko-KR.json +1 -9
  129. package/src/i18n/locales/pt-PT.json +1 -9
  130. package/src/i18n/locales/zh-CN.json +1 -9
  131. package/src/index.ts +4 -1
  132. package/src/models/interfaces.ts +24 -1
  133. package/src/types/bip39.d.ts +1 -0
  134. package/src/types/buffer.d.ts +1 -0
  135. package/src/types/color.d.ts +1 -0
  136. package/src/types/elliptic.d.ts +1 -0
  137. package/src/types/expo-crypto.d.ts +1 -0
  138. package/src/types/expo-secure-store.d.ts +1 -0
  139. package/src/ui/context/OxyContext.tsx +35 -3
  140. package/src/ui/context/hooks/useAuthOperations.ts +212 -98
  141. package/src/ui/screens/AccountSettingsScreen.tsx +1 -201
  142. package/src/ui/screens/OxyAuthScreen.tsx +16 -8
  143. package/src/ui/screens/PrivacySettingsScreen.tsx +0 -2
  144. package/src/ui/screens/SessionManagementScreen.tsx +43 -26
  145. package/src/ui/stores/authStore.ts +31 -2
  146. package/lib/commonjs/core/mixins/OxyServices.totp.js +0 -53
  147. package/lib/commonjs/core/mixins/OxyServices.totp.js.map +0 -1
  148. package/lib/commonjs/ui/components/profile/TwoFactorSetupModal.js +0 -467
  149. package/lib/commonjs/ui/components/profile/TwoFactorSetupModal.js.map +0 -1
  150. package/lib/module/core/mixins/OxyServices.totp.js +0 -49
  151. package/lib/module/core/mixins/OxyServices.totp.js.map +0 -1
  152. package/lib/module/ui/components/profile/TwoFactorSetupModal.js +0 -460
  153. package/lib/module/ui/components/profile/TwoFactorSetupModal.js.map +0 -1
  154. package/lib/typescript/core/mixins/OxyServices.totp.d.ts +0 -66
  155. package/lib/typescript/core/mixins/OxyServices.totp.d.ts.map +0 -1
  156. package/lib/typescript/ui/components/profile/TwoFactorSetupModal.d.ts +0 -11
  157. package/lib/typescript/ui/components/profile/TwoFactorSetupModal.d.ts.map +0 -1
  158. package/src/core/mixins/OxyServices.totp.ts +0 -36
  159. package/src/ui/components/profile/TwoFactorSetupModal.tsx +0 -442
@@ -60,7 +60,7 @@ const OxyAuthScreen: React.FC<BaseScreenProps> = ({
60
60
  }) => {
61
61
  const themeValue = (theme === 'light' || theme === 'dark') ? theme : 'light';
62
62
  const colors = useThemeColors(themeValue);
63
- const { oxyServices, signIn } = useOxy();
63
+ const { oxyServices, signIn, switchSession } = useOxy();
64
64
 
65
65
  const [authSession, setAuthSession] = useState<AuthSession | null>(null);
66
66
  const [isLoading, setIsLoading] = useState(true);
@@ -78,12 +78,19 @@ const OxyAuthScreen: React.FC<BaseScreenProps> = ({
78
78
  isProcessingRef.current = true;
79
79
 
80
80
  try {
81
- // Get token and user data
82
- await oxyServices.getTokenBySession(sessionId);
83
- const user = await oxyServices.getUserBySession(sessionId);
84
-
85
- if (onAuthenticated) {
86
- onAuthenticated(user);
81
+ // Switch to the new session (this will get token, user data, and update state)
82
+ if (switchSession) {
83
+ const user = await switchSession(sessionId);
84
+ if (onAuthenticated) {
85
+ onAuthenticated(user);
86
+ }
87
+ } else {
88
+ // Fallback if switchSession not available (shouldn't happen, but for safety)
89
+ await oxyServices.getTokenBySession(sessionId);
90
+ const user = await oxyServices.getUserBySession(sessionId);
91
+ if (onAuthenticated) {
92
+ onAuthenticated(user);
93
+ }
87
94
  }
88
95
  } catch (err) {
89
96
  if (__DEV__) {
@@ -92,7 +99,7 @@ const OxyAuthScreen: React.FC<BaseScreenProps> = ({
92
99
  setError('Authorization successful but failed to complete sign in. Please try again.');
93
100
  isProcessingRef.current = false;
94
101
  }
95
- }, [oxyServices, onAuthenticated]);
102
+ }, [oxyServices, switchSession, onAuthenticated]);
96
103
 
97
104
  // Connect to socket for real-time updates
98
105
  const connectSocket = useCallback((sessionToken: string) => {
@@ -517,3 +524,4 @@ const styles = StyleSheet.create({
517
524
 
518
525
  export default OxyAuthScreen;
519
526
 
527
+
@@ -21,7 +21,6 @@ interface PrivacySettings {
21
21
  hideOnlineStatus: boolean;
22
22
  hideLastSeen: boolean;
23
23
  profileVisibility: boolean;
24
- twoFactorEnabled: boolean;
25
24
  loginAlerts: boolean;
26
25
  blockScreenshots: boolean;
27
26
  login: boolean;
@@ -52,7 +51,6 @@ const PrivacySettingsScreen: React.FC<BaseScreenProps> = ({
52
51
  hideOnlineStatus: false,
53
52
  hideLastSeen: false,
54
53
  profileVisibility: true,
55
- twoFactorEnabled: false,
56
54
  loginAlerts: true,
57
55
  blockScreenshots: false,
58
56
  login: true,
@@ -21,6 +21,17 @@ import { useThemeStyles } from '../hooks/useThemeStyles';
21
21
  import { normalizeTheme } from '../utils/themeUtils';
22
22
  import { useOxy } from '../context/OxyContext';
23
23
 
24
+ // Button background colors for session actions
25
+ const SWITCH_BUTTON_BG = {
26
+ dark: '#1E2A38',
27
+ light: '#E6F2FF',
28
+ } as const;
29
+
30
+ const LOGOUT_BUTTON_BG = {
31
+ dark: '#3A1E1E',
32
+ light: '#FFEBEE',
33
+ } as const;
34
+
24
35
  const SessionManagementScreen: React.FC<BaseScreenProps> = ({
25
36
  onClose,
26
37
  theme,
@@ -45,7 +56,7 @@ const SessionManagementScreen: React.FC<BaseScreenProps> = ({
45
56
  const normalizedTheme = normalizeTheme(theme);
46
57
  const themeStyles = useThemeStyles(normalizedTheme);
47
58
  // Extract commonly used colors for readability
48
- const { textColor, backgroundColor, secondaryBackgroundColor, borderColor, primaryColor, dangerColor, successColor, isDarkTheme } = themeStyles;
59
+ const { textColor, backgroundColor, borderColor, primaryColor, dangerColor, successColor, isDarkTheme } = themeStyles;
49
60
 
50
61
  // Memoized load sessions function - prevents unnecessary re-renders
51
62
  const loadSessions = useCallback(async (isRefresh = false) => {
@@ -92,9 +103,14 @@ const SessionManagementScreen: React.FC<BaseScreenProps> = ({
92
103
  });
93
104
  }, [logout, refreshSessions]);
94
105
 
106
+ // Memoized bulk action items - prevents unnecessary re-renders when dependencies haven't changed
107
+ const otherSessionsCount = useMemo(() =>
108
+ userSessions.filter(s => s.sessionId !== activeSessionId).length,
109
+ [userSessions, activeSessionId]
110
+ );
111
+
95
112
  // Memoized logout other sessions handler - prevents unnecessary re-renders
96
113
  const handleLogoutOtherSessions = useCallback(async () => {
97
- const otherSessionsCount = userSessions.filter(s => s.sessionId !== activeSessionId).length;
98
114
  if (otherSessionsCount === 0) {
99
115
  toast.info('No other sessions to logout.');
100
116
  return;
@@ -119,7 +135,7 @@ const SessionManagementScreen: React.FC<BaseScreenProps> = ({
119
135
  }
120
136
  }
121
137
  );
122
- }, [userSessions, activeSessionId, logout, refreshSessions]);
138
+ }, [otherSessionsCount, userSessions, activeSessionId, logout, refreshSessions]);
123
139
 
124
140
  // Memoized logout all sessions handler - prevents unnecessary re-renders
125
141
  const handleLogoutAllSessions = useCallback(async () => {
@@ -132,6 +148,7 @@ const SessionManagementScreen: React.FC<BaseScreenProps> = ({
132
148
  } catch (error) {
133
149
  console.error('Logout all sessions failed:', error);
134
150
  toast.error('Failed to logout all sessions. Please try again.');
151
+ } finally {
135
152
  setActionLoading(null);
136
153
  }
137
154
  }
@@ -171,22 +188,18 @@ const SessionManagementScreen: React.FC<BaseScreenProps> = ({
171
188
  }
172
189
  }, [activeSessionId, switchSession]);
173
190
 
191
+ // Memoized refresh handler for pull-to-refresh
192
+ const handleRefresh = useCallback(() => {
193
+ loadSessions(true);
194
+ }, [loadSessions]);
195
+
174
196
  useEffect(() => {
175
197
  loadSessions();
176
198
  }, [loadSessions]);
177
199
 
178
- if (loading) {
179
- return (
180
- <View style={[styles.container, styles.centerContent, { backgroundColor }]}>
181
- <ActivityIndicator size="large" color={primaryColor} />
182
- <Text style={[styles.loadingText, { color: textColor }]}>Loading sessions...</Text>
183
- </View>
184
- );
185
- }
186
-
187
200
  // Memoized session items - prevents unnecessary re-renders when dependencies haven't changed
188
201
  const sessionItems = useMemo(() => {
189
- return userSessions.map((session: ClientSession) => {
202
+ return userSessions.map((session) => {
190
203
  const isCurrent = session.sessionId === activeSessionId;
191
204
  const subtitleParts: string[] = [];
192
205
  if (session.deviceId) subtitleParts.push(`Device ${session.deviceId.substring(0, 10)}...`);
@@ -205,7 +218,7 @@ const SessionManagementScreen: React.FC<BaseScreenProps> = ({
205
218
  <View style={styles.sessionActionsRow}>
206
219
  <TouchableOpacity
207
220
  onPress={() => handleSwitchSession(session.sessionId)}
208
- style={[styles.sessionPillButton, { backgroundColor: isDarkTheme ? '#1E2A38' : '#E6F2FF', borderColor: primaryColor }]}
221
+ style={[styles.sessionPillButton, { backgroundColor: isDarkTheme ? SWITCH_BUTTON_BG.dark : SWITCH_BUTTON_BG.light, borderColor: primaryColor }]}
209
222
  disabled={switchLoading === session.sessionId || actionLoading === session.sessionId}
210
223
  >
211
224
  {switchLoading === session.sessionId ? (
@@ -216,7 +229,7 @@ const SessionManagementScreen: React.FC<BaseScreenProps> = ({
216
229
  </TouchableOpacity>
217
230
  <TouchableOpacity
218
231
  onPress={() => handleLogoutSession(session.sessionId)}
219
- style={[styles.sessionPillButton, { backgroundColor: isDarkTheme ? '#3A1E1E' : '#FFEBEE', borderColor: dangerColor }]}
232
+ style={[styles.sessionPillButton, { backgroundColor: isDarkTheme ? LOGOUT_BUTTON_BG.dark : LOGOUT_BUTTON_BG.light, borderColor: dangerColor }]}
220
233
  disabled={actionLoading === session.sessionId || switchLoading === session.sessionId}
221
234
  >
222
235
  {actionLoading === session.sessionId ? (
@@ -237,12 +250,6 @@ const SessionManagementScreen: React.FC<BaseScreenProps> = ({
237
250
  });
238
251
  }, [userSessions, activeSessionId, formatRelative, successColor, primaryColor, isDarkTheme, switchLoading, actionLoading, handleSwitchSession, handleLogoutSession, dangerColor]);
239
252
 
240
- // Memoized bulk action items - prevents unnecessary re-renders when dependencies haven't changed
241
- const otherSessionsCount = useMemo(() =>
242
- userSessions.filter(s => s.sessionId !== activeSessionId).length,
243
- [userSessions, activeSessionId]
244
- );
245
-
246
253
  const bulkItems = useMemo(() => [
247
254
  {
248
255
  id: 'logout-others',
@@ -270,6 +277,15 @@ const SessionManagementScreen: React.FC<BaseScreenProps> = ({
270
277
  },
271
278
  ], [otherSessionsCount, primaryColor, dangerColor, handleLogoutOtherSessions, handleLogoutAllSessions, actionLoading]);
272
279
 
280
+ if (loading) {
281
+ return (
282
+ <View style={[styles.container, styles.centerContent, { backgroundColor }]}>
283
+ <ActivityIndicator size="large" color={primaryColor} />
284
+ <Text style={[styles.loadingText, { color: textColor }]}>Loading sessions...</Text>
285
+ </View>
286
+ );
287
+ }
288
+
273
289
  return (
274
290
  <View style={[styles.container, { backgroundColor }]}>
275
291
  <Header
@@ -285,7 +301,7 @@ const SessionManagementScreen: React.FC<BaseScreenProps> = ({
285
301
  refreshControl={
286
302
  <RefreshControl
287
303
  refreshing={refreshing}
288
- onRefresh={() => loadSessions(true)}
304
+ onRefresh={handleRefresh}
289
305
  tintColor={primaryColor}
290
306
  />
291
307
  }
@@ -293,12 +309,12 @@ const SessionManagementScreen: React.FC<BaseScreenProps> = ({
293
309
  {userSessions.length > 0 ? (
294
310
  <>
295
311
  {lastRefreshed && (
296
- <Text style={[styles.metaText, { color: isDarkTheme ? '#777' : '#777', marginBottom: 6 }]}>Last refreshed {formatRelative(lastRefreshed.toISOString())}</Text>
312
+ <Text style={[styles.metaText, { color: '#777', marginBottom: 6 }]}>Last refreshed {formatRelative(lastRefreshed.toISOString())}</Text>
297
313
  )}
298
314
  <View style={styles.fullBleed}>
299
315
  <GroupedSection items={sessionItems} />
300
316
  </View>
301
- <View style={{ height: 12 }} />
317
+ <View style={styles.sectionSpacer} />
302
318
  <View style={styles.fullBleed}>
303
319
  <GroupedSection items={bulkItems} />
304
320
  </View>
@@ -326,8 +342,6 @@ const styles = StyleSheet.create({
326
342
  justifyContent: 'center',
327
343
  alignItems: 'center',
328
344
  },
329
-
330
-
331
345
  scrollView: {
332
346
  flex: 1,
333
347
  },
@@ -376,6 +390,9 @@ const styles = StyleSheet.create({
376
390
  width: '100%',
377
391
  alignSelf: 'stretch',
378
392
  },
393
+ sectionSpacer: {
394
+ height: 12,
395
+ },
379
396
  emptyState: {
380
397
  alignItems: 'center',
381
398
  paddingVertical: 40,
@@ -7,12 +7,21 @@ export interface AuthState {
7
7
  isLoading: boolean;
8
8
  error: string | null;
9
9
  lastUserFetch: number | null; // Timestamp of last user fetch for caching
10
+
11
+ // Identity sync state (offline-first)
12
+ isIdentitySynced: boolean;
13
+ isSyncing: boolean;
14
+
10
15
  loginSuccess: (user: User) => void;
11
16
  loginFailure: (error: string) => void;
12
17
  logout: () => void;
13
18
  fetchUser: (oxyServices: { getCurrentUser: () => Promise<User> }, forceRefresh?: boolean) => Promise<void>;
14
19
  updateUser: (updates: Partial<User>, oxyServices: { updateProfile: (updates: Partial<User>) => Promise<User>; getCurrentUser: () => Promise<User> }) => Promise<void>;
15
20
  setUser: (user: User) => void; // Direct user setter for caching
21
+
22
+ // Identity sync actions
23
+ setIdentitySynced: (synced: boolean) => void;
24
+ setSyncing: (syncing: boolean) => void;
16
25
  }
17
26
 
18
27
  export const useAuthStore = create<AuthState>((set: (state: Partial<AuthState>) => void, get: () => AuthState) => ({
@@ -21,10 +30,30 @@ export const useAuthStore = create<AuthState>((set: (state: Partial<AuthState>)
21
30
  isLoading: false,
22
31
  error: null,
23
32
  lastUserFetch: null,
24
- loginSuccess: (user: User) => set({ isLoading: false, isAuthenticated: true, user, lastUserFetch: Date.now() }),
33
+
34
+ // Identity sync state (offline-first)
35
+ isIdentitySynced: true, // Assume synced until proven otherwise
36
+ isSyncing: false,
37
+
38
+ loginSuccess: (user: User) => set({
39
+ isLoading: false,
40
+ isAuthenticated: true,
41
+ user,
42
+ lastUserFetch: Date.now(),
43
+ isIdentitySynced: true, // If login succeeded, identity is synced
44
+ }),
25
45
  loginFailure: (error: string) => set({ isLoading: false, error }),
26
- logout: () => set({ user: null, isAuthenticated: false, lastUserFetch: null }),
46
+ logout: () => set({
47
+ user: null,
48
+ isAuthenticated: false,
49
+ lastUserFetch: null,
50
+ // Keep identity sync state - user might still have local identity
51
+ }),
27
52
  setUser: (user: User) => set({ user, lastUserFetch: Date.now() }),
53
+
54
+ // Identity sync actions
55
+ setIdentitySynced: (synced: boolean) => set({ isIdentitySynced: synced }),
56
+ setSyncing: (syncing: boolean) => set({ isSyncing: syncing }),
28
57
  fetchUser: async (oxyServices, forceRefresh = false) => {
29
58
  const state = get();
30
59
  const now = Date.now();
@@ -1,53 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.OxyServicesTotpMixin = OxyServicesTotpMixin;
7
- /**
8
- * TOTP Enrollment Methods Mixin
9
- */
10
-
11
- function OxyServicesTotpMixin(Base) {
12
- return class extends Base {
13
- constructor(...args) {
14
- super(...args);
15
- }
16
- async startTotpEnrollment(sessionId) {
17
- try {
18
- return await this.makeRequest('POST', '/api/auth/totp/enroll/start', {
19
- sessionId
20
- }, {
21
- cache: false
22
- });
23
- } catch (error) {
24
- throw this.handleError(error);
25
- }
26
- }
27
- async verifyTotpEnrollment(sessionId, code) {
28
- try {
29
- return await this.makeRequest('POST', '/api/auth/totp/enroll/verify', {
30
- sessionId,
31
- code
32
- }, {
33
- cache: false
34
- });
35
- } catch (error) {
36
- throw this.handleError(error);
37
- }
38
- }
39
- async disableTotp(sessionId, code) {
40
- try {
41
- return await this.makeRequest('POST', '/api/auth/totp/disable', {
42
- sessionId,
43
- code
44
- }, {
45
- cache: false
46
- });
47
- } catch (error) {
48
- throw this.handleError(error);
49
- }
50
- }
51
- };
52
- }
53
- //# sourceMappingURL=OxyServices.totp.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":["OxyServicesTotpMixin","Base","constructor","args","startTotpEnrollment","sessionId","makeRequest","cache","error","handleError","verifyTotpEnrollment","code","disableTotp"],"sourceRoot":"../../../../src","sources":["core/mixins/OxyServices.totp.ts"],"mappings":";;;;;;AAAA;AACA;AACA;;AAGO,SAASA,oBAAoBA,CAAmCC,IAAO,EAAE;EAC9E,OAAO,cAAcA,IAAI,CAAC;IACxBC,WAAWA,CAAC,GAAGC,IAAW,EAAE;MAC1B,KAAK,CAAC,GAAIA,IAAc,CAAC;IAC3B;IACA,MAAMC,mBAAmBA,CAACC,SAAiB,EAAkF;MAC3H,IAAI;QACF,OAAO,MAAM,IAAI,CAACC,WAAW,CAAC,MAAM,EAAE,6BAA6B,EAAE;UAAED;QAAU,CAAC,EAAE;UAAEE,KAAK,EAAE;QAAM,CAAC,CAAC;MACvG,CAAC,CAAC,OAAOC,KAAK,EAAE;QACd,MAAM,IAAI,CAACC,WAAW,CAACD,KAAK,CAAC;MAC/B;IACF;IAEA,MAAME,oBAAoBA,CAACL,SAAiB,EAAEM,IAAY,EAA+E;MACvI,IAAI;QACF,OAAO,MAAM,IAAI,CAACL,WAAW,CAAC,MAAM,EAAE,8BAA8B,EAAE;UAAED,SAAS;UAAEM;QAAK,CAAC,EAAE;UAAEJ,KAAK,EAAE;QAAM,CAAC,CAAC;MAC9G,CAAC,CAAC,OAAOC,KAAK,EAAE;QACd,MAAM,IAAI,CAACC,WAAW,CAACD,KAAK,CAAC;MAC/B;IACF;IAEA,MAAMI,WAAWA,CAACP,SAAiB,EAAEM,IAAY,EAAkC;MACjF,IAAI;QACF,OAAO,MAAM,IAAI,CAACL,WAAW,CAAC,MAAM,EAAE,wBAAwB,EAAE;UAAED,SAAS;UAAEM;QAAK,CAAC,EAAE;UAAEJ,KAAK,EAAE;QAAM,CAAC,CAAC;MACxG,CAAC,CAAC,OAAOC,KAAK,EAAE;QACd,MAAM,IAAI,CAACC,WAAW,CAACD,KAAK,CAAC;MAC/B;IACF;EACF,CAAC;AACH","ignoreList":[]}