@oxyhq/services 5.16.33 → 5.16.35

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 (240) hide show
  1. package/README.md +26 -8
  2. package/lib/commonjs/core/OxyServices.base.js.map +1 -1
  3. package/lib/commonjs/core/mixins/OxyServices.user.js.map +1 -1
  4. package/lib/commonjs/core/mixins/OxyServices.utility.js.map +1 -1
  5. package/lib/commonjs/core/services/AuthService.js +156 -0
  6. package/lib/commonjs/core/services/AuthService.js.map +1 -0
  7. package/lib/commonjs/core/services/SessionService.js +1 -2
  8. package/lib/commonjs/core/services/SessionService.js.map +1 -1
  9. package/lib/commonjs/core/services/SessionTransportService.js +64 -0
  10. package/lib/commonjs/core/services/SessionTransportService.js.map +1 -0
  11. package/lib/commonjs/core/services/TokenService.js +9 -17
  12. package/lib/commonjs/core/services/TokenService.js.map +1 -1
  13. package/lib/commonjs/core/services/UserService.js +123 -0
  14. package/lib/commonjs/core/services/UserService.js.map +1 -0
  15. package/lib/commonjs/core/services/index.js +34 -0
  16. package/lib/commonjs/core/services/index.js.map +1 -0
  17. package/lib/commonjs/crypto/index.js.map +1 -1
  18. package/lib/commonjs/crypto/keyManager.js +3 -2
  19. package/lib/commonjs/crypto/keyManager.js.map +1 -1
  20. package/lib/commonjs/crypto/signatureService.js +28 -122
  21. package/lib/commonjs/crypto/signatureService.js.map +1 -1
  22. package/lib/commonjs/index.js +12 -0
  23. package/lib/commonjs/index.js.map +1 -1
  24. package/lib/commonjs/models/interfaces.js +11 -11
  25. package/lib/commonjs/models/interfaces.js.map +1 -1
  26. package/lib/commonjs/shared/crypto/messageBuilders.js +79 -0
  27. package/lib/commonjs/shared/crypto/messageBuilders.js.map +1 -0
  28. package/lib/commonjs/shared/crypto/platform.js +118 -0
  29. package/lib/commonjs/shared/crypto/platform.js.map +1 -0
  30. package/lib/commonjs/shared/crypto/signature.js +191 -0
  31. package/lib/commonjs/shared/crypto/signature.js.map +1 -0
  32. package/lib/commonjs/shared/index.js +94 -0
  33. package/lib/commonjs/shared/index.js.map +1 -0
  34. package/lib/commonjs/shared/models/index.js +2 -0
  35. package/lib/commonjs/shared/models/index.js.map +1 -0
  36. package/lib/commonjs/shared/transport/index.js +260 -0
  37. package/lib/commonjs/shared/transport/index.js.map +1 -0
  38. package/lib/commonjs/shared/utils/index.js +82 -0
  39. package/lib/commonjs/shared/utils/index.js.map +1 -0
  40. package/lib/commonjs/ui/context/OxyContext.js +4 -40
  41. package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
  42. package/lib/commonjs/ui/context/hooks/useAuthOperations.js +23 -61
  43. package/lib/commonjs/ui/context/hooks/useAuthOperations.js.map +1 -1
  44. package/lib/commonjs/ui/context/hooks/useLanguageManagement.js.map +1 -1
  45. package/lib/commonjs/ui/hooks/queries/useServicesQueries.js +4 -12
  46. package/lib/commonjs/ui/hooks/queries/useServicesQueries.js.map +1 -1
  47. package/lib/commonjs/ui/hooks/useLanguageManagement.js.map +1 -1
  48. package/lib/commonjs/ui/hooks/useSessionManagement.js +0 -8
  49. package/lib/commonjs/ui/hooks/useSessionManagement.js.map +1 -1
  50. package/lib/commonjs/ui/index.js +2 -0
  51. package/lib/commonjs/ui/index.js.map +1 -1
  52. package/lib/commonjs/ui/screens/AccountSettingsScreen.js.map +1 -1
  53. package/lib/commonjs/ui/screens/OxyAuthScreen.js +2 -11
  54. package/lib/commonjs/ui/screens/OxyAuthScreen.js.map +1 -1
  55. package/lib/commonjs/ui/utils/sessionHelpers.js +11 -26
  56. package/lib/commonjs/ui/utils/sessionHelpers.js.map +1 -1
  57. package/lib/commonjs/utils/sessionUtils.js +1 -8
  58. package/lib/commonjs/utils/sessionUtils.js.map +1 -1
  59. package/lib/module/core/OxyServices.base.js.map +1 -1
  60. package/lib/module/core/mixins/OxyServices.user.js.map +1 -1
  61. package/lib/module/core/mixins/OxyServices.utility.js.map +1 -1
  62. package/lib/module/core/services/AuthService.js +151 -0
  63. package/lib/module/core/services/AuthService.js.map +1 -0
  64. package/lib/module/core/services/SessionService.js +1 -2
  65. package/lib/module/core/services/SessionService.js.map +1 -1
  66. package/lib/module/core/services/SessionTransportService.js +59 -0
  67. package/lib/module/core/services/SessionTransportService.js.map +1 -0
  68. package/lib/module/core/services/TokenService.js +9 -17
  69. package/lib/module/core/services/TokenService.js.map +1 -1
  70. package/lib/module/core/services/UserService.js +118 -0
  71. package/lib/module/core/services/UserService.js.map +1 -0
  72. package/lib/module/core/services/index.js +16 -0
  73. package/lib/module/core/services/index.js.map +1 -0
  74. package/lib/module/crypto/index.js +9 -0
  75. package/lib/module/crypto/index.js.map +1 -1
  76. package/lib/module/crypto/keyManager.js +3 -2
  77. package/lib/module/crypto/keyManager.js.map +1 -1
  78. package/lib/module/crypto/signatureService.js +26 -122
  79. package/lib/module/crypto/signatureService.js.map +1 -1
  80. package/lib/module/index.js +2 -0
  81. package/lib/module/index.js.map +1 -1
  82. package/lib/module/models/interfaces.js +11 -11
  83. package/lib/module/models/interfaces.js.map +1 -1
  84. package/lib/module/shared/crypto/messageBuilders.js +70 -0
  85. package/lib/module/shared/crypto/messageBuilders.js.map +1 -0
  86. package/lib/module/shared/crypto/platform.js +112 -0
  87. package/lib/module/shared/crypto/platform.js.map +1 -0
  88. package/lib/module/shared/crypto/signature.js +186 -0
  89. package/lib/module/shared/crypto/signature.js.map +1 -0
  90. package/lib/module/shared/index.js +30 -0
  91. package/lib/module/shared/index.js.map +1 -0
  92. package/lib/module/shared/models/index.js +2 -0
  93. package/lib/module/shared/models/index.js.map +1 -0
  94. package/lib/module/shared/transport/index.js +254 -0
  95. package/lib/module/shared/transport/index.js.map +1 -0
  96. package/lib/module/shared/utils/index.js +74 -0
  97. package/lib/module/shared/utils/index.js.map +1 -0
  98. package/lib/module/ui/context/OxyContext.js +4 -40
  99. package/lib/module/ui/context/OxyContext.js.map +1 -1
  100. package/lib/module/ui/context/hooks/useAuthOperations.js +23 -61
  101. package/lib/module/ui/context/hooks/useAuthOperations.js.map +1 -1
  102. package/lib/module/ui/context/hooks/useLanguageManagement.js.map +1 -1
  103. package/lib/module/ui/hooks/queries/useServicesQueries.js +5 -13
  104. package/lib/module/ui/hooks/queries/useServicesQueries.js.map +1 -1
  105. package/lib/module/ui/hooks/useLanguageManagement.js.map +1 -1
  106. package/lib/module/ui/hooks/useSessionManagement.js +0 -8
  107. package/lib/module/ui/hooks/useSessionManagement.js.map +1 -1
  108. package/lib/module/ui/index.js +1 -0
  109. package/lib/module/ui/index.js.map +1 -1
  110. package/lib/module/ui/screens/AccountSettingsScreen.js.map +1 -1
  111. package/lib/module/ui/screens/OxyAuthScreen.js +2 -11
  112. package/lib/module/ui/screens/OxyAuthScreen.js.map +1 -1
  113. package/lib/module/ui/utils/sessionHelpers.js +11 -26
  114. package/lib/module/ui/utils/sessionHelpers.js.map +1 -1
  115. package/lib/module/utils/sessionUtils.js +1 -8
  116. package/lib/module/utils/sessionUtils.js.map +1 -1
  117. package/lib/typescript/core/OxyServices.base.d.ts.map +1 -1
  118. package/lib/typescript/core/mixins/OxyServices.analytics.d.ts.map +1 -1
  119. package/lib/typescript/core/mixins/OxyServices.assets.d.ts.map +1 -1
  120. package/lib/typescript/core/mixins/OxyServices.auth.d.ts +1 -1
  121. package/lib/typescript/core/mixins/OxyServices.auth.d.ts.map +1 -1
  122. package/lib/typescript/core/mixins/OxyServices.developer.d.ts.map +1 -1
  123. package/lib/typescript/core/mixins/OxyServices.devices.d.ts.map +1 -1
  124. package/lib/typescript/core/mixins/OxyServices.karma.d.ts.map +1 -1
  125. package/lib/typescript/core/mixins/OxyServices.language.d.ts.map +1 -1
  126. package/lib/typescript/core/mixins/OxyServices.location.d.ts.map +1 -1
  127. package/lib/typescript/core/mixins/OxyServices.payment.d.ts.map +1 -1
  128. package/lib/typescript/core/mixins/OxyServices.privacy.d.ts.map +1 -1
  129. package/lib/typescript/core/mixins/OxyServices.security.d.ts.map +1 -1
  130. package/lib/typescript/core/mixins/OxyServices.user.d.ts +2 -1
  131. package/lib/typescript/core/mixins/OxyServices.user.d.ts.map +1 -1
  132. package/lib/typescript/core/mixins/OxyServices.utility.d.ts.map +1 -1
  133. package/lib/typescript/core/mixins/index.d.ts +13 -13
  134. package/lib/typescript/core/mixins/index.d.ts.map +1 -1
  135. package/lib/typescript/core/services/AuthService.d.ts +50 -0
  136. package/lib/typescript/core/services/AuthService.d.ts.map +1 -0
  137. package/lib/typescript/core/services/SessionService.d.ts +3 -5
  138. package/lib/typescript/core/services/SessionService.d.ts.map +1 -1
  139. package/lib/typescript/core/services/SessionTransportService.d.ts +31 -0
  140. package/lib/typescript/core/services/SessionTransportService.d.ts.map +1 -0
  141. package/lib/typescript/core/services/TokenService.d.ts +3 -8
  142. package/lib/typescript/core/services/TokenService.d.ts.map +1 -1
  143. package/lib/typescript/core/services/UserService.d.ts +39 -0
  144. package/lib/typescript/core/services/UserService.d.ts.map +1 -0
  145. package/lib/typescript/core/services/index.d.ts +13 -0
  146. package/lib/typescript/core/services/index.d.ts.map +1 -0
  147. package/lib/typescript/crypto/index.d.ts +9 -0
  148. package/lib/typescript/crypto/index.d.ts.map +1 -1
  149. package/lib/typescript/crypto/keyManager.d.ts.map +1 -1
  150. package/lib/typescript/crypto/signatureService.d.ts +10 -13
  151. package/lib/typescript/crypto/signatureService.d.ts.map +1 -1
  152. package/lib/typescript/index.d.ts +2 -1
  153. package/lib/typescript/index.d.ts.map +1 -1
  154. package/lib/typescript/models/interfaces.d.ts +15 -69
  155. package/lib/typescript/models/interfaces.d.ts.map +1 -1
  156. package/lib/typescript/models/session.d.ts +2 -4
  157. package/lib/typescript/models/session.d.ts.map +1 -1
  158. package/lib/typescript/shared/crypto/messageBuilders.d.ts +38 -0
  159. package/lib/typescript/shared/crypto/messageBuilders.d.ts.map +1 -0
  160. package/lib/typescript/shared/crypto/platform.d.ts +54 -0
  161. package/lib/typescript/shared/crypto/platform.d.ts.map +1 -0
  162. package/lib/typescript/shared/crypto/signature.d.ts +72 -0
  163. package/lib/typescript/shared/crypto/signature.d.ts.map +1 -0
  164. package/lib/typescript/shared/index.d.ts +20 -0
  165. package/lib/typescript/shared/index.d.ts.map +1 -0
  166. package/lib/typescript/shared/models/index.d.ts +163 -0
  167. package/lib/typescript/shared/models/index.d.ts.map +1 -0
  168. package/lib/typescript/shared/transport/index.d.ts +73 -0
  169. package/lib/typescript/shared/transport/index.d.ts.map +1 -0
  170. package/lib/typescript/shared/utils/index.d.ts +28 -0
  171. package/lib/typescript/shared/utils/index.d.ts.map +1 -0
  172. package/lib/typescript/ui/context/OxyContext.d.ts +2 -1
  173. package/lib/typescript/ui/context/OxyContext.d.ts.map +1 -1
  174. package/lib/typescript/ui/context/hooks/useAuthOperations.d.ts +2 -1
  175. package/lib/typescript/ui/context/hooks/useAuthOperations.d.ts.map +1 -1
  176. package/lib/typescript/ui/context/hooks/useLanguageManagement.d.ts +2 -1
  177. package/lib/typescript/ui/context/hooks/useLanguageManagement.d.ts.map +1 -1
  178. package/lib/typescript/ui/hooks/mutations/useAccountMutations.d.ts +1 -1
  179. package/lib/typescript/ui/hooks/mutations/useAccountMutations.d.ts.map +1 -1
  180. package/lib/typescript/ui/hooks/queries/useAccountQueries.d.ts +1 -1
  181. package/lib/typescript/ui/hooks/queries/useAccountQueries.d.ts.map +1 -1
  182. package/lib/typescript/ui/hooks/queries/useServicesQueries.d.ts.map +1 -1
  183. package/lib/typescript/ui/hooks/useLanguageManagement.d.ts +2 -1
  184. package/lib/typescript/ui/hooks/useLanguageManagement.d.ts.map +1 -1
  185. package/lib/typescript/ui/hooks/useSessionManagement.d.ts +2 -1
  186. package/lib/typescript/ui/hooks/useSessionManagement.d.ts.map +1 -1
  187. package/lib/typescript/ui/index.d.ts +1 -1
  188. package/lib/typescript/ui/index.d.ts.map +1 -1
  189. package/lib/typescript/ui/screens/OxyAuthScreen.d.ts.map +1 -1
  190. package/lib/typescript/ui/stores/authStore.d.ts +1 -1
  191. package/lib/typescript/ui/stores/authStore.d.ts.map +1 -1
  192. package/lib/typescript/ui/utils/avatarUtils.d.ts +1 -1
  193. package/lib/typescript/ui/utils/avatarUtils.d.ts.map +1 -1
  194. package/lib/typescript/ui/utils/sessionHelpers.d.ts +2 -6
  195. package/lib/typescript/ui/utils/sessionHelpers.d.ts.map +1 -1
  196. package/lib/typescript/utils/sessionUtils.d.ts.map +1 -1
  197. package/package.json +1 -1
  198. package/src/core/OxyServices.base.ts +2 -1
  199. package/src/core/mixins/OxyServices.auth.ts +1 -1
  200. package/src/core/mixins/OxyServices.user.ts +2 -1
  201. package/src/core/mixins/OxyServices.utility.ts +2 -1
  202. package/src/core/services/AuthService.ts +153 -0
  203. package/src/core/services/SessionService.ts +3 -5
  204. package/src/core/services/SessionTransportService.ts +69 -0
  205. package/src/core/services/TokenService.ts +10 -18
  206. package/src/core/services/UserService.ts +125 -0
  207. package/src/core/services/index.ts +14 -0
  208. package/src/crypto/index.ts +9 -0
  209. package/src/crypto/keyManager.ts +3 -2
  210. package/src/crypto/signatureService.ts +43 -142
  211. package/src/index.ts +3 -2
  212. package/src/models/interfaces.ts +21 -74
  213. package/src/models/session.ts +3 -5
  214. package/src/shared/crypto/messageBuilders.ts +89 -0
  215. package/src/shared/crypto/platform.ts +140 -0
  216. package/src/shared/crypto/signature.ts +235 -0
  217. package/src/shared/index.ts +28 -0
  218. package/src/shared/models/index.ts +173 -0
  219. package/src/shared/transport/index.ts +349 -0
  220. package/src/shared/utils/index.ts +73 -0
  221. package/src/ui/context/OxyContext.tsx +22 -57
  222. package/src/ui/context/hooks/useAuthOperations.ts +33 -65
  223. package/src/ui/context/hooks/useLanguageManagement.ts +2 -1
  224. package/src/ui/hooks/auth/index.ts +0 -2
  225. package/src/ui/hooks/mutations/useAccountMutations.ts +1 -1
  226. package/src/ui/hooks/mutations/useServicesMutations.ts +1 -1
  227. package/src/ui/hooks/queries/useAccountQueries.ts +1 -1
  228. package/src/ui/hooks/queries/useServicesQueries.ts +3 -8
  229. package/src/ui/hooks/useLanguageManagement.ts +2 -1
  230. package/src/ui/hooks/useSessionManagement.ts +3 -9
  231. package/src/ui/index.ts +2 -1
  232. package/src/ui/screens/AccountSettingsScreen.tsx +6 -6
  233. package/src/ui/screens/AccountSwitcherScreen.tsx +1 -1
  234. package/src/ui/screens/OxyAuthScreen.tsx +2 -11
  235. package/src/ui/screens/ProfileScreen.tsx +1 -1
  236. package/src/ui/stores/authStore.ts +1 -1
  237. package/src/ui/types/navigation.ts +1 -1
  238. package/src/ui/utils/avatarUtils.ts +1 -1
  239. package/src/ui/utils/sessionHelpers.ts +15 -32
  240. package/src/utils/sessionUtils.ts +1 -8
@@ -1,5 +1,6 @@
1
1
  import { useCallback } from 'react';
2
- import type { ApiError, User } from '../../../models/interfaces';
2
+ import type { ApiError } from '../../../models/interfaces';
3
+ import type { User } from '../../../shared';
3
4
  import type { AuthState } from '../../stores/authStore';
4
5
  import type { ClientSession, SessionLoginResponse } from '../../../models/session';
5
6
  import { DeviceManager } from '../../../utils/deviceManager';
@@ -102,51 +103,26 @@ export const useAuthOperations = ({
102
103
  const challengeResponse = await oxyServices.requestChallenge(publicKey);
103
104
  challenge = challengeResponse.challenge;
104
105
  } catch (error) {
105
- // Check if user is not registered - auto-register and retry
106
- const errorCode = (error as any)?.code;
107
- const errorStatus = (error as any)?.status;
106
+ // Network error - generate challenge locally for offline sign-in
108
107
  const errorMessage = error instanceof Error ? error.message : String(error);
109
-
110
- if (errorCode === 'USER_NOT_REGISTERED' || (errorStatus === 404 && errorMessage.includes('not registered'))) {
108
+ const isNetworkError =
109
+ errorMessage.includes('Network') ||
110
+ errorMessage.includes('network') ||
111
+ errorMessage.includes('Failed to fetch') ||
112
+ errorMessage.includes('fetch failed') ||
113
+ (error as any)?.code === 'NETWORK_ERROR' ||
114
+ (error as any)?.status === 0;
115
+
116
+ if (isNetworkError) {
111
117
  if (__DEV__ && logger) {
112
- logger('User not registered, auto-registering before sign-in');
113
- }
114
- try {
115
- // Auto-register the user
116
- const { signature, timestamp } = await SignatureService.createRegistrationSignature();
117
- await oxyServices.register(publicKey, signature, timestamp);
118
-
119
- // Retry requesting challenge after registration
120
- const challengeResponse = await oxyServices.requestChallenge(publicKey);
121
- challenge = challengeResponse.challenge;
122
- } catch (registerError) {
123
- // If registration fails, re-throw the original error
124
- if (__DEV__ && logger) {
125
- logger('Auto-registration failed:', registerError);
126
- }
127
- throw error; // Re-throw original "not registered" error
118
+ logger('Network unavailable, performing offline sign-in');
128
119
  }
120
+ // Generate challenge locally
121
+ challenge = await SignatureService.generateChallenge();
122
+ isOffline = true;
129
123
  } else {
130
- // Network error - generate challenge locally for offline sign-in
131
- const isNetworkError =
132
- errorMessage.includes('Network') ||
133
- errorMessage.includes('network') ||
134
- errorMessage.includes('Failed to fetch') ||
135
- errorMessage.includes('fetch failed') ||
136
- (error as any)?.code === 'NETWORK_ERROR' ||
137
- errorStatus === 0;
138
-
139
- if (isNetworkError) {
140
- if (__DEV__ && logger) {
141
- logger('Network unavailable, performing offline sign-in');
142
- }
143
- // Generate challenge locally
144
- challenge = await SignatureService.generateChallenge();
145
- isOffline = true;
146
- } else {
147
- // Re-throw non-network errors
148
- throw error;
149
- }
124
+ // Re-throw non-network errors
125
+ throw error;
150
126
  }
151
127
  }
152
128
 
@@ -171,9 +147,9 @@ export const useAuthOperations = ({
171
147
  const localDeviceId = `device_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
172
148
  const expiresAt = new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString(); // 7 days
173
149
 
174
- // Create minimal user object with publicKey as id (canonical identity)
150
+ // Create minimal user object with publicKey as id
175
151
  fullUser = {
176
- id: publicKey, // publicKey is the canonical user identity
152
+ id: publicKey, // Use publicKey as id (per migration document)
177
153
  publicKey,
178
154
  username: '',
179
155
  privacySettings: {},
@@ -195,7 +171,7 @@ export const useAuthOperations = ({
195
171
  deviceId: localDeviceId,
196
172
  expiresAt,
197
173
  lastActive: new Date().toISOString(),
198
- publicKey, // Canonical user identity
174
+ userId: publicKey,
199
175
  isCurrent: true,
200
176
  };
201
177
 
@@ -229,10 +205,17 @@ export const useAuthOperations = ({
229
205
  // Get full user data
230
206
  fullUser = await oxyServices.getUserBySession(sessionResponse.sessionId);
231
207
 
232
- // user.id is now publicKey (canonical identity) - this is correct
233
- // Ensure publicKey field is set for consistency
234
- if (!fullUser.publicKey && fullUser.id) {
235
- fullUser.publicKey = fullUser.id;
208
+ // IMPORTANT: user.id should be MongoDB ObjectId, not publicKey
209
+ // The API should return the correct id (ObjectId) from the database
210
+ // If it doesn't, we need to fix the API, not work around it here
211
+ // Validate that id is ObjectId format (24 hex characters)
212
+ if (fullUser.id && !/^[0-9a-fA-F]{24}$/.test(fullUser.id)) {
213
+ console.warn('[useAuthOperations] User.id is not MongoDB ObjectId format:', {
214
+ id: fullUser.id.substring(0, 20),
215
+ publicKey: fullUser.publicKey.substring(0, 20),
216
+ message: 'API should return MongoDB ObjectId as user.id, not publicKey'
217
+ });
218
+ // Don't override - let the API fix this issue
236
219
  }
237
220
 
238
221
  // Fetch device sessions
@@ -240,8 +223,7 @@ export const useAuthOperations = ({
240
223
  try {
241
224
  allDeviceSessions = await fetchSessionsWithFallback(oxyServices, sessionResponse.sessionId, {
242
225
  fallbackDeviceId: sessionResponse.deviceId,
243
- fallbackUserId: fullUser.id, // Still pass for backward compatibility
244
- fallbackPublicKey: fullUser.publicKey || fullUser.id, // publicKey is canonical identity
226
+ fallbackUserId: fullUser.id,
245
227
  logger,
246
228
  });
247
229
  } catch (error) {
@@ -311,13 +293,6 @@ export const useAuthOperations = ({
311
293
  setAuthState({ isLoading: true, error: null });
312
294
 
313
295
  try {
314
- // SESSION CLEANUP: Clear all sessions before creating new identity
315
- // New identity means old sessions are no longer valid
316
- await clearSessionState();
317
- if (__DEV__ && logger) {
318
- logger('Cleared all sessions before creating new identity');
319
- }
320
-
321
296
  // Generate new key pair directly (works offline)
322
297
  const { publicKey, privateKey } = await KeyManager.generateKeyPair();
323
298
  await KeyManager.importKeyPair(privateKey);
@@ -489,13 +464,6 @@ export const useAuthOperations = ({
489
464
  setAuthState({ isLoading: true, error: null });
490
465
 
491
466
  try {
492
- // SESSION CLEANUP: Clear all sessions before importing new identity
493
- // Importing a different identity means old sessions are no longer valid
494
- await clearSessionState();
495
- if (__DEV__ && logger) {
496
- logger('Cleared all sessions before importing identity');
497
- }
498
-
499
467
  // Decrypt private key from backup data
500
468
  const Crypto = await import('expo-crypto');
501
469
 
@@ -1,5 +1,6 @@
1
1
  import { useCallback, useEffect, useMemo, useState } from 'react';
2
- import type { ApiError, User } from '../../../models/interfaces';
2
+ import type { ApiError } from '../../../models/interfaces';
3
+ import type { User } from '../../../shared';
3
4
  import {
4
5
  getLanguageMetadata,
5
6
  getLanguageName,
@@ -4,5 +4,3 @@
4
4
  export { useUsernameValidation, USERNAME_MIN_LENGTH, USERNAME_REGEX, USERNAME_FORMAT_ERROR, USERNAME_DEBOUNCE_MS } from './useUsernameValidation';
5
5
  export type { UsernameValidationResult } from './useUsernameValidation';
6
6
 
7
-
8
-
@@ -1,5 +1,5 @@
1
1
  import { useMutation, useQueryClient } from '@tanstack/react-query';
2
- import type { User } from '../../../models/interfaces';
2
+ import type { User } from '../../../shared';
3
3
  import { queryKeys, invalidateAccountQueries, invalidateUserQueries } from '../queries/queryKeys';
4
4
  import { useOxy } from '../../context/OxyContext';
5
5
  import { toast } from '../../../lib/sonner';
@@ -1,5 +1,5 @@
1
1
  import { useMutation, useQueryClient } from '@tanstack/react-query';
2
- import type { User } from '../../../models/interfaces';
2
+ import type { User } from '../../../shared';
3
3
  import { queryKeys, invalidateSessionQueries } from '../queries/queryKeys';
4
4
  import { useOxy } from '../../context/OxyContext';
5
5
  import { toast } from '../../../lib/sonner';
@@ -1,5 +1,5 @@
1
1
  import { useQuery, useQueries } from '@tanstack/react-query';
2
- import type { User } from '../../../models/interfaces';
2
+ import type { User } from '../../../shared';
3
3
  import type { OxyServices } from '../../../core';
4
4
  import { queryKeys } from './queryKeys';
5
5
  import { useOxy } from '../../context/OxyContext';
@@ -8,7 +8,7 @@ import { fetchSessionsWithFallback, mapSessionsToClient } from '../../utils/sess
8
8
  * Get all active sessions for the current user
9
9
  */
10
10
  export const useSessions = (userId?: string, options?: { enabled?: boolean }) => {
11
- const { oxyServices, activeSessionId, user } = useOxy();
11
+ const { oxyServices, activeSessionId } = useOxy();
12
12
 
13
13
  return useQuery({
14
14
  queryKey: queryKeys.sessions.list(userId),
@@ -17,14 +17,12 @@ export const useSessions = (userId?: string, options?: { enabled?: boolean }) =>
17
17
  throw new Error('No active session');
18
18
  }
19
19
 
20
- const publicKey = user?.publicKey || user?.id || ''; // user.id is now publicKey
21
20
  const sessions = await fetchSessionsWithFallback(oxyServices, activeSessionId, {
22
21
  fallbackDeviceId: undefined,
23
22
  fallbackUserId: userId,
24
- fallbackPublicKey: publicKey,
25
23
  });
26
24
 
27
- return sessions; // Already mapped by fetchSessionsWithFallback
25
+ return mapSessionsToClient(sessions, activeSessionId);
28
26
  },
29
27
  enabled: (options?.enabled !== false) && !!activeSessionId,
30
28
  staleTime: 2 * 60 * 1000, // 2 minutes (sessions change frequently)
@@ -51,15 +49,12 @@ export const useSession = (sessionId: string | null, options?: { enabled?: boole
51
49
  }
52
50
 
53
51
  const now = new Date();
54
- // user.id is now publicKey (canonical identity)
55
- const publicKey = validation.user.publicKey || validation.user.id || '';
56
52
  return {
57
53
  sessionId,
58
54
  deviceId: '', // Device ID not available from validation response
59
55
  expiresAt: validation.expiresAt || new Date(now.getTime() + 7 * 24 * 60 * 60 * 1000).toISOString(),
60
56
  lastActive: validation.lastActivity || now.toISOString(),
61
- publicKey, // Canonical user identity
62
- userId: validation.user.id?.toString(), // Optional MongoDB ObjectId
57
+ userId: validation.user.id?.toString() ?? '',
63
58
  isCurrent: false,
64
59
  } as ClientSession;
65
60
  },
@@ -1,5 +1,6 @@
1
1
  import { useCallback, useEffect, useMemo, useState } from 'react';
2
- import type { ApiError, User } from '../../models/interfaces';
2
+ import type { ApiError } from '../../models/interfaces';
3
+ import type { User } from '../../shared';
3
4
  import {
4
5
  getLanguageMetadata,
5
6
  getLanguageName,
@@ -1,5 +1,6 @@
1
1
  import { useCallback, useMemo, useRef, useState } from 'react';
2
- import type { ApiError, User } from '../../models/interfaces';
2
+ import type { ApiError } from '../../models/interfaces';
3
+ import type { User } from '../../shared';
3
4
  import type { ClientSession } from '../../models/session';
4
5
  import { mergeSessions, normalizeAndSortSessions, sessionsArraysEqual } from '../../utils/sessionUtils';
5
6
  import { fetchSessionsWithFallback, mapSessionsToClient, validateSessionBatch } from '../utils/sessionHelpers';
@@ -255,10 +256,8 @@ export const useSessionManagement = ({
255
256
  await activateSession(sessionId, user);
256
257
 
257
258
  try {
258
- const publicKey = user.publicKey || user.id || ''; // user.id is now publicKey
259
259
  const deviceSessions = await fetchSessionsWithFallback(oxyServices, sessionId, {
260
- fallbackUserId: user.id, // Still pass for backward compatibility
261
- fallbackPublicKey: publicKey,
260
+ fallbackUserId: user.id,
262
261
  logger,
263
262
  });
264
263
  updateSessions(deviceSessions, { merge: true });
@@ -332,13 +331,8 @@ export const useSessionManagement = ({
332
331
 
333
332
  const refreshPromise = (async () => {
334
333
  try {
335
- // Get publicKey from active session or current user
336
- const activeSession = sessions.find(s => s.sessionId === activeSessionId);
337
- const publicKey = activeSession?.publicKey || activeUserId || ''; // Fallback to userId if publicKey not available
338
-
339
334
  const deviceSessions = await fetchSessionsWithFallback(oxyServices, activeSessionId, {
340
335
  fallbackUserId: activeUserId,
341
- fallbackPublicKey: publicKey,
342
336
  logger,
343
337
  });
344
338
  updateSessions(deviceSessions, { merge: true });
package/src/ui/index.ts CHANGED
@@ -81,4 +81,5 @@ export {
81
81
 
82
82
  // Re-export core services for convenience in UI context
83
83
  export { OxyServices } from '../core';
84
- export type { User, LoginResponse, ApiError } from '../models/interfaces';
84
+ // Note: User and LoginResponse are available from the shared module (exported from main index)
85
+ export type { ApiError } from '../models/interfaces';
@@ -233,7 +233,7 @@ const AccountSettingsScreen: React.FC<BaseScreenProps & { initialField?: string;
233
233
 
234
234
  // Handle locations - convert single location to array format
235
235
  if (finalUser.locations && Array.isArray(finalUser.locations)) {
236
- setLocations(finalUser.locations.map((loc, index) => ({
236
+ setLocations(finalUser.locations.map((loc: any, index: number) => ({
237
237
  id: loc.id || `existing-${index}`,
238
238
  name: loc.name,
239
239
  label: loc.label,
@@ -252,17 +252,17 @@ const AccountSettingsScreen: React.FC<BaseScreenProps & { initialField?: string;
252
252
 
253
253
  // Handle links - simple and direct like other fields
254
254
  if (finalUser.linksMetadata && Array.isArray(finalUser.linksMetadata)) {
255
- const urls = finalUser.linksMetadata.map(l => l.url);
255
+ const urls = finalUser.linksMetadata.map((l: any) => l.url);
256
256
  setLinks(urls);
257
- const metadataWithIds = finalUser.linksMetadata.map((link, index) => ({
257
+ const metadataWithIds = finalUser.linksMetadata.map((link: any, index: number) => ({
258
258
  ...link,
259
259
  id: link.id || `existing-${index}`
260
260
  }));
261
261
  setLinksMetadata(metadataWithIds);
262
262
  } else if (Array.isArray(finalUser.links)) {
263
- const simpleLinks = finalUser.links.map(l => typeof l === 'string' ? l : l.link).filter(Boolean);
263
+ const simpleLinks = finalUser.links.map((l: any) => typeof l === 'string' ? l : l.link).filter(Boolean);
264
264
  setLinks(simpleLinks);
265
- const linksWithMetadata = simpleLinks.map((url, index) => ({
265
+ const linksWithMetadata = simpleLinks.map((url: string, index: number) => ({
266
266
  url,
267
267
  title: url.replace(/^https?:\/\//, '').replace(/\/$/, ''),
268
268
  description: `Link to ${url}`,
@@ -553,7 +553,7 @@ const AccountSettingsScreen: React.FC<BaseScreenProps & { initialField?: string;
553
553
  }
554
554
 
555
555
  if (currentUser.linksMetadata && Array.isArray(currentUser.linksMetadata)) {
556
- setLinksMetadata(currentUser.linksMetadata.map((link, index) => ({
556
+ setLinksMetadata(currentUser.linksMetadata.map((link: any, index: number) => ({
557
557
  ...link,
558
558
  id: link.id || `existing-${index}`
559
559
  })));
@@ -15,7 +15,7 @@ import {
15
15
  import type { BaseScreenProps } from '../types/navigation';
16
16
  import type { ClientSession } from '../../models/session';
17
17
  import { fontFamilies } from '../styles/fonts';
18
- import type { User } from '../../models/interfaces';
18
+ import type { User } from '../../shared';
19
19
  import { toast } from '../../lib/sonner';
20
20
  import { confirmAction } from '../utils/confirmAction';
21
21
  import OxyIcon from '../components/icon/OxyIcon';
@@ -28,6 +28,7 @@ import { useThemeColors } from '../styles';
28
28
  import { useOxy } from '../context/OxyContext';
29
29
  import QRCode from 'react-native-qrcode-svg';
30
30
  import OxyLogo from '../components/OxyLogo';
31
+ import { generateSessionToken } from '../../shared';
31
32
 
32
33
  // Deep link scheme for Oxy Accounts app
33
34
  const OXY_ACCOUNTS_SCHEME = 'oxyaccounts://';
@@ -220,7 +221,7 @@ const OxyAuthScreen: React.FC<BaseScreenProps> = ({
220
221
 
221
222
  try {
222
223
  // Generate a unique session token for this auth request
223
- const sessionToken = generateSessionToken();
224
+ const sessionToken = await generateSessionToken(32);
224
225
  const expiresAt = Date.now() + AUTH_SESSION_EXPIRY_MS;
225
226
 
226
227
  // Register the auth session with the server
@@ -242,16 +243,6 @@ const OxyAuthScreen: React.FC<BaseScreenProps> = ({
242
243
  }
243
244
  }, [oxyServices, connectSocket]);
244
245
 
245
- // Generate a random session token
246
- const generateSessionToken = (): string => {
247
- const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
248
- let result = '';
249
- for (let i = 0; i < 32; i++) {
250
- result += chars.charAt(Math.floor(Math.random() * chars.length));
251
- }
252
- return result;
253
- };
254
-
255
246
  // Clean up on unmount
256
247
  useEffect(() => {
257
248
  return () => {
@@ -10,7 +10,7 @@ import { Ionicons } from '@expo/vector-icons';
10
10
  import { useI18n } from '../hooks/useI18n';
11
11
  import { useOxy } from '../context/OxyContext';
12
12
  import { logger } from '../../utils/loggerUtils';
13
- import type { User } from '../../models/interfaces';
13
+ import type { User } from '../../shared';
14
14
  import { extractErrorMessage } from '../utils/errorHandlers';
15
15
 
16
16
  interface ProfileScreenProps extends BaseScreenProps {
@@ -1,5 +1,5 @@
1
1
  import { create } from 'zustand';
2
- import type { User } from '../../models/interfaces';
2
+ import type { User } from '../../shared';
3
3
 
4
4
  export interface AuthState {
5
5
  user: User | null;
@@ -1,7 +1,7 @@
1
1
  import type { ReactNode, RefObject } from 'react';
2
2
  import type { QueryClient } from '@tanstack/react-query';
3
3
  import type { RouteName } from '../navigation/routes';
4
- import type { User } from '../../models/interfaces';
4
+ import type { User } from '../../shared';
5
5
  import type { ClientSession } from '../../models/session';
6
6
 
7
7
  // Re-export RouteName from routes for convenience
@@ -1,5 +1,5 @@
1
1
  import type { OxyServices } from '../../core';
2
- import type { User } from '../../models/interfaces';
2
+ import type { User } from '../../shared';
3
3
  import { useAccountStore } from '../stores/accountStore';
4
4
  import { useAuthStore } from '../stores/authStore';
5
5
  import { QueryClient } from '@tanstack/react-query';
@@ -7,16 +7,14 @@ interface DeviceSession {
7
7
  deviceName?: string;
8
8
  expiresAt?: string;
9
9
  lastActive?: string;
10
- user?: { id?: string; publicKey?: string; _id?: { toString(): string } };
10
+ user?: { id?: string; _id?: { toString(): string } };
11
11
  userId?: string;
12
- publicKey?: string;
13
12
  isCurrent?: boolean;
14
13
  }
15
14
 
16
15
  export interface FetchSessionsWithFallbackOptions {
17
16
  fallbackDeviceId?: string;
18
17
  fallbackUserId?: string;
19
- fallbackPublicKey?: string; // Canonical user identity
20
18
  logger?: (message: string, error?: unknown) => void;
21
19
  }
22
20
 
@@ -39,41 +37,27 @@ export interface SessionValidationResult {
39
37
  * @param sessions - Raw session array returned from the API
40
38
  * @param fallbackDeviceId - Device identifier to use when missing from payload
41
39
  * @param fallbackUserId - User identifier to use when missing from payload
42
- * @param fallbackPublicKey - Public key to use when missing from payload (canonical identity)
43
40
  */
44
41
  export const mapSessionsToClient = (
45
42
  sessions: DeviceSession[],
46
43
  fallbackDeviceId?: string,
47
44
  fallbackUserId?: string,
48
- fallbackPublicKey?: string,
49
45
  ): ClientSession[] => {
50
46
  const now = new Date();
51
47
 
52
- return sessions.map((session) => {
53
- // publicKey is the canonical user identity (user.id now equals publicKey)
54
- // Extract from user.id (which is now publicKey), user.publicKey, or session.publicKey
55
- const publicKey =
56
- session.user?.id || // user.id is now publicKey (canonical identifier)
57
- session.user?.publicKey ||
58
- session.publicKey ||
59
- fallbackPublicKey ||
60
- '';
61
-
62
- // userId is MongoDB ObjectId (internal backend reference, optional)
63
- const userId =
48
+ return sessions.map((session) => ({
49
+ sessionId: session.sessionId,
50
+ deviceId: session.deviceId || fallbackDeviceId || '',
51
+ expiresAt: session.expiresAt || new Date(now.getTime() + 7 * 24 * 60 * 60 * 1000).toISOString(),
52
+ lastActive: session.lastActive || now.toISOString(),
53
+ userId:
54
+ session.user?.id ||
64
55
  session.userId ||
65
- (session.user?._id ? session.user._id.toString() : undefined);
66
-
67
- return {
68
- sessionId: session.sessionId,
69
- deviceId: session.deviceId || fallbackDeviceId || '',
70
- expiresAt: session.expiresAt || new Date(now.getTime() + 7 * 24 * 60 * 60 * 1000).toISOString(),
71
- lastActive: session.lastActive || now.toISOString(),
72
- publicKey, // Canonical user identity - REQUIRED
73
- userId, // MongoDB ObjectId (optional, for backward compatibility)
74
- isCurrent: Boolean(session.isCurrent),
75
- };
76
- });
56
+ (session.user?._id ? session.user._id.toString() : undefined) ||
57
+ fallbackUserId ||
58
+ '',
59
+ isCurrent: Boolean(session.isCurrent),
60
+ }));
77
61
  };
78
62
 
79
63
  /**
@@ -89,20 +73,19 @@ export const fetchSessionsWithFallback = async (
89
73
  {
90
74
  fallbackDeviceId,
91
75
  fallbackUserId,
92
- fallbackPublicKey,
93
76
  logger,
94
77
  }: FetchSessionsWithFallbackOptions = {},
95
78
  ): Promise<ClientSession[]> => {
96
79
  try {
97
80
  const deviceSessions = await oxyServices.getDeviceSessions(sessionId);
98
- return mapSessionsToClient(deviceSessions, fallbackDeviceId, fallbackUserId, fallbackPublicKey);
81
+ return mapSessionsToClient(deviceSessions, fallbackDeviceId, fallbackUserId);
99
82
  } catch (error) {
100
83
  if (__DEV__ && logger) {
101
84
  logger('Failed to get device sessions, falling back to user sessions', error);
102
85
  }
103
86
 
104
87
  const userSessions = await oxyServices.getSessionsBySessionId(sessionId);
105
- return mapSessionsToClient(userSessions, fallbackDeviceId, fallbackUserId, fallbackPublicKey);
88
+ return mapSessionsToClient(userSessions, fallbackDeviceId, fallbackUserId);
106
89
  }
107
90
  };
108
91
 
@@ -12,19 +12,12 @@ import type { ClientSession } from '../models/session';
12
12
  */
13
13
  export function normalizeSession(session: Partial<ClientSession> & { sessionId: string }): ClientSession {
14
14
  const now = new Date().toISOString();
15
-
16
- // publicKey is required (canonical user identity)
17
- if (!session.publicKey) {
18
- throw new Error(`Session ${session.sessionId} is missing required publicKey field`);
19
- }
20
-
21
15
  return {
22
16
  sessionId: session.sessionId,
23
17
  deviceId: session.deviceId || '',
24
18
  expiresAt: session.expiresAt || now,
25
19
  lastActive: session.lastActive || now,
26
- publicKey: session.publicKey, // Canonical user identity - required
27
- userId: session.userId, // Optional MongoDB ObjectId for backward compatibility
20
+ userId: session.userId || '',
28
21
  };
29
22
  }
30
23