@oxyhq/services 5.2.4 → 5.2.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.
- package/lib/commonjs/ui/components/OxyProvider.js +22 -3
- package/lib/commonjs/ui/components/OxyProvider.js.map +1 -1
- package/lib/commonjs/ui/context/OxyContext.js +31 -3
- package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
- package/lib/commonjs/ui/navigation/OxyRouter.js +11 -2
- package/lib/commonjs/ui/navigation/OxyRouter.js.map +1 -1
- package/lib/module/ui/components/OxyProvider.js +22 -3
- package/lib/module/ui/components/OxyProvider.js.map +1 -1
- package/lib/module/ui/context/OxyContext.js +31 -3
- package/lib/module/ui/context/OxyContext.js.map +1 -1
- package/lib/module/ui/navigation/OxyRouter.js +11 -2
- package/lib/module/ui/navigation/OxyRouter.js.map +1 -1
- package/lib/typescript/ui/components/OxyProvider.d.ts.map +1 -1
- package/lib/typescript/ui/context/OxyContext.d.ts.map +1 -1
- package/lib/typescript/ui/navigation/OxyRouter.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/ui/components/OxyProvider.tsx +25 -3
- package/src/ui/context/OxyContext.tsx +32 -2
- package/src/ui/navigation/OxyRouter.tsx +14 -1
- package/lib/commonjs/ui/context/LegacyOxyContext.js +0 -643
- package/lib/commonjs/ui/context/LegacyOxyContext.js.map +0 -1
- package/lib/commonjs/ui/context/SecureOxyContext.js +0 -408
- package/lib/commonjs/ui/context/SecureOxyContext.js.map +0 -1
- package/lib/module/ui/context/LegacyOxyContext.js +0 -639
- package/lib/module/ui/context/LegacyOxyContext.js.map +0 -1
- package/lib/module/ui/context/SecureOxyContext.js +0 -403
- package/lib/module/ui/context/SecureOxyContext.js.map +0 -1
- package/lib/typescript/ui/context/LegacyOxyContext.d.ts +0 -40
- package/lib/typescript/ui/context/LegacyOxyContext.d.ts.map +0 -1
- package/lib/typescript/ui/context/SecureOxyContext.d.ts +0 -39
- package/lib/typescript/ui/context/SecureOxyContext.d.ts.map +0 -1
- package/src/ui/context/LegacyOxyContext.tsx +0 -735
- package/src/ui/context/SecureOxyContext.tsx +0 -473
|
@@ -1,473 +0,0 @@
|
|
|
1
|
-
import React, { createContext, useContext, useState, useEffect, useCallback, ReactNode, useMemo } from 'react';
|
|
2
|
-
import { OxyServices } from '../../core';
|
|
3
|
-
import { User } from '../../models/interfaces';
|
|
4
|
-
import { SecureLoginResponse, SecureClientSession, MinimalUserData } from '../../models/secureSession';
|
|
5
|
-
|
|
6
|
-
// Define the secure context shape
|
|
7
|
-
export interface SecureOxyContextState {
|
|
8
|
-
// Authentication state
|
|
9
|
-
user: User | null; // Current active user (loaded from server)
|
|
10
|
-
minimalUser: MinimalUserData | null; // Minimal user data for UI
|
|
11
|
-
sessions: SecureClientSession[]; // All active sessions
|
|
12
|
-
activeSessionId: string | null;
|
|
13
|
-
isAuthenticated: boolean;
|
|
14
|
-
isLoading: boolean;
|
|
15
|
-
error: string | null;
|
|
16
|
-
|
|
17
|
-
// Auth methods
|
|
18
|
-
secureLogin: (username: string, password: string, deviceName?: string) => Promise<User>;
|
|
19
|
-
logout: (targetSessionId?: string) => Promise<void>;
|
|
20
|
-
logoutAll: () => Promise<void>;
|
|
21
|
-
signUp: (username: string, email: string, password: string) => Promise<User>;
|
|
22
|
-
|
|
23
|
-
// Multi-session methods
|
|
24
|
-
switchSession: (sessionId: string) => Promise<void>;
|
|
25
|
-
removeSession: (sessionId: string) => Promise<void>;
|
|
26
|
-
refreshSessions: () => Promise<void>;
|
|
27
|
-
|
|
28
|
-
// Access to services
|
|
29
|
-
oxyServices: OxyServices;
|
|
30
|
-
bottomSheetRef?: React.RefObject<any>;
|
|
31
|
-
|
|
32
|
-
// Methods to directly control the bottom sheet
|
|
33
|
-
showBottomSheet?: (screenOrConfig?: string | { screen: string; props?: Record<string, any> }) => void;
|
|
34
|
-
hideBottomSheet?: () => void;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
// Create the context with default values
|
|
38
|
-
const SecureOxyContext = createContext<SecureOxyContextState | null>(null);
|
|
39
|
-
|
|
40
|
-
// Props for the SecureOxyContextProvider
|
|
41
|
-
export interface SecureOxyContextProviderProps {
|
|
42
|
-
children: ReactNode;
|
|
43
|
-
oxyServices: OxyServices;
|
|
44
|
-
storageKeyPrefix?: string;
|
|
45
|
-
onAuthStateChange?: (user: User | null) => void;
|
|
46
|
-
bottomSheetRef?: React.RefObject<any>;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// Platform storage implementation
|
|
50
|
-
interface StorageInterface {
|
|
51
|
-
getItem: (key: string) => Promise<string | null>;
|
|
52
|
-
setItem: (key: string, value: string) => Promise<void>;
|
|
53
|
-
removeItem: (key: string) => Promise<void>;
|
|
54
|
-
clear: () => Promise<void>;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
// Web localStorage implementation
|
|
58
|
-
class WebStorage implements StorageInterface {
|
|
59
|
-
async getItem(key: string): Promise<string | null> {
|
|
60
|
-
return localStorage.getItem(key);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
async setItem(key: string, value: string): Promise<void> {
|
|
64
|
-
localStorage.setItem(key, value);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
async removeItem(key: string): Promise<void> {
|
|
68
|
-
localStorage.removeItem(key);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
async clear(): Promise<void> {
|
|
72
|
-
localStorage.clear();
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// React Native AsyncStorage implementation
|
|
77
|
-
let AsyncStorage: StorageInterface;
|
|
78
|
-
|
|
79
|
-
// Determine the platform and set up storage
|
|
80
|
-
const isReactNative = (): boolean => {
|
|
81
|
-
return typeof navigator !== 'undefined' && navigator.product === 'ReactNative';
|
|
82
|
-
};
|
|
83
|
-
|
|
84
|
-
// Get appropriate storage for the platform
|
|
85
|
-
const getStorage = async (): Promise<StorageInterface> => {
|
|
86
|
-
if (isReactNative()) {
|
|
87
|
-
if (!AsyncStorage) {
|
|
88
|
-
try {
|
|
89
|
-
const asyncStorageModule = await import('@react-native-async-storage/async-storage');
|
|
90
|
-
AsyncStorage = asyncStorageModule.default;
|
|
91
|
-
} catch (error) {
|
|
92
|
-
console.error('Failed to import AsyncStorage:', error);
|
|
93
|
-
throw new Error('AsyncStorage is required in React Native environment');
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
return AsyncStorage;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
return new WebStorage();
|
|
100
|
-
};
|
|
101
|
-
|
|
102
|
-
// Storage keys for secure sessions
|
|
103
|
-
const getSecureStorageKeys = (prefix = 'oxy_secure') => ({
|
|
104
|
-
sessions: `${prefix}_sessions`, // Array of SecureClientSession objects
|
|
105
|
-
activeSessionId: `${prefix}_active_session_id`, // ID of currently active session
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
export const SecureOxyContextProvider: React.FC<SecureOxyContextProviderProps> = ({
|
|
109
|
-
children,
|
|
110
|
-
oxyServices,
|
|
111
|
-
storageKeyPrefix = 'oxy_secure',
|
|
112
|
-
onAuthStateChange,
|
|
113
|
-
bottomSheetRef,
|
|
114
|
-
}) => {
|
|
115
|
-
// Authentication state
|
|
116
|
-
const [user, setUser] = useState<User | null>(null);
|
|
117
|
-
const [minimalUser, setMinimalUser] = useState<MinimalUserData | null>(null);
|
|
118
|
-
const [sessions, setSessions] = useState<SecureClientSession[]>([]);
|
|
119
|
-
const [activeSessionId, setActiveSessionId] = useState<string | null>(null);
|
|
120
|
-
const [isLoading, setIsLoading] = useState(true);
|
|
121
|
-
const [error, setError] = useState<string | null>(null);
|
|
122
|
-
const [storage, setStorage] = useState<StorageInterface | null>(null);
|
|
123
|
-
|
|
124
|
-
// Storage keys (memoized to prevent infinite loops)
|
|
125
|
-
const keys = useMemo(() => getSecureStorageKeys(storageKeyPrefix), [storageKeyPrefix]);
|
|
126
|
-
|
|
127
|
-
// Initialize storage
|
|
128
|
-
useEffect(() => {
|
|
129
|
-
const initStorage = async () => {
|
|
130
|
-
try {
|
|
131
|
-
const platformStorage = await getStorage();
|
|
132
|
-
setStorage(platformStorage);
|
|
133
|
-
} catch (error) {
|
|
134
|
-
console.error('Failed to initialize storage:', error);
|
|
135
|
-
setError('Failed to initialize storage');
|
|
136
|
-
}
|
|
137
|
-
};
|
|
138
|
-
|
|
139
|
-
initStorage();
|
|
140
|
-
}, []);
|
|
141
|
-
|
|
142
|
-
// Effect to initialize authentication state
|
|
143
|
-
useEffect(() => {
|
|
144
|
-
const initAuth = async () => {
|
|
145
|
-
if (!storage) return;
|
|
146
|
-
|
|
147
|
-
setIsLoading(true);
|
|
148
|
-
try {
|
|
149
|
-
// Load stored sessions
|
|
150
|
-
const sessionsData = await storage.getItem(keys.sessions);
|
|
151
|
-
const storedActiveSessionId = await storage.getItem(keys.activeSessionId);
|
|
152
|
-
|
|
153
|
-
console.log('SecureAuth - sessionsData:', sessionsData);
|
|
154
|
-
console.log('SecureAuth - activeSessionId:', storedActiveSessionId);
|
|
155
|
-
|
|
156
|
-
if (sessionsData) {
|
|
157
|
-
const parsedSessions: SecureClientSession[] = JSON.parse(sessionsData);
|
|
158
|
-
setSessions(parsedSessions);
|
|
159
|
-
|
|
160
|
-
if (storedActiveSessionId && parsedSessions.length > 0) {
|
|
161
|
-
const activeSession = parsedSessions.find(s => s.sessionId === storedActiveSessionId);
|
|
162
|
-
|
|
163
|
-
if (activeSession) {
|
|
164
|
-
console.log('SecureAuth - activeSession found:', activeSession);
|
|
165
|
-
|
|
166
|
-
// Validate session
|
|
167
|
-
try {
|
|
168
|
-
const validation = await oxyServices.validateSession(activeSession.sessionId);
|
|
169
|
-
|
|
170
|
-
if (validation.valid) {
|
|
171
|
-
console.log('SecureAuth - session validated successfully');
|
|
172
|
-
setActiveSessionId(activeSession.sessionId);
|
|
173
|
-
|
|
174
|
-
// Get access token for API calls
|
|
175
|
-
await oxyServices.getTokenBySession(activeSession.sessionId);
|
|
176
|
-
|
|
177
|
-
// Load full user data
|
|
178
|
-
const fullUser = await oxyServices.getUserBySession(activeSession.sessionId);
|
|
179
|
-
setUser(fullUser);
|
|
180
|
-
setMinimalUser({
|
|
181
|
-
id: fullUser.id,
|
|
182
|
-
username: fullUser.username,
|
|
183
|
-
avatar: fullUser.avatar
|
|
184
|
-
});
|
|
185
|
-
|
|
186
|
-
if (onAuthStateChange) {
|
|
187
|
-
onAuthStateChange(fullUser);
|
|
188
|
-
}
|
|
189
|
-
} else {
|
|
190
|
-
console.log('SecureAuth - session invalid, removing');
|
|
191
|
-
await removeInvalidSession(activeSession.sessionId);
|
|
192
|
-
}
|
|
193
|
-
} catch (error) {
|
|
194
|
-
console.error('SecureAuth - session validation error:', error);
|
|
195
|
-
await removeInvalidSession(activeSession.sessionId);
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
} catch (err) {
|
|
201
|
-
console.error('Secure auth initialization error:', err);
|
|
202
|
-
await clearAllStorage();
|
|
203
|
-
} finally {
|
|
204
|
-
setIsLoading(false);
|
|
205
|
-
}
|
|
206
|
-
};
|
|
207
|
-
|
|
208
|
-
if (storage) {
|
|
209
|
-
initAuth();
|
|
210
|
-
}
|
|
211
|
-
}, [storage, oxyServices, keys, onAuthStateChange]);
|
|
212
|
-
|
|
213
|
-
// Remove invalid session
|
|
214
|
-
const removeInvalidSession = useCallback(async (sessionId: string): Promise<void> => {
|
|
215
|
-
const filteredSessions = sessions.filter(s => s.sessionId !== sessionId);
|
|
216
|
-
setSessions(filteredSessions);
|
|
217
|
-
await saveSessionsToStorage(filteredSessions);
|
|
218
|
-
|
|
219
|
-
// If there are other sessions, switch to the first one
|
|
220
|
-
if (filteredSessions.length > 0) {
|
|
221
|
-
await switchToSession(filteredSessions[0].sessionId);
|
|
222
|
-
} else {
|
|
223
|
-
// No valid sessions left
|
|
224
|
-
setActiveSessionId(null);
|
|
225
|
-
setUser(null);
|
|
226
|
-
setMinimalUser(null);
|
|
227
|
-
await storage?.removeItem(keys.activeSessionId);
|
|
228
|
-
|
|
229
|
-
if (onAuthStateChange) {
|
|
230
|
-
onAuthStateChange(null);
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
}, [sessions, storage, keys, onAuthStateChange]);
|
|
234
|
-
|
|
235
|
-
// Save sessions to storage
|
|
236
|
-
const saveSessionsToStorage = useCallback(async (sessionsList: SecureClientSession[]): Promise<void> => {
|
|
237
|
-
if (!storage) return;
|
|
238
|
-
await storage.setItem(keys.sessions, JSON.stringify(sessionsList));
|
|
239
|
-
}, [storage, keys.sessions]);
|
|
240
|
-
|
|
241
|
-
// Save active session ID to storage
|
|
242
|
-
const saveActiveSessionId = useCallback(async (sessionId: string): Promise<void> => {
|
|
243
|
-
if (!storage) return;
|
|
244
|
-
await storage.setItem(keys.activeSessionId, sessionId);
|
|
245
|
-
}, [storage, keys.activeSessionId]);
|
|
246
|
-
|
|
247
|
-
// Clear all storage
|
|
248
|
-
const clearAllStorage = useCallback(async (): Promise<void> => {
|
|
249
|
-
if (!storage) return;
|
|
250
|
-
try {
|
|
251
|
-
await storage.removeItem(keys.sessions);
|
|
252
|
-
await storage.removeItem(keys.activeSessionId);
|
|
253
|
-
} catch (err) {
|
|
254
|
-
console.error('Clear secure storage error:', err);
|
|
255
|
-
}
|
|
256
|
-
}, [storage, keys]);
|
|
257
|
-
|
|
258
|
-
// Switch to a different session
|
|
259
|
-
const switchToSession = useCallback(async (sessionId: string): Promise<void> => {
|
|
260
|
-
try {
|
|
261
|
-
setIsLoading(true);
|
|
262
|
-
|
|
263
|
-
// Get access token for this session
|
|
264
|
-
await oxyServices.getTokenBySession(sessionId);
|
|
265
|
-
|
|
266
|
-
// Load full user data
|
|
267
|
-
const fullUser = await oxyServices.getUserBySession(sessionId);
|
|
268
|
-
|
|
269
|
-
setActiveSessionId(sessionId);
|
|
270
|
-
setUser(fullUser);
|
|
271
|
-
setMinimalUser({
|
|
272
|
-
id: fullUser.id,
|
|
273
|
-
username: fullUser.username,
|
|
274
|
-
avatar: fullUser.avatar
|
|
275
|
-
});
|
|
276
|
-
|
|
277
|
-
await saveActiveSessionId(sessionId);
|
|
278
|
-
|
|
279
|
-
if (onAuthStateChange) {
|
|
280
|
-
onAuthStateChange(fullUser);
|
|
281
|
-
}
|
|
282
|
-
} catch (error) {
|
|
283
|
-
console.error('Switch session error:', error);
|
|
284
|
-
setError('Failed to switch session');
|
|
285
|
-
} finally {
|
|
286
|
-
setIsLoading(false);
|
|
287
|
-
}
|
|
288
|
-
}, [oxyServices, onAuthStateChange, saveActiveSessionId]);
|
|
289
|
-
|
|
290
|
-
// Secure login method
|
|
291
|
-
const secureLogin = async (username: string, password: string, deviceName?: string): Promise<User> => {
|
|
292
|
-
if (!storage) throw new Error('Storage not initialized');
|
|
293
|
-
|
|
294
|
-
setIsLoading(true);
|
|
295
|
-
setError(null);
|
|
296
|
-
|
|
297
|
-
try {
|
|
298
|
-
const response: SecureLoginResponse = await oxyServices.secureLogin(username, password, deviceName);
|
|
299
|
-
|
|
300
|
-
// Create client session object
|
|
301
|
-
const clientSession: SecureClientSession = {
|
|
302
|
-
sessionId: response.sessionId,
|
|
303
|
-
deviceId: response.deviceId,
|
|
304
|
-
expiresAt: response.expiresAt,
|
|
305
|
-
lastActive: new Date().toISOString()
|
|
306
|
-
};
|
|
307
|
-
|
|
308
|
-
// Add to sessions list
|
|
309
|
-
const updatedSessions = [...sessions, clientSession];
|
|
310
|
-
setSessions(updatedSessions);
|
|
311
|
-
await saveSessionsToStorage(updatedSessions);
|
|
312
|
-
|
|
313
|
-
// Set as active session
|
|
314
|
-
setActiveSessionId(response.sessionId);
|
|
315
|
-
await saveActiveSessionId(response.sessionId);
|
|
316
|
-
|
|
317
|
-
// Get access token for API calls
|
|
318
|
-
await oxyServices.getTokenBySession(response.sessionId);
|
|
319
|
-
|
|
320
|
-
// Load full user data
|
|
321
|
-
const fullUser = await oxyServices.getUserBySession(response.sessionId);
|
|
322
|
-
setUser(fullUser);
|
|
323
|
-
setMinimalUser(response.user);
|
|
324
|
-
|
|
325
|
-
if (onAuthStateChange) {
|
|
326
|
-
onAuthStateChange(fullUser);
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
return fullUser;
|
|
330
|
-
} catch (error: any) {
|
|
331
|
-
setError(error.message || 'Login failed');
|
|
332
|
-
throw error;
|
|
333
|
-
} finally {
|
|
334
|
-
setIsLoading(false);
|
|
335
|
-
}
|
|
336
|
-
};
|
|
337
|
-
|
|
338
|
-
// Logout method
|
|
339
|
-
const logout = async (targetSessionId?: string): Promise<void> => {
|
|
340
|
-
if (!activeSessionId) return;
|
|
341
|
-
|
|
342
|
-
try {
|
|
343
|
-
const sessionToLogout = targetSessionId || activeSessionId;
|
|
344
|
-
await oxyServices.logoutSecureSession(activeSessionId, sessionToLogout);
|
|
345
|
-
|
|
346
|
-
// Remove session from local storage
|
|
347
|
-
const filteredSessions = sessions.filter(s => s.sessionId !== sessionToLogout);
|
|
348
|
-
setSessions(filteredSessions);
|
|
349
|
-
await saveSessionsToStorage(filteredSessions);
|
|
350
|
-
|
|
351
|
-
// If logging out active session
|
|
352
|
-
if (sessionToLogout === activeSessionId) {
|
|
353
|
-
if (filteredSessions.length > 0) {
|
|
354
|
-
// Switch to another session
|
|
355
|
-
await switchToSession(filteredSessions[0].sessionId);
|
|
356
|
-
} else {
|
|
357
|
-
// No sessions left
|
|
358
|
-
setActiveSessionId(null);
|
|
359
|
-
setUser(null);
|
|
360
|
-
setMinimalUser(null);
|
|
361
|
-
await storage?.removeItem(keys.activeSessionId);
|
|
362
|
-
|
|
363
|
-
if (onAuthStateChange) {
|
|
364
|
-
onAuthStateChange(null);
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
} catch (error) {
|
|
369
|
-
console.error('Logout error:', error);
|
|
370
|
-
setError('Logout failed');
|
|
371
|
-
}
|
|
372
|
-
};
|
|
373
|
-
|
|
374
|
-
// Logout all sessions
|
|
375
|
-
const logoutAll = async (): Promise<void> => {
|
|
376
|
-
if (!activeSessionId) return;
|
|
377
|
-
|
|
378
|
-
try {
|
|
379
|
-
await oxyServices.logoutAllSecureSessions(activeSessionId);
|
|
380
|
-
|
|
381
|
-
// Clear all local data
|
|
382
|
-
setSessions([]);
|
|
383
|
-
setActiveSessionId(null);
|
|
384
|
-
setUser(null);
|
|
385
|
-
setMinimalUser(null);
|
|
386
|
-
await clearAllStorage();
|
|
387
|
-
|
|
388
|
-
if (onAuthStateChange) {
|
|
389
|
-
onAuthStateChange(null);
|
|
390
|
-
}
|
|
391
|
-
} catch (error) {
|
|
392
|
-
console.error('Logout all error:', error);
|
|
393
|
-
setError('Logout all failed');
|
|
394
|
-
}
|
|
395
|
-
};
|
|
396
|
-
|
|
397
|
-
// Sign up method (placeholder - you can implement based on your needs)
|
|
398
|
-
const signUp = async (username: string, email: string, password: string): Promise<User> => {
|
|
399
|
-
// Implement sign up logic similar to secureLogin
|
|
400
|
-
throw new Error('Sign up not implemented yet');
|
|
401
|
-
};
|
|
402
|
-
|
|
403
|
-
// Switch session method
|
|
404
|
-
const switchSession = async (sessionId: string): Promise<void> => {
|
|
405
|
-
await switchToSession(sessionId);
|
|
406
|
-
};
|
|
407
|
-
|
|
408
|
-
// Remove session method
|
|
409
|
-
const removeSession = async (sessionId: string): Promise<void> => {
|
|
410
|
-
await logout(sessionId);
|
|
411
|
-
};
|
|
412
|
-
|
|
413
|
-
// Refresh sessions method
|
|
414
|
-
const refreshSessions = async (): Promise<void> => {
|
|
415
|
-
if (!activeSessionId) return;
|
|
416
|
-
|
|
417
|
-
try {
|
|
418
|
-
const serverSessions = await oxyServices.getSessionsBySessionId(activeSessionId);
|
|
419
|
-
|
|
420
|
-
// Update local sessions with server data
|
|
421
|
-
const updatedSessions: SecureClientSession[] = serverSessions.map(serverSession => ({
|
|
422
|
-
sessionId: serverSession.sessionId,
|
|
423
|
-
deviceId: serverSession.deviceId,
|
|
424
|
-
expiresAt: new Date().toISOString(), // You might want to get this from server
|
|
425
|
-
lastActive: new Date().toISOString()
|
|
426
|
-
}));
|
|
427
|
-
|
|
428
|
-
setSessions(updatedSessions);
|
|
429
|
-
await saveSessionsToStorage(updatedSessions);
|
|
430
|
-
} catch (error) {
|
|
431
|
-
console.error('Refresh sessions error:', error);
|
|
432
|
-
}
|
|
433
|
-
};
|
|
434
|
-
|
|
435
|
-
// Context value
|
|
436
|
-
const contextValue: SecureOxyContextState = {
|
|
437
|
-
user,
|
|
438
|
-
minimalUser,
|
|
439
|
-
sessions,
|
|
440
|
-
activeSessionId,
|
|
441
|
-
isAuthenticated: !!user,
|
|
442
|
-
isLoading,
|
|
443
|
-
error,
|
|
444
|
-
secureLogin,
|
|
445
|
-
logout,
|
|
446
|
-
logoutAll,
|
|
447
|
-
signUp,
|
|
448
|
-
switchSession,
|
|
449
|
-
removeSession,
|
|
450
|
-
refreshSessions,
|
|
451
|
-
oxyServices,
|
|
452
|
-
bottomSheetRef,
|
|
453
|
-
showBottomSheet: undefined, // Implement as needed
|
|
454
|
-
hideBottomSheet: undefined, // Implement as needed
|
|
455
|
-
};
|
|
456
|
-
|
|
457
|
-
return (
|
|
458
|
-
<SecureOxyContext.Provider value={contextValue}>
|
|
459
|
-
{children}
|
|
460
|
-
</SecureOxyContext.Provider>
|
|
461
|
-
);
|
|
462
|
-
};
|
|
463
|
-
|
|
464
|
-
// Hook to use the secure context
|
|
465
|
-
export const useSecureOxyContext = (): SecureOxyContextState => {
|
|
466
|
-
const context = useContext(SecureOxyContext);
|
|
467
|
-
if (!context) {
|
|
468
|
-
throw new Error('useSecureOxyContext must be used within a SecureOxyContextProvider');
|
|
469
|
-
}
|
|
470
|
-
return context;
|
|
471
|
-
};
|
|
472
|
-
|
|
473
|
-
export default SecureOxyContext;
|