@oxyhq/services 5.16.17 → 5.16.18

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 (227) hide show
  1. package/lib/commonjs/core/mixins/OxyServices.security.js +42 -0
  2. package/lib/commonjs/core/mixins/OxyServices.security.js.map +1 -1
  3. package/lib/commonjs/models/interfaces.js +2 -0
  4. package/lib/commonjs/models/interfaces.js.map +1 -1
  5. package/lib/commonjs/ui/components/FollowButton.js +19 -1
  6. package/lib/commonjs/ui/components/FollowButton.js.map +1 -1
  7. package/lib/commonjs/ui/components/GroupedItem.js +1 -27
  8. package/lib/commonjs/ui/components/GroupedItem.js.map +1 -1
  9. package/lib/commonjs/ui/components/Section.js +2 -1
  10. package/lib/commonjs/ui/components/Section.js.map +1 -1
  11. package/lib/commonjs/ui/components/SectionTitle.js +1 -2
  12. package/lib/commonjs/ui/components/SectionTitle.js.map +1 -1
  13. package/lib/commonjs/ui/components/fileManagement/FileViewer.js +3 -3
  14. package/lib/commonjs/ui/components/fileManagement/FileViewer.js.map +1 -1
  15. package/lib/commonjs/ui/context/OxyContext.js +44 -6
  16. package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
  17. package/lib/commonjs/ui/context/hooks/useAuthOperations.js +9 -2
  18. package/lib/commonjs/ui/context/hooks/useAuthOperations.js.map +1 -1
  19. package/lib/commonjs/ui/context/hooks/useDeviceManagement.js +1 -1
  20. package/lib/commonjs/ui/context/hooks/useLanguageManagement.js +1 -1
  21. package/lib/commonjs/ui/context/hooks/useSessionManagement.js +3 -3
  22. package/lib/commonjs/ui/context/hooks/useStorage.js +2 -2
  23. package/lib/commonjs/ui/hooks/queries/useAccountQueries.js +1 -1
  24. package/lib/commonjs/ui/hooks/queries/useAccountQueries.js.map +1 -1
  25. package/lib/commonjs/ui/hooks/queries/useServicesQueries.js +1 -1
  26. package/lib/commonjs/ui/hooks/useSessionSocket.js +22 -7
  27. package/lib/commonjs/ui/hooks/useSessionSocket.js.map +1 -1
  28. package/lib/commonjs/ui/screens/AccountCenterScreen.js +13 -13
  29. package/lib/commonjs/ui/screens/AccountCenterScreen.js.map +1 -1
  30. package/lib/commonjs/ui/screens/AccountOverviewScreen.js +17 -17
  31. package/lib/commonjs/ui/screens/AccountOverviewScreen.js.map +1 -1
  32. package/lib/commonjs/ui/screens/AccountSettingsScreen.js +2 -2
  33. package/lib/commonjs/ui/screens/AccountSettingsScreen.js.map +1 -1
  34. package/lib/commonjs/ui/screens/AccountSwitcherScreen.js +10 -9
  35. package/lib/commonjs/ui/screens/AccountSwitcherScreen.js.map +1 -1
  36. package/lib/commonjs/ui/screens/AppInfoScreen.js +15 -15
  37. package/lib/commonjs/ui/screens/AppInfoScreen.js.map +1 -1
  38. package/lib/commonjs/ui/screens/FeedbackScreen.js +1 -1
  39. package/lib/commonjs/ui/screens/FeedbackScreen.js.map +1 -1
  40. package/lib/commonjs/ui/screens/FileManagementScreen.js +1 -1
  41. package/lib/commonjs/ui/screens/HelpSupportScreen.js +3 -3
  42. package/lib/commonjs/ui/screens/HelpSupportScreen.js.map +1 -1
  43. package/lib/commonjs/ui/screens/HistoryViewScreen.js +2 -2
  44. package/lib/commonjs/ui/screens/HistoryViewScreen.js.map +1 -1
  45. package/lib/commonjs/ui/screens/LanguageSelectorScreen.js +3 -1
  46. package/lib/commonjs/ui/screens/LanguageSelectorScreen.js.map +1 -1
  47. package/lib/commonjs/ui/screens/LegalDocumentsScreen.js +4 -4
  48. package/lib/commonjs/ui/screens/LegalDocumentsScreen.js.map +1 -1
  49. package/lib/commonjs/ui/screens/PaymentGatewayScreen.js +1 -1
  50. package/lib/commonjs/ui/screens/PaymentGatewayScreen.js.map +1 -1
  51. package/lib/commonjs/ui/screens/PremiumSubscriptionScreen.js +1 -2
  52. package/lib/commonjs/ui/screens/PremiumSubscriptionScreen.js.map +1 -1
  53. package/lib/commonjs/ui/screens/ProfileScreen.js +44 -16
  54. package/lib/commonjs/ui/screens/ProfileScreen.js.map +1 -1
  55. package/lib/commonjs/ui/screens/SavesCollectionsScreen.js.map +1 -1
  56. package/lib/commonjs/ui/screens/karma/KarmaAboutScreen.js +3 -1
  57. package/lib/commonjs/ui/screens/karma/KarmaAboutScreen.js.map +1 -1
  58. package/lib/commonjs/ui/screens/karma/KarmaCenterScreen.js +2 -2
  59. package/lib/commonjs/ui/screens/karma/KarmaCenterScreen.js.map +1 -1
  60. package/lib/commonjs/ui/screens/karma/KarmaRewardsScreen.js +8 -5
  61. package/lib/commonjs/ui/screens/karma/KarmaRewardsScreen.js.map +1 -1
  62. package/lib/commonjs/ui/utils/errorHandlers.js +49 -2
  63. package/lib/commonjs/ui/utils/errorHandlers.js.map +1 -1
  64. package/lib/commonjs/ui/utils/sessionHelpers.js +0 -2
  65. package/lib/commonjs/ui/utils/sessionHelpers.js.map +1 -1
  66. package/lib/commonjs/utils/languageUtils.js +11 -11
  67. package/lib/commonjs/utils/languageUtils.js.map +1 -1
  68. package/lib/module/core/mixins/OxyServices.security.js +42 -0
  69. package/lib/module/core/mixins/OxyServices.security.js.map +1 -1
  70. package/lib/module/models/interfaces.js +2 -0
  71. package/lib/module/models/interfaces.js.map +1 -1
  72. package/lib/module/ui/components/FollowButton.js +19 -1
  73. package/lib/module/ui/components/FollowButton.js.map +1 -1
  74. package/lib/module/ui/components/GroupedItem.js +1 -29
  75. package/lib/module/ui/components/GroupedItem.js.map +1 -1
  76. package/lib/module/ui/components/Section.js +2 -1
  77. package/lib/module/ui/components/Section.js.map +1 -1
  78. package/lib/module/ui/components/SectionTitle.js +1 -2
  79. package/lib/module/ui/components/SectionTitle.js.map +1 -1
  80. package/lib/module/ui/components/fileManagement/FileViewer.js +3 -3
  81. package/lib/module/ui/components/fileManagement/FileViewer.js.map +1 -1
  82. package/lib/module/ui/context/OxyContext.js +45 -7
  83. package/lib/module/ui/context/OxyContext.js.map +1 -1
  84. package/lib/module/ui/context/hooks/useAuthOperations.js +9 -2
  85. package/lib/module/ui/context/hooks/useAuthOperations.js.map +1 -1
  86. package/lib/module/ui/context/hooks/useDeviceManagement.js +1 -1
  87. package/lib/module/ui/context/hooks/useDeviceManagement.js.map +1 -1
  88. package/lib/module/ui/context/hooks/useLanguageManagement.js +1 -1
  89. package/lib/module/ui/context/hooks/useLanguageManagement.js.map +1 -1
  90. package/lib/module/ui/context/hooks/useSessionManagement.js +3 -3
  91. package/lib/module/ui/context/hooks/useSessionManagement.js.map +1 -1
  92. package/lib/module/ui/context/hooks/useStorage.js +2 -2
  93. package/lib/module/ui/context/hooks/useStorage.js.map +1 -1
  94. package/lib/module/ui/hooks/queries/useAccountQueries.js +1 -1
  95. package/lib/module/ui/hooks/queries/useAccountQueries.js.map +1 -1
  96. package/lib/module/ui/hooks/queries/useServicesQueries.js +1 -1
  97. package/lib/module/ui/hooks/queries/useServicesQueries.js.map +1 -1
  98. package/lib/module/ui/hooks/useSessionSocket.js +22 -7
  99. package/lib/module/ui/hooks/useSessionSocket.js.map +1 -1
  100. package/lib/module/ui/screens/AccountCenterScreen.js +13 -13
  101. package/lib/module/ui/screens/AccountCenterScreen.js.map +1 -1
  102. package/lib/module/ui/screens/AccountOverviewScreen.js +17 -17
  103. package/lib/module/ui/screens/AccountOverviewScreen.js.map +1 -1
  104. package/lib/module/ui/screens/AccountSettingsScreen.js +2 -2
  105. package/lib/module/ui/screens/AccountSettingsScreen.js.map +1 -1
  106. package/lib/module/ui/screens/AccountSwitcherScreen.js +11 -10
  107. package/lib/module/ui/screens/AccountSwitcherScreen.js.map +1 -1
  108. package/lib/module/ui/screens/AppInfoScreen.js +15 -15
  109. package/lib/module/ui/screens/AppInfoScreen.js.map +1 -1
  110. package/lib/module/ui/screens/FeedbackScreen.js +1 -1
  111. package/lib/module/ui/screens/FeedbackScreen.js.map +1 -1
  112. package/lib/module/ui/screens/FileManagementScreen.js +1 -1
  113. package/lib/module/ui/screens/HelpSupportScreen.js +3 -3
  114. package/lib/module/ui/screens/HelpSupportScreen.js.map +1 -1
  115. package/lib/module/ui/screens/HistoryViewScreen.js +2 -2
  116. package/lib/module/ui/screens/HistoryViewScreen.js.map +1 -1
  117. package/lib/module/ui/screens/LanguageSelectorScreen.js +4 -2
  118. package/lib/module/ui/screens/LanguageSelectorScreen.js.map +1 -1
  119. package/lib/module/ui/screens/LegalDocumentsScreen.js +4 -4
  120. package/lib/module/ui/screens/LegalDocumentsScreen.js.map +1 -1
  121. package/lib/module/ui/screens/PaymentGatewayScreen.js +1 -1
  122. package/lib/module/ui/screens/PaymentGatewayScreen.js.map +1 -1
  123. package/lib/module/ui/screens/PremiumSubscriptionScreen.js +1 -2
  124. package/lib/module/ui/screens/PremiumSubscriptionScreen.js.map +1 -1
  125. package/lib/module/ui/screens/ProfileScreen.js +44 -16
  126. package/lib/module/ui/screens/ProfileScreen.js.map +1 -1
  127. package/lib/module/ui/screens/SavesCollectionsScreen.js.map +1 -1
  128. package/lib/module/ui/screens/karma/KarmaAboutScreen.js +3 -1
  129. package/lib/module/ui/screens/karma/KarmaAboutScreen.js.map +1 -1
  130. package/lib/module/ui/screens/karma/KarmaCenterScreen.js +3 -3
  131. package/lib/module/ui/screens/karma/KarmaCenterScreen.js.map +1 -1
  132. package/lib/module/ui/screens/karma/KarmaRewardsScreen.js +9 -6
  133. package/lib/module/ui/screens/karma/KarmaRewardsScreen.js.map +1 -1
  134. package/lib/module/ui/utils/errorHandlers.js +46 -0
  135. package/lib/module/ui/utils/errorHandlers.js.map +1 -1
  136. package/lib/module/ui/utils/sessionHelpers.js +0 -2
  137. package/lib/module/ui/utils/sessionHelpers.js.map +1 -1
  138. package/lib/module/utils/languageUtils.js +11 -11
  139. package/lib/module/utils/languageUtils.js.map +1 -1
  140. package/lib/typescript/core/mixins/OxyServices.security.d.ts +12 -0
  141. package/lib/typescript/core/mixins/OxyServices.security.d.ts.map +1 -1
  142. package/lib/typescript/core/mixins/index.d.ts +2 -0
  143. package/lib/typescript/core/mixins/index.d.ts.map +1 -1
  144. package/lib/typescript/models/interfaces.d.ts +1 -1
  145. package/lib/typescript/models/interfaces.d.ts.map +1 -1
  146. package/lib/typescript/ui/components/FollowButton.d.ts.map +1 -1
  147. package/lib/typescript/ui/components/GroupedItem.d.ts.map +1 -1
  148. package/lib/typescript/ui/components/Section.d.ts.map +1 -1
  149. package/lib/typescript/ui/components/SectionTitle.d.ts.map +1 -1
  150. package/lib/typescript/ui/context/OxyContext.d.ts.map +1 -1
  151. package/lib/typescript/ui/context/hooks/useAuthOperations.d.ts +1 -1
  152. package/lib/typescript/ui/context/hooks/useAuthOperations.d.ts.map +1 -1
  153. package/lib/typescript/ui/context/hooks/useLanguageManagement.d.ts +1 -1
  154. package/lib/typescript/ui/context/hooks/useLanguageManagement.d.ts.map +1 -1
  155. package/lib/typescript/ui/context/hooks/useSessionManagement.d.ts +1 -1
  156. package/lib/typescript/ui/context/hooks/useSessionManagement.d.ts.map +1 -1
  157. package/lib/typescript/ui/context/hooks/useStorage.d.ts +1 -1
  158. package/lib/typescript/ui/context/hooks/useStorage.d.ts.map +1 -1
  159. package/lib/typescript/ui/hooks/useSessionSocket.d.ts.map +1 -1
  160. package/lib/typescript/ui/screens/LanguageSelectorScreen.d.ts.map +1 -1
  161. package/lib/typescript/ui/screens/PremiumSubscriptionScreen.d.ts.map +1 -1
  162. package/lib/typescript/ui/screens/ProfileScreen.d.ts.map +1 -1
  163. package/lib/typescript/ui/screens/SavesCollectionsScreen.d.ts.map +1 -1
  164. package/lib/typescript/ui/screens/karma/KarmaAboutScreen.d.ts.map +1 -1
  165. package/lib/typescript/ui/screens/karma/KarmaRewardsScreen.d.ts.map +1 -1
  166. package/lib/typescript/ui/utils/errorHandlers.d.ts +5 -0
  167. package/lib/typescript/ui/utils/errorHandlers.d.ts.map +1 -1
  168. package/lib/typescript/ui/utils/sessionHelpers.d.ts.map +1 -1
  169. package/package.json +1 -1
  170. package/src/core/mixins/OxyServices.security.ts +44 -0
  171. package/src/models/interfaces.ts +4 -0
  172. package/src/ui/components/FollowButton.tsx +19 -1
  173. package/src/ui/components/GroupedItem.tsx +1 -29
  174. package/src/ui/components/Section.tsx +1 -0
  175. package/src/ui/components/SectionTitle.tsx +0 -1
  176. package/src/ui/components/fileManagement/FileViewer.tsx +3 -3
  177. package/src/ui/context/OxyContext.tsx +30 -9
  178. package/src/ui/context/hooks/useAuthOperations.ts +16 -9
  179. package/src/ui/context/hooks/useDeviceManagement.ts +1 -1
  180. package/src/ui/context/hooks/useLanguageManagement.ts +2 -2
  181. package/src/ui/context/hooks/useSessionManagement.ts +3 -3
  182. package/src/ui/context/hooks/useStorage.ts +2 -2
  183. package/src/ui/hooks/queries/useAccountQueries.ts +1 -1
  184. package/src/ui/hooks/queries/useServicesQueries.ts +1 -1
  185. package/src/ui/hooks/useSessionSocket.ts +8 -7
  186. package/src/ui/screens/AccountCenterScreen.tsx +13 -13
  187. package/src/ui/screens/AccountOverviewScreen.tsx +17 -17
  188. package/src/ui/screens/AccountSettingsScreen.tsx +2 -2
  189. package/src/ui/screens/AccountSwitcherScreen.tsx +8 -8
  190. package/src/ui/screens/AppInfoScreen.tsx +15 -15
  191. package/src/ui/screens/FeedbackScreen.tsx +1 -1
  192. package/src/ui/screens/FileManagementScreen.tsx +1 -1
  193. package/src/ui/screens/HelpSupportScreen.tsx +3 -3
  194. package/src/ui/screens/HistoryViewScreen.tsx +2 -2
  195. package/src/ui/screens/LanguageSelectorScreen.tsx +4 -1
  196. package/src/ui/screens/LegalDocumentsScreen.tsx +4 -4
  197. package/src/ui/screens/PaymentGatewayScreen.tsx +1 -1
  198. package/src/ui/screens/PremiumSubscriptionScreen.tsx +0 -1
  199. package/src/ui/screens/ProfileScreen.tsx +61 -22
  200. package/src/ui/screens/SavesCollectionsScreen.tsx +10 -1
  201. package/src/ui/screens/karma/KarmaAboutScreen.tsx +8 -1
  202. package/src/ui/screens/karma/KarmaCenterScreen.tsx +2 -2
  203. package/src/ui/screens/karma/KarmaRewardsScreen.tsx +9 -6
  204. package/src/ui/utils/errorHandlers.ts +58 -0
  205. package/src/ui/utils/sessionHelpers.ts +0 -2
  206. package/src/utils/languageUtils.ts +11 -11
  207. package/lib/commonjs/ui/context/utils/errorHandlers.js +0 -100
  208. package/lib/commonjs/ui/context/utils/errorHandlers.js.map +0 -1
  209. package/lib/commonjs/ui/context/utils/sessionHelpers.js +0 -103
  210. package/lib/commonjs/ui/context/utils/sessionHelpers.js.map +0 -1
  211. package/lib/commonjs/ui/context/utils/storageHelpers.js +0 -119
  212. package/lib/commonjs/ui/context/utils/storageHelpers.js.map +0 -1
  213. package/lib/module/ui/context/utils/errorHandlers.js +0 -93
  214. package/lib/module/ui/context/utils/errorHandlers.js.map +0 -1
  215. package/lib/module/ui/context/utils/sessionHelpers.js +0 -96
  216. package/lib/module/ui/context/utils/sessionHelpers.js.map +0 -1
  217. package/lib/module/ui/context/utils/storageHelpers.js +0 -111
  218. package/lib/module/ui/context/utils/storageHelpers.js.map +0 -1
  219. package/lib/typescript/ui/context/utils/errorHandlers.d.ts +0 -30
  220. package/lib/typescript/ui/context/utils/errorHandlers.d.ts.map +0 -1
  221. package/lib/typescript/ui/context/utils/sessionHelpers.d.ts +0 -59
  222. package/lib/typescript/ui/context/utils/sessionHelpers.d.ts.map +0 -1
  223. package/lib/typescript/ui/context/utils/storageHelpers.d.ts +0 -31
  224. package/lib/typescript/ui/context/utils/storageHelpers.d.ts.map +0 -1
  225. package/src/ui/context/utils/errorHandlers.ts +0 -146
  226. package/src/ui/context/utils/sessionHelpers.ts +0 -146
  227. package/src/ui/context/utils/storageHelpers.ts +0 -134
@@ -415,6 +415,8 @@ export type SecurityEventType =
415
415
  | 'device_removed'
416
416
  | 'account_recovery'
417
417
  | 'security_settings_changed'
418
+ | 'private_key_exported'
419
+ | 'backup_created'
418
420
  | 'suspicious_activity';
419
421
 
420
422
  /**
@@ -435,6 +437,8 @@ export const SECURITY_EVENT_SEVERITY_MAP: Record<SecurityEventType, SecurityEven
435
437
  'device_removed': 'medium',
436
438
  'security_settings_changed': 'medium',
437
439
  'account_recovery': 'high',
440
+ 'private_key_exported': 'high',
441
+ 'backup_created': 'high',
438
442
  'suspicious_activity': 'critical',
439
443
  };
440
444
 
@@ -53,8 +53,26 @@ const FollowButton: React.FC<FollowButtonProps> = ({
53
53
  preventParentActions = true,
54
54
  theme = 'light',
55
55
  }) => {
56
- const { oxyServices, isAuthenticated } = useOxy();
56
+ const { oxyServices, isAuthenticated, user: currentUser } = useOxy();
57
57
  const colors = useThemeColors(theme);
58
+
59
+ // Safety check: Don't render follow button on own profile
60
+ // This provides a fallback in case parent components don't handle this check
61
+ // Normalize IDs by trimming whitespace and comparing as strings
62
+ const normalizeId = (id: string | undefined | null): string => {
63
+ if (!id) return '';
64
+ return String(id).trim();
65
+ };
66
+
67
+ const currentUserId = normalizeId(currentUser?.id);
68
+ const targetUserId = normalizeId(userId);
69
+
70
+ // Don't render if:
71
+ // 1. Not authenticated (can't follow anyway)
72
+ // 2. Viewing own profile (currentUser.id matches userId)
73
+ if (!isAuthenticated || (currentUserId && targetUserId && currentUserId === targetUserId)) {
74
+ return null;
75
+ }
58
76
  const {
59
77
  isFollowing,
60
78
  isLoading,
@@ -9,34 +9,6 @@ import { darkenColor } from '../utils/colorUtils';
9
9
  import { normalizeColorScheme } from '../utils/themeUtils';
10
10
  import { Colors } from '../constants/theme';
11
11
 
12
- /**
13
- * Maps Ionicons-style icon names to valid MaterialCommunityIcons names
14
- */
15
- const mapIconName = (iconName: string): string => {
16
- const iconMap: Record<string, string> = {
17
- 'person': 'account',
18
- 'person-circle': 'account-circle',
19
- 'person-outline': 'account-outline',
20
- 'person-add': 'account-plus',
21
- 'shield-checkmark': 'shield-check',
22
- 'notifications': 'bell',
23
- 'people': 'account-group',
24
- 'time': 'clock',
25
- 'time-outline': 'clock-outline',
26
- 'trash': 'delete',
27
- 'trash-outline': 'delete-outline',
28
- 'search': 'magnify',
29
- 'language': 'translate',
30
- 'language-outline': 'translate',
31
- 'settings': 'cog',
32
- 'document-text': 'file-document',
33
- 'information-circle': 'information',
34
- 'information-circle-outline': 'information-outline',
35
- 'log-out': 'logout',
36
- };
37
-
38
- return iconMap[iconName] || iconName;
39
- };
40
12
 
41
13
  interface GroupedItemProps {
42
14
  icon?: string;
@@ -91,7 +63,7 @@ const GroupedItemComponent = ({
91
63
  <View style={styles.actionIcon}>{customIcon}</View>
92
64
  ) : icon ? (
93
65
  <View style={[styles.iconContainer, { backgroundColor: finalIconColor }]}>
94
- <MaterialCommunityIcons name={mapIconName(icon) as any} size={22} color={darkenColor(finalIconColor)} />
66
+ <MaterialCommunityIcons name={icon as any} size={22} color={darkenColor(finalIconColor)} />
95
67
  </View>
96
68
  ) : null}
97
69
  <View style={styles.actionTextContainer}>
@@ -32,6 +32,7 @@ const Section: React.FC<SectionProps> = ({
32
32
  const styles = StyleSheet.create({
33
33
  section: {
34
34
  marginBottom: 10,
35
+ gap: 12,
35
36
  },
36
37
  firstSection: {
37
38
  marginTop: 8,
@@ -27,7 +27,6 @@ const styles = StyleSheet.create({
27
27
  fontSize: 16,
28
28
  fontWeight: '600',
29
29
  fontFamily: fontFamilies.phuduSemiBold,
30
- marginBottom: 12,
31
30
  },
32
31
  });
33
32
 
@@ -105,7 +105,7 @@ export const FileViewer: React.FC<FileViewerProps> = ({
105
105
  const items = [
106
106
  {
107
107
  id: 'filename',
108
- icon: 'document-text',
108
+ icon: 'file-document',
109
109
  iconColor: themeStyles.colors.iconSecurity,
110
110
  title: 'File Name',
111
111
  subtitle: file.filename,
@@ -119,14 +119,14 @@ export const FileViewer: React.FC<FileViewerProps> = ({
119
119
  },
120
120
  {
121
121
  id: 'type',
122
- icon: 'code',
122
+ icon: 'code-tags',
123
123
  iconColor: themeStyles.colors.iconData,
124
124
  title: 'Type',
125
125
  subtitle: file.contentType,
126
126
  },
127
127
  {
128
128
  id: 'uploaded',
129
- icon: 'time',
129
+ icon: 'clock',
130
130
  iconColor: themeStyles.colors.iconPersonalInfo,
131
131
  title: 'Uploaded',
132
132
  subtitle: new Date(file.uploadDate).toLocaleString(),
@@ -24,7 +24,7 @@ import { useSessionManagement } from '../hooks/useSessionManagement';
24
24
  import { useAuthOperations } from './hooks/useAuthOperations';
25
25
  import { useDeviceManagement } from '../hooks/useDeviceManagement';
26
26
  import { getStorageKeys } from '../utils/storageHelpers';
27
- import { isInvalidSessionError } from '../utils/errorHandlers';
27
+ import { isInvalidSessionError, isTimeoutOrNetworkError } from '../utils/errorHandlers';
28
28
  import type { RouteName } from '../navigation/routes';
29
29
  import { showBottomSheet as globalShowBottomSheet } from '../navigation/bottomSheetManager';
30
30
  import { useQueryClient } from '@tanstack/react-query';
@@ -33,6 +33,7 @@ import { KeyManager } from '../../crypto/keyManager';
33
33
  import { translate } from '../../i18n';
34
34
  import { updateAvatarVisibility, updateProfileWithAvatar } from '../utils/avatarUtils';
35
35
  import { useAccountStore } from '../stores/accountStore';
36
+ import { logger as loggerUtil } from '../../utils/loggerUtils';
36
37
 
37
38
  export interface OxyContextState {
38
39
  user: User | null;
@@ -115,9 +116,10 @@ const loadUseFollowHook = (): UseFollowHook => {
115
116
  return cachedUseFollowHook;
116
117
  } catch (error) {
117
118
  if (__DEV__) {
118
- console.warn(
119
+ loggerUtil.warn(
119
120
  'useFollow hook is not available. Please import useFollow from @oxyhq/services directly.',
120
- error,
121
+ { component: 'OxyContext', method: 'loadUseFollowHook' },
122
+ error
121
123
  );
122
124
  }
123
125
 
@@ -425,8 +427,19 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
425
427
  await syncIdentity();
426
428
  }
427
429
  }
428
- } catch (syncError) {
429
- logger('Error syncing identity on reconnect', syncError);
430
+ } catch (syncError: any) {
431
+ // Skip sync silently if username is required (expected when offline onboarding)
432
+ if (syncError?.code === 'USERNAME_REQUIRED' || syncError?.message === 'USERNAME_REQUIRED') {
433
+ if (__DEV__) {
434
+ loggerUtil.debug('Sync skipped - username required', { component: 'OxyContext', method: 'checkNetworkAndSync' }, syncError as unknown);
435
+ }
436
+ // Don't log or show error - username will be set later
437
+ } else if (!isTimeoutOrNetworkError(syncError)) {
438
+ // Only log unexpected errors - timeouts/network issues are expected when offline
439
+ logger('Error syncing identity on reconnect', syncError);
440
+ } else if (__DEV__) {
441
+ loggerUtil.debug('Identity sync timeout (expected when offline)', { component: 'OxyContext', method: 'checkNetworkAndSync' }, syncError as unknown);
442
+ }
430
443
  }
431
444
 
432
445
  // TanStack Query will automatically retry pending mutations
@@ -509,10 +522,13 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
509
522
  });
510
523
  }
511
524
  } catch (validationError) {
512
- // Silently handle expected 401 errors (expired/invalid sessions) during restoration
525
+ // Silently handle expected errors (invalid sessions, timeouts, network issues) during restoration
513
526
  // Only log unexpected errors
514
- if (!isInvalidSessionError(validationError)) {
527
+ if (!isInvalidSessionError(validationError) && !isTimeoutOrNetworkError(validationError)) {
515
528
  logger('Session validation failed during init', validationError);
529
+ } else if (__DEV__ && isTimeoutOrNetworkError(validationError)) {
530
+ // Only log timeouts in dev mode for debugging
531
+ loggerUtil.debug('Session validation timeout (expected when offline)', { component: 'OxyContext', method: 'restoreSessionsFromStorage' }, validationError as unknown);
516
532
  }
517
533
  }
518
534
  }
@@ -526,7 +542,7 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
526
542
  try {
527
543
  await switchSession(storedActiveSessionId);
528
544
  } catch (switchError) {
529
- // Silently handle expected 401 errors (expired/invalid active session)
545
+ // Silently handle expected errors (invalid sessions, timeouts, network issues)
530
546
  if (isInvalidSessionError(switchError)) {
531
547
  await storage.removeItem(storageKeys.activeSessionId);
532
548
  updateSessions(
@@ -534,6 +550,11 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
534
550
  { merge: false },
535
551
  );
536
552
  // Don't log expected session errors during restoration
553
+ } else if (isTimeoutOrNetworkError(switchError)) {
554
+ // Timeout/network error - non-critical, don't block
555
+ if (__DEV__) {
556
+ loggerUtil.debug('Active session validation timeout (expected when offline)', { component: 'OxyContext', method: 'restoreSessionsFromStorage' }, switchError as unknown);
557
+ }
537
558
  } else {
538
559
  // Only log unexpected errors
539
560
  logger('Active session validation error', switchError);
@@ -542,7 +563,7 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
542
563
  }
543
564
  } catch (error) {
544
565
  if (__DEV__) {
545
- console.error('Auth init error', error);
566
+ loggerUtil.error('Auth init error', error instanceof Error ? error : new Error(String(error)), { component: 'OxyContext', method: 'restoreSessionsFromStorage' });
546
567
  }
547
568
  await clearSessionState();
548
569
  } finally {
@@ -3,9 +3,9 @@ import type { ApiError, User } from '../../../models/interfaces';
3
3
  import type { AuthState } from '../../stores/authStore';
4
4
  import type { ClientSession, SessionLoginResponse } from '../../../models/session';
5
5
  import { DeviceManager } from '../../../utils/deviceManager';
6
- import { fetchSessionsWithFallback, mapSessionsToClient } from '../utils/sessionHelpers';
7
- import { handleAuthError, isInvalidSessionError } from '../utils/errorHandlers';
8
- import type { StorageInterface } from '../utils/storageHelpers';
6
+ import { fetchSessionsWithFallback, mapSessionsToClient } from '../../utils/sessionHelpers';
7
+ import { handleAuthError, isInvalidSessionError } from '../../utils/errorHandlers';
8
+ import type { StorageInterface } from '../../utils/storageHelpers';
9
9
  import type { OxyServices } from '../../../core';
10
10
  import { KeyManager, SignatureService, RecoveryPhraseService } from '../../../crypto';
11
11
 
@@ -342,7 +342,7 @@ export const useAuthOperations = ({
342
342
  defaultMessage: 'Failed to create identity',
343
343
  code: REGISTER_ERROR_CODE,
344
344
  onError,
345
- setAuthError: (msg) => setAuthState({ error: msg }),
345
+ setAuthError: (msg: string) => setAuthState({ error: msg }),
346
346
  logger,
347
347
  });
348
348
  loginFailure(message);
@@ -405,6 +405,13 @@ export const useAuthOperations = ({
405
405
  // Sign in
406
406
  const user = await performSignIn(publicKey);
407
407
 
408
+ // Check if user has username - required for syncing
409
+ if (!user.username) {
410
+ const usernameError = new Error('USERNAME_REQUIRED');
411
+ (usernameError as any).code = 'USERNAME_REQUIRED';
412
+ throw usernameError;
413
+ }
414
+
408
415
  // TanStack Query will automatically retry any pending mutations
409
416
 
410
417
  return user;
@@ -413,7 +420,7 @@ export const useAuthOperations = ({
413
420
  defaultMessage: 'Failed to sync identity',
414
421
  code: REGISTER_ERROR_CODE,
415
422
  onError,
416
- setAuthError: (msg) => setAuthState({ error: msg }),
423
+ setAuthError: (msg: string) => setAuthState({ error: msg }),
417
424
  logger,
418
425
  });
419
426
  loginFailure(message);
@@ -474,7 +481,7 @@ export const useAuthOperations = ({
474
481
  defaultMessage: 'Failed to import identity',
475
482
  code: REGISTER_ERROR_CODE,
476
483
  onError,
477
- setAuthError: (msg) => setAuthState({ error: msg }),
484
+ setAuthError: (msg: string) => setAuthState({ error: msg }),
478
485
  logger,
479
486
  });
480
487
  loginFailure(message);
@@ -508,7 +515,7 @@ export const useAuthOperations = ({
508
515
  defaultMessage: 'Sign in failed',
509
516
  code: LOGIN_ERROR_CODE,
510
517
  onError,
511
- setAuthError: (msg) => setAuthState({ error: msg }),
518
+ setAuthError: (msg: string) => setAuthState({ error: msg }),
512
519
  logger,
513
520
  });
514
521
  loginFailure(message);
@@ -554,7 +561,7 @@ export const useAuthOperations = ({
554
561
  defaultMessage: 'Logout failed',
555
562
  code: LOGOUT_ERROR_CODE,
556
563
  onError,
557
- setAuthError: (msg) => setAuthState({ error: msg }),
564
+ setAuthError: (msg: string) => setAuthState({ error: msg }),
558
565
  logger,
559
566
  status: isInvalid ? 401 : undefined,
560
567
  });
@@ -592,7 +599,7 @@ export const useAuthOperations = ({
592
599
  defaultMessage: 'Logout all failed',
593
600
  code: LOGOUT_ALL_ERROR_CODE,
594
601
  onError,
595
- setAuthError: (msg) => setAuthState({ error: msg }),
602
+ setAuthError: (msg: string) => setAuthState({ error: msg }),
596
603
  logger,
597
604
  });
598
605
  throw error instanceof Error ? error : new Error('Logout all failed');
@@ -2,7 +2,7 @@ import { useCallback } from 'react';
2
2
  import type { ApiError } from '../../../models/interfaces';
3
3
  import { DeviceManager } from '../../../utils/deviceManager';
4
4
  import type { OxyServices } from '../../../core';
5
- import { handleAuthError } from '../utils/errorHandlers';
5
+ import { handleAuthError } from '../../utils/errorHandlers';
6
6
 
7
7
  export interface UseDeviceManagementOptions {
8
8
  oxyServices: OxyServices;
@@ -7,8 +7,8 @@ import {
7
7
  normalizeLanguageCode,
8
8
  type LanguageMetadata,
9
9
  } from '../../../utils/languageUtils';
10
- import type { StorageInterface } from '../utils/storageHelpers';
11
- import { extractErrorMessage } from '../utils/errorHandlers';
10
+ import type { StorageInterface } from '../../utils/storageHelpers';
11
+ import { extractErrorMessage } from '../../utils/errorHandlers';
12
12
 
13
13
  export interface UseLanguageManagementOptions {
14
14
  storage: StorageInterface | null;
@@ -2,9 +2,9 @@ import { useCallback, useMemo, useRef, useState } from 'react';
2
2
  import type { ApiError, User } from '../../../models/interfaces';
3
3
  import type { ClientSession } from '../../../models/session';
4
4
  import { mergeSessions, normalizeAndSortSessions, sessionsArraysEqual } from '../../../utils/sessionUtils';
5
- import { fetchSessionsWithFallback, mapSessionsToClient, validateSessionBatch } from '../utils/sessionHelpers';
6
- import { getStorageKeys, type StorageInterface } from '../utils/storageHelpers';
7
- import { handleAuthError, isInvalidSessionError } from '../utils/errorHandlers';
5
+ import { fetchSessionsWithFallback, mapSessionsToClient, validateSessionBatch } from '../../utils/sessionHelpers';
6
+ import { getStorageKeys, type StorageInterface } from '../../utils/storageHelpers';
7
+ import { handleAuthError, isInvalidSessionError } from '../../utils/errorHandlers';
8
8
  import type { OxyServices } from '../../../core';
9
9
  import type { QueryClient } from '@tanstack/react-query';
10
10
  import { clearQueryCache } from '../../hooks/queryClient';
@@ -1,7 +1,7 @@
1
1
  import { useCallback, useEffect, useRef, useState } from 'react';
2
2
  import type { ApiError } from '../../../models/interfaces';
3
- import { createPlatformStorage, type StorageInterface } from '../utils/storageHelpers';
4
- import { extractErrorMessage } from '../utils/errorHandlers';
3
+ import { createPlatformStorage, type StorageInterface } from '../../utils/storageHelpers';
4
+ import { extractErrorMessage } from '../../utils/errorHandlers';
5
5
 
6
6
  export interface UseStorageOptions {
7
7
  onError?: (error: ApiError) => void;
@@ -132,7 +132,7 @@ export const usePrivacySettings = (userId?: string, options?: { enabled?: boolea
132
132
  const targetUserId = userId || user?.id;
133
133
 
134
134
  return useQuery({
135
- queryKey: queryKeys.privacy.settings(userId),
135
+ queryKey: queryKeys.privacy.settings(targetUserId),
136
136
  queryFn: async () => {
137
137
  if (!targetUserId) {
138
138
  throw new Error('User ID is required');
@@ -2,7 +2,7 @@ import { useQuery } from '@tanstack/react-query';
2
2
  import type { ClientSession } from '../../../models/session';
3
3
  import { queryKeys } from './queryKeys';
4
4
  import { useOxy } from '../../context/OxyContext';
5
- import { fetchSessionsWithFallback, mapSessionsToClient } from '../../context/utils/sessionHelpers';
5
+ import { fetchSessionsWithFallback, mapSessionsToClient } from '../../utils/sessionHelpers';
6
6
 
7
7
  /**
8
8
  * Get all active sessions for the current user
@@ -1,6 +1,7 @@
1
1
  import { useEffect, useRef } from 'react';
2
2
  import io from 'socket.io-client';
3
3
  import { toast } from '../../lib/sonner';
4
+ import { logger } from '../../utils/loggerUtils';
4
5
 
5
6
  interface UseSessionSocketProps {
6
7
  userId: string | null | undefined;
@@ -113,7 +114,7 @@ export function useSessionSocket({ userId, activeSessionId, currentDeviceId, ref
113
114
  await clearSessionStateRef.current();
114
115
  } catch (error) {
115
116
  if (__DEV__) {
116
- console.error('Failed to clear session state after session_removed:', error);
117
+ logger.error('Failed to clear session state after session_removed', error instanceof Error ? error : new Error(String(error)), { component: 'useSessionSocket' });
117
118
  }
118
119
  }
119
120
  } else {
@@ -121,7 +122,7 @@ export function useSessionSocket({ userId, activeSessionId, currentDeviceId, ref
121
122
  refreshSessionsRef.current().catch((error) => {
122
123
  // Silently handle errors from refresh - they're expected if sessions were removed
123
124
  if (__DEV__) {
124
- console.debug('Failed to refresh sessions after session_removed:', error);
125
+ logger.debug('Failed to refresh sessions after session_removed', { component: 'useSessionSocket' }, error as unknown);
125
126
  }
126
127
  });
127
128
  }
@@ -146,7 +147,7 @@ export function useSessionSocket({ userId, activeSessionId, currentDeviceId, ref
146
147
  await clearSessionStateRef.current();
147
148
  } catch (error) {
148
149
  if (__DEV__) {
149
- console.error('Failed to clear session state after device_removed:', error);
150
+ logger.error('Failed to clear session state after device_removed', error instanceof Error ? error : new Error(String(error)), { component: 'useSessionSocket' });
150
151
  }
151
152
  }
152
153
  } else {
@@ -154,7 +155,7 @@ export function useSessionSocket({ userId, activeSessionId, currentDeviceId, ref
154
155
  refreshSessionsRef.current().catch((error) => {
155
156
  // Silently handle errors from refresh - they're expected if sessions were removed
156
157
  if (__DEV__) {
157
- console.debug('Failed to refresh sessions after device_removed:', error);
158
+ logger.debug('Failed to refresh sessions after device_removed', { component: 'useSessionSocket' }, error as unknown);
158
159
  }
159
160
  });
160
161
  }
@@ -179,7 +180,7 @@ export function useSessionSocket({ userId, activeSessionId, currentDeviceId, ref
179
180
  await clearSessionStateRef.current();
180
181
  } catch (error) {
181
182
  if (__DEV__) {
182
- console.error('Failed to clear session state after sessions_removed:', error);
183
+ logger.error('Failed to clear session state after sessions_removed', error instanceof Error ? error : new Error(String(error)), { component: 'useSessionSocket' });
183
184
  }
184
185
  }
185
186
  } else {
@@ -187,7 +188,7 @@ export function useSessionSocket({ userId, activeSessionId, currentDeviceId, ref
187
188
  refreshSessionsRef.current().catch((error) => {
188
189
  // Silently handle errors from refresh - they're expected if sessions were removed
189
190
  if (__DEV__) {
190
- console.debug('Failed to refresh sessions after sessions_removed:', error);
191
+ logger.debug('Failed to refresh sessions after sessions_removed', { component: 'useSessionSocket' }, error as unknown);
191
192
  }
192
193
  });
193
194
  }
@@ -196,7 +197,7 @@ export function useSessionSocket({ userId, activeSessionId, currentDeviceId, ref
196
197
  refreshSessionsRef.current().catch((error) => {
197
198
  // Log but don't throw - refresh errors shouldn't break the socket handler
198
199
  if (__DEV__) {
199
- console.debug('Failed to refresh sessions after session_update:', error);
200
+ logger.debug('Failed to refresh sessions after session_update', { component: 'useSessionSocket' }, error as unknown);
200
201
  }
201
202
  });
202
203
 
@@ -102,9 +102,9 @@ const AccountCenterScreen: React.FC<BaseScreenProps> = ({
102
102
  <QuickActions
103
103
  theme={normalizedTheme}
104
104
  actions={useMemo(() => [
105
- { id: 'overview', icon: 'person-circle', iconColor: colors.iconSecurity, title: t('accountCenter.quickActions.overview') || 'Overview', onPress: () => navigate?.('AccountOverview') },
106
- { id: 'settings', icon: 'settings', iconColor: colors.iconData, title: t('accountCenter.quickActions.editProfile') || 'Edit Profile', onPress: () => navigate?.('EditProfile') },
107
- { id: 'sessions', icon: 'shield-checkmark', iconColor: colors.iconSecurity, title: t('accountCenter.quickActions.sessions') || 'Sessions', onPress: () => navigate?.('SessionManagement') },
105
+ { id: 'overview', icon: 'account-circle', iconColor: colors.iconSecurity, title: t('accountCenter.quickActions.overview') || 'Overview', onPress: () => navigate?.('AccountOverview') },
106
+ { id: 'settings', icon: 'cog', iconColor: colors.iconData, title: t('accountCenter.quickActions.editProfile') || 'Edit Profile', onPress: () => navigate?.('EditProfile') },
107
+ { id: 'sessions', icon: 'shield-check', iconColor: colors.iconSecurity, title: t('accountCenter.quickActions.sessions') || 'Sessions', onPress: () => navigate?.('SessionManagement') },
108
108
  { id: 'premium', icon: 'star', iconColor: colors.iconPayments, title: t('accountCenter.quickActions.premium') || 'Premium', onPress: () => navigate?.('PremiumSubscription') },
109
109
  ...(user?.isPremium ? [{ id: 'billing', icon: 'card', iconColor: colors.iconPersonalInfo, title: t('accountCenter.quickActions.billing') || 'Billing', onPress: () => navigate?.('PaymentGateway') }] : []),
110
110
  ...(sessions && sessions.length > 1 ? [{ id: 'switch', icon: 'swap-horizontal', iconColor: colors.iconStorage, title: t('accountCenter.quickActions.switch') || 'Switch', onPress: () => navigate?.('AccountSwitcher') }] : []),
@@ -119,7 +119,7 @@ const AccountCenterScreen: React.FC<BaseScreenProps> = ({
119
119
  items={useMemo(() => [
120
120
  {
121
121
  id: 'overview',
122
- icon: 'person-circle',
122
+ icon: 'account-circle',
123
123
  iconColor: colors.iconSecurity,
124
124
  title: t('accountCenter.items.accountOverview.title') || 'Account Overview',
125
125
  subtitle: t('accountCenter.items.accountOverview.subtitle') || 'Complete account information',
@@ -127,7 +127,7 @@ const AccountCenterScreen: React.FC<BaseScreenProps> = ({
127
127
  },
128
128
  {
129
129
  id: 'settings',
130
- icon: 'settings',
130
+ icon: 'cog',
131
131
  iconColor: colors.iconData,
132
132
  title: t('accountCenter.items.editProfile.title') || 'Edit Profile',
133
133
  subtitle: t('accountCenter.items.editProfile.subtitle') || 'Manage your profile and preferences',
@@ -135,7 +135,7 @@ const AccountCenterScreen: React.FC<BaseScreenProps> = ({
135
135
  },
136
136
  {
137
137
  id: 'sessions',
138
- icon: 'shield-checkmark',
138
+ icon: 'shield-check',
139
139
  iconColor: colors.iconSecurity,
140
140
  title: t('accountCenter.items.manageSessions.title') || 'Manage Sessions',
141
141
  subtitle: t('accountCenter.items.manageSessions.subtitle') || 'Security and active devices',
@@ -177,7 +177,7 @@ const AccountCenterScreen: React.FC<BaseScreenProps> = ({
177
177
  items={useMemo(() => [
178
178
  {
179
179
  id: 'switch',
180
- icon: 'people',
180
+ icon: 'account-group',
181
181
  iconColor: colors.iconStorage,
182
182
  title: t('accountCenter.items.switchAccount.title') || 'Switch Account',
183
183
  subtitle: t('accountCenter.items.switchAccount.subtitle', { count: sessions.length }) || `${sessions.length} accounts available`,
@@ -185,7 +185,7 @@ const AccountCenterScreen: React.FC<BaseScreenProps> = ({
185
185
  },
186
186
  {
187
187
  id: 'add',
188
- icon: 'person-add',
188
+ icon: 'account-plus',
189
189
  iconColor: colors.iconPersonalInfo,
190
190
  title: t('accountCenter.items.addAccount.title') || 'Add Another Account',
191
191
  subtitle: t('accountCenter.items.addAccount.subtitle') || 'Sign in with a different account',
@@ -204,7 +204,7 @@ const AccountCenterScreen: React.FC<BaseScreenProps> = ({
204
204
  items={useMemo(() => [
205
205
  {
206
206
  id: 'add',
207
- icon: 'person-add',
207
+ icon: 'account-plus',
208
208
  iconColor: colors.iconPersonalInfo,
209
209
  title: t('accountCenter.items.addAccount.title') || 'Add Another Account',
210
210
  subtitle: t('accountCenter.items.addAccount.subtitle') || 'Sign in with a different account',
@@ -222,7 +222,7 @@ const AccountCenterScreen: React.FC<BaseScreenProps> = ({
222
222
  items={useMemo(() => [
223
223
  ...(Platform.OS !== 'web' ? [{
224
224
  id: 'notifications',
225
- icon: 'notifications',
225
+ icon: 'bell',
226
226
  iconColor: colors.iconStorage,
227
227
  title: t('accountCenter.items.notifications.title') || 'Notifications',
228
228
  subtitle: t('accountCenter.items.notifications.subtitle') || 'Manage notification settings',
@@ -230,7 +230,7 @@ const AccountCenterScreen: React.FC<BaseScreenProps> = ({
230
230
  }] : []),
231
231
  {
232
232
  id: 'language',
233
- icon: 'language',
233
+ icon: 'translate',
234
234
  iconColor: colors.iconPersonalInfo,
235
235
  title: t('language.title') || 'Language',
236
236
  subtitle: t('language.subtitle') || 'Choose your preferred language',
@@ -246,7 +246,7 @@ const AccountCenterScreen: React.FC<BaseScreenProps> = ({
246
246
  },
247
247
  {
248
248
  id: 'appinfo',
249
- icon: 'information-circle',
249
+ icon: 'information',
250
250
  iconColor: '#8E8E93',
251
251
  title: t('accountCenter.items.appInfo.title') || 'App Information',
252
252
  subtitle: t('accountCenter.items.appInfo.subtitle') || 'Version and system details',
@@ -260,7 +260,7 @@ const AccountCenterScreen: React.FC<BaseScreenProps> = ({
260
260
  {/* Sign Out Section */}
261
261
  <Section >
262
262
  <GroupedItem
263
- icon="log-out"
263
+ icon="logout"
264
264
  iconColor={dangerColor}
265
265
  title={isLoading ? (t('accountCenter.signingOut') || 'Signing out...') : (t('common.actions.signOut') || 'Sign Out')}
266
266