@oxyhq/services 5.16.33 → 5.16.35
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 +3 -2
- package/lib/commonjs/crypto/keyManager.js.map +1 -1
- package/lib/commonjs/crypto/signatureService.js +28 -122
- package/lib/commonjs/crypto/signatureService.js.map +1 -1
- package/lib/commonjs/index.js +12 -0
- 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/shared/crypto/messageBuilders.js +79 -0
- package/lib/commonjs/shared/crypto/messageBuilders.js.map +1 -0
- package/lib/commonjs/shared/crypto/platform.js +118 -0
- package/lib/commonjs/shared/crypto/platform.js.map +1 -0
- package/lib/commonjs/shared/crypto/signature.js +191 -0
- package/lib/commonjs/shared/crypto/signature.js.map +1 -0
- package/lib/commonjs/shared/index.js +94 -0
- package/lib/commonjs/shared/index.js.map +1 -0
- package/lib/commonjs/shared/models/index.js +2 -0
- package/lib/commonjs/shared/models/index.js.map +1 -0
- package/lib/commonjs/shared/transport/index.js +260 -0
- package/lib/commonjs/shared/transport/index.js.map +1 -0
- package/lib/commonjs/shared/utils/index.js +82 -0
- package/lib/commonjs/shared/utils/index.js.map +1 -0
- 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 +23 -61
- 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 +2 -11
- 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 +3 -2
- package/lib/module/crypto/keyManager.js.map +1 -1
- package/lib/module/crypto/signatureService.js +26 -122
- package/lib/module/crypto/signatureService.js.map +1 -1
- package/lib/module/index.js +2 -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/shared/crypto/messageBuilders.js +70 -0
- package/lib/module/shared/crypto/messageBuilders.js.map +1 -0
- package/lib/module/shared/crypto/platform.js +112 -0
- package/lib/module/shared/crypto/platform.js.map +1 -0
- package/lib/module/shared/crypto/signature.js +186 -0
- package/lib/module/shared/crypto/signature.js.map +1 -0
- package/lib/module/shared/index.js +30 -0
- package/lib/module/shared/index.js.map +1 -0
- package/lib/module/shared/models/index.js +2 -0
- package/lib/module/shared/models/index.js.map +1 -0
- package/lib/module/shared/transport/index.js +254 -0
- package/lib/module/shared/transport/index.js.map +1 -0
- package/lib/module/shared/utils/index.js +74 -0
- package/lib/module/shared/utils/index.js.map +1 -0
- 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 +23 -61
- 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 +2 -11
- 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 +2 -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/shared/crypto/messageBuilders.d.ts +38 -0
- package/lib/typescript/shared/crypto/messageBuilders.d.ts.map +1 -0
- package/lib/typescript/shared/crypto/platform.d.ts +54 -0
- package/lib/typescript/shared/crypto/platform.d.ts.map +1 -0
- package/lib/typescript/shared/crypto/signature.d.ts +72 -0
- package/lib/typescript/shared/crypto/signature.d.ts.map +1 -0
- package/lib/typescript/shared/index.d.ts +20 -0
- package/lib/typescript/shared/index.d.ts.map +1 -0
- package/lib/typescript/shared/models/index.d.ts +163 -0
- package/lib/typescript/shared/models/index.d.ts.map +1 -0
- package/lib/typescript/shared/transport/index.d.ts +73 -0
- package/lib/typescript/shared/transport/index.d.ts.map +1 -0
- package/lib/typescript/shared/utils/index.d.ts +28 -0
- package/lib/typescript/shared/utils/index.d.ts.map +1 -0
- 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 +1 -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 +43 -142
- package/src/index.ts +3 -2
- package/src/models/interfaces.ts +21 -74
- package/src/models/session.ts +3 -5
- package/src/shared/crypto/messageBuilders.ts +89 -0
- package/src/shared/crypto/platform.ts +140 -0
- package/src/shared/crypto/signature.ts +235 -0
- package/src/shared/index.ts +28 -0
- package/src/shared/models/index.ts +173 -0
- package/src/shared/transport/index.ts +349 -0
- package/src/shared/utils/index.ts +73 -0
- package/src/ui/context/OxyContext.tsx +22 -57
- package/src/ui/context/hooks/useAuthOperations.ts +33 -65
- package/src/ui/context/hooks/useLanguageManagement.ts +2 -1
- package/src/ui/hooks/auth/index.ts +0 -2
- 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 +2 -11
- 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
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth Service
|
|
3
|
+
*
|
|
4
|
+
* Handles authentication operations:
|
|
5
|
+
* - Challenge retrieval
|
|
6
|
+
* - Signing orchestration (delegated to Accounts/KeyManager)
|
|
7
|
+
* - Session verification
|
|
8
|
+
* - Access token retrieval
|
|
9
|
+
* - Registration
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import type { OxyConfig } from '../../models/interfaces';
|
|
13
|
+
import type { User, LoginResponse, ChallengePayload } from '../../shared';
|
|
14
|
+
import { HttpService } from '../HttpService';
|
|
15
|
+
import { SignatureService } from '../../crypto/signatureService';
|
|
16
|
+
|
|
17
|
+
export interface PublicKeyCheckResponse {
|
|
18
|
+
registered: boolean;
|
|
19
|
+
message: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export class AuthService {
|
|
23
|
+
private httpService: HttpService;
|
|
24
|
+
|
|
25
|
+
constructor(config: OxyConfig) {
|
|
26
|
+
this.httpService = new HttpService(config);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Check if a public key is registered on the server
|
|
31
|
+
*/
|
|
32
|
+
async checkPublicKeyRegistered(publicKey: string): Promise<PublicKeyCheckResponse> {
|
|
33
|
+
try {
|
|
34
|
+
return await this.httpService.request<PublicKeyCheckResponse>({
|
|
35
|
+
method: 'GET',
|
|
36
|
+
url: `/api/auth/check-publickey?publicKey=${encodeURIComponent(publicKey)}`,
|
|
37
|
+
cache: true,
|
|
38
|
+
cacheTTL: 2 * 60 * 1000,
|
|
39
|
+
});
|
|
40
|
+
} catch (error) {
|
|
41
|
+
throw error;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Request an authentication challenge
|
|
47
|
+
*/
|
|
48
|
+
async requestChallenge(publicKey: string): Promise<ChallengePayload> {
|
|
49
|
+
try {
|
|
50
|
+
return await this.httpService.request<ChallengePayload>({
|
|
51
|
+
method: 'POST',
|
|
52
|
+
url: '/api/auth/challenge',
|
|
53
|
+
data: { publicKey },
|
|
54
|
+
cache: false,
|
|
55
|
+
});
|
|
56
|
+
} catch (error) {
|
|
57
|
+
throw error;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Verify a challenge and authenticate (creates session)
|
|
63
|
+
* This orchestrates signing via SignatureService (which uses KeyManager)
|
|
64
|
+
*/
|
|
65
|
+
async verifyChallenge(challenge: string): Promise<LoginResponse> {
|
|
66
|
+
try {
|
|
67
|
+
// Sign the challenge using SignatureService (requires private key)
|
|
68
|
+
const signedChallenge = await SignatureService.signChallenge(challenge);
|
|
69
|
+
|
|
70
|
+
// Verify challenge and get session
|
|
71
|
+
return await this.httpService.request<LoginResponse>({
|
|
72
|
+
method: 'POST',
|
|
73
|
+
url: '/api/auth/verify',
|
|
74
|
+
data: {
|
|
75
|
+
publicKey: signedChallenge.publicKey,
|
|
76
|
+
challenge: challenge,
|
|
77
|
+
signature: signedChallenge.challenge,
|
|
78
|
+
timestamp: signedChallenge.timestamp,
|
|
79
|
+
},
|
|
80
|
+
cache: false,
|
|
81
|
+
});
|
|
82
|
+
} catch (error) {
|
|
83
|
+
throw error;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Register a new identity with the server
|
|
89
|
+
*/
|
|
90
|
+
async register(publicKey: string, signature: string, timestamp: number, username?: string, email?: string): Promise<User> {
|
|
91
|
+
try {
|
|
92
|
+
return await this.httpService.request<User>({
|
|
93
|
+
method: 'POST',
|
|
94
|
+
url: '/api/auth/register',
|
|
95
|
+
data: {
|
|
96
|
+
publicKey,
|
|
97
|
+
signature,
|
|
98
|
+
timestamp,
|
|
99
|
+
username,
|
|
100
|
+
email,
|
|
101
|
+
},
|
|
102
|
+
cache: false,
|
|
103
|
+
});
|
|
104
|
+
} catch (error) {
|
|
105
|
+
throw error;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Register using current identity (signs automatically)
|
|
111
|
+
*/
|
|
112
|
+
async registerCurrentIdentity(username?: string, email?: string): Promise<User> {
|
|
113
|
+
try {
|
|
114
|
+
const { signature, publicKey, timestamp } = await SignatureService.createRegistrationSignature();
|
|
115
|
+
return this.register(publicKey, signature, timestamp, username, email);
|
|
116
|
+
} catch (error) {
|
|
117
|
+
throw error;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Get user by public key
|
|
123
|
+
*/
|
|
124
|
+
async getUserByPublicKey(publicKey: string): Promise<User> {
|
|
125
|
+
try {
|
|
126
|
+
return await this.httpService.request<User>({
|
|
127
|
+
method: 'GET',
|
|
128
|
+
url: `/api/auth/user/${encodeURIComponent(publicKey)}`,
|
|
129
|
+
cache: true,
|
|
130
|
+
cacheTTL: 2 * 60 * 1000,
|
|
131
|
+
});
|
|
132
|
+
} catch (error) {
|
|
133
|
+
throw error;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Get user by session ID
|
|
139
|
+
*/
|
|
140
|
+
async getUserBySession(sessionId: string): Promise<User> {
|
|
141
|
+
try {
|
|
142
|
+
return await this.httpService.request<User>({
|
|
143
|
+
method: 'GET',
|
|
144
|
+
url: `/api/auth/user/session/${encodeURIComponent(sessionId)}`,
|
|
145
|
+
cache: true,
|
|
146
|
+
cacheTTL: 2 * 60 * 1000,
|
|
147
|
+
});
|
|
148
|
+
} catch (error) {
|
|
149
|
+
throw error;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
@@ -8,20 +8,18 @@
|
|
|
8
8
|
* - Single source of truth for session operations
|
|
9
9
|
* - Handles both online and offline sessions
|
|
10
10
|
* - Integrates with TokenService for token management
|
|
11
|
-
* -
|
|
12
|
-
* - Sessions are bound to local identity stored in Accounts app
|
|
11
|
+
* - userId is always MongoDB ObjectId, never publicKey
|
|
13
12
|
*/
|
|
14
13
|
|
|
15
14
|
import type { OxyServices } from '../OxyServices';
|
|
16
15
|
import { tokenService } from './TokenService';
|
|
17
16
|
import type { ClientSession, SessionLoginResponse } from '../../models/session';
|
|
18
|
-
import type { User } from '../../
|
|
17
|
+
import type { User } from '../../shared';
|
|
19
18
|
|
|
20
19
|
export interface Session {
|
|
21
20
|
sessionId: string;
|
|
22
21
|
deviceId: string;
|
|
23
|
-
|
|
24
|
-
userId?: string; // MongoDB ObjectId (internal backend reference, optional)
|
|
22
|
+
userId: string; // MongoDB ObjectId - PRIMARY IDENTIFIER
|
|
25
23
|
expiresAt: string;
|
|
26
24
|
lastActive: string;
|
|
27
25
|
isCurrent: boolean;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session Transport Service
|
|
3
|
+
*
|
|
4
|
+
* Uses shared transport abstraction for WebSocket/SSE/polling
|
|
5
|
+
* Provides unified interface for session status updates
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { OxyConfig } from '../../models/interfaces';
|
|
9
|
+
import {
|
|
10
|
+
TransportFactory,
|
|
11
|
+
type TransportConfig,
|
|
12
|
+
type TransportCallbacks,
|
|
13
|
+
type TransportUpdate,
|
|
14
|
+
} from '../../shared';
|
|
15
|
+
|
|
16
|
+
export class SessionTransportService {
|
|
17
|
+
private transport: any = null;
|
|
18
|
+
private config: OxyConfig;
|
|
19
|
+
|
|
20
|
+
constructor(config: OxyConfig) {
|
|
21
|
+
this.config = config;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Connect to session status updates
|
|
26
|
+
* Automatically chooses best available transport (WebSocket > SSE > Polling)
|
|
27
|
+
*/
|
|
28
|
+
async connect(
|
|
29
|
+
sessionToken: string,
|
|
30
|
+
callbacks: TransportCallbacks
|
|
31
|
+
): Promise<void> {
|
|
32
|
+
const transportConfig: TransportConfig = {
|
|
33
|
+
baseURL: this.config.baseURL,
|
|
34
|
+
namespace: 'auth-session',
|
|
35
|
+
sessionToken,
|
|
36
|
+
pollingInterval: 3000, // 3 seconds
|
|
37
|
+
reconnectAttempts: 3,
|
|
38
|
+
reconnectDelay: 1000,
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
this.transport = await TransportFactory.create(transportConfig, callbacks);
|
|
42
|
+
await this.transport.connect();
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Disconnect from session updates
|
|
47
|
+
*/
|
|
48
|
+
disconnect(): void {
|
|
49
|
+
if (this.transport) {
|
|
50
|
+
this.transport.disconnect();
|
|
51
|
+
this.transport = null;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Check if currently connected
|
|
57
|
+
*/
|
|
58
|
+
isConnected(): boolean {
|
|
59
|
+
return this.transport?.isConnected() ?? false;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Get the transport type being used
|
|
64
|
+
*/
|
|
65
|
+
getTransportType(): string {
|
|
66
|
+
return this.transport?.getType() ?? 'none';
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
@@ -8,17 +8,17 @@
|
|
|
8
8
|
* - Single storage location (no duplication)
|
|
9
9
|
* - Automatic token refresh when expiring soon
|
|
10
10
|
* - Type-safe token payload handling
|
|
11
|
-
* -
|
|
11
|
+
* - userId is always MongoDB ObjectId, never publicKey
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
import { jwtDecode } from 'jwt-decode';
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
17
|
* AccessTokenPayload - Matches the token payload structure from API
|
|
18
|
-
*
|
|
18
|
+
* userId is always MongoDB ObjectId (24 hex characters), never publicKey
|
|
19
19
|
*/
|
|
20
20
|
interface AccessTokenPayload {
|
|
21
|
-
|
|
21
|
+
userId: string; // MongoDB ObjectId - PRIMARY IDENTIFIER
|
|
22
22
|
sessionId: string; // Session UUID
|
|
23
23
|
deviceId: string; // Device identifier
|
|
24
24
|
type: 'access';
|
|
@@ -116,29 +116,21 @@ class TokenService {
|
|
|
116
116
|
}
|
|
117
117
|
|
|
118
118
|
/**
|
|
119
|
-
* Get
|
|
120
|
-
* Returns
|
|
119
|
+
* Get userId from current access token
|
|
120
|
+
* Returns MongoDB ObjectId (never publicKey)
|
|
121
121
|
*/
|
|
122
|
-
|
|
122
|
+
getUserIdFromToken(): string | null {
|
|
123
123
|
const token = this.tokenStore.accessToken;
|
|
124
124
|
if (!token) return null;
|
|
125
125
|
|
|
126
126
|
try {
|
|
127
127
|
const decoded = jwtDecode<AccessTokenPayload>(token);
|
|
128
|
-
return decoded.
|
|
128
|
+
return decoded.userId || null;
|
|
129
129
|
} catch {
|
|
130
130
|
return null;
|
|
131
131
|
}
|
|
132
132
|
}
|
|
133
133
|
|
|
134
|
-
/**
|
|
135
|
-
* @deprecated Use getPublicKeyFromToken() instead. This method is kept for backward compatibility.
|
|
136
|
-
* Get userId from current access token (returns publicKey, not MongoDB ObjectId)
|
|
137
|
-
*/
|
|
138
|
-
getUserIdFromToken(): string | null {
|
|
139
|
-
return this.getPublicKeyFromToken();
|
|
140
|
-
}
|
|
141
|
-
|
|
142
134
|
/**
|
|
143
135
|
* Refresh access token if expiring soon
|
|
144
136
|
* Returns promise that resolves when token is refreshed (or already valid)
|
|
@@ -201,10 +193,10 @@ class TokenService {
|
|
|
201
193
|
throw new Error('No access token in refresh response');
|
|
202
194
|
}
|
|
203
195
|
|
|
204
|
-
// Validate new token has
|
|
196
|
+
// Validate new token has correct userId format (ObjectId)
|
|
205
197
|
const newDecoded = jwtDecode<AccessTokenPayload>(newToken);
|
|
206
|
-
if (
|
|
207
|
-
throw new Error(
|
|
198
|
+
if (newDecoded.userId && !/^[0-9a-fA-F]{24}$/.test(newDecoded.userId)) {
|
|
199
|
+
throw new Error(`Invalid userId format in refreshed token: ${newDecoded.userId.substring(0, 20)}...`);
|
|
208
200
|
}
|
|
209
201
|
|
|
210
202
|
this.setTokens(newToken);
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* User Service
|
|
3
|
+
*
|
|
4
|
+
* Handles user profile operations (no key handling):
|
|
5
|
+
* - Profile fetch/update
|
|
6
|
+
* - Profile search
|
|
7
|
+
* - User recommendations
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type { OxyConfig } from '../../models/interfaces';
|
|
11
|
+
import type { User, SearchProfilesResponse, PaginationInfo } from '../../shared';
|
|
12
|
+
import { HttpService } from '../HttpService';
|
|
13
|
+
|
|
14
|
+
export interface PaginationParams {
|
|
15
|
+
limit?: number;
|
|
16
|
+
offset?: number;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export class UserService {
|
|
20
|
+
private httpService: HttpService;
|
|
21
|
+
|
|
22
|
+
constructor(config: OxyConfig) {
|
|
23
|
+
this.httpService = new HttpService(config);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Get user profile by ID
|
|
28
|
+
*/
|
|
29
|
+
async getUserById(userId: string): Promise<User> {
|
|
30
|
+
try {
|
|
31
|
+
return await this.httpService.request<User>({
|
|
32
|
+
method: 'GET',
|
|
33
|
+
url: `/api/profiles/${userId}`,
|
|
34
|
+
cache: true,
|
|
35
|
+
cacheTTL: 5 * 60 * 1000,
|
|
36
|
+
});
|
|
37
|
+
} catch (error) {
|
|
38
|
+
throw error;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Get profile by username
|
|
44
|
+
*/
|
|
45
|
+
async getProfileByUsername(username: string): Promise<User> {
|
|
46
|
+
try {
|
|
47
|
+
return await this.httpService.request<User>({
|
|
48
|
+
method: 'GET',
|
|
49
|
+
url: `/api/profiles/username/${username}`,
|
|
50
|
+
cache: true,
|
|
51
|
+
cacheTTL: 5 * 60 * 1000,
|
|
52
|
+
});
|
|
53
|
+
} catch (error) {
|
|
54
|
+
throw error;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Search user profiles
|
|
60
|
+
*/
|
|
61
|
+
async searchProfiles(query: string, pagination?: PaginationParams): Promise<SearchProfilesResponse> {
|
|
62
|
+
try {
|
|
63
|
+
const params = new URLSearchParams();
|
|
64
|
+
params.set('query', query);
|
|
65
|
+
if (pagination?.limit) params.set('limit', pagination.limit.toString());
|
|
66
|
+
if (pagination?.offset) params.set('offset', pagination.offset.toString());
|
|
67
|
+
|
|
68
|
+
const response = await this.httpService.request<SearchProfilesResponse | User[]>({
|
|
69
|
+
method: 'GET',
|
|
70
|
+
url: `/api/profiles/search?${params.toString()}`,
|
|
71
|
+
cache: true,
|
|
72
|
+
cacheTTL: 2 * 60 * 1000,
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
// Handle response format
|
|
76
|
+
if (Array.isArray(response)) {
|
|
77
|
+
const limit = pagination?.limit ?? response.length;
|
|
78
|
+
const paginationInfo: PaginationInfo = {
|
|
79
|
+
total: response.length,
|
|
80
|
+
limit,
|
|
81
|
+
offset: pagination?.offset ?? 0,
|
|
82
|
+
hasMore: limit > 0 && response.length === limit,
|
|
83
|
+
};
|
|
84
|
+
return { data: response, pagination: paginationInfo };
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return response;
|
|
88
|
+
} catch (error) {
|
|
89
|
+
throw error;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Get profile recommendations
|
|
95
|
+
*/
|
|
96
|
+
async getProfileRecommendations(): Promise<User[]> {
|
|
97
|
+
try {
|
|
98
|
+
return await this.httpService.request<User[]>({
|
|
99
|
+
method: 'GET',
|
|
100
|
+
url: '/api/profiles/recommendations',
|
|
101
|
+
cache: true,
|
|
102
|
+
cacheTTL: 5 * 60 * 1000,
|
|
103
|
+
});
|
|
104
|
+
} catch (error) {
|
|
105
|
+
throw error;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Update user profile
|
|
111
|
+
*/
|
|
112
|
+
async updateProfile(updates: Partial<User>): Promise<User> {
|
|
113
|
+
try {
|
|
114
|
+
return await this.httpService.request<User>({
|
|
115
|
+
method: 'PATCH',
|
|
116
|
+
url: '/api/profiles/me',
|
|
117
|
+
data: updates,
|
|
118
|
+
cache: false,
|
|
119
|
+
});
|
|
120
|
+
} catch (error) {
|
|
121
|
+
throw error;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Focused Services
|
|
3
|
+
*
|
|
4
|
+
* Single-responsibility services replacing the mixin pattern:
|
|
5
|
+
* - AuthService: Authentication, challenges, registration
|
|
6
|
+
* - SessionService: Session management (already exists)
|
|
7
|
+
* - UserService: User profile operations
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
export { AuthService } from './AuthService';
|
|
11
|
+
export { sessionService } from './SessionService';
|
|
12
|
+
export { UserService } from './UserService';
|
|
13
|
+
export { tokenService } from './TokenService';
|
|
14
|
+
|
package/src/crypto/index.ts
CHANGED
|
@@ -3,6 +3,15 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Provides cryptographic identity management for the Oxy ecosystem.
|
|
5
5
|
* Handles key generation, secure storage, and digital signatures.
|
|
6
|
+
*
|
|
7
|
+
* ⚠️ IMPORTANT: KeyManager is primarily intended for use in the Oxy Accounts app.
|
|
8
|
+
* While it's exported here for convenience, third-party applications should NOT
|
|
9
|
+
* generate or store user identities. The Accounts app is the identity wallet.
|
|
10
|
+
*
|
|
11
|
+
* For third-party apps:
|
|
12
|
+
* - Use SignatureService for signing operations (but keys come from Accounts app)
|
|
13
|
+
* - Do NOT call KeyManager.createIdentity() or KeyManager.importKeyPair()
|
|
14
|
+
* - The Oxy Accounts app handles all identity generation and key storage
|
|
6
15
|
*/
|
|
7
16
|
|
|
8
17
|
// Import polyfills first - this ensures Buffer is available for crypto libraries
|
package/src/crypto/keyManager.ts
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
import { ec as EC } from 'elliptic';
|
|
9
9
|
import type { ECKeyPair } from 'elliptic';
|
|
10
10
|
import { Platform } from 'react-native';
|
|
11
|
+
import { shortenPublicKey as sharedShortenPublicKey } from '../shared';
|
|
11
12
|
|
|
12
13
|
// Lazy imports for React Native specific modules
|
|
13
14
|
let SecureStore: typeof import('expo-secure-store') | null = null;
|
|
@@ -539,8 +540,8 @@ export class KeyManager {
|
|
|
539
540
|
* Format: first 8 chars...last 8 chars
|
|
540
541
|
*/
|
|
541
542
|
static shortenPublicKey(publicKey: string): string {
|
|
542
|
-
|
|
543
|
-
return
|
|
543
|
+
// Use shared utility
|
|
544
|
+
return sharedShortenPublicKey(publicKey);
|
|
544
545
|
}
|
|
545
546
|
}
|
|
546
547
|
|