@oxyhq/services 5.16.32 → 5.16.34
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/README.md +26 -8
- package/lib/commonjs/core/OxyServices.base.js.map +1 -1
- package/lib/commonjs/core/mixins/OxyServices.user.js.map +1 -1
- package/lib/commonjs/core/mixins/OxyServices.utility.js.map +1 -1
- package/lib/commonjs/core/services/AuthService.js +156 -0
- package/lib/commonjs/core/services/AuthService.js.map +1 -0
- package/lib/commonjs/core/services/SessionService.js +1 -2
- package/lib/commonjs/core/services/SessionService.js.map +1 -1
- package/lib/commonjs/core/services/SessionTransportService.js +64 -0
- package/lib/commonjs/core/services/SessionTransportService.js.map +1 -0
- package/lib/commonjs/core/services/TokenService.js +9 -17
- package/lib/commonjs/core/services/TokenService.js.map +1 -1
- package/lib/commonjs/core/services/UserService.js +123 -0
- package/lib/commonjs/core/services/UserService.js.map +1 -0
- package/lib/commonjs/core/services/index.js +34 -0
- package/lib/commonjs/core/services/index.js.map +1 -0
- package/lib/commonjs/crypto/index.js.map +1 -1
- package/lib/commonjs/crypto/keyManager.js +5 -2
- package/lib/commonjs/crypto/keyManager.js.map +1 -1
- package/lib/commonjs/crypto/signatureService.js +36 -121
- package/lib/commonjs/crypto/signatureService.js.map +1 -1
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/models/interfaces.js +11 -11
- package/lib/commonjs/models/interfaces.js.map +1 -1
- package/lib/commonjs/ui/context/OxyContext.js +4 -40
- package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
- package/lib/commonjs/ui/context/hooks/useAuthOperations.js +14 -25
- package/lib/commonjs/ui/context/hooks/useAuthOperations.js.map +1 -1
- package/lib/commonjs/ui/context/hooks/useLanguageManagement.js.map +1 -1
- package/lib/commonjs/ui/hooks/queries/useServicesQueries.js +4 -12
- package/lib/commonjs/ui/hooks/queries/useServicesQueries.js.map +1 -1
- package/lib/commonjs/ui/hooks/useLanguageManagement.js.map +1 -1
- package/lib/commonjs/ui/hooks/useSessionManagement.js +0 -8
- package/lib/commonjs/ui/hooks/useSessionManagement.js.map +1 -1
- package/lib/commonjs/ui/index.js +2 -0
- package/lib/commonjs/ui/index.js.map +1 -1
- package/lib/commonjs/ui/screens/AccountSettingsScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/OxyAuthScreen.js +9 -13
- package/lib/commonjs/ui/screens/OxyAuthScreen.js.map +1 -1
- package/lib/commonjs/ui/utils/sessionHelpers.js +11 -26
- package/lib/commonjs/ui/utils/sessionHelpers.js.map +1 -1
- package/lib/commonjs/utils/sessionUtils.js +1 -8
- package/lib/commonjs/utils/sessionUtils.js.map +1 -1
- package/lib/module/core/OxyServices.base.js.map +1 -1
- package/lib/module/core/mixins/OxyServices.user.js.map +1 -1
- package/lib/module/core/mixins/OxyServices.utility.js.map +1 -1
- package/lib/module/core/services/AuthService.js +151 -0
- package/lib/module/core/services/AuthService.js.map +1 -0
- package/lib/module/core/services/SessionService.js +1 -2
- package/lib/module/core/services/SessionService.js.map +1 -1
- package/lib/module/core/services/SessionTransportService.js +59 -0
- package/lib/module/core/services/SessionTransportService.js.map +1 -0
- package/lib/module/core/services/TokenService.js +9 -17
- package/lib/module/core/services/TokenService.js.map +1 -1
- package/lib/module/core/services/UserService.js +118 -0
- package/lib/module/core/services/UserService.js.map +1 -0
- package/lib/module/core/services/index.js +16 -0
- package/lib/module/core/services/index.js.map +1 -0
- package/lib/module/crypto/index.js +9 -0
- package/lib/module/crypto/index.js.map +1 -1
- package/lib/module/crypto/keyManager.js +5 -2
- package/lib/module/crypto/keyManager.js.map +1 -1
- package/lib/module/crypto/signatureService.js +36 -122
- package/lib/module/crypto/signatureService.js.map +1 -1
- package/lib/module/index.js +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/models/interfaces.js +11 -11
- package/lib/module/models/interfaces.js.map +1 -1
- package/lib/module/ui/context/OxyContext.js +4 -40
- package/lib/module/ui/context/OxyContext.js.map +1 -1
- package/lib/module/ui/context/hooks/useAuthOperations.js +14 -25
- package/lib/module/ui/context/hooks/useAuthOperations.js.map +1 -1
- package/lib/module/ui/context/hooks/useLanguageManagement.js.map +1 -1
- package/lib/module/ui/hooks/queries/useServicesQueries.js +5 -13
- package/lib/module/ui/hooks/queries/useServicesQueries.js.map +1 -1
- package/lib/module/ui/hooks/useLanguageManagement.js.map +1 -1
- package/lib/module/ui/hooks/useSessionManagement.js +0 -8
- package/lib/module/ui/hooks/useSessionManagement.js.map +1 -1
- package/lib/module/ui/index.js +1 -0
- package/lib/module/ui/index.js.map +1 -1
- package/lib/module/ui/screens/AccountSettingsScreen.js.map +1 -1
- package/lib/module/ui/screens/OxyAuthScreen.js +7 -9
- package/lib/module/ui/screens/OxyAuthScreen.js.map +1 -1
- package/lib/module/ui/utils/sessionHelpers.js +11 -26
- package/lib/module/ui/utils/sessionHelpers.js.map +1 -1
- package/lib/module/utils/sessionUtils.js +1 -8
- package/lib/module/utils/sessionUtils.js.map +1 -1
- package/lib/typescript/core/OxyServices.base.d.ts.map +1 -1
- package/lib/typescript/core/mixins/OxyServices.analytics.d.ts.map +1 -1
- package/lib/typescript/core/mixins/OxyServices.assets.d.ts.map +1 -1
- package/lib/typescript/core/mixins/OxyServices.auth.d.ts +1 -1
- package/lib/typescript/core/mixins/OxyServices.auth.d.ts.map +1 -1
- package/lib/typescript/core/mixins/OxyServices.developer.d.ts.map +1 -1
- package/lib/typescript/core/mixins/OxyServices.devices.d.ts.map +1 -1
- package/lib/typescript/core/mixins/OxyServices.karma.d.ts.map +1 -1
- package/lib/typescript/core/mixins/OxyServices.language.d.ts.map +1 -1
- package/lib/typescript/core/mixins/OxyServices.location.d.ts.map +1 -1
- package/lib/typescript/core/mixins/OxyServices.payment.d.ts.map +1 -1
- package/lib/typescript/core/mixins/OxyServices.privacy.d.ts.map +1 -1
- package/lib/typescript/core/mixins/OxyServices.security.d.ts.map +1 -1
- package/lib/typescript/core/mixins/OxyServices.user.d.ts +2 -1
- package/lib/typescript/core/mixins/OxyServices.user.d.ts.map +1 -1
- package/lib/typescript/core/mixins/OxyServices.utility.d.ts.map +1 -1
- package/lib/typescript/core/mixins/index.d.ts +13 -13
- package/lib/typescript/core/mixins/index.d.ts.map +1 -1
- package/lib/typescript/core/services/AuthService.d.ts +50 -0
- package/lib/typescript/core/services/AuthService.d.ts.map +1 -0
- package/lib/typescript/core/services/SessionService.d.ts +3 -5
- package/lib/typescript/core/services/SessionService.d.ts.map +1 -1
- package/lib/typescript/core/services/SessionTransportService.d.ts +31 -0
- package/lib/typescript/core/services/SessionTransportService.d.ts.map +1 -0
- package/lib/typescript/core/services/TokenService.d.ts +3 -8
- package/lib/typescript/core/services/TokenService.d.ts.map +1 -1
- package/lib/typescript/core/services/UserService.d.ts +39 -0
- package/lib/typescript/core/services/UserService.d.ts.map +1 -0
- package/lib/typescript/core/services/index.d.ts +13 -0
- package/lib/typescript/core/services/index.d.ts.map +1 -0
- package/lib/typescript/crypto/index.d.ts +9 -0
- package/lib/typescript/crypto/index.d.ts.map +1 -1
- package/lib/typescript/crypto/keyManager.d.ts.map +1 -1
- package/lib/typescript/crypto/signatureService.d.ts +10 -13
- package/lib/typescript/crypto/signatureService.d.ts.map +1 -1
- package/lib/typescript/index.d.ts +1 -1
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/models/interfaces.d.ts +15 -69
- package/lib/typescript/models/interfaces.d.ts.map +1 -1
- package/lib/typescript/models/session.d.ts +2 -4
- package/lib/typescript/models/session.d.ts.map +1 -1
- package/lib/typescript/ui/context/OxyContext.d.ts +2 -1
- package/lib/typescript/ui/context/OxyContext.d.ts.map +1 -1
- package/lib/typescript/ui/context/hooks/useAuthOperations.d.ts +2 -1
- package/lib/typescript/ui/context/hooks/useAuthOperations.d.ts.map +1 -1
- package/lib/typescript/ui/context/hooks/useLanguageManagement.d.ts +2 -1
- package/lib/typescript/ui/context/hooks/useLanguageManagement.d.ts.map +1 -1
- package/lib/typescript/ui/hooks/mutations/useAccountMutations.d.ts +1 -1
- package/lib/typescript/ui/hooks/mutations/useAccountMutations.d.ts.map +1 -1
- package/lib/typescript/ui/hooks/queries/useAccountQueries.d.ts +1 -1
- package/lib/typescript/ui/hooks/queries/useAccountQueries.d.ts.map +1 -1
- package/lib/typescript/ui/hooks/queries/useServicesQueries.d.ts.map +1 -1
- package/lib/typescript/ui/hooks/useLanguageManagement.d.ts +2 -1
- package/lib/typescript/ui/hooks/useLanguageManagement.d.ts.map +1 -1
- package/lib/typescript/ui/hooks/useSessionManagement.d.ts +2 -1
- package/lib/typescript/ui/hooks/useSessionManagement.d.ts.map +1 -1
- package/lib/typescript/ui/index.d.ts +1 -1
- package/lib/typescript/ui/index.d.ts.map +1 -1
- package/lib/typescript/ui/screens/OxyAuthScreen.d.ts.map +1 -1
- package/lib/typescript/ui/stores/authStore.d.ts +1 -1
- package/lib/typescript/ui/stores/authStore.d.ts.map +1 -1
- package/lib/typescript/ui/utils/avatarUtils.d.ts +1 -1
- package/lib/typescript/ui/utils/avatarUtils.d.ts.map +1 -1
- package/lib/typescript/ui/utils/sessionHelpers.d.ts +2 -6
- package/lib/typescript/ui/utils/sessionHelpers.d.ts.map +1 -1
- package/lib/typescript/utils/sessionUtils.d.ts.map +1 -1
- package/package.json +2 -1
- package/src/core/OxyServices.base.ts +2 -1
- package/src/core/mixins/OxyServices.auth.ts +1 -1
- package/src/core/mixins/OxyServices.user.ts +2 -1
- package/src/core/mixins/OxyServices.utility.ts +2 -1
- package/src/core/services/AuthService.ts +153 -0
- package/src/core/services/SessionService.ts +3 -5
- package/src/core/services/SessionTransportService.ts +69 -0
- package/src/core/services/TokenService.ts +10 -18
- package/src/core/services/UserService.ts +125 -0
- package/src/core/services/index.ts +14 -0
- package/src/crypto/index.ts +9 -0
- package/src/crypto/keyManager.ts +3 -2
- package/src/crypto/signatureService.ts +44 -142
- package/src/index.ts +1 -2
- package/src/models/interfaces.ts +21 -74
- package/src/models/session.ts +3 -5
- package/src/ui/context/OxyContext.tsx +22 -57
- package/src/ui/context/hooks/useAuthOperations.ts +17 -24
- package/src/ui/context/hooks/useLanguageManagement.ts +2 -1
- package/src/ui/hooks/auth/index.ts +0 -1
- package/src/ui/hooks/mutations/useAccountMutations.ts +1 -1
- package/src/ui/hooks/mutations/useServicesMutations.ts +1 -1
- package/src/ui/hooks/queries/useAccountQueries.ts +1 -1
- package/src/ui/hooks/queries/useServicesQueries.ts +3 -8
- package/src/ui/hooks/useLanguageManagement.ts +2 -1
- package/src/ui/hooks/useSessionManagement.ts +3 -9
- package/src/ui/index.ts +2 -1
- package/src/ui/screens/AccountSettingsScreen.tsx +6 -6
- package/src/ui/screens/AccountSwitcherScreen.tsx +1 -1
- package/src/ui/screens/OxyAuthScreen.tsx +5 -9
- package/src/ui/screens/ProfileScreen.tsx +1 -1
- package/src/ui/stores/authStore.ts +1 -1
- package/src/ui/types/navigation.ts +1 -1
- package/src/ui/utils/avatarUtils.ts +1 -1
- package/src/ui/utils/sessionHelpers.ts +15 -32
- package/src/utils/sessionUtils.ts +1 -8
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { useCallback } from 'react';
|
|
2
|
-
import type { ApiError
|
|
2
|
+
import type { ApiError } from '../../../models/interfaces';
|
|
3
|
+
import type { User } from '@oxyhq/shared';
|
|
3
4
|
import type { AuthState } from '../../stores/authStore';
|
|
4
5
|
import type { ClientSession, SessionLoginResponse } from '../../../models/session';
|
|
5
6
|
import { DeviceManager } from '../../../utils/deviceManager';
|
|
@@ -146,9 +147,9 @@ export const useAuthOperations = ({
|
|
|
146
147
|
const localDeviceId = `device_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
147
148
|
const expiresAt = new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString(); // 7 days
|
|
148
149
|
|
|
149
|
-
// Create minimal user object with publicKey as id
|
|
150
|
+
// Create minimal user object with publicKey as id
|
|
150
151
|
fullUser = {
|
|
151
|
-
id: publicKey, // publicKey
|
|
152
|
+
id: publicKey, // Use publicKey as id (per migration document)
|
|
152
153
|
publicKey,
|
|
153
154
|
username: '',
|
|
154
155
|
privacySettings: {},
|
|
@@ -170,7 +171,7 @@ export const useAuthOperations = ({
|
|
|
170
171
|
deviceId: localDeviceId,
|
|
171
172
|
expiresAt,
|
|
172
173
|
lastActive: new Date().toISOString(),
|
|
173
|
-
publicKey,
|
|
174
|
+
userId: publicKey,
|
|
174
175
|
isCurrent: true,
|
|
175
176
|
};
|
|
176
177
|
|
|
@@ -204,10 +205,17 @@ export const useAuthOperations = ({
|
|
|
204
205
|
// Get full user data
|
|
205
206
|
fullUser = await oxyServices.getUserBySession(sessionResponse.sessionId);
|
|
206
207
|
|
|
207
|
-
// user.id
|
|
208
|
-
//
|
|
209
|
-
|
|
210
|
-
|
|
208
|
+
// IMPORTANT: user.id should be MongoDB ObjectId, not publicKey
|
|
209
|
+
// The API should return the correct id (ObjectId) from the database
|
|
210
|
+
// If it doesn't, we need to fix the API, not work around it here
|
|
211
|
+
// Validate that id is ObjectId format (24 hex characters)
|
|
212
|
+
if (fullUser.id && !/^[0-9a-fA-F]{24}$/.test(fullUser.id)) {
|
|
213
|
+
console.warn('[useAuthOperations] User.id is not MongoDB ObjectId format:', {
|
|
214
|
+
id: fullUser.id.substring(0, 20),
|
|
215
|
+
publicKey: fullUser.publicKey.substring(0, 20),
|
|
216
|
+
message: 'API should return MongoDB ObjectId as user.id, not publicKey'
|
|
217
|
+
});
|
|
218
|
+
// Don't override - let the API fix this issue
|
|
211
219
|
}
|
|
212
220
|
|
|
213
221
|
// Fetch device sessions
|
|
@@ -215,8 +223,7 @@ export const useAuthOperations = ({
|
|
|
215
223
|
try {
|
|
216
224
|
allDeviceSessions = await fetchSessionsWithFallback(oxyServices, sessionResponse.sessionId, {
|
|
217
225
|
fallbackDeviceId: sessionResponse.deviceId,
|
|
218
|
-
fallbackUserId: fullUser.id,
|
|
219
|
-
fallbackPublicKey: fullUser.publicKey || fullUser.id, // publicKey is canonical identity
|
|
226
|
+
fallbackUserId: fullUser.id,
|
|
220
227
|
logger,
|
|
221
228
|
});
|
|
222
229
|
} catch (error) {
|
|
@@ -286,13 +293,6 @@ export const useAuthOperations = ({
|
|
|
286
293
|
setAuthState({ isLoading: true, error: null });
|
|
287
294
|
|
|
288
295
|
try {
|
|
289
|
-
// SESSION CLEANUP: Clear all sessions before creating new identity
|
|
290
|
-
// New identity means old sessions are no longer valid
|
|
291
|
-
await clearSessionState();
|
|
292
|
-
if (__DEV__ && logger) {
|
|
293
|
-
logger('Cleared all sessions before creating new identity');
|
|
294
|
-
}
|
|
295
|
-
|
|
296
296
|
// Generate new key pair directly (works offline)
|
|
297
297
|
const { publicKey, privateKey } = await KeyManager.generateKeyPair();
|
|
298
298
|
await KeyManager.importKeyPair(privateKey);
|
|
@@ -464,13 +464,6 @@ export const useAuthOperations = ({
|
|
|
464
464
|
setAuthState({ isLoading: true, error: null });
|
|
465
465
|
|
|
466
466
|
try {
|
|
467
|
-
// SESSION CLEANUP: Clear all sessions before importing new identity
|
|
468
|
-
// Importing a different identity means old sessions are no longer valid
|
|
469
|
-
await clearSessionState();
|
|
470
|
-
if (__DEV__ && logger) {
|
|
471
|
-
logger('Cleared all sessions before importing identity');
|
|
472
|
-
}
|
|
473
|
-
|
|
474
467
|
// Decrypt private key from backup data
|
|
475
468
|
const Crypto = await import('expo-crypto');
|
|
476
469
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { useCallback, useEffect, useMemo, useState } from 'react';
|
|
2
|
-
import type { ApiError
|
|
2
|
+
import type { ApiError } from '../../../models/interfaces';
|
|
3
|
+
import type { User } from '@oxyhq/shared';
|
|
3
4
|
import {
|
|
4
5
|
getLanguageMetadata,
|
|
5
6
|
getLanguageName,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
|
2
|
-
import type { User } from '
|
|
2
|
+
import type { User } from '@oxyhq/shared';
|
|
3
3
|
import { queryKeys, invalidateAccountQueries, invalidateUserQueries } from '../queries/queryKeys';
|
|
4
4
|
import { useOxy } from '../../context/OxyContext';
|
|
5
5
|
import { toast } from '../../../lib/sonner';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
|
2
|
-
import type { User } from '
|
|
2
|
+
import type { User } from '@oxyhq/shared';
|
|
3
3
|
import { queryKeys, invalidateSessionQueries } from '../queries/queryKeys';
|
|
4
4
|
import { useOxy } from '../../context/OxyContext';
|
|
5
5
|
import { toast } from '../../../lib/sonner';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useQuery, useQueries } from '@tanstack/react-query';
|
|
2
|
-
import type { User } from '
|
|
2
|
+
import type { User } from '@oxyhq/shared';
|
|
3
3
|
import type { OxyServices } from '../../../core';
|
|
4
4
|
import { queryKeys } from './queryKeys';
|
|
5
5
|
import { useOxy } from '../../context/OxyContext';
|
|
@@ -8,7 +8,7 @@ import { fetchSessionsWithFallback, mapSessionsToClient } from '../../utils/sess
|
|
|
8
8
|
* Get all active sessions for the current user
|
|
9
9
|
*/
|
|
10
10
|
export const useSessions = (userId?: string, options?: { enabled?: boolean }) => {
|
|
11
|
-
const { oxyServices, activeSessionId
|
|
11
|
+
const { oxyServices, activeSessionId } = useOxy();
|
|
12
12
|
|
|
13
13
|
return useQuery({
|
|
14
14
|
queryKey: queryKeys.sessions.list(userId),
|
|
@@ -17,14 +17,12 @@ export const useSessions = (userId?: string, options?: { enabled?: boolean }) =>
|
|
|
17
17
|
throw new Error('No active session');
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
const publicKey = user?.publicKey || user?.id || ''; // user.id is now publicKey
|
|
21
20
|
const sessions = await fetchSessionsWithFallback(oxyServices, activeSessionId, {
|
|
22
21
|
fallbackDeviceId: undefined,
|
|
23
22
|
fallbackUserId: userId,
|
|
24
|
-
fallbackPublicKey: publicKey,
|
|
25
23
|
});
|
|
26
24
|
|
|
27
|
-
return sessions;
|
|
25
|
+
return mapSessionsToClient(sessions, activeSessionId);
|
|
28
26
|
},
|
|
29
27
|
enabled: (options?.enabled !== false) && !!activeSessionId,
|
|
30
28
|
staleTime: 2 * 60 * 1000, // 2 minutes (sessions change frequently)
|
|
@@ -51,15 +49,12 @@ export const useSession = (sessionId: string | null, options?: { enabled?: boole
|
|
|
51
49
|
}
|
|
52
50
|
|
|
53
51
|
const now = new Date();
|
|
54
|
-
// user.id is now publicKey (canonical identity)
|
|
55
|
-
const publicKey = validation.user.publicKey || validation.user.id || '';
|
|
56
52
|
return {
|
|
57
53
|
sessionId,
|
|
58
54
|
deviceId: '', // Device ID not available from validation response
|
|
59
55
|
expiresAt: validation.expiresAt || new Date(now.getTime() + 7 * 24 * 60 * 60 * 1000).toISOString(),
|
|
60
56
|
lastActive: validation.lastActivity || now.toISOString(),
|
|
61
|
-
|
|
62
|
-
userId: validation.user.id?.toString(), // Optional MongoDB ObjectId
|
|
57
|
+
userId: validation.user.id?.toString() ?? '',
|
|
63
58
|
isCurrent: false,
|
|
64
59
|
} as ClientSession;
|
|
65
60
|
},
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { useCallback, useEffect, useMemo, useState } from 'react';
|
|
2
|
-
import type { ApiError
|
|
2
|
+
import type { ApiError } from '../../models/interfaces';
|
|
3
|
+
import type { User } from '@oxyhq/shared';
|
|
3
4
|
import {
|
|
4
5
|
getLanguageMetadata,
|
|
5
6
|
getLanguageName,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { useCallback, useMemo, useRef, useState } from 'react';
|
|
2
|
-
import type { ApiError
|
|
2
|
+
import type { ApiError } from '../../models/interfaces';
|
|
3
|
+
import type { User } from '@oxyhq/shared';
|
|
3
4
|
import type { ClientSession } from '../../models/session';
|
|
4
5
|
import { mergeSessions, normalizeAndSortSessions, sessionsArraysEqual } from '../../utils/sessionUtils';
|
|
5
6
|
import { fetchSessionsWithFallback, mapSessionsToClient, validateSessionBatch } from '../utils/sessionHelpers';
|
|
@@ -255,10 +256,8 @@ export const useSessionManagement = ({
|
|
|
255
256
|
await activateSession(sessionId, user);
|
|
256
257
|
|
|
257
258
|
try {
|
|
258
|
-
const publicKey = user.publicKey || user.id || ''; // user.id is now publicKey
|
|
259
259
|
const deviceSessions = await fetchSessionsWithFallback(oxyServices, sessionId, {
|
|
260
|
-
fallbackUserId: user.id,
|
|
261
|
-
fallbackPublicKey: publicKey,
|
|
260
|
+
fallbackUserId: user.id,
|
|
262
261
|
logger,
|
|
263
262
|
});
|
|
264
263
|
updateSessions(deviceSessions, { merge: true });
|
|
@@ -332,13 +331,8 @@ export const useSessionManagement = ({
|
|
|
332
331
|
|
|
333
332
|
const refreshPromise = (async () => {
|
|
334
333
|
try {
|
|
335
|
-
// Get publicKey from active session or current user
|
|
336
|
-
const activeSession = sessions.find(s => s.sessionId === activeSessionId);
|
|
337
|
-
const publicKey = activeSession?.publicKey || activeUserId || ''; // Fallback to userId if publicKey not available
|
|
338
|
-
|
|
339
334
|
const deviceSessions = await fetchSessionsWithFallback(oxyServices, activeSessionId, {
|
|
340
335
|
fallbackUserId: activeUserId,
|
|
341
|
-
fallbackPublicKey: publicKey,
|
|
342
336
|
logger,
|
|
343
337
|
});
|
|
344
338
|
updateSessions(deviceSessions, { merge: true });
|
package/src/ui/index.ts
CHANGED
|
@@ -81,4 +81,5 @@ export {
|
|
|
81
81
|
|
|
82
82
|
// Re-export core services for convenience in UI context
|
|
83
83
|
export { OxyServices } from '../core';
|
|
84
|
-
|
|
84
|
+
// Note: User and LoginResponse should be imported from @oxyhq/shared
|
|
85
|
+
export type { ApiError } from '../models/interfaces';
|
|
@@ -233,7 +233,7 @@ const AccountSettingsScreen: React.FC<BaseScreenProps & { initialField?: string;
|
|
|
233
233
|
|
|
234
234
|
// Handle locations - convert single location to array format
|
|
235
235
|
if (finalUser.locations && Array.isArray(finalUser.locations)) {
|
|
236
|
-
setLocations(finalUser.locations.map((loc, index) => ({
|
|
236
|
+
setLocations(finalUser.locations.map((loc: any, index: number) => ({
|
|
237
237
|
id: loc.id || `existing-${index}`,
|
|
238
238
|
name: loc.name,
|
|
239
239
|
label: loc.label,
|
|
@@ -252,17 +252,17 @@ const AccountSettingsScreen: React.FC<BaseScreenProps & { initialField?: string;
|
|
|
252
252
|
|
|
253
253
|
// Handle links - simple and direct like other fields
|
|
254
254
|
if (finalUser.linksMetadata && Array.isArray(finalUser.linksMetadata)) {
|
|
255
|
-
const urls = finalUser.linksMetadata.map(l => l.url);
|
|
255
|
+
const urls = finalUser.linksMetadata.map((l: any) => l.url);
|
|
256
256
|
setLinks(urls);
|
|
257
|
-
const metadataWithIds = finalUser.linksMetadata.map((link, index) => ({
|
|
257
|
+
const metadataWithIds = finalUser.linksMetadata.map((link: any, index: number) => ({
|
|
258
258
|
...link,
|
|
259
259
|
id: link.id || `existing-${index}`
|
|
260
260
|
}));
|
|
261
261
|
setLinksMetadata(metadataWithIds);
|
|
262
262
|
} else if (Array.isArray(finalUser.links)) {
|
|
263
|
-
const simpleLinks = finalUser.links.map(l => typeof l === 'string' ? l : l.link).filter(Boolean);
|
|
263
|
+
const simpleLinks = finalUser.links.map((l: any) => typeof l === 'string' ? l : l.link).filter(Boolean);
|
|
264
264
|
setLinks(simpleLinks);
|
|
265
|
-
const linksWithMetadata = simpleLinks.map((url, index) => ({
|
|
265
|
+
const linksWithMetadata = simpleLinks.map((url: string, index: number) => ({
|
|
266
266
|
url,
|
|
267
267
|
title: url.replace(/^https?:\/\//, '').replace(/\/$/, ''),
|
|
268
268
|
description: `Link to ${url}`,
|
|
@@ -553,7 +553,7 @@ const AccountSettingsScreen: React.FC<BaseScreenProps & { initialField?: string;
|
|
|
553
553
|
}
|
|
554
554
|
|
|
555
555
|
if (currentUser.linksMetadata && Array.isArray(currentUser.linksMetadata)) {
|
|
556
|
-
setLinksMetadata(currentUser.linksMetadata.map((link, index) => ({
|
|
556
|
+
setLinksMetadata(currentUser.linksMetadata.map((link: any, index: number) => ({
|
|
557
557
|
...link,
|
|
558
558
|
id: link.id || `existing-${index}`
|
|
559
559
|
})));
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
import type { BaseScreenProps } from '../types/navigation';
|
|
16
16
|
import type { ClientSession } from '../../models/session';
|
|
17
17
|
import { fontFamilies } from '../styles/fonts';
|
|
18
|
-
import type { User } from '
|
|
18
|
+
import type { User } from '@oxyhq/shared';
|
|
19
19
|
import { toast } from '../../lib/sonner';
|
|
20
20
|
import { confirmAction } from '../utils/confirmAction';
|
|
21
21
|
import OxyIcon from '../components/icon/OxyIcon';
|
|
@@ -220,7 +220,7 @@ const OxyAuthScreen: React.FC<BaseScreenProps> = ({
|
|
|
220
220
|
|
|
221
221
|
try {
|
|
222
222
|
// Generate a unique session token for this auth request
|
|
223
|
-
const sessionToken = generateSessionToken();
|
|
223
|
+
const sessionToken = await generateSessionToken();
|
|
224
224
|
const expiresAt = Date.now() + AUTH_SESSION_EXPIRY_MS;
|
|
225
225
|
|
|
226
226
|
// Register the auth session with the server
|
|
@@ -242,14 +242,10 @@ const OxyAuthScreen: React.FC<BaseScreenProps> = ({
|
|
|
242
242
|
}
|
|
243
243
|
}, [oxyServices, connectSocket]);
|
|
244
244
|
|
|
245
|
-
// Generate a random session token
|
|
246
|
-
const generateSessionToken = (): string => {
|
|
247
|
-
const
|
|
248
|
-
|
|
249
|
-
for (let i = 0; i < 32; i++) {
|
|
250
|
-
result += chars.charAt(Math.floor(Math.random() * chars.length));
|
|
251
|
-
}
|
|
252
|
-
return result;
|
|
245
|
+
// Generate a random session token using secure random bytes
|
|
246
|
+
const generateSessionToken = async (): Promise<string> => {
|
|
247
|
+
const { generateSessionToken: sharedGenerate } = await import('@oxyhq/shared');
|
|
248
|
+
return sharedGenerate(32); // 32 bytes = 64 hex characters
|
|
253
249
|
};
|
|
254
250
|
|
|
255
251
|
// Clean up on unmount
|
|
@@ -10,7 +10,7 @@ import { Ionicons } from '@expo/vector-icons';
|
|
|
10
10
|
import { useI18n } from '../hooks/useI18n';
|
|
11
11
|
import { useOxy } from '../context/OxyContext';
|
|
12
12
|
import { logger } from '../../utils/loggerUtils';
|
|
13
|
-
import type { User } from '
|
|
13
|
+
import type { User } from '@oxyhq/shared';
|
|
14
14
|
import { extractErrorMessage } from '../utils/errorHandlers';
|
|
15
15
|
|
|
16
16
|
interface ProfileScreenProps extends BaseScreenProps {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ReactNode, RefObject } from 'react';
|
|
2
2
|
import type { QueryClient } from '@tanstack/react-query';
|
|
3
3
|
import type { RouteName } from '../navigation/routes';
|
|
4
|
-
import type { User } from '
|
|
4
|
+
import type { User } from '@oxyhq/shared';
|
|
5
5
|
import type { ClientSession } from '../../models/session';
|
|
6
6
|
|
|
7
7
|
// Re-export RouteName from routes for convenience
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { OxyServices } from '../../core';
|
|
2
|
-
import type { User } from '
|
|
2
|
+
import type { User } from '@oxyhq/shared';
|
|
3
3
|
import { useAccountStore } from '../stores/accountStore';
|
|
4
4
|
import { useAuthStore } from '../stores/authStore';
|
|
5
5
|
import { QueryClient } from '@tanstack/react-query';
|
|
@@ -7,16 +7,14 @@ interface DeviceSession {
|
|
|
7
7
|
deviceName?: string;
|
|
8
8
|
expiresAt?: string;
|
|
9
9
|
lastActive?: string;
|
|
10
|
-
user?: { id?: string;
|
|
10
|
+
user?: { id?: string; _id?: { toString(): string } };
|
|
11
11
|
userId?: string;
|
|
12
|
-
publicKey?: string;
|
|
13
12
|
isCurrent?: boolean;
|
|
14
13
|
}
|
|
15
14
|
|
|
16
15
|
export interface FetchSessionsWithFallbackOptions {
|
|
17
16
|
fallbackDeviceId?: string;
|
|
18
17
|
fallbackUserId?: string;
|
|
19
|
-
fallbackPublicKey?: string; // Canonical user identity
|
|
20
18
|
logger?: (message: string, error?: unknown) => void;
|
|
21
19
|
}
|
|
22
20
|
|
|
@@ -39,41 +37,27 @@ export interface SessionValidationResult {
|
|
|
39
37
|
* @param sessions - Raw session array returned from the API
|
|
40
38
|
* @param fallbackDeviceId - Device identifier to use when missing from payload
|
|
41
39
|
* @param fallbackUserId - User identifier to use when missing from payload
|
|
42
|
-
* @param fallbackPublicKey - Public key to use when missing from payload (canonical identity)
|
|
43
40
|
*/
|
|
44
41
|
export const mapSessionsToClient = (
|
|
45
42
|
sessions: DeviceSession[],
|
|
46
43
|
fallbackDeviceId?: string,
|
|
47
44
|
fallbackUserId?: string,
|
|
48
|
-
fallbackPublicKey?: string,
|
|
49
45
|
): ClientSession[] => {
|
|
50
46
|
const now = new Date();
|
|
51
47
|
|
|
52
|
-
return sessions.map((session) => {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
session.
|
|
59
|
-
fallbackPublicKey ||
|
|
60
|
-
'';
|
|
61
|
-
|
|
62
|
-
// userId is MongoDB ObjectId (internal backend reference, optional)
|
|
63
|
-
const userId =
|
|
48
|
+
return sessions.map((session) => ({
|
|
49
|
+
sessionId: session.sessionId,
|
|
50
|
+
deviceId: session.deviceId || fallbackDeviceId || '',
|
|
51
|
+
expiresAt: session.expiresAt || new Date(now.getTime() + 7 * 24 * 60 * 60 * 1000).toISOString(),
|
|
52
|
+
lastActive: session.lastActive || now.toISOString(),
|
|
53
|
+
userId:
|
|
54
|
+
session.user?.id ||
|
|
64
55
|
session.userId ||
|
|
65
|
-
(session.user?._id ? session.user._id.toString() : undefined)
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
expiresAt: session.expiresAt || new Date(now.getTime() + 7 * 24 * 60 * 60 * 1000).toISOString(),
|
|
71
|
-
lastActive: session.lastActive || now.toISOString(),
|
|
72
|
-
publicKey, // Canonical user identity - REQUIRED
|
|
73
|
-
userId, // MongoDB ObjectId (optional, for backward compatibility)
|
|
74
|
-
isCurrent: Boolean(session.isCurrent),
|
|
75
|
-
};
|
|
76
|
-
});
|
|
56
|
+
(session.user?._id ? session.user._id.toString() : undefined) ||
|
|
57
|
+
fallbackUserId ||
|
|
58
|
+
'',
|
|
59
|
+
isCurrent: Boolean(session.isCurrent),
|
|
60
|
+
}));
|
|
77
61
|
};
|
|
78
62
|
|
|
79
63
|
/**
|
|
@@ -89,20 +73,19 @@ export const fetchSessionsWithFallback = async (
|
|
|
89
73
|
{
|
|
90
74
|
fallbackDeviceId,
|
|
91
75
|
fallbackUserId,
|
|
92
|
-
fallbackPublicKey,
|
|
93
76
|
logger,
|
|
94
77
|
}: FetchSessionsWithFallbackOptions = {},
|
|
95
78
|
): Promise<ClientSession[]> => {
|
|
96
79
|
try {
|
|
97
80
|
const deviceSessions = await oxyServices.getDeviceSessions(sessionId);
|
|
98
|
-
return mapSessionsToClient(deviceSessions, fallbackDeviceId, fallbackUserId
|
|
81
|
+
return mapSessionsToClient(deviceSessions, fallbackDeviceId, fallbackUserId);
|
|
99
82
|
} catch (error) {
|
|
100
83
|
if (__DEV__ && logger) {
|
|
101
84
|
logger('Failed to get device sessions, falling back to user sessions', error);
|
|
102
85
|
}
|
|
103
86
|
|
|
104
87
|
const userSessions = await oxyServices.getSessionsBySessionId(sessionId);
|
|
105
|
-
return mapSessionsToClient(userSessions, fallbackDeviceId, fallbackUserId
|
|
88
|
+
return mapSessionsToClient(userSessions, fallbackDeviceId, fallbackUserId);
|
|
106
89
|
}
|
|
107
90
|
};
|
|
108
91
|
|
|
@@ -12,19 +12,12 @@ import type { ClientSession } from '../models/session';
|
|
|
12
12
|
*/
|
|
13
13
|
export function normalizeSession(session: Partial<ClientSession> & { sessionId: string }): ClientSession {
|
|
14
14
|
const now = new Date().toISOString();
|
|
15
|
-
|
|
16
|
-
// publicKey is required (canonical user identity)
|
|
17
|
-
if (!session.publicKey) {
|
|
18
|
-
throw new Error(`Session ${session.sessionId} is missing required publicKey field`);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
15
|
return {
|
|
22
16
|
sessionId: session.sessionId,
|
|
23
17
|
deviceId: session.deviceId || '',
|
|
24
18
|
expiresAt: session.expiresAt || now,
|
|
25
19
|
lastActive: session.lastActive || now,
|
|
26
|
-
|
|
27
|
-
userId: session.userId, // Optional MongoDB ObjectId for backward compatibility
|
|
20
|
+
userId: session.userId || '',
|
|
28
21
|
};
|
|
29
22
|
}
|
|
30
23
|
|