@oxyhq/services 5.5.4 → 5.5.6

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 (32) hide show
  1. package/lib/commonjs/core/AuthManager.js +352 -0
  2. package/lib/commonjs/core/AuthManager.js.map +1 -0
  3. package/lib/commonjs/core/index.js +13 -2
  4. package/lib/commonjs/core/index.js.map +1 -1
  5. package/lib/commonjs/ui/context/OxyContext.js +87 -456
  6. package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
  7. package/lib/commonjs/ui/hooks/useAuthFetch.js +22 -60
  8. package/lib/commonjs/ui/hooks/useAuthFetch.js.map +1 -1
  9. package/lib/commonjs/ui/screens/SessionManagementScreen.js.map +1 -1
  10. package/lib/module/core/AuthManager.js +347 -0
  11. package/lib/module/core/AuthManager.js.map +1 -0
  12. package/lib/module/core/index.js +6 -2
  13. package/lib/module/core/index.js.map +1 -1
  14. package/lib/module/ui/context/OxyContext.js +87 -456
  15. package/lib/module/ui/context/OxyContext.js.map +1 -1
  16. package/lib/module/ui/hooks/useAuthFetch.js +22 -60
  17. package/lib/module/ui/hooks/useAuthFetch.js.map +1 -1
  18. package/lib/module/ui/screens/SessionManagementScreen.js.map +1 -1
  19. package/lib/typescript/core/AuthManager.d.ts +100 -0
  20. package/lib/typescript/core/AuthManager.d.ts.map +1 -0
  21. package/lib/typescript/core/index.d.ts +6 -2
  22. package/lib/typescript/core/index.d.ts.map +1 -1
  23. package/lib/typescript/ui/context/OxyContext.d.ts +7 -10
  24. package/lib/typescript/ui/context/OxyContext.d.ts.map +1 -1
  25. package/lib/typescript/ui/hooks/useAuthFetch.d.ts +4 -9
  26. package/lib/typescript/ui/hooks/useAuthFetch.d.ts.map +1 -1
  27. package/package.json +1 -1
  28. package/src/core/AuthManager.ts +366 -0
  29. package/src/core/index.ts +7 -2
  30. package/src/ui/context/OxyContext.tsx +99 -508
  31. package/src/ui/hooks/useAuthFetch.ts +22 -60
  32. package/src/ui/screens/SessionManagementScreen.tsx +9 -9
@@ -1,18 +1,14 @@
1
1
  "use strict";
2
2
 
3
3
  import React, { createContext, useContext, useState, useEffect, useCallback, useMemo } from 'react';
4
- import { DeviceManager } from '../../utils/deviceManager';
4
+ import { AuthManager } from '../../core/AuthManager';
5
5
 
6
- // Define the context shape
6
+ // Context interface with session management support
7
7
  import { jsx as _jsx } from "react/jsx-runtime";
8
- // Create the context with default values
9
8
  const OxyContext = /*#__PURE__*/createContext(null);
10
9
 
11
- // Props for the OxyContextProvider
10
+ // Storage implementation
12
11
 
13
- // Platform storage implementation
14
-
15
- // Web localStorage implementation
16
12
  class WebStorage {
17
13
  async getItem(key) {
18
14
  return localStorage.getItem(key);
@@ -27,16 +23,10 @@ class WebStorage {
27
23
  localStorage.clear();
28
24
  }
29
25
  }
30
-
31
- // React Native AsyncStorage implementation
32
26
  let AsyncStorage;
33
-
34
- // Determine the platform and set up storage
35
27
  const isReactNative = () => {
36
28
  return typeof navigator !== 'undefined' && navigator.product === 'ReactNative';
37
29
  };
38
-
39
- // Get appropriate storage for the platform
40
30
  const getStorage = async () => {
41
31
  if (isReactNative()) {
42
32
  if (!AsyncStorage) {
@@ -52,13 +42,6 @@ const getStorage = async () => {
52
42
  }
53
43
  return new WebStorage();
54
44
  };
55
-
56
- // Storage keys for secure sessions
57
- const getSecureStorageKeys = (prefix = 'oxy_secure') => ({
58
- sessions: `${prefix}_sessions`,
59
- // Array of SecureClientSession objects
60
- activeSessionId: `${prefix}_active_session_id` // ID of currently active session
61
- });
62
45
  export const OxyContextProvider = ({
63
46
  children,
64
47
  oxyServices,
@@ -66,17 +49,29 @@ export const OxyContextProvider = ({
66
49
  onAuthStateChange,
67
50
  bottomSheetRef
68
51
  }) => {
69
- // Authentication state
70
- const [user, setUser] = useState(null);
71
- const [minimalUser, setMinimalUser] = useState(null);
72
- const [sessions, setSessions] = useState([]);
73
- const [activeSessionId, setActiveSessionId] = useState(null);
74
- const [isLoading, setIsLoading] = useState(true);
75
- const [error, setError] = useState(null);
76
52
  const [storage, setStorage] = useState(null);
53
+ const [authState, setAuthState] = useState({
54
+ isAuthenticated: false,
55
+ accessToken: null,
56
+ user: null,
57
+ activeSessionId: null,
58
+ sessions: [],
59
+ isLoading: true,
60
+ error: null
61
+ });
77
62
 
78
- // Storage keys (memoized to prevent infinite loops)
79
- const keys = useMemo(() => getSecureStorageKeys(storageKeyPrefix), [storageKeyPrefix]);
63
+ // Create AuthManager instance
64
+ const authManager = useMemo(() => {
65
+ return new AuthManager({
66
+ oxyServices,
67
+ onStateChange: newState => {
68
+ setAuthState(newState);
69
+ if (onAuthStateChange) {
70
+ onAuthStateChange(newState.user);
71
+ }
72
+ }
73
+ });
74
+ }, [oxyServices, onAuthStateChange]);
80
75
 
81
76
  // Initialize storage
82
77
  useEffect(() => {
@@ -86,449 +81,102 @@ export const OxyContextProvider = ({
86
81
  setStorage(platformStorage);
87
82
  } catch (error) {
88
83
  console.error('Failed to initialize storage:', error);
89
- setError('Failed to initialize storage');
84
+ setAuthState(prev => ({
85
+ ...prev,
86
+ error: 'Failed to initialize storage',
87
+ isLoading: false
88
+ }));
90
89
  }
91
90
  };
92
91
  initStorage();
93
92
  }, []);
94
93
 
95
- // Effect to initialize authentication state
94
+ // Initialize authentication
96
95
  useEffect(() => {
97
96
  const initAuth = async () => {
98
97
  if (!storage) return;
99
- setIsLoading(true);
100
98
  try {
101
- // Load stored sessions
102
- const sessionsData = await storage.getItem(keys.sessions);
103
- const storedActiveSessionId = await storage.getItem(keys.activeSessionId);
104
- console.log('SecureAuth - sessionsData:', sessionsData);
105
- console.log('SecureAuth - activeSessionId:', storedActiveSessionId);
106
- if (sessionsData) {
107
- const parsedSessions = JSON.parse(sessionsData);
108
-
109
- // Migrate old session format to include user info
110
- const migratedSessions = [];
111
- let shouldUpdateStorage = false;
112
- for (const session of parsedSessions) {
113
- if (!session.userId || !session.username) {
114
- // Session is missing user info, try to fetch it
115
- try {
116
- const sessionUser = await oxyServices.getUserBySession(session.sessionId);
117
- migratedSessions.push({
118
- ...session,
119
- userId: sessionUser.id,
120
- username: sessionUser.username
121
- });
122
- shouldUpdateStorage = true;
123
- console.log(`Migrated session ${session.sessionId} for user ${sessionUser.username}`);
124
- } catch (error) {
125
- // Session might be invalid, skip it
126
- console.log(`Removing invalid session ${session.sessionId}:`, error);
127
- shouldUpdateStorage = true;
128
- }
129
- } else {
130
- // Session already has user info
131
- migratedSessions.push(session);
132
- }
133
- }
134
-
135
- // Update storage if we made changes
136
- if (shouldUpdateStorage) {
137
- await saveSessionsToStorage(migratedSessions);
138
- }
139
- setSessions(migratedSessions);
140
- if (storedActiveSessionId && migratedSessions.length > 0) {
141
- const activeSession = migratedSessions.find(s => s.sessionId === storedActiveSessionId);
142
- if (activeSession) {
143
- console.log('SecureAuth - activeSession found:', activeSession);
144
-
145
- // Validate session
146
- try {
147
- const validation = await oxyServices.validateSession(activeSession.sessionId);
148
- if (validation.valid) {
149
- console.log('SecureAuth - session validated successfully');
150
- setActiveSessionId(activeSession.sessionId);
151
-
152
- // Get access token for API calls
153
- await oxyServices.getTokenBySession(activeSession.sessionId);
154
-
155
- // Load full user data
156
- const fullUser = await oxyServices.getUserBySession(activeSession.sessionId);
157
- setUser(fullUser);
158
- setMinimalUser({
159
- id: fullUser.id,
160
- username: fullUser.username,
161
- avatar: fullUser.avatar
162
- });
163
- if (onAuthStateChange) {
164
- onAuthStateChange(fullUser);
165
- }
166
- } else {
167
- console.log('SecureAuth - session invalid, removing');
168
- await removeInvalidSession(activeSession.sessionId);
169
- }
170
- } catch (error) {
171
- console.error('SecureAuth - session validation error:', error);
172
- await removeInvalidSession(activeSession.sessionId);
173
- }
174
- }
175
- }
176
- }
177
- } catch (err) {
178
- console.error('Secure auth initialization error:', err);
179
- await clearAllStorage();
180
- } finally {
181
- setIsLoading(false);
99
+ const activeSessionId = await storage.getItem(`${storageKeyPrefix}_active_session_id`);
100
+ await authManager.initialize(activeSessionId);
101
+ } catch (error) {
102
+ console.error('Auth initialization failed:', error);
103
+ await storage.removeItem(`${storageKeyPrefix}_active_session_id`);
182
104
  }
183
105
  };
184
106
  if (storage) {
185
107
  initAuth();
186
108
  }
187
- }, [storage, oxyServices, keys, onAuthStateChange]);
109
+ }, [storage, authManager, storageKeyPrefix]);
188
110
 
189
- // Remove invalid session
190
- const removeInvalidSession = useCallback(async sessionId => {
191
- const filteredSessions = sessions.filter(s => s.sessionId !== sessionId);
192
- setSessions(filteredSessions);
193
- await saveSessionsToStorage(filteredSessions);
111
+ // Auth methods that integrate with storage
112
+ const login = useCallback(async (username, password, deviceName) => {
113
+ await authManager.login(username, password, deviceName);
194
114
 
195
- // If there are other sessions, switch to the first one
196
- if (filteredSessions.length > 0) {
197
- await switchToSession(filteredSessions[0].sessionId);
198
- } else {
199
- // No valid sessions left
200
- setActiveSessionId(null);
201
- setUser(null);
202
- setMinimalUser(null);
203
- await storage?.removeItem(keys.activeSessionId);
204
- if (onAuthStateChange) {
205
- onAuthStateChange(null);
206
- }
115
+ // Save session ID to storage
116
+ const sessionId = authManager.getActiveSessionId();
117
+ if (sessionId && storage) {
118
+ await storage.setItem(`${storageKeyPrefix}_active_session_id`, sessionId);
207
119
  }
208
- }, [sessions, storage, keys, onAuthStateChange]);
209
-
210
- // Save sessions to storage
211
- const saveSessionsToStorage = useCallback(async sessionsList => {
212
- if (!storage) return;
213
- await storage.setItem(keys.sessions, JSON.stringify(sessionsList));
214
- }, [storage, keys.sessions]);
215
-
216
- // Save active session ID to storage
217
- const saveActiveSessionId = useCallback(async sessionId => {
218
- if (!storage) return;
219
- await storage.setItem(keys.activeSessionId, sessionId);
220
- }, [storage, keys.activeSessionId]);
120
+ return authManager.getCurrentUser();
121
+ }, [authManager, storage, storageKeyPrefix]);
122
+ const logout = useCallback(async targetSessionId => {
123
+ await authManager.logout(targetSessionId);
221
124
 
222
- // Clear all storage
223
- const clearAllStorage = useCallback(async () => {
224
- if (!storage) return;
225
- try {
226
- await storage.removeItem(keys.sessions);
227
- await storage.removeItem(keys.activeSessionId);
228
- } catch (err) {
229
- console.error('Clear secure storage error:', err);
125
+ // Clear from storage if logging out current session
126
+ if (!targetSessionId && storage) {
127
+ await storage.removeItem(`${storageKeyPrefix}_active_session_id`);
230
128
  }
231
- }, [storage, keys]);
232
-
233
- // Switch to a different session
234
- const switchToSession = useCallback(async sessionId => {
235
- try {
236
- setIsLoading(true);
237
-
238
- // Get access token for this session
239
- await oxyServices.getTokenBySession(sessionId);
240
-
241
- // Load full user data
242
- const fullUser = await oxyServices.getUserBySession(sessionId);
243
- setActiveSessionId(sessionId);
244
- setUser(fullUser);
245
- setMinimalUser({
246
- id: fullUser.id,
247
- username: fullUser.username,
248
- avatar: fullUser.avatar
249
- });
250
- await saveActiveSessionId(sessionId);
251
- if (onAuthStateChange) {
252
- onAuthStateChange(fullUser);
253
- }
254
- } catch (error) {
255
- console.error('Switch session error:', error);
256
- setError('Failed to switch session');
257
- } finally {
258
- setIsLoading(false);
259
- }
260
- }, [oxyServices, onAuthStateChange, saveActiveSessionId]);
261
-
262
- // Secure login method
263
- const login = async (username, password, deviceName) => {
264
- if (!storage) throw new Error('Storage not initialized');
265
- setIsLoading(true);
266
- setError(null);
267
- try {
268
- // Get device fingerprint for enhanced device identification
269
- const deviceFingerprint = DeviceManager.getDeviceFingerprint();
270
-
271
- // Get or generate persistent device info
272
- const deviceInfo = await DeviceManager.getDeviceInfo();
273
- console.log('SecureAuth - Using device fingerprint:', deviceFingerprint);
274
- console.log('SecureAuth - Using device ID:', deviceInfo.deviceId);
275
- const response = await oxyServices.secureLogin(username, password, deviceName || deviceInfo.deviceName || DeviceManager.getDefaultDeviceName(), deviceFingerprint);
276
-
277
- // Create client session object with user info for duplicate detection
278
- const clientSession = {
279
- sessionId: response.sessionId,
280
- deviceId: response.deviceId,
281
- expiresAt: response.expiresAt,
282
- lastActive: new Date().toISOString(),
283
- userId: response.user.id,
284
- username: response.user.username
285
- };
286
-
287
- // Check if this user already has a session (prevent duplicate accounts)
288
- const existingUserSessionIndex = sessions.findIndex(s => s.userId === response.user.id || s.username === response.user.username);
289
- let updatedSessions;
290
- if (existingUserSessionIndex !== -1) {
291
- // User already has a session - replace it with the new one (reused session scenario)
292
- const existingSession = sessions[existingUserSessionIndex];
293
- updatedSessions = [...sessions];
294
- updatedSessions[existingUserSessionIndex] = clientSession;
295
- console.log(`Reusing/updating existing session for user ${response.user.username}. Previous session: ${existingSession.sessionId}, New session: ${response.sessionId}`);
296
-
297
- // If the replaced session was the active one, update active session
298
- if (activeSessionId === existingSession.sessionId) {
299
- setActiveSessionId(response.sessionId);
300
- await saveActiveSessionId(response.sessionId);
301
- }
302
- } else {
303
- // Add new session for new user
304
- updatedSessions = [...sessions, clientSession];
305
- console.log(`Added new session for user ${response.user.username} on device ${response.deviceId}`);
306
- }
307
- setSessions(updatedSessions);
308
- await saveSessionsToStorage(updatedSessions);
309
-
310
- // Set as active session
311
- setActiveSessionId(response.sessionId);
312
- await saveActiveSessionId(response.sessionId);
313
-
314
- // Get access token for API calls
315
- await oxyServices.getTokenBySession(response.sessionId);
316
-
317
- // Load full user data
318
- const fullUser = await oxyServices.getUserBySession(response.sessionId);
319
- setUser(fullUser);
320
- setMinimalUser(response.user);
321
- if (onAuthStateChange) {
322
- onAuthStateChange(fullUser);
323
- }
324
- return fullUser;
325
- } catch (error) {
326
- setError(error.message || 'Login failed');
327
- throw error;
328
- } finally {
329
- setIsLoading(false);
330
- }
331
- };
332
-
333
- // Logout method
334
- const logout = async targetSessionId => {
335
- if (!activeSessionId) return;
336
- try {
337
- const sessionToLogout = targetSessionId || activeSessionId;
338
- await oxyServices.logoutSecureSession(activeSessionId, sessionToLogout);
339
-
340
- // Remove session from local storage
341
- const filteredSessions = sessions.filter(s => s.sessionId !== sessionToLogout);
342
- setSessions(filteredSessions);
343
- await saveSessionsToStorage(filteredSessions);
129
+ }, [authManager, storage, storageKeyPrefix]);
130
+ const refreshSessions = useCallback(async () => {
131
+ await authManager.refreshSessions();
132
+ }, [authManager]);
133
+ const switchSession = useCallback(async sessionId => {
134
+ await authManager.switchSession(sessionId);
344
135
 
345
- // If logging out active session
346
- if (sessionToLogout === activeSessionId) {
347
- if (filteredSessions.length > 0) {
348
- // Switch to another session
349
- await switchToSession(filteredSessions[0].sessionId);
350
- } else {
351
- // No sessions left
352
- setActiveSessionId(null);
353
- setUser(null);
354
- setMinimalUser(null);
355
- await storage?.removeItem(keys.activeSessionId);
356
- if (onAuthStateChange) {
357
- onAuthStateChange(null);
358
- }
359
- }
360
- }
361
- } catch (error) {
362
- console.error('Logout error:', error);
363
- setError('Logout failed');
364
- }
365
- };
366
-
367
- // Logout all sessions
368
- const logoutAll = async () => {
369
- console.log('logoutAll called with activeSessionId:', activeSessionId);
370
- if (!activeSessionId) {
371
- console.error('No active session ID found, cannot logout all');
372
- setError('No active session found');
373
- throw new Error('No active session found');
374
- }
375
- if (!oxyServices) {
376
- console.error('OxyServices not initialized');
377
- setError('Service not available');
378
- throw new Error('Service not available');
379
- }
380
- try {
381
- console.log('Calling oxyServices.logoutAllSecureSessions with sessionId:', activeSessionId);
382
- await oxyServices.logoutAllSecureSessions(activeSessionId);
383
- console.log('logoutAllSecureSessions completed successfully');
384
-
385
- // Clear all local data
386
- setSessions([]);
387
- setActiveSessionId(null);
388
- setUser(null);
389
- setMinimalUser(null);
390
- await clearAllStorage();
391
- console.log('Local storage cleared');
392
- if (onAuthStateChange) {
393
- onAuthStateChange(null);
394
- console.log('Auth state change callback called');
395
- }
396
- } catch (error) {
397
- console.error('Logout all error:', error);
398
- setError(`Logout all failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
399
- throw error;
400
- }
401
- };
402
-
403
- // Sign up method
404
- const signUp = async (username, email, password) => {
405
- if (!storage) throw new Error('Storage not initialized');
406
- setIsLoading(true);
407
- setError(null);
408
- try {
409
- // Create new account using the OxyServices signUp method
410
- const response = await oxyServices.signUp(username, email, password);
411
- console.log('SignUp successful:', response);
412
-
413
- // Now log the user in securely to create a session
414
- // This will handle the session creation and device registration
415
- const user = await login(username, password);
416
- return user;
417
- } catch (error) {
418
- setError(error.message || 'Sign up failed');
419
- throw error;
420
- } finally {
421
- setIsLoading(false);
422
- }
423
- };
424
-
425
- // Switch session method
426
- const switchSession = async sessionId => {
427
- await switchToSession(sessionId);
428
- };
429
-
430
- // Remove session method
431
- const removeSession = async sessionId => {
432
- await logout(sessionId);
433
- };
434
-
435
- // Refresh sessions method
436
- const refreshSessions = async () => {
437
- if (!activeSessionId) return;
438
- try {
439
- const serverSessions = await oxyServices.getSessionsBySessionId(activeSessionId);
440
-
441
- // Update local sessions with server data
442
- const updatedSessions = serverSessions.map(serverSession => ({
443
- sessionId: serverSession.sessionId,
444
- deviceId: serverSession.deviceId,
445
- expiresAt: new Date().toISOString(),
446
- // You might want to get this from server
447
- lastActive: new Date().toISOString()
448
- }));
449
- setSessions(updatedSessions);
450
- await saveSessionsToStorage(updatedSessions);
451
- } catch (error) {
452
- console.error('Refresh sessions error:', error);
453
- }
454
- };
455
-
456
- // Device management methods
457
- const getDeviceSessions = async () => {
458
- if (!activeSessionId) throw new Error('No active session');
459
- try {
460
- return await oxyServices.getDeviceSessions(activeSessionId);
461
- } catch (error) {
462
- console.error('Get device sessions error:', error);
463
- throw error;
136
+ // Update storage with new active session
137
+ if (storage) {
138
+ await storage.setItem(`${storageKeyPrefix}_active_session_id`, sessionId);
464
139
  }
465
- };
466
- const logoutAllDeviceSessions = async () => {
467
- if (!activeSessionId) throw new Error('No active session');
468
- try {
469
- await oxyServices.logoutAllDeviceSessions(activeSessionId);
140
+ }, [authManager, storage, storageKeyPrefix]);
141
+ const removeSession = useCallback(async sessionId => {
142
+ await authManager.removeSession(sessionId);
143
+ }, [authManager]);
144
+ const logoutAll = useCallback(async () => {
145
+ await authManager.logoutAll();
470
146
 
471
- // Clear all local sessions since we logged out from all devices
472
- setSessions([]);
473
- setActiveSessionId(null);
474
- setUser(null);
475
- setMinimalUser(null);
476
- await clearAllStorage();
477
- if (onAuthStateChange) {
478
- onAuthStateChange(null);
479
- }
480
- } catch (error) {
481
- console.error('Logout all device sessions error:', error);
482
- throw error;
147
+ // Clear from storage
148
+ if (storage) {
149
+ await storage.removeItem(`${storageKeyPrefix}_active_session_id`);
483
150
  }
484
- };
485
- const updateDeviceName = async deviceName => {
486
- if (!activeSessionId) throw new Error('No active session');
487
- try {
488
- await oxyServices.updateDeviceName(activeSessionId, deviceName);
151
+ }, [authManager, storage, storageKeyPrefix]);
152
+ const signUp = useCallback(async (username, email, password) => {
153
+ await authManager.signUp(username, email, password);
489
154
 
490
- // Update local device info
491
- await DeviceManager.updateDeviceName(deviceName);
492
- } catch (error) {
493
- console.error('Update device name error:', error);
494
- throw error;
155
+ // Save session ID to storage after auto-login
156
+ const sessionId = authManager.getActiveSessionId();
157
+ if (sessionId && storage) {
158
+ await storage.setItem(`${storageKeyPrefix}_active_session_id`, sessionId);
495
159
  }
496
- };
160
+ return authManager.getCurrentUser();
161
+ }, [authManager, storage, storageKeyPrefix]);
497
162
 
498
- // Bottom sheet control methods
163
+ // Bottom sheet controls
499
164
  const showBottomSheet = useCallback(screenOrConfig => {
500
- console.log('showBottomSheet called with:', screenOrConfig);
501
165
  if (bottomSheetRef?.current) {
502
- console.log('bottomSheetRef is available');
503
-
504
- // First, show the bottom sheet
505
166
  if (bottomSheetRef.current.expand) {
506
- console.log('Expanding bottom sheet');
507
167
  bottomSheetRef.current.expand();
508
168
  } else if (bottomSheetRef.current.present) {
509
- console.log('Presenting bottom sheet');
510
169
  bottomSheetRef.current.present();
511
- } else {
512
- console.warn('No expand or present method available on bottomSheetRef');
513
170
  }
514
-
515
- // Then navigate to the specified screen if provided
516
171
  if (screenOrConfig) {
517
- // Add a small delay to ensure the bottom sheet is opened first
518
172
  setTimeout(() => {
519
173
  if (typeof screenOrConfig === 'string') {
520
- // Simple screen name
521
- console.log('Navigating to screen:', screenOrConfig);
522
174
  bottomSheetRef.current?._navigateToScreen?.(screenOrConfig);
523
175
  } else {
524
- // Screen with props
525
- console.log('Navigating to screen with props:', screenOrConfig.screen, screenOrConfig.props);
526
176
  bottomSheetRef.current?._navigateToScreen?.(screenOrConfig.screen, screenOrConfig.props);
527
177
  }
528
178
  }, 100);
529
179
  }
530
- } else {
531
- console.warn('bottomSheetRef is not available');
532
180
  }
533
181
  }, [bottomSheetRef]);
534
182
  const hideBottomSheet = useCallback(() => {
@@ -536,37 +184,22 @@ export const OxyContextProvider = ({
536
184
  bottomSheetRef.current.dismiss?.();
537
185
  }
538
186
  }, [bottomSheetRef]);
539
-
540
- // Compute comprehensive authentication status
541
- // This is the single source of truth for authentication across the entire app
542
- const isAuthenticated = useMemo(() => {
543
- // User is authenticated if:
544
- // 1. We have a full user object loaded, OR
545
- // 2. We have an active session with a valid token
546
- // This covers both the loaded state and the loading-but-authenticated state
547
- return !!user || !!activeSessionId && !!oxyServices?.getCurrentUserId();
548
- }, [user, activeSessionId, oxyServices]);
549
-
550
- // Context value
551
187
  const contextValue = {
552
- user,
553
- minimalUser,
554
- sessions,
555
- activeSessionId,
556
- isAuthenticated,
557
- isLoading,
558
- error,
188
+ isAuthenticated: authState.isAuthenticated,
189
+ user: authState.user,
190
+ isLoading: authState.isLoading,
191
+ error: authState.error,
192
+ sessions: authState.sessions,
193
+ activeSessionId: authState.activeSessionId,
559
194
  login,
560
195
  logout,
561
- logoutAll,
562
196
  signUp,
197
+ refreshSessions,
563
198
  switchSession,
564
199
  removeSession,
565
- refreshSessions,
566
- getDeviceSessions,
567
- logoutAllDeviceSessions,
568
- updateDeviceName,
200
+ logoutAll,
569
201
  oxyServices,
202
+ authManager,
570
203
  bottomSheetRef,
571
204
  showBottomSheet,
572
205
  hideBottomSheet
@@ -576,8 +209,6 @@ export const OxyContextProvider = ({
576
209
  children: children
577
210
  });
578
211
  };
579
-
580
- // Hook to use the context
581
212
  export const useOxy = () => {
582
213
  const context = useContext(OxyContext);
583
214
  if (!context) {