@oxyhq/services 5.9.2 → 5.9.3

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 (202) hide show
  1. package/README.md +1 -33
  2. package/lib/commonjs/core/OxyServices.js +159 -0
  3. package/lib/commonjs/core/OxyServices.js.map +1 -0
  4. package/lib/commonjs/core/OxyServicesMain.js +51 -0
  5. package/lib/commonjs/core/OxyServicesMain.js.map +1 -0
  6. package/lib/commonjs/core/analytics/AnalyticsService.js +67 -0
  7. package/lib/commonjs/core/analytics/AnalyticsService.js.map +1 -0
  8. package/lib/commonjs/core/auth/AuthService.js +526 -0
  9. package/lib/commonjs/core/auth/AuthService.js.map +1 -0
  10. package/lib/commonjs/core/devices/DeviceService.js +61 -0
  11. package/lib/commonjs/core/devices/DeviceService.js.map +1 -0
  12. package/lib/commonjs/core/files/FileService.js +176 -0
  13. package/lib/commonjs/core/files/FileService.js.map +1 -0
  14. package/lib/commonjs/core/index.js +103 -1701
  15. package/lib/commonjs/core/index.js.map +1 -1
  16. package/lib/commonjs/core/karma/KarmaService.js +100 -0
  17. package/lib/commonjs/core/karma/KarmaService.js.map +1 -0
  18. package/lib/commonjs/core/locations/LocationService.js +131 -0
  19. package/lib/commonjs/core/locations/LocationService.js.map +1 -0
  20. package/lib/commonjs/core/payments/PaymentService.js +124 -0
  21. package/lib/commonjs/core/payments/PaymentService.js.map +1 -0
  22. package/lib/commonjs/core/users/UserService.js +234 -0
  23. package/lib/commonjs/core/users/UserService.js.map +1 -0
  24. package/lib/commonjs/index.js +164 -3
  25. package/lib/commonjs/index.js.map +1 -1
  26. package/lib/commonjs/models/session.js +2 -0
  27. package/lib/commonjs/{types/middleware.js.map → models/session.js.map} +1 -1
  28. package/lib/commonjs/ui/context/OxyContext.js +28 -24
  29. package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
  30. package/lib/commonjs/ui/screens/AccountSwitcherScreen.js +2 -2
  31. package/lib/commonjs/ui/screens/AccountSwitcherScreen.js.map +1 -1
  32. package/lib/commonjs/ui/screens/FileManagementScreen.js +12 -12
  33. package/lib/commonjs/ui/screens/FileManagementScreen.js.map +1 -1
  34. package/lib/commonjs/ui/screens/ProfileScreen.js +2 -2
  35. package/lib/commonjs/ui/screens/ProfileScreen.js.map +1 -1
  36. package/lib/commonjs/ui/screens/SessionManagementScreen.js.map +1 -1
  37. package/lib/commonjs/ui/screens/SignInScreen.js +1 -1
  38. package/lib/commonjs/ui/screens/SignInScreen.js.map +1 -1
  39. package/lib/commonjs/ui/screens/karma/KarmaCenterScreen.js +1 -1
  40. package/lib/commonjs/ui/screens/karma/KarmaCenterScreen.js.map +1 -1
  41. package/lib/commonjs/ui/screens/karma/KarmaLeaderboardScreen.js +1 -1
  42. package/lib/commonjs/ui/screens/karma/KarmaLeaderboardScreen.js.map +1 -1
  43. package/lib/commonjs/ui/screens/karma/KarmaRulesScreen.js +1 -1
  44. package/lib/commonjs/ui/screens/karma/KarmaRulesScreen.js.map +1 -1
  45. package/lib/commonjs/ui/stores/followStore.js +4 -4
  46. package/lib/commonjs/ui/stores/followStore.js.map +1 -1
  47. package/lib/commonjs/utils/apiUtils.js +93 -0
  48. package/lib/commonjs/utils/apiUtils.js.map +1 -0
  49. package/lib/commonjs/utils/asyncUtils.js +219 -0
  50. package/lib/commonjs/utils/asyncUtils.js.map +1 -0
  51. package/lib/commonjs/utils/errorUtils.js +148 -0
  52. package/lib/commonjs/utils/errorUtils.js.map +1 -0
  53. package/lib/commonjs/utils/hookUtils.js +399 -0
  54. package/lib/commonjs/utils/hookUtils.js.map +1 -0
  55. package/lib/commonjs/utils/loggerUtils.js +160 -0
  56. package/lib/commonjs/utils/loggerUtils.js.map +1 -0
  57. package/lib/commonjs/utils/validationUtils.js +174 -0
  58. package/lib/commonjs/utils/validationUtils.js.map +1 -0
  59. package/lib/module/core/OxyServices.js +153 -0
  60. package/lib/module/core/OxyServices.js.map +1 -0
  61. package/lib/module/core/OxyServicesMain.js +47 -0
  62. package/lib/module/core/OxyServicesMain.js.map +1 -0
  63. package/lib/module/core/analytics/AnalyticsService.js +62 -0
  64. package/lib/module/core/analytics/AnalyticsService.js.map +1 -0
  65. package/lib/module/core/auth/AuthService.js +521 -0
  66. package/lib/module/core/auth/AuthService.js.map +1 -0
  67. package/lib/module/core/devices/DeviceService.js +57 -0
  68. package/lib/module/core/devices/DeviceService.js.map +1 -0
  69. package/lib/module/core/files/FileService.js +171 -0
  70. package/lib/module/core/files/FileService.js.map +1 -0
  71. package/lib/module/core/index.js +25 -1690
  72. package/lib/module/core/index.js.map +1 -1
  73. package/lib/module/core/karma/KarmaService.js +95 -0
  74. package/lib/module/core/karma/KarmaService.js.map +1 -0
  75. package/lib/module/core/locations/LocationService.js +127 -0
  76. package/lib/module/core/locations/LocationService.js.map +1 -0
  77. package/lib/module/core/payments/PaymentService.js +119 -0
  78. package/lib/module/core/payments/PaymentService.js.map +1 -0
  79. package/lib/module/core/users/UserService.js +230 -0
  80. package/lib/module/core/users/UserService.js.map +1 -0
  81. package/lib/module/index.js +8 -4
  82. package/lib/module/index.js.map +1 -1
  83. package/lib/module/models/session.js +2 -0
  84. package/lib/module/{types/middleware.js.map → models/session.js.map} +1 -1
  85. package/lib/module/ui/context/OxyContext.js +28 -24
  86. package/lib/module/ui/context/OxyContext.js.map +1 -1
  87. package/lib/module/ui/screens/AccountSwitcherScreen.js +2 -2
  88. package/lib/module/ui/screens/AccountSwitcherScreen.js.map +1 -1
  89. package/lib/module/ui/screens/FileManagementScreen.js +12 -12
  90. package/lib/module/ui/screens/FileManagementScreen.js.map +1 -1
  91. package/lib/module/ui/screens/ProfileScreen.js +2 -2
  92. package/lib/module/ui/screens/ProfileScreen.js.map +1 -1
  93. package/lib/module/ui/screens/SessionManagementScreen.js.map +1 -1
  94. package/lib/module/ui/screens/SignInScreen.js +1 -1
  95. package/lib/module/ui/screens/SignInScreen.js.map +1 -1
  96. package/lib/module/ui/screens/karma/KarmaCenterScreen.js +1 -1
  97. package/lib/module/ui/screens/karma/KarmaCenterScreen.js.map +1 -1
  98. package/lib/module/ui/screens/karma/KarmaLeaderboardScreen.js +1 -1
  99. package/lib/module/ui/screens/karma/KarmaLeaderboardScreen.js.map +1 -1
  100. package/lib/module/ui/screens/karma/KarmaRulesScreen.js +1 -1
  101. package/lib/module/ui/screens/karma/KarmaRulesScreen.js.map +1 -1
  102. package/lib/module/ui/stores/followStore.js +4 -4
  103. package/lib/module/ui/stores/followStore.js.map +1 -1
  104. package/lib/module/utils/apiUtils.js +85 -0
  105. package/lib/module/utils/apiUtils.js.map +1 -0
  106. package/lib/module/utils/asyncUtils.js +202 -0
  107. package/lib/module/utils/asyncUtils.js.map +1 -0
  108. package/lib/module/utils/errorUtils.js +139 -0
  109. package/lib/module/utils/errorUtils.js.map +1 -0
  110. package/lib/module/utils/hookUtils.js +381 -0
  111. package/lib/module/utils/hookUtils.js.map +1 -0
  112. package/lib/module/utils/loggerUtils.js +149 -0
  113. package/lib/module/utils/loggerUtils.js.map +1 -0
  114. package/lib/module/utils/validationUtils.js +154 -0
  115. package/lib/module/utils/validationUtils.js.map +1 -0
  116. package/lib/typescript/core/OxyServices.d.ts +64 -0
  117. package/lib/typescript/core/OxyServices.d.ts.map +1 -0
  118. package/lib/typescript/core/OxyServicesMain.d.ts +33 -0
  119. package/lib/typescript/core/OxyServicesMain.d.ts.map +1 -0
  120. package/lib/typescript/core/analytics/AnalyticsService.d.ts +26 -0
  121. package/lib/typescript/core/analytics/AnalyticsService.d.ts.map +1 -0
  122. package/lib/typescript/core/auth/AuthService.d.ts +165 -0
  123. package/lib/typescript/core/auth/AuthService.d.ts.map +1 -0
  124. package/lib/typescript/core/devices/DeviceService.d.ts +20 -0
  125. package/lib/typescript/core/devices/DeviceService.d.ts.map +1 -0
  126. package/lib/typescript/core/files/FileService.d.ts +59 -0
  127. package/lib/typescript/core/files/FileService.d.ts.map +1 -0
  128. package/lib/typescript/core/index.d.ts +19 -656
  129. package/lib/typescript/core/index.d.ts.map +1 -1
  130. package/lib/typescript/core/karma/KarmaService.d.ts +50 -0
  131. package/lib/typescript/core/karma/KarmaService.d.ts.map +1 -0
  132. package/lib/typescript/core/locations/LocationService.d.ts +39 -0
  133. package/lib/typescript/core/locations/LocationService.d.ts.map +1 -0
  134. package/lib/typescript/core/payments/PaymentService.d.ts +50 -0
  135. package/lib/typescript/core/payments/PaymentService.d.ts.map +1 -0
  136. package/lib/typescript/core/users/UserService.d.ts +111 -0
  137. package/lib/typescript/core/users/UserService.d.ts.map +1 -0
  138. package/lib/typescript/index.d.ts +7 -3
  139. package/lib/typescript/index.d.ts.map +1 -1
  140. package/lib/typescript/models/{secureSession.d.ts → session.d.ts} +4 -4
  141. package/lib/typescript/models/session.d.ts.map +1 -0
  142. package/lib/typescript/ui/context/OxyContext.d.ts +2 -2
  143. package/lib/typescript/ui/context/OxyContext.d.ts.map +1 -1
  144. package/lib/typescript/utils/apiUtils.d.ts +61 -0
  145. package/lib/typescript/utils/apiUtils.d.ts.map +1 -0
  146. package/lib/typescript/utils/asyncUtils.d.ts +64 -0
  147. package/lib/typescript/utils/asyncUtils.d.ts.map +1 -0
  148. package/lib/typescript/utils/errorUtils.d.ts +45 -0
  149. package/lib/typescript/utils/errorUtils.d.ts.map +1 -0
  150. package/lib/typescript/utils/hookUtils.d.ts +102 -0
  151. package/lib/typescript/utils/hookUtils.d.ts.map +1 -0
  152. package/lib/typescript/utils/loggerUtils.d.ts +49 -0
  153. package/lib/typescript/utils/loggerUtils.d.ts.map +1 -0
  154. package/lib/typescript/utils/validationUtils.d.ts +80 -0
  155. package/lib/typescript/utils/validationUtils.d.ts.map +1 -0
  156. package/package.json +2 -8
  157. package/src/core/OxyServices.ts +168 -0
  158. package/src/core/OxyServicesMain.ts +57 -0
  159. package/src/core/analytics/AnalyticsService.ts +64 -0
  160. package/src/core/auth/AuthService.ts +544 -0
  161. package/src/core/devices/DeviceService.ts +55 -0
  162. package/src/core/files/FileService.ts +194 -0
  163. package/src/core/index.ts +27 -1765
  164. package/src/core/karma/KarmaService.ts +104 -0
  165. package/src/core/locations/LocationService.ts +141 -0
  166. package/src/core/payments/PaymentService.ts +133 -0
  167. package/src/core/users/UserService.ts +241 -0
  168. package/src/index.ts +29 -8
  169. package/src/models/{secureSession.ts → session.ts} +5 -5
  170. package/src/ui/context/OxyContext.tsx +34 -30
  171. package/src/ui/screens/AccountSwitcherScreen.tsx +4 -4
  172. package/src/ui/screens/FileManagementScreen.tsx +12 -12
  173. package/src/ui/screens/ProfileScreen.tsx +3 -3
  174. package/src/ui/screens/SessionManagementScreen.tsx +2 -2
  175. package/src/ui/screens/SignInScreen.tsx +1 -1
  176. package/src/ui/screens/karma/KarmaCenterScreen.tsx +2 -2
  177. package/src/ui/screens/karma/KarmaLeaderboardScreen.tsx +3 -3
  178. package/src/ui/screens/karma/KarmaRulesScreen.tsx +3 -3
  179. package/src/ui/stores/followStore.ts +4 -4
  180. package/src/utils/apiUtils.ts +102 -0
  181. package/src/utils/asyncUtils.ts +265 -0
  182. package/src/utils/errorUtils.ts +172 -0
  183. package/src/utils/hookUtils.ts +397 -0
  184. package/src/utils/loggerUtils.ts +153 -0
  185. package/src/utils/validationUtils.ts +158 -0
  186. package/lib/commonjs/middleware.js +0 -17
  187. package/lib/commonjs/middleware.js.map +0 -1
  188. package/lib/commonjs/models/secureSession.js +0 -2
  189. package/lib/commonjs/models/secureSession.js.map +0 -1
  190. package/lib/commonjs/types/middleware.js +0 -6
  191. package/lib/module/middleware.js +0 -12
  192. package/lib/module/middleware.js.map +0 -1
  193. package/lib/module/models/secureSession.js +0 -2
  194. package/lib/module/models/secureSession.js.map +0 -1
  195. package/lib/module/types/middleware.js +0 -4
  196. package/lib/typescript/middleware.d.ts +0 -9
  197. package/lib/typescript/middleware.d.ts.map +0 -1
  198. package/lib/typescript/models/secureSession.d.ts.map +0 -1
  199. package/lib/typescript/types/middleware.d.ts +0 -19
  200. package/lib/typescript/types/middleware.d.ts.map +0 -1
  201. package/src/middleware.ts +0 -11
  202. package/src/types/middleware.ts +0 -20
@@ -2,7 +2,7 @@ import React, { createContext, useContext, useEffect, useCallback, ReactNode, us
2
2
  import { View, Text } from 'react-native';
3
3
  import { OxyServices } from '../../core';
4
4
  import { User, ApiError } from '../../models/interfaces';
5
- import { SecureLoginResponse, SecureClientSession, MinimalUserData } from '../../models/secureSession';
5
+ import { SessionLoginResponse, ClientSession, MinimalUserData } from '../../models/session';
6
6
  import { DeviceManager } from '../../utils/deviceManager';
7
7
  import { useSessionSocket } from '../hooks/useSessionSocket';
8
8
  import { toast } from '../../lib/sonner';
@@ -13,7 +13,7 @@ export interface OxyContextState {
13
13
  // Authentication state
14
14
  user: User | null; // Current active user (loaded from server)
15
15
  minimalUser: MinimalUserData | null; // Minimal user data for UI
16
- sessions: SecureClientSession[]; // All active sessions
16
+ sessions: ClientSession[]; // All active sessions
17
17
  activeSessionId: string | null;
18
18
  isAuthenticated: boolean; // Single source of truth for authentication - use this instead of service methods
19
19
  isLoading: boolean;
@@ -111,8 +111,8 @@ const getStorage = async (): Promise<StorageInterface> => {
111
111
  return new WebStorage();
112
112
  };
113
113
 
114
- // Storage keys for secure sessions
115
- const getSecureStorageKeys = (prefix = 'oxy_secure') => ({
114
+ // Storage keys for sessions
115
+ const getStorageKeys = (prefix = 'oxy_session') => ({
116
116
  activeSessionId: `${prefix}_active_session_id`, // Only store the active session ID
117
117
  });
118
118
 
@@ -120,7 +120,7 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
120
120
  children,
121
121
  oxyServices: providedOxyServices,
122
122
  baseURL,
123
- storageKeyPrefix = 'oxy_secure',
123
+ storageKeyPrefix = 'oxy_session',
124
124
  onAuthStateChange,
125
125
  onError,
126
126
  bottomSheetRef,
@@ -151,14 +151,14 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
151
151
 
152
152
  // Local state for non-auth fields
153
153
  const [minimalUser, setMinimalUser] = React.useState<MinimalUserData | null>(null);
154
- const [sessions, setSessions] = React.useState<SecureClientSession[]>([]);
154
+ const [sessions, setSessions] = React.useState<ClientSession[]>([]);
155
155
  const [activeSessionId, setActiveSessionId] = React.useState<string | null>(null);
156
156
  const [storage, setStorage] = React.useState<StorageInterface | null>(null);
157
157
  // Add a new state to track token restoration
158
158
  const [tokenReady, setTokenReady] = React.useState(false);
159
159
 
160
160
  // Storage keys (memoized to prevent infinite loops)
161
- const keys = useMemo(() => getSecureStorageKeys(storageKeyPrefix), [storageKeyPrefix]);
161
+ const keys = useMemo(() => getStorageKeys(storageKeyPrefix), [storageKeyPrefix]);
162
162
 
163
163
  // Clear all storage - defined before initAuth to avoid dependency issues
164
164
  const clearAllStorage = useCallback(async (): Promise<void> => {
@@ -166,7 +166,7 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
166
166
  try {
167
167
  await storage.removeItem(keys.activeSessionId);
168
168
  } catch (err) {
169
- console.error('Clear secure storage error:', err);
169
+ console.error('Clear storage error:', err);
170
170
  }
171
171
  }, [storage, keys]);
172
172
 
@@ -195,17 +195,19 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
195
195
  // Only load the active session ID from storage
196
196
  const storedActiveSessionId = await storage.getItem(keys.activeSessionId);
197
197
 
198
- console.log('SecureAuth - activeSessionId:', storedActiveSessionId);
199
- console.log('SecureAuth - storage available:', !!storage);
200
- console.log('SecureAuth - oxyServices available:', !!oxyServices);
198
+ console.log('Auth - activeSessionId:', storedActiveSessionId);
199
+ console.log('Auth - storage available:', !!storage);
200
+ console.log('Auth - oxyServices available:', !!oxyServices);
201
201
 
202
202
  if (storedActiveSessionId) {
203
203
  // Validate the stored session with the backend
204
204
  try {
205
- const validation = await oxyServices.validateSession(storedActiveSessionId);
205
+ const validation = await oxyServices.validateSession(storedActiveSessionId, {
206
+ useHeaderValidation: true
207
+ });
206
208
 
207
209
  if (validation.valid) {
208
- console.log('SecureAuth - session validated successfully');
210
+ console.log('Auth - session validated successfully');
209
211
  setActiveSessionId(storedActiveSessionId);
210
212
 
211
213
  // Get access token for API calls
@@ -222,7 +224,7 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
222
224
 
223
225
  // Load sessions from backend
224
226
  const serverSessions = await oxyServices.getSessionsBySessionId(storedActiveSessionId);
225
- const clientSessions: SecureClientSession[] = serverSessions.map(serverSession => ({
227
+ const clientSessions: ClientSession[] = serverSessions.map(serverSession => ({
226
228
  sessionId: serverSession.sessionId,
227
229
  deviceId: serverSession.deviceId,
228
230
  expiresAt: serverSession.expiresAt || new Date().toISOString(),
@@ -235,18 +237,18 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
235
237
  onAuthStateChange(fullUser);
236
238
  }
237
239
  } else {
238
- console.log('SecureAuth - session invalid, clearing storage');
240
+ console.log('Auth - session invalid, clearing storage');
239
241
  await clearAllStorage();
240
242
  }
241
243
  } catch (error) {
242
- console.error('SecureAuth - session validation error:', error);
244
+ console.error('Auth - session validation error:', error);
243
245
  await clearAllStorage();
244
246
  }
245
247
  } else {
246
- console.log('SecureAuth - no stored session found, user needs to login');
248
+ console.log('Auth - no stored session found, user needs to login');
247
249
  }
248
250
  } catch (err) {
249
- console.error('Secure auth initialization error:', err);
251
+ console.error('Auth initialization error:', err);
250
252
  await clearAllStorage();
251
253
  } finally {
252
254
  useAuthStore.setState({ isLoading: false });
@@ -320,7 +322,7 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
320
322
  }
321
323
  }, [oxyServices, onAuthStateChange, loginSuccess, saveActiveSessionId]);
322
324
 
323
- // Secure login method - only store session ID, retrieve data from backend
325
+ // Login method - only store session ID, retrieve data from backend
324
326
  const login = useCallback(async (username: string, password: string, deviceName?: string): Promise<User> => {
325
327
  if (!storage) throw new Error('Storage not initialized');
326
328
  useAuthStore.setState({ isLoading: true, error: null });
@@ -332,10 +334,10 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
332
334
  // Get or generate persistent device info
333
335
  const deviceInfo = await DeviceManager.getDeviceInfo();
334
336
 
335
- console.log('SecureAuth - Using device fingerprint:', deviceFingerprint);
336
- console.log('SecureAuth - Using device ID:', deviceInfo.deviceId);
337
+ console.log('Auth - Using device fingerprint:', deviceFingerprint);
338
+ console.log('Auth - Using device ID:', deviceInfo.deviceId);
337
339
 
338
- const response: SecureLoginResponse = await oxyServices.secureLogin(
340
+ const response: SessionLoginResponse = await oxyServices.signIn(
339
341
  username,
340
342
  password,
341
343
  deviceName || deviceInfo.deviceName || DeviceManager.getDefaultDeviceName(),
@@ -356,7 +358,7 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
356
358
 
357
359
  // Load sessions from backend
358
360
  const serverSessions = await oxyServices.getSessionsBySessionId(response.sessionId);
359
- const clientSessions: SecureClientSession[] = serverSessions.map(serverSession => ({
361
+ const clientSessions: ClientSession[] = serverSessions.map(serverSession => ({
360
362
  sessionId: serverSession.sessionId,
361
363
  deviceId: serverSession.deviceId,
362
364
  expiresAt: serverSession.expiresAt || new Date().toISOString(),
@@ -384,7 +386,7 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
384
386
 
385
387
  try {
386
388
  const sessionToLogout = targetSessionId || activeSessionId;
387
- await oxyServices.logoutSecureSession(activeSessionId, sessionToLogout);
389
+ await oxyServices.logoutSession(activeSessionId, sessionToLogout);
388
390
 
389
391
  // Remove session from local state
390
392
  const filteredSessions = sessions.filter(s => s.sessionId !== sessionToLogout);
@@ -430,9 +432,9 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
430
432
  }
431
433
 
432
434
  try {
433
- console.log('Calling oxyServices.logoutAllSecureSessions with sessionId:', activeSessionId);
434
- await oxyServices.logoutAllSecureSessions(activeSessionId);
435
- console.log('logoutAllSecureSessions completed successfully');
435
+ console.log('Calling oxyServices.logoutAllSessions with sessionId:', activeSessionId);
436
+ await oxyServices.logoutAllSessions(activeSessionId);
437
+ console.log('logoutAllSessions completed successfully');
436
438
 
437
439
  // Clear all local data
438
440
  setSessions([]);
@@ -485,7 +487,7 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
485
487
 
486
488
  console.log('SignUp successful:', response);
487
489
 
488
- // Now log the user in securely to create a session
490
+ // Now log the user in to create a session
489
491
  // This will handle the session creation and device registration
490
492
  const user = await login(username, password);
491
493
 
@@ -523,7 +525,7 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
523
525
  console.log('refreshSessions: Server sessions received:', serverSessions);
524
526
 
525
527
  // Update local sessions with server data
526
- const updatedSessions: SecureClientSession[] = serverSessions.map(serverSession => ({
528
+ const updatedSessions: ClientSession[] = serverSessions.map(serverSession => ({
527
529
  sessionId: serverSession.sessionId,
528
530
  deviceId: serverSession.deviceId,
529
531
  expiresAt: serverSession.expiresAt || new Date().toISOString(),
@@ -545,7 +547,9 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
545
547
  for (const session of otherSessions) {
546
548
  try {
547
549
  // Try to validate this session
548
- await oxyServices.validateSession(session.sessionId);
550
+ await oxyServices.validateSession(session.sessionId, {
551
+ useHeaderValidation: true
552
+ });
549
553
  console.log('Found valid session, switching to:', session.sessionId);
550
554
  await switchToSession(session.sessionId);
551
555
  return; // Successfully switched to another session
@@ -13,7 +13,7 @@ import {
13
13
  } from 'react-native';
14
14
  import { BaseScreenProps } from '../navigation/types';
15
15
  import { useOxy } from '../context/OxyContext';
16
- import { SecureClientSession } from '../../models/secureSession';
16
+ import { ClientSession } from '../../models/session';
17
17
  import { fontFamilies } from '../styles/fonts';
18
18
  import { User } from '../../models/interfaces';
19
19
  import { toast } from '../../lib/sonner';
@@ -23,7 +23,7 @@ import { Ionicons } from '@expo/vector-icons';
23
23
  import Avatar from '../components/Avatar';
24
24
  import { Header, GroupedSection } from '../components';
25
25
 
26
- interface SessionWithUser extends SecureClientSession {
26
+ interface SessionWithUser extends ClientSession {
27
27
  userProfile?: User;
28
28
  isLoadingProfile?: boolean;
29
29
  }
@@ -217,7 +217,7 @@ const ModernAccountSwitcherScreen: React.FC<BaseScreenProps> = ({
217
217
  async () => {
218
218
  setRemoteLogoutSessionId(sessionId);
219
219
  try {
220
- await oxyServices?.logoutSecureSession(user?.sessionId || '', sessionId);
220
+ await oxyServices?.logoutSession(user?.sessionId || '', sessionId);
221
221
  // Refresh device sessions list
222
222
  await loadAllDeviceSessions();
223
223
  toast.success(`Signed out from ${deviceName} successfully!`);
@@ -244,7 +244,7 @@ const ModernAccountSwitcherScreen: React.FC<BaseScreenProps> = ({
244
244
  async () => {
245
245
  setLoggingOutAllDevices(true);
246
246
  try {
247
- await oxyServices?.logoutAllDeviceSessions(user?.sessionId || '', undefined, true);
247
+ await oxyServices?.logoutAllDeviceSessions(user?.sessionId || '');
248
248
  // Refresh device sessions list
249
249
  await loadAllDeviceSessions();
250
250
  toast.success('Signed out from all other devices successfully!');
@@ -118,7 +118,7 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
118
118
  setLoading(true);
119
119
  }
120
120
 
121
- const response = await oxyServices.listUserFiles(targetUserId);
121
+ const response = await oxyServices.files.listUserFiles(targetUserId);
122
122
  setFiles(response.files || []);
123
123
  } catch (error: any) {
124
124
  console.error('Failed to load files:', error);
@@ -172,7 +172,7 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
172
172
  await Promise.all(
173
173
  photosToLoad.map(async (photo) => {
174
174
  try {
175
- const downloadUrl = oxyServices.getFileDownloadUrl(photo.id);
175
+ const downloadUrl = oxyServices.files.getFileDownloadUrl(photo.id);
176
176
 
177
177
  if (Platform.OS === 'web') {
178
178
  const img = new (window as any).Image();
@@ -340,7 +340,7 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
340
340
  console.log('Current user ID:', user?.id);
341
341
  setDeleting(fileId);
342
342
 
343
- const result = await oxyServices.deleteFile(fileId);
343
+ const result = await oxyServices.files.deleteFile(fileId);
344
344
  console.log('Delete result:', result);
345
345
 
346
346
  toast.success('File deleted successfully');
@@ -408,7 +408,7 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
408
408
  console.log('Downloading file:', { fileId, filename });
409
409
 
410
410
  // Use the public download URL method
411
- const downloadUrl = oxyServices.getFileDownloadUrl(fileId);
411
+ const downloadUrl = oxyServices.files.getFileDownloadUrl(fileId);
412
412
  console.log('Download URL:', downloadUrl);
413
413
 
414
414
  try {
@@ -426,7 +426,7 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
426
426
  console.warn('Link download failed, trying fetch method:', linkError);
427
427
 
428
428
  // Method 2: Fallback to authenticated download
429
- const blob = await oxyServices.getFileContentAsBlob(fileId);
429
+ const blob = await oxyServices.files.getFileContentAsBlob(fileId);
430
430
  const url = window.URL.createObjectURL(blob);
431
431
 
432
432
  const link = document.createElement('a');
@@ -491,11 +491,11 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
491
491
  file.contentType.startsWith('video/') ||
492
492
  file.contentType.startsWith('audio/')) {
493
493
  // For images, PDFs, videos, and audio, we'll use the URL directly
494
- const downloadUrl = oxyServices.getFileDownloadUrl(file.id);
494
+ const downloadUrl = oxyServices.files.getFileDownloadUrl(file.id);
495
495
  setFileContent(downloadUrl);
496
496
  } else {
497
497
  // For text files, get the content using authenticated request
498
- const content = await oxyServices.getFileContentAsText(file.id);
498
+ const content = await oxyServices.files.getFileContentAsText(file.id);
499
499
  setFileContent(content);
500
500
  }
501
501
  } catch (error: any) {
@@ -532,7 +532,7 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
532
532
  };
533
533
 
534
534
  const renderSimplePhotoItem = useCallback((photo: FileMetadata, index: number) => {
535
- const downloadUrl = oxyServices.getFileDownloadUrl(photo.id);
535
+ const downloadUrl = oxyServices.files.getFileDownloadUrl(photo.id);
536
536
 
537
537
  // Calculate photo item width based on actual container size from bottom sheet
538
538
  let itemsPerRow = 3; // Default for mobile
@@ -598,7 +598,7 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
598
598
  }, [oxyServices, containerWidth]);
599
599
 
600
600
  const renderJustifiedPhotoItem = useCallback((photo: FileMetadata, width: number, height: number, isLast: boolean) => {
601
- const downloadUrl = oxyServices.getFileDownloadUrl(photo.id);
601
+ const downloadUrl = oxyServices.files.getFileDownloadUrl(photo.id);
602
602
 
603
603
  return (
604
604
  <TouchableOpacity
@@ -689,7 +689,7 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
689
689
  {isImage && (
690
690
  Platform.OS === 'web' ? (
691
691
  <img
692
- src={oxyServices.getFileDownloadUrl(file.id)}
692
+ src={oxyServices.files.getFileDownloadUrl(file.id)}
693
693
  style={{
694
694
  width: '100%',
695
695
  height: '100%',
@@ -709,7 +709,7 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
709
709
  />
710
710
  ) : (
711
711
  <Image
712
- source={{ uri: oxyServices.getFileDownloadUrl(file.id) }}
712
+ source={{ uri: oxyServices.files.getFileDownloadUrl(file.id) }}
713
713
  style={styles.previewImage}
714
714
  resizeMode="cover"
715
715
  onError={() => {
@@ -817,7 +817,7 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
817
817
  };
818
818
 
819
819
  const renderPhotoItem = (photo: FileMetadata, index: number) => {
820
- const downloadUrl = oxyServices.getFileDownloadUrl(photo.id);
820
+ const downloadUrl = oxyServices.files.getFileDownloadUrl(photo.id);
821
821
 
822
822
  // Calculate photo item width based on actual container size from bottom sheet
823
823
  let itemsPerRow = 3; // Default for mobile
@@ -61,7 +61,7 @@ const ProfileScreen: React.FC<ProfileScreenProps> = ({ userId, username, theme,
61
61
 
62
62
  // Load user profile and karma total
63
63
  Promise.all([
64
- oxyServices.getUserById(userId).catch(err => {
64
+ oxyServices.users.getUserById(userId).catch((err: any) => {
65
65
  console.error('getUserById error:', err);
66
66
  // If this is the current user and the API call fails, use current user data as fallback
67
67
  if (currentUser && currentUser.id === userId) {
@@ -70,8 +70,8 @@ const ProfileScreen: React.FC<ProfileScreenProps> = ({ userId, username, theme,
70
70
  }
71
71
  throw err;
72
72
  }),
73
- oxyServices.getUserKarmaTotal ?
74
- oxyServices.getUserKarmaTotal(userId).catch(err => {
73
+ oxyServices.karma.getUserKarmaTotal ?
74
+ oxyServices.karma.getUserKarmaTotal(userId).catch((err: any) => {
75
75
  console.warn('getUserKarmaTotal error:', err);
76
76
  return { total: undefined };
77
77
  }) :
@@ -16,7 +16,7 @@ import { fontFamilies } from '../styles/fonts';
16
16
  import { toast } from '../../lib/sonner';
17
17
  import { Ionicons } from '@expo/vector-icons';
18
18
  import OxyIcon from '../components/icon/OxyIcon';
19
- import { SecureClientSession } from '../../models/secureSession';
19
+ import { ClientSession } from '../../models/session';
20
20
  import { confirmAction } from '../utils/confirmAction';
21
21
  import { Header } from '../components';
22
22
 
@@ -189,7 +189,7 @@ const SessionManagementScreen: React.FC<BaseScreenProps> = ({
189
189
  >
190
190
  {userSessions.length > 0 ? (
191
191
  <>
192
- {userSessions.map((session: SecureClientSession) => (
192
+ {userSessions.map((session: ClientSession) => (
193
193
  <View
194
194
  key={session.sessionId}
195
195
  style={[
@@ -136,7 +136,7 @@ const SignInScreen: React.FC<BaseScreenProps> = ({
136
136
 
137
137
  try {
138
138
  // First check if username exists by trying to get profile
139
- const profile = await oxyServices.getUserProfileByUsername(usernameToValidate);
139
+ const profile = await oxyServices.users.getProfileByUsername(usernameToValidate);
140
140
 
141
141
  if (profile) {
142
142
  const profileData = {
@@ -38,8 +38,8 @@ const KarmaCenterScreen: React.FC<BaseScreenProps> = ({
38
38
  setIsLoading(true);
39
39
  setError(null);
40
40
  Promise.all([
41
- oxyServices.getUserKarmaTotal(user.id),
42
- oxyServices.getUserKarmaHistory(user.id, 20, 0),
41
+ oxyServices.karma.getUserKarmaTotal(user.id),
42
+ oxyServices.karma.getUserKarmaHistory(user.id, 20, 0),
43
43
  ])
44
44
  .then(([totalRes, historyRes]) => {
45
45
  setKarmaTotal(totalRes.total);
@@ -19,9 +19,9 @@ const KarmaLeaderboardScreen: React.FC<BaseScreenProps> = ({ goBack, theme, navi
19
19
  useEffect(() => {
20
20
  setIsLoading(true);
21
21
  setError(null);
22
- oxyServices.getKarmaLeaderboard()
23
- .then((data) => setLeaderboard(Array.isArray(data) ? data : []))
24
- .catch((err) => setError(err.message || 'Failed to load leaderboard'))
22
+ oxyServices.karma.getKarmaLeaderboard()
23
+ .then((data: any) => setLeaderboard(Array.isArray(data) ? data : []))
24
+ .catch((err: any) => setError(err.message || 'Failed to load leaderboard'))
25
25
  .finally(() => setIsLoading(false));
26
26
  }, [oxyServices]);
27
27
 
@@ -18,9 +18,9 @@ const KarmaRulesScreen: React.FC<BaseScreenProps> = ({ goBack, theme }) => {
18
18
  useEffect(() => {
19
19
  setIsLoading(true);
20
20
  setError(null);
21
- oxyServices.getKarmaRules()
22
- .then((data) => setRules(Array.isArray(data) ? data : []))
23
- .catch((err) => setError(err.message || 'Failed to load rules'))
21
+ oxyServices.karma.getKarmaRules()
22
+ .then((data: any) => setRules(Array.isArray(data) ? data : []))
23
+ .catch((err: any) => setError(err.message || 'Failed to load rules'))
24
24
  .finally(() => setIsLoading(false));
25
25
  }, [oxyServices]);
26
26
 
@@ -53,7 +53,7 @@ export const useFollowStore = create<FollowState>((set: any, get: any) => ({
53
53
  errors: { ...state.errors, [userId]: null },
54
54
  }));
55
55
  try {
56
- const response = await oxyServices.getFollowStatus(userId);
56
+ const response = await oxyServices.users.getFollowStatus(userId);
57
57
  set((state: FollowState) => ({
58
58
  followingUsers: { ...state.followingUsers, [userId]: response.isFollowing },
59
59
  fetchingUsers: { ...state.fetchingUsers, [userId]: false },
@@ -75,10 +75,10 @@ export const useFollowStore = create<FollowState>((set: any, get: any) => ({
75
75
  let response: any;
76
76
  let newFollowState;
77
77
  if (isCurrentlyFollowing) {
78
- response = await oxyServices.unfollowUser(userId);
78
+ response = await oxyServices.users.unfollowUser(userId);
79
79
  newFollowState = false;
80
80
  } else {
81
- response = await oxyServices.followUser(userId);
81
+ response = await oxyServices.users.followUser(userId);
82
82
  newFollowState = true;
83
83
  }
84
84
 
@@ -158,7 +158,7 @@ export const useFollowStore = create<FollowState>((set: any, get: any) => ({
158
158
  loadingCounts: { ...state.loadingCounts, [userId]: true },
159
159
  }));
160
160
  try {
161
- const user = await oxyServices.getUserById(userId);
161
+ const user = await oxyServices.users.getUserById(userId);
162
162
  if (user && user._count) {
163
163
  set((state: FollowState) => ({
164
164
  followerCounts: {
@@ -0,0 +1,102 @@
1
+ /**
2
+ * Utility functions for common API patterns
3
+ */
4
+
5
+ /**
6
+ * Build URL search parameters from an object
7
+ * @param params Object with parameter key-value pairs
8
+ * @returns URLSearchParams instance
9
+ */
10
+ export function buildSearchParams(params: Record<string, any>): URLSearchParams {
11
+ const searchParams = new URLSearchParams();
12
+
13
+ for (const [key, value] of Object.entries(params)) {
14
+ if (value !== undefined && value !== null) {
15
+ searchParams.append(key, value.toString());
16
+ }
17
+ }
18
+
19
+ return searchParams;
20
+ }
21
+
22
+ /**
23
+ * Build URL with search parameters
24
+ * @param baseUrl Base URL
25
+ * @param params Object with parameter key-value pairs
26
+ * @returns Complete URL with search parameters
27
+ */
28
+ export function buildUrl(baseUrl: string, params?: Record<string, any>): string {
29
+ if (!params) return baseUrl;
30
+
31
+ const searchParams = buildSearchParams(params);
32
+ const queryString = searchParams.toString();
33
+
34
+ return queryString ? `${baseUrl}?${queryString}` : baseUrl;
35
+ }
36
+
37
+ /**
38
+ * Common pagination parameters
39
+ */
40
+ export interface PaginationParams {
41
+ limit?: number;
42
+ offset?: number;
43
+ }
44
+
45
+ /**
46
+ * Build pagination search parameters
47
+ * @param params Pagination parameters
48
+ * @returns URLSearchParams with pagination
49
+ */
50
+ export function buildPaginationParams(params: PaginationParams): URLSearchParams {
51
+ return buildSearchParams(params);
52
+ }
53
+
54
+ /**
55
+ * Common API response wrapper
56
+ */
57
+ export interface ApiResponse<T = any> {
58
+ data: T;
59
+ message?: string;
60
+ success?: boolean;
61
+ }
62
+
63
+ /**
64
+ * Common error response wrapper
65
+ */
66
+ export interface ErrorResponse {
67
+ message: string;
68
+ code: string;
69
+ status: number;
70
+ details?: any;
71
+ }
72
+
73
+ /**
74
+ * Validate required parameters
75
+ * @param params Object to validate
76
+ * @param requiredKeys Array of required keys
77
+ * @throws Error if any required key is missing
78
+ */
79
+ export function validateRequiredParams(params: Record<string, any>, requiredKeys: string[]): void {
80
+ const missing = requiredKeys.filter(key => params[key] === undefined || params[key] === null);
81
+
82
+ if (missing.length > 0) {
83
+ throw new Error(`Missing required parameters: ${missing.join(', ')}`);
84
+ }
85
+ }
86
+
87
+ /**
88
+ * Safe JSON parsing with error handling
89
+ * @param data Data to parse
90
+ * @param fallback Fallback value if parsing fails
91
+ * @returns Parsed data or fallback
92
+ */
93
+ export function safeJsonParse<T>(data: any, fallback: T): T {
94
+ if (typeof data === 'string') {
95
+ try {
96
+ return JSON.parse(data);
97
+ } catch {
98
+ return fallback;
99
+ }
100
+ }
101
+ return data as T;
102
+ }