@oxyhq/services 5.16.39 → 5.16.41

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 (267) hide show
  1. package/lib/commonjs/adapters/expo/crypto.js +56 -0
  2. package/lib/commonjs/adapters/expo/crypto.js.map +1 -0
  3. package/lib/commonjs/adapters/expo/fetch.js +30 -0
  4. package/lib/commonjs/adapters/expo/fetch.js.map +1 -0
  5. package/lib/commonjs/adapters/expo/index.js +48 -0
  6. package/lib/commonjs/adapters/expo/index.js.map +1 -0
  7. package/lib/commonjs/adapters/expo/storage.js +201 -0
  8. package/lib/commonjs/adapters/expo/storage.js.map +1 -0
  9. package/lib/commonjs/adapters/index.js +41 -0
  10. package/lib/commonjs/adapters/index.js.map +1 -0
  11. package/lib/commonjs/adapters/node/crypto.js +40 -0
  12. package/lib/commonjs/adapters/node/crypto.js.map +1 -0
  13. package/lib/commonjs/adapters/node/fetch.js +62 -0
  14. package/lib/commonjs/adapters/node/fetch.js.map +1 -0
  15. package/lib/commonjs/adapters/node/index.js +34 -0
  16. package/lib/commonjs/adapters/node/index.js.map +1 -0
  17. package/lib/commonjs/adapters/node/storage.js +163 -0
  18. package/lib/commonjs/adapters/node/storage.js.map +1 -0
  19. package/lib/commonjs/core/identity-session/DeviceManager.js +237 -0
  20. package/lib/commonjs/core/identity-session/DeviceManager.js.map +1 -0
  21. package/lib/commonjs/core/identity-session/INTEGRATION_GUIDE.md +287 -0
  22. package/lib/commonjs/core/identity-session/IdentityManager.js +400 -0
  23. package/lib/commonjs/core/identity-session/IdentityManager.js.map +1 -0
  24. package/lib/commonjs/core/identity-session/IdentitySessionCore.js +394 -0
  25. package/lib/commonjs/core/identity-session/IdentitySessionCore.js.map +1 -0
  26. package/lib/commonjs/core/identity-session/RefreshManager.js +137 -0
  27. package/lib/commonjs/core/identity-session/RefreshManager.js.map +1 -0
  28. package/lib/commonjs/core/identity-session/SessionManager.js +427 -0
  29. package/lib/commonjs/core/identity-session/SessionManager.js.map +1 -0
  30. package/lib/commonjs/core/identity-session/createIdentitySessionCore.js +24 -0
  31. package/lib/commonjs/core/identity-session/createIdentitySessionCore.js.map +1 -0
  32. package/lib/commonjs/core/identity-session/errors.js +176 -0
  33. package/lib/commonjs/core/identity-session/errors.js.map +1 -0
  34. package/lib/commonjs/core/identity-session/index.js +80 -0
  35. package/lib/commonjs/core/identity-session/index.js.map +1 -0
  36. package/lib/commonjs/core/identity-session/types.js +2 -0
  37. package/lib/commonjs/core/identity-session/types.js.map +1 -0
  38. package/lib/commonjs/core/index.js +2 -21
  39. package/lib/commonjs/core/index.js.map +1 -1
  40. package/lib/commonjs/index.js +58 -8
  41. package/lib/commonjs/index.js.map +1 -1
  42. package/lib/commonjs/models/interfaces.js +7 -0
  43. package/lib/commonjs/models/interfaces.js.map +1 -1
  44. package/lib/commonjs/ui/context/OxyContext.js +434 -820
  45. package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
  46. package/lib/commonjs/ui/hooks/useAvatarPicker.js +52 -0
  47. package/lib/commonjs/ui/hooks/useAvatarPicker.js.map +1 -0
  48. package/lib/commonjs/ui/hooks/useIdentityTransfer.js +125 -0
  49. package/lib/commonjs/ui/hooks/useIdentityTransfer.js.map +1 -0
  50. package/lib/commonjs/ui/hooks/useTransferCodesPersistence.js +81 -0
  51. package/lib/commonjs/ui/hooks/useTransferCodesPersistence.js.map +1 -0
  52. package/lib/commonjs/ui/screens/AccountCenterScreen.js +7 -2
  53. package/lib/commonjs/ui/screens/AccountCenterScreen.js.map +1 -1
  54. package/lib/commonjs/ui/screens/AccountSettingsScreen.js +12 -5
  55. package/lib/commonjs/ui/screens/AccountSettingsScreen.js.map +1 -1
  56. package/lib/commonjs/ui/screens/AccountSwitcherScreen.js +2 -2
  57. package/lib/commonjs/ui/screens/AccountSwitcherScreen.js.map +1 -1
  58. package/lib/commonjs/ui/screens/ProfileScreen.js +6 -6
  59. package/lib/commonjs/ui/screens/ProfileScreen.js.map +1 -1
  60. package/lib/commonjs/ui/utils/sessionHelpers.js +7 -1
  61. package/lib/commonjs/ui/utils/sessionHelpers.js.map +1 -1
  62. package/lib/commonjs/utils/index.js +0 -7
  63. package/lib/commonjs/utils/index.js.map +1 -1
  64. package/lib/commonjs/utils/sessionUtils.js +8 -1
  65. package/lib/commonjs/utils/sessionUtils.js.map +1 -1
  66. package/lib/module/adapters/expo/crypto.js +51 -0
  67. package/lib/module/adapters/expo/crypto.js.map +1 -0
  68. package/lib/module/adapters/expo/fetch.js +26 -0
  69. package/lib/module/adapters/expo/fetch.js.map +1 -0
  70. package/lib/module/adapters/expo/index.js +45 -0
  71. package/lib/module/adapters/expo/index.js.map +1 -0
  72. package/lib/module/adapters/expo/storage.js +198 -0
  73. package/lib/module/adapters/expo/storage.js.map +1 -0
  74. package/lib/module/adapters/index.js +38 -0
  75. package/lib/module/adapters/index.js.map +1 -0
  76. package/lib/module/adapters/node/crypto.js +36 -0
  77. package/lib/module/adapters/node/crypto.js.map +1 -0
  78. package/lib/module/adapters/node/fetch.js +57 -0
  79. package/lib/module/adapters/node/fetch.js.map +1 -0
  80. package/lib/module/adapters/node/index.js +31 -0
  81. package/lib/module/adapters/node/index.js.map +1 -0
  82. package/lib/module/adapters/node/storage.js +159 -0
  83. package/lib/module/adapters/node/storage.js.map +1 -0
  84. package/lib/module/core/identity-session/DeviceManager.js +232 -0
  85. package/lib/module/core/identity-session/DeviceManager.js.map +1 -0
  86. package/lib/module/core/identity-session/INTEGRATION_GUIDE.md +287 -0
  87. package/lib/module/core/identity-session/IdentityManager.js +395 -0
  88. package/lib/module/core/identity-session/IdentityManager.js.map +1 -0
  89. package/lib/module/core/identity-session/IdentitySessionCore.js +390 -0
  90. package/lib/module/core/identity-session/IdentitySessionCore.js.map +1 -0
  91. package/lib/module/core/identity-session/RefreshManager.js +132 -0
  92. package/lib/module/core/identity-session/RefreshManager.js.map +1 -0
  93. package/lib/module/core/identity-session/SessionManager.js +422 -0
  94. package/lib/module/core/identity-session/SessionManager.js.map +1 -0
  95. package/lib/module/core/identity-session/createIdentitySessionCore.js +21 -0
  96. package/lib/module/core/identity-session/createIdentitySessionCore.js.map +1 -0
  97. package/lib/module/core/identity-session/errors.js +170 -0
  98. package/lib/module/core/identity-session/errors.js.map +1 -0
  99. package/lib/module/core/identity-session/index.js +17 -0
  100. package/lib/module/core/identity-session/index.js.map +1 -0
  101. package/lib/module/core/identity-session/types.js +2 -0
  102. package/lib/module/core/identity-session/types.js.map +1 -0
  103. package/lib/module/core/index.js +2 -3
  104. package/lib/module/core/index.js.map +1 -1
  105. package/lib/module/index.js +12 -2
  106. package/lib/module/index.js.map +1 -1
  107. package/lib/module/models/interfaces.js +7 -0
  108. package/lib/module/models/interfaces.js.map +1 -1
  109. package/lib/module/ui/context/OxyContext.js +436 -822
  110. package/lib/module/ui/context/OxyContext.js.map +1 -1
  111. package/lib/module/ui/hooks/useAvatarPicker.js +48 -0
  112. package/lib/module/ui/hooks/useAvatarPicker.js.map +1 -0
  113. package/lib/module/ui/hooks/useIdentityTransfer.js +121 -0
  114. package/lib/module/ui/hooks/useIdentityTransfer.js.map +1 -0
  115. package/lib/module/ui/hooks/useTransferCodesPersistence.js +77 -0
  116. package/lib/module/ui/hooks/useTransferCodesPersistence.js.map +1 -0
  117. package/lib/module/ui/screens/AccountCenterScreen.js +7 -2
  118. package/lib/module/ui/screens/AccountCenterScreen.js.map +1 -1
  119. package/lib/module/ui/screens/AccountSettingsScreen.js +12 -5
  120. package/lib/module/ui/screens/AccountSettingsScreen.js.map +1 -1
  121. package/lib/module/ui/screens/AccountSwitcherScreen.js +2 -2
  122. package/lib/module/ui/screens/AccountSwitcherScreen.js.map +1 -1
  123. package/lib/module/ui/screens/ProfileScreen.js +6 -6
  124. package/lib/module/ui/screens/ProfileScreen.js.map +1 -1
  125. package/lib/module/ui/utils/sessionHelpers.js +7 -1
  126. package/lib/module/ui/utils/sessionHelpers.js.map +1 -1
  127. package/lib/module/utils/index.js +2 -1
  128. package/lib/module/utils/index.js.map +1 -1
  129. package/lib/module/utils/sessionUtils.js +8 -1
  130. package/lib/module/utils/sessionUtils.js.map +1 -1
  131. package/lib/typescript/adapters/expo/crypto.d.ts +17 -0
  132. package/lib/typescript/adapters/expo/crypto.d.ts.map +1 -0
  133. package/lib/typescript/adapters/expo/fetch.d.ts +16 -0
  134. package/lib/typescript/adapters/expo/fetch.d.ts.map +1 -0
  135. package/lib/typescript/adapters/expo/index.d.ts +23 -0
  136. package/lib/typescript/adapters/expo/index.d.ts.map +1 -0
  137. package/lib/typescript/adapters/expo/storage.d.ts +23 -0
  138. package/lib/typescript/adapters/expo/storage.d.ts.map +1 -0
  139. package/lib/typescript/adapters/index.d.ts +13 -0
  140. package/lib/typescript/adapters/index.d.ts.map +1 -0
  141. package/lib/typescript/adapters/node/crypto.d.ts +17 -0
  142. package/lib/typescript/adapters/node/crypto.d.ts.map +1 -0
  143. package/lib/typescript/adapters/node/fetch.d.ts +16 -0
  144. package/lib/typescript/adapters/node/fetch.d.ts.map +1 -0
  145. package/lib/typescript/adapters/node/index.d.ts +23 -0
  146. package/lib/typescript/adapters/node/index.d.ts.map +1 -0
  147. package/lib/typescript/adapters/node/storage.d.ts +23 -0
  148. package/lib/typescript/adapters/node/storage.d.ts.map +1 -0
  149. package/lib/typescript/core/identity-session/DeviceManager.d.ts +64 -0
  150. package/lib/typescript/core/identity-session/DeviceManager.d.ts.map +1 -0
  151. package/lib/typescript/core/identity-session/IdentityManager.d.ts +88 -0
  152. package/lib/typescript/core/identity-session/IdentityManager.d.ts.map +1 -0
  153. package/lib/typescript/core/identity-session/IdentitySessionCore.d.ts +141 -0
  154. package/lib/typescript/core/identity-session/IdentitySessionCore.d.ts.map +1 -0
  155. package/lib/typescript/core/identity-session/RefreshManager.d.ts +36 -0
  156. package/lib/typescript/core/identity-session/RefreshManager.d.ts.map +1 -0
  157. package/lib/typescript/core/identity-session/SessionManager.d.ts +104 -0
  158. package/lib/typescript/core/identity-session/SessionManager.d.ts.map +1 -0
  159. package/lib/typescript/core/identity-session/createIdentitySessionCore.d.ts +11 -0
  160. package/lib/typescript/core/identity-session/createIdentitySessionCore.d.ts.map +1 -0
  161. package/lib/typescript/core/identity-session/errors.d.ts +63 -0
  162. package/lib/typescript/core/identity-session/errors.d.ts.map +1 -0
  163. package/lib/typescript/core/identity-session/index.d.ts +14 -0
  164. package/lib/typescript/core/identity-session/index.d.ts.map +1 -0
  165. package/lib/typescript/core/identity-session/types.d.ts +196 -0
  166. package/lib/typescript/core/identity-session/types.d.ts.map +1 -0
  167. package/lib/typescript/core/index.d.ts +1 -3
  168. package/lib/typescript/core/index.d.ts.map +1 -1
  169. package/lib/typescript/core/mixins/index.d.ts +2 -2
  170. package/lib/typescript/index.d.ts +3 -2
  171. package/lib/typescript/index.d.ts.map +1 -1
  172. package/lib/typescript/models/interfaces.d.ts +5 -36
  173. package/lib/typescript/models/interfaces.d.ts.map +1 -1
  174. package/lib/typescript/models/session.d.ts +3 -16
  175. package/lib/typescript/models/session.d.ts.map +1 -1
  176. package/lib/typescript/ui/context/OxyContext.d.ts +2 -25
  177. package/lib/typescript/ui/context/OxyContext.d.ts.map +1 -1
  178. package/lib/typescript/ui/hooks/mutations/useAccountMutations.d.ts +7 -8
  179. package/lib/typescript/ui/hooks/mutations/useAccountMutations.d.ts.map +1 -1
  180. package/lib/typescript/ui/hooks/mutations/useServicesMutations.d.ts +1 -1
  181. package/lib/typescript/ui/hooks/mutations/useServicesMutations.d.ts.map +1 -1
  182. package/lib/typescript/ui/hooks/queries/useAccountQueries.d.ts +5 -5
  183. package/lib/typescript/ui/hooks/queries/useAccountQueries.d.ts.map +1 -1
  184. package/lib/typescript/ui/hooks/useAvatarPicker.d.ts +18 -0
  185. package/lib/typescript/ui/hooks/useAvatarPicker.d.ts.map +1 -0
  186. package/lib/typescript/ui/hooks/useIdentityTransfer.d.ts +24 -0
  187. package/lib/typescript/ui/hooks/useIdentityTransfer.d.ts.map +1 -0
  188. package/lib/typescript/ui/hooks/useTransferCodesPersistence.d.ts +6 -0
  189. package/lib/typescript/ui/hooks/useTransferCodesPersistence.d.ts.map +1 -0
  190. package/lib/typescript/ui/screens/AccountCenterScreen.d.ts.map +1 -1
  191. package/lib/typescript/ui/screens/AccountSettingsScreen.d.ts.map +1 -1
  192. package/lib/typescript/ui/utils/sessionHelpers.d.ts +1 -0
  193. package/lib/typescript/ui/utils/sessionHelpers.d.ts.map +1 -1
  194. package/lib/typescript/utils/index.d.ts +0 -2
  195. package/lib/typescript/utils/index.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/adapters/expo/crypto.ts +55 -0
  199. package/src/adapters/expo/fetch.ts +28 -0
  200. package/src/adapters/expo/index.ts +51 -0
  201. package/src/adapters/expo/storage.ts +228 -0
  202. package/src/adapters/index.ts +40 -0
  203. package/src/adapters/node/crypto.ts +39 -0
  204. package/src/adapters/node/fetch.ts +59 -0
  205. package/src/adapters/node/index.ts +37 -0
  206. package/src/adapters/node/storage.ts +170 -0
  207. package/src/core/identity-session/DeviceManager.ts +273 -0
  208. package/src/core/identity-session/INTEGRATION_GUIDE.md +287 -0
  209. package/src/core/identity-session/IdentityManager.ts +474 -0
  210. package/src/core/identity-session/IdentitySessionCore.ts +464 -0
  211. package/src/core/identity-session/RefreshManager.ts +189 -0
  212. package/src/core/identity-session/SessionManager.ts +500 -0
  213. package/src/core/identity-session/createIdentitySessionCore.ts +19 -0
  214. package/src/core/identity-session/errors.ts +197 -0
  215. package/src/core/identity-session/index.ts +15 -0
  216. package/src/core/identity-session/types.ts +188 -0
  217. package/src/core/index.ts +3 -4
  218. package/src/index.ts +28 -3
  219. package/src/models/interfaces.ts +12 -39
  220. package/src/models/session.ts +6 -16
  221. package/src/ui/context/OxyContext.tsx +442 -871
  222. package/src/ui/hooks/auth/index.ts +1 -0
  223. package/src/ui/hooks/useAvatarPicker.ts +62 -0
  224. package/src/ui/hooks/useIdentityTransfer.ts +135 -0
  225. package/src/ui/hooks/useTransferCodesPersistence.ts +80 -0
  226. package/src/ui/screens/AccountCenterScreen.tsx +7 -2
  227. package/src/ui/screens/AccountSettingsScreen.tsx +15 -8
  228. package/src/ui/screens/AccountSwitcherScreen.tsx +2 -2
  229. package/src/ui/screens/ProfileScreen.tsx +10 -10
  230. package/src/ui/utils/sessionHelpers.ts +7 -0
  231. package/src/utils/index.ts +1 -2
  232. package/src/utils/sessionUtils.ts +8 -0
  233. package/lib/commonjs/ui/context/hooks/useAuthOperations.js +0 -704
  234. package/lib/commonjs/ui/context/hooks/useAuthOperations.js.map +0 -1
  235. package/lib/commonjs/ui/context/hooks/useDeviceManagement.js +0 -73
  236. package/lib/commonjs/ui/context/hooks/useDeviceManagement.js.map +0 -1
  237. package/lib/commonjs/ui/hooks/useDeviceManagement.js +0 -73
  238. package/lib/commonjs/ui/hooks/useDeviceManagement.js.map +0 -1
  239. package/lib/commonjs/ui/hooks/useSessionManagement.js +0 -281
  240. package/lib/commonjs/ui/hooks/useSessionManagement.js.map +0 -1
  241. package/lib/commonjs/utils/deviceManager.js +0 -177
  242. package/lib/commonjs/utils/deviceManager.js.map +0 -1
  243. package/lib/module/ui/context/hooks/useAuthOperations.js +0 -698
  244. package/lib/module/ui/context/hooks/useAuthOperations.js.map +0 -1
  245. package/lib/module/ui/context/hooks/useDeviceManagement.js +0 -68
  246. package/lib/module/ui/context/hooks/useDeviceManagement.js.map +0 -1
  247. package/lib/module/ui/hooks/useDeviceManagement.js +0 -68
  248. package/lib/module/ui/hooks/useDeviceManagement.js.map +0 -1
  249. package/lib/module/ui/hooks/useSessionManagement.js +0 -276
  250. package/lib/module/ui/hooks/useSessionManagement.js.map +0 -1
  251. package/lib/module/utils/deviceManager.js +0 -171
  252. package/lib/module/utils/deviceManager.js.map +0 -1
  253. package/lib/typescript/ui/context/hooks/useAuthOperations.d.ts +0 -59
  254. package/lib/typescript/ui/context/hooks/useAuthOperations.d.ts.map +0 -1
  255. package/lib/typescript/ui/context/hooks/useDeviceManagement.d.ts +0 -27
  256. package/lib/typescript/ui/context/hooks/useDeviceManagement.d.ts.map +0 -1
  257. package/lib/typescript/ui/hooks/useDeviceManagement.d.ts +0 -27
  258. package/lib/typescript/ui/hooks/useDeviceManagement.d.ts.map +0 -1
  259. package/lib/typescript/ui/hooks/useSessionManagement.d.ts +0 -41
  260. package/lib/typescript/ui/hooks/useSessionManagement.d.ts.map +0 -1
  261. package/lib/typescript/utils/deviceManager.d.ts +0 -66
  262. package/lib/typescript/utils/deviceManager.d.ts.map +0 -1
  263. package/src/ui/context/hooks/useAuthOperations.ts +0 -773
  264. package/src/ui/context/hooks/useDeviceManagement.ts +0 -108
  265. package/src/ui/hooks/useDeviceManagement.ts +0 -108
  266. package/src/ui/hooks/useSessionManagement.ts +0 -401
  267. package/src/utils/deviceManager.ts +0 -198
@@ -1,704 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.useAuthOperations = void 0;
7
- var _react = require("react");
8
- var _deviceManager = require("../../../utils/deviceManager");
9
- var _sessionHelpers = require("../../utils/sessionHelpers");
10
- var _errorHandlers = require("../../utils/errorHandlers");
11
- var _crypto = require("../../../crypto");
12
- function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
13
- const LOGIN_ERROR_CODE = 'LOGIN_ERROR';
14
- const REGISTER_ERROR_CODE = 'REGISTER_ERROR';
15
- const LOGOUT_ERROR_CODE = 'LOGOUT_ERROR';
16
- const LOGOUT_ALL_ERROR_CODE = 'LOGOUT_ALL_ERROR';
17
-
18
- /**
19
- * Authentication operations using public key cryptography.
20
- * No passwords required - identity is based on ECDSA key pairs.
21
- */
22
- const useAuthOperations = ({
23
- oxyServices,
24
- storage,
25
- sessions,
26
- activeSessionId,
27
- setActiveSessionId,
28
- updateSessions,
29
- saveActiveSessionId,
30
- clearSessionState,
31
- switchSession,
32
- applyLanguagePreference,
33
- onAuthStateChange,
34
- onError,
35
- loginSuccess,
36
- loginFailure,
37
- logoutStore,
38
- setAuthState,
39
- setIdentitySynced,
40
- setSyncing,
41
- logger
42
- }) => {
43
- /**
44
- * Clear session data if identity has changed
45
- * Internal helper to avoid code duplication
46
- */
47
- const clearSessionsIfIdentityChanged = (0, _react.useCallback)(async (oldPublicKey, newPublicKey) => {
48
- if (oldPublicKey && oldPublicKey !== newPublicKey) {
49
- if (__DEV__ && logger) {
50
- logger('CRITICAL: Identity changed - clearing all session data', {
51
- oldPublicKey: oldPublicKey.substring(0, 16) + '...',
52
- newPublicKey: newPublicKey.substring(0, 16) + '...'
53
- });
54
- }
55
-
56
- // Clear all session state to prevent old identity's data from showing up
57
- await clearSessionState();
58
-
59
- // Logout from auth store (clears user, isAuthenticated, etc.)
60
- logoutStore();
61
-
62
- // Force KeyManager cache invalidation
63
- _crypto.KeyManager.invalidateCache();
64
- if (__DEV__ && logger) {
65
- logger('Session state cleared for new identity');
66
- }
67
- }
68
- }, [clearSessionState, logoutStore, logger]);
69
-
70
- /**
71
- * Internal function to perform challenge-response sign in (works offline)
72
- */
73
- const performSignIn = (0, _react.useCallback)(async publicKey => {
74
- const deviceFingerprintObj = _deviceManager.DeviceManager.getDeviceFingerprint();
75
- const deviceFingerprint = JSON.stringify(deviceFingerprintObj);
76
- const deviceInfo = await _deviceManager.DeviceManager.getDeviceInfo();
77
- const deviceName = deviceInfo.deviceName || _deviceManager.DeviceManager.getDefaultDeviceName();
78
- let challenge;
79
- let isOffline = false;
80
-
81
- // Try to request challenge from server (online)
82
- try {
83
- const challengeResponse = await oxyServices.requestChallenge(publicKey);
84
- challenge = challengeResponse.challenge;
85
- } catch (error) {
86
- // Network error - generate challenge locally for offline sign-in
87
- const errorMessage = error instanceof Error ? error.message : String(error);
88
- const isNetworkError = errorMessage.includes('Network') || errorMessage.includes('network') || errorMessage.includes('Failed to fetch') || errorMessage.includes('fetch failed') || error?.code === 'NETWORK_ERROR' || error?.status === 0;
89
- if (isNetworkError) {
90
- if (__DEV__ && logger) {
91
- logger('Network unavailable, performing offline sign-in');
92
- }
93
- // Generate challenge locally
94
- challenge = await _crypto.SignatureService.generateChallenge();
95
- isOffline = true;
96
- } else {
97
- // Re-throw non-network errors
98
- throw error;
99
- }
100
- }
101
-
102
- // Note: Biometric authentication check should be handled by the app layer
103
- // (e.g., accounts app) before calling signIn. The biometric preference is stored
104
- // in local storage as 'oxy_biometric_enabled' and can be checked there.
105
-
106
- // Sign the challenge
107
- const {
108
- challenge: signature,
109
- timestamp
110
- } = await _crypto.SignatureService.signChallenge(challenge);
111
- let fullUser;
112
- let sessionResponse;
113
- if (isOffline) {
114
- // Offline sign-in: create local session and minimal user object
115
- if (__DEV__ && logger) {
116
- logger('Creating offline session');
117
- }
118
-
119
- // Generate a local session ID
120
- const localSessionId = `offline_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
121
- const localDeviceId = `device_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
122
- const expiresAt = new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString(); // 7 days
123
-
124
- // Create minimal user object with publicKey as id
125
- fullUser = {
126
- id: publicKey,
127
- // Use publicKey as id (per migration document)
128
- publicKey,
129
- username: '',
130
- privacySettings: {}
131
- };
132
- sessionResponse = {
133
- sessionId: localSessionId,
134
- deviceId: localDeviceId,
135
- expiresAt,
136
- user: {
137
- id: publicKey,
138
- username: ''
139
- }
140
- };
141
-
142
- // Store offline session locally
143
- const offlineSession = {
144
- sessionId: localSessionId,
145
- deviceId: localDeviceId,
146
- expiresAt,
147
- lastActive: new Date().toISOString(),
148
- userId: publicKey,
149
- isCurrent: true
150
- };
151
- setActiveSessionId(localSessionId);
152
- await saveActiveSessionId(localSessionId);
153
- updateSessions([offlineSession], {
154
- merge: true
155
- });
156
-
157
- // Mark session as offline for later sync
158
- if (storage) {
159
- await storage.setItem(`oxy_session_${localSessionId}_offline`, 'true');
160
- }
161
- if (__DEV__ && logger) {
162
- logger('Offline sign-in successful');
163
- }
164
- } else {
165
- // Online sign-in: use normal flow
166
- // Verify and create session
167
- sessionResponse = await oxyServices.verifyChallenge(publicKey, challenge, signature, timestamp, deviceName, deviceFingerprint);
168
-
169
- // Get token for the session
170
- await oxyServices.getTokenBySession(sessionResponse.sessionId);
171
-
172
- // Get full user data
173
- fullUser = await oxyServices.getUserBySession(sessionResponse.sessionId);
174
-
175
- // IMPORTANT: user.id should be MongoDB ObjectId, not publicKey
176
- // The API should return the correct id (ObjectId) from the database
177
- // If it doesn't, we need to fix the API, not work around it here
178
- // Validate that id is ObjectId format (24 hex characters)
179
- if (fullUser.id && !/^[0-9a-fA-F]{24}$/.test(fullUser.id)) {
180
- console.warn('[useAuthOperations] User.id is not MongoDB ObjectId format:', {
181
- id: fullUser.id.substring(0, 20),
182
- publicKey: fullUser.publicKey.substring(0, 20),
183
- message: 'API should return MongoDB ObjectId as user.id, not publicKey'
184
- });
185
- // Don't override - let the API fix this issue
186
- }
187
-
188
- // Fetch device sessions
189
- let allDeviceSessions = [];
190
- try {
191
- allDeviceSessions = await (0, _sessionHelpers.fetchSessionsWithFallback)(oxyServices, sessionResponse.sessionId, {
192
- fallbackDeviceId: sessionResponse.deviceId,
193
- fallbackUserId: fullUser.id,
194
- logger
195
- });
196
- } catch (error) {
197
- if (__DEV__) {
198
- console.warn('Failed to fetch device sessions after login:', error);
199
- }
200
- }
201
-
202
- // Check for existing session for same user
203
- const existingSession = allDeviceSessions.find(session => session.userId?.toString() === fullUser.id?.toString() && session.sessionId !== sessionResponse.sessionId);
204
- if (existingSession) {
205
- // Logout duplicate session
206
- try {
207
- await oxyServices.logoutSession(sessionResponse.sessionId, sessionResponse.sessionId);
208
- } catch (logoutError) {
209
- if (__DEV__) {
210
- console.warn('Failed to logout duplicate session:', logoutError);
211
- }
212
- }
213
- await switchSession(existingSession.sessionId);
214
- updateSessions(allDeviceSessions.filter(session => session.sessionId !== sessionResponse.sessionId), {
215
- merge: false
216
- });
217
- onAuthStateChange?.(fullUser);
218
- return fullUser;
219
- }
220
- setActiveSessionId(sessionResponse.sessionId);
221
- await saveActiveSessionId(sessionResponse.sessionId);
222
- updateSessions(allDeviceSessions, {
223
- merge: true
224
- });
225
- }
226
- await applyLanguagePreference(fullUser);
227
- loginSuccess(fullUser);
228
- onAuthStateChange?.(fullUser);
229
- return fullUser;
230
- }, [applyLanguagePreference, logger, loginSuccess, onAuthStateChange, oxyServices, saveActiveSessionId, setActiveSessionId, switchSession, updateSessions, storage]);
231
-
232
- /**
233
- * Create a new identity (offline-first)
234
- * Identity is purely cryptographic - no username or email required
235
- *
236
- * This function generates keys locally and does NOT register with the server yet.
237
- * Registration will happen during syncIdentity() or when username is provided.
238
- *
239
- * @param username - Optional username to set during registration (if online)
240
- */
241
- const createIdentity = (0, _react.useCallback)(async username => {
242
- if (!storage) throw new Error('Storage not initialized');
243
- setAuthState({
244
- isLoading: true,
245
- error: null
246
- });
247
- try {
248
- // CRITICAL: Get old public key before creating new identity
249
- // If identity changes, we must clear all session data to prevent data leakage
250
- const oldPublicKey = await _crypto.KeyManager.getPublicKey().catch(() => null);
251
- if (__DEV__ && logger) {
252
- logger('Creating new identity', {
253
- hadPreviousIdentity: !!oldPublicKey
254
- });
255
- }
256
-
257
- // Generate new key pair directly (works offline)
258
- const {
259
- publicKey,
260
- privateKey
261
- } = await _crypto.KeyManager.generateKeyPair();
262
- await _crypto.KeyManager.importKeyPair(privateKey);
263
- if (__DEV__ && logger) {
264
- logger('Identity keys generated', {
265
- publicKey: publicKey.substring(0, 16) + '...'
266
- });
267
- }
268
-
269
- // Clear sessions if identity changed (prevents data leakage)
270
- await clearSessionsIfIdentityChanged(oldPublicKey, publicKey);
271
-
272
- // Mark as not synced initially
273
- await storage.setItem('oxy_identity_synced', 'false');
274
- setIdentitySynced(false);
275
-
276
- // If username provided, try to register immediately (online only)
277
- if (username) {
278
- // Validate username format before attempting registration
279
- const trimmedUsername = username.trim();
280
- if (trimmedUsername && /^[a-zA-Z0-9]{3,30}$/.test(trimmedUsername)) {
281
- try {
282
- const {
283
- signature,
284
- timestamp
285
- } = await _crypto.SignatureService.createRegistrationSignature();
286
- await oxyServices.register(publicKey, signature, timestamp, trimmedUsername);
287
-
288
- // Mark as synced (Zustand store + storage)
289
- await storage.setItem('oxy_identity_synced', 'true');
290
- setIdentitySynced(true);
291
- if (__DEV__ && logger) {
292
- logger('Identity synced with server successfully with username');
293
- }
294
- return {
295
- synced: true
296
- };
297
- } catch (syncError) {
298
- // Offline or server error - identity created locally but not synced
299
- if (__DEV__ && logger) {
300
- logger('Identity created locally with username (offline), will sync when online', syncError);
301
- }
302
- return {
303
- synced: false
304
- };
305
- }
306
- }
307
- }
308
-
309
- // No username provided - defer registration until later
310
- if (__DEV__ && logger) {
311
- logger('Identity created locally without username, will register during sync');
312
- }
313
- return {
314
- synced: false
315
- };
316
- } catch (error) {
317
- // CRITICAL: Never delete identity on error - it may have been successfully created
318
- // Only log the error and let the user recover using their backup file
319
- // Identity deletion should ONLY happen when explicitly requested by the user
320
- if (__DEV__ && logger) {
321
- logger('Error during identity creation (identity may still exist):', error);
322
- }
323
-
324
- // Check if identity was actually created (keys exist)
325
- const hasIdentity = await _crypto.KeyManager.hasIdentity().catch(() => false);
326
- if (hasIdentity) {
327
- // Identity exists - don't delete it! Just mark as not synced
328
- await storage.setItem('oxy_identity_synced', 'false').catch(() => {});
329
- setIdentitySynced(false);
330
- if (__DEV__ && logger) {
331
- logger('Identity was created but sync failed - user can sync later');
332
- }
333
- } else {
334
- // No identity exists - this was a generation failure, safe to clean up sync flag
335
- await storage.removeItem('oxy_identity_synced').catch(() => {});
336
- setIdentitySynced(false);
337
- }
338
- const message = (0, _errorHandlers.handleAuthError)(error, {
339
- defaultMessage: 'Failed to create identity',
340
- code: REGISTER_ERROR_CODE,
341
- onError,
342
- setAuthError: msg => setAuthState({
343
- error: msg
344
- }),
345
- logger
346
- });
347
- loginFailure(message);
348
- throw error;
349
- } finally {
350
- setAuthState({
351
- isLoading: false
352
- });
353
- }
354
- }, [oxyServices, storage, setAuthState, loginFailure, onError, logger, setIdentitySynced, clearSessionsIfIdentityChanged]);
355
-
356
- /**
357
- * Check if identity is synced with server (reads from storage for persistence)
358
- */
359
- const isIdentitySyncedFn = (0, _react.useCallback)(async () => {
360
- if (!storage) return true;
361
- const synced = await storage.getItem('oxy_identity_synced');
362
- const isSynced = synced !== 'false';
363
- setIdentitySynced(isSynced);
364
- return isSynced;
365
- }, [storage, setIdentitySynced]);
366
-
367
- /**
368
- * Sync local identity with server (call when online)
369
- * TanStack Query handles offline mutations automatically
370
- *
371
- * @param username - Optional username to set during sync
372
- */
373
- const syncIdentity = (0, _react.useCallback)(async username => {
374
- if (!storage) throw new Error('Storage not initialized');
375
- setAuthState({
376
- isLoading: true,
377
- error: null
378
- });
379
- setSyncing(true);
380
- try {
381
- const publicKey = await _crypto.KeyManager.getPublicKey();
382
- if (!publicKey) {
383
- throw new Error('No identity found on this device');
384
- }
385
-
386
- // Check if already synced
387
- const alreadySynced = await storage.getItem('oxy_identity_synced');
388
- if (alreadySynced === 'true') {
389
- setIdentitySynced(true);
390
- return await performSignIn(publicKey);
391
- }
392
-
393
- // Check if already registered on server
394
- const {
395
- registered
396
- } = await oxyServices.checkPublicKeyRegistered(publicKey);
397
- if (!registered) {
398
- // Register with server (identity is just the publicKey)
399
- const {
400
- signature,
401
- timestamp
402
- } = await _crypto.SignatureService.createRegistrationSignature();
403
- await oxyServices.register(publicKey, signature, timestamp, username);
404
- }
405
-
406
- // Mark as synced (Zustand store + storage)
407
- await storage.setItem('oxy_identity_synced', 'true');
408
- setIdentitySynced(true);
409
-
410
- // Sign in
411
- const user = await performSignIn(publicKey);
412
-
413
- // TanStack Query will automatically retry any pending mutations
414
-
415
- return user;
416
- } catch (error) {
417
- const message = (0, _errorHandlers.handleAuthError)(error, {
418
- defaultMessage: 'Failed to sync identity',
419
- code: REGISTER_ERROR_CODE,
420
- onError,
421
- setAuthError: msg => setAuthState({
422
- error: msg
423
- }),
424
- logger
425
- });
426
- loginFailure(message);
427
- throw error;
428
- } finally {
429
- setAuthState({
430
- isLoading: false
431
- });
432
- setSyncing(false);
433
- }
434
- }, [oxyServices, storage, setAuthState, performSignIn, loginFailure, onError, logger, setSyncing, setIdentitySynced]);
435
-
436
- /**
437
- * Import identity from backup file data (offline-first)
438
- *
439
- * @param backupData - The backup data to import
440
- * @param password - Password to decrypt the backup
441
- * @param username - Optional username to set during registration
442
- */
443
- const importIdentity = (0, _react.useCallback)(async (backupData, password, username) => {
444
- if (!storage) throw new Error('Storage not initialized');
445
-
446
- // Validate arguments - ensure backupData is an object, not a string (old signature)
447
- if (!backupData || typeof backupData !== 'object' || Array.isArray(backupData)) {
448
- throw new Error('Invalid backup data. Please use the backup file import feature.');
449
- }
450
- if (!backupData.encrypted || !backupData.salt || !backupData.iv || !backupData.publicKey) {
451
- throw new Error('Invalid backup data structure. Missing required fields.');
452
- }
453
- if (!password || typeof password !== 'string') {
454
- throw new Error('Password is required for backup file import.');
455
- }
456
- setAuthState({
457
- isLoading: true,
458
- error: null
459
- });
460
- try {
461
- // CRITICAL: Get old public key before importing new identity
462
- // If identity changes, we must clear all session data to prevent data leakage
463
- const oldPublicKey = await _crypto.KeyManager.getPublicKey().catch(() => null);
464
- if (__DEV__ && logger) {
465
- logger('Importing identity from backup', {
466
- hadPreviousIdentity: !!oldPublicKey,
467
- backupPublicKey: backupData.publicKey.substring(0, 16) + '...'
468
- });
469
- }
470
-
471
- // Decrypt private key from backup data
472
- const Crypto = await Promise.resolve().then(() => _interopRequireWildcard(require('expo-crypto')));
473
-
474
- // Convert hex strings to Uint8Array
475
- const saltBytes = new Uint8Array(backupData.salt.match(/.{1,2}/g)?.map(byte => parseInt(byte, 16)) || []);
476
- const ivBytes = new Uint8Array(backupData.iv.match(/.{1,2}/g)?.map(byte => parseInt(byte, 16)) || []);
477
-
478
- // Derive key from password (same algorithm as EncryptedBackupGenerator)
479
- const saltHex = Array.from(saltBytes).map(b => b.toString(16).padStart(2, '0')).join('');
480
- let key = password + saltHex;
481
- for (let i = 0; i < 10000; i++) {
482
- key = await Crypto.digestStringAsync(Crypto.CryptoDigestAlgorithm.SHA256, key);
483
- }
484
- const keyBytes = new Uint8Array(32);
485
- for (let i = 0; i < 64 && i < key.length; i += 2) {
486
- keyBytes[i / 2] = parseInt(key.substring(i, i + 2), 16);
487
- }
488
-
489
- // Decrypt private key (XOR decryption - same as encryption)
490
- const encryptedBytes = Buffer.from(backupData.encrypted, 'base64');
491
- const decryptedBytes = new Uint8Array(encryptedBytes.length);
492
- for (let i = 0; i < encryptedBytes.length; i++) {
493
- decryptedBytes[i] = encryptedBytes[i] ^ keyBytes[i % keyBytes.length] ^ ivBytes[i % ivBytes.length];
494
- }
495
- const privateKey = new TextDecoder().decode(decryptedBytes);
496
-
497
- // Import the key pair
498
- const publicKey = await _crypto.KeyManager.importKeyPair(privateKey);
499
- if (__DEV__ && logger) {
500
- logger('Identity keys imported', {
501
- publicKey: publicKey.substring(0, 16) + '...'
502
- });
503
- }
504
-
505
- // Verify public key matches
506
- if (publicKey !== backupData.publicKey) {
507
- throw new Error('Backup file is corrupted or password is incorrect');
508
- }
509
-
510
- // Clear sessions if identity changed (prevents data leakage)
511
- await clearSessionsIfIdentityChanged(oldPublicKey, publicKey);
512
-
513
- // Mark as not synced
514
- await storage.setItem('oxy_identity_synced', 'false');
515
- setIdentitySynced(false);
516
-
517
- // Try to sync with server
518
- try {
519
- // Check if this identity is already registered
520
- const {
521
- registered
522
- } = await oxyServices.checkPublicKeyRegistered(publicKey);
523
- if (registered) {
524
- // Identity exists, mark as synced
525
- await storage.setItem('oxy_identity_synced', 'true');
526
- setIdentitySynced(true);
527
- return {
528
- synced: true
529
- };
530
- } else {
531
- // Need to register this identity (identity is just the publicKey)
532
- const {
533
- signature,
534
- timestamp
535
- } = await _crypto.SignatureService.createRegistrationSignature();
536
- await oxyServices.register(publicKey, signature, timestamp, username);
537
- await storage.setItem('oxy_identity_synced', 'true');
538
- setIdentitySynced(true);
539
- return {
540
- synced: true
541
- };
542
- }
543
- } catch (syncError) {
544
- // Offline - identity restored locally but not synced
545
- if (__DEV__) {
546
- console.log('[Auth] Identity imported locally, will sync when online:', syncError);
547
- }
548
- return {
549
- synced: false
550
- };
551
- }
552
- } catch (error) {
553
- const message = (0, _errorHandlers.handleAuthError)(error, {
554
- defaultMessage: 'Failed to import identity. Please check your password and backup file.',
555
- code: REGISTER_ERROR_CODE,
556
- onError,
557
- setAuthError: msg => setAuthState({
558
- error: msg
559
- }),
560
- logger
561
- });
562
- loginFailure(message);
563
- throw error;
564
- } finally {
565
- setAuthState({
566
- isLoading: false
567
- });
568
- }
569
- }, [oxyServices, storage, setAuthState, loginFailure, onError, logger, setIdentitySynced, clearSessionsIfIdentityChanged]);
570
-
571
- /**
572
- * Sign in with existing identity on device
573
- */
574
- const signIn = (0, _react.useCallback)(async deviceName => {
575
- if (!storage) throw new Error('Storage not initialized');
576
- setAuthState({
577
- isLoading: true,
578
- error: null
579
- });
580
- try {
581
- // Get stored public key
582
- const publicKey = await _crypto.KeyManager.getPublicKey();
583
- if (!publicKey) {
584
- throw new Error('No identity found on this device. Please create or import an identity.');
585
- }
586
- return await performSignIn(publicKey);
587
- } catch (error) {
588
- const message = (0, _errorHandlers.handleAuthError)(error, {
589
- defaultMessage: 'Sign in failed',
590
- code: LOGIN_ERROR_CODE,
591
- onError,
592
- setAuthError: msg => setAuthState({
593
- error: msg
594
- }),
595
- logger
596
- });
597
- loginFailure(message);
598
- throw error;
599
- } finally {
600
- setAuthState({
601
- isLoading: false
602
- });
603
- }
604
- }, [storage, setAuthState, performSignIn, loginFailure, onError, logger]);
605
-
606
- /**
607
- * Logout from session
608
- */
609
- const logout = (0, _react.useCallback)(async targetSessionId => {
610
- if (!activeSessionId) return;
611
- try {
612
- const sessionToLogout = targetSessionId || activeSessionId;
613
- await oxyServices.logoutSession(activeSessionId, sessionToLogout);
614
- const filteredSessions = sessions.filter(session => session.sessionId !== sessionToLogout);
615
- updateSessions(filteredSessions, {
616
- merge: false
617
- });
618
- if (sessionToLogout === activeSessionId) {
619
- if (filteredSessions.length > 0) {
620
- await switchSession(filteredSessions[0].sessionId);
621
- } else {
622
- await clearSessionState();
623
- return;
624
- }
625
- }
626
- } catch (error) {
627
- const isInvalid = (0, _errorHandlers.isInvalidSessionError)(error);
628
- if (isInvalid && targetSessionId === activeSessionId) {
629
- await clearSessionState();
630
- return;
631
- }
632
- (0, _errorHandlers.handleAuthError)(error, {
633
- defaultMessage: 'Logout failed',
634
- code: LOGOUT_ERROR_CODE,
635
- onError,
636
- setAuthError: msg => setAuthState({
637
- error: msg
638
- }),
639
- logger,
640
- status: isInvalid ? 401 : undefined
641
- });
642
- }
643
- }, [activeSessionId, clearSessionState, logger, onError, oxyServices, sessions, setAuthState, switchSession, updateSessions]);
644
-
645
- /**
646
- * Logout from all sessions
647
- */
648
- const logoutAll = (0, _react.useCallback)(async () => {
649
- if (!activeSessionId) {
650
- const error = new Error('No active session found');
651
- setAuthState({
652
- error: error.message
653
- });
654
- onError?.({
655
- message: error.message,
656
- code: LOGOUT_ALL_ERROR_CODE,
657
- status: 404
658
- });
659
- throw error;
660
- }
661
- try {
662
- await oxyServices.logoutAllSessions(activeSessionId);
663
- await clearSessionState();
664
- } catch (error) {
665
- (0, _errorHandlers.handleAuthError)(error, {
666
- defaultMessage: 'Logout all failed',
667
- code: LOGOUT_ALL_ERROR_CODE,
668
- onError,
669
- setAuthError: msg => setAuthState({
670
- error: msg
671
- }),
672
- logger
673
- });
674
- throw error instanceof Error ? error : new Error('Logout all failed');
675
- }
676
- }, [activeSessionId, clearSessionState, logger, onError, oxyServices, setAuthState]);
677
-
678
- /**
679
- * Check if device has an identity stored
680
- */
681
- const hasIdentity = (0, _react.useCallback)(async () => {
682
- return _crypto.KeyManager.hasIdentity();
683
- }, []);
684
-
685
- /**
686
- * Get the public key of the stored identity
687
- */
688
- const getPublicKey = (0, _react.useCallback)(async () => {
689
- return _crypto.KeyManager.getPublicKey();
690
- }, []);
691
- return {
692
- createIdentity,
693
- importIdentity,
694
- signIn,
695
- logout,
696
- logoutAll,
697
- hasIdentity,
698
- getPublicKey,
699
- isIdentitySynced: isIdentitySyncedFn,
700
- syncIdentity
701
- };
702
- };
703
- exports.useAuthOperations = useAuthOperations;
704
- //# sourceMappingURL=useAuthOperations.js.map