@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,235 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Signature Verification Service
|
|
3
|
+
*
|
|
4
|
+
* Unified signature verification used by both backend (API) and SDK.
|
|
5
|
+
* Uses platform adapters for crypto operations while keeping message construction shared.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { ec as EC } from 'elliptic';
|
|
9
|
+
import { getCryptoAdapter, PlatformDetector } from './platform';
|
|
10
|
+
import {
|
|
11
|
+
buildAuthMessage,
|
|
12
|
+
buildRegistrationMessage,
|
|
13
|
+
buildRequestMessage,
|
|
14
|
+
isTimestampFresh,
|
|
15
|
+
} from './messageBuilders';
|
|
16
|
+
|
|
17
|
+
const ec = new EC('secp256k1');
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Maximum age for signed messages (5 minutes)
|
|
21
|
+
*/
|
|
22
|
+
export const MAX_SIGNATURE_AGE_MS = 5 * 60 * 1000;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Challenge TTL (5 minutes)
|
|
26
|
+
*/
|
|
27
|
+
export const CHALLENGE_TTL_MS = 5 * 60 * 1000;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Signature Service
|
|
31
|
+
* Provides signature verification that works across all platforms
|
|
32
|
+
*/
|
|
33
|
+
export class SignatureService {
|
|
34
|
+
/**
|
|
35
|
+
* Verify an ECDSA signature
|
|
36
|
+
*
|
|
37
|
+
* @param message - The original message that was signed
|
|
38
|
+
* @param signature - The signature in DER format (hex encoded)
|
|
39
|
+
* @param publicKey - The public key (hex encoded, uncompressed)
|
|
40
|
+
* @returns true if the signature is valid
|
|
41
|
+
*/
|
|
42
|
+
static async verify(
|
|
43
|
+
message: string,
|
|
44
|
+
signature: string,
|
|
45
|
+
publicKey: string
|
|
46
|
+
): Promise<boolean> {
|
|
47
|
+
try {
|
|
48
|
+
const key = ec.keyFromPublic(publicKey, 'hex');
|
|
49
|
+
const adapter = await getCryptoAdapter();
|
|
50
|
+
const messageHash = await adapter.sha256(message);
|
|
51
|
+
return key.verify(messageHash, signature);
|
|
52
|
+
} catch {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Synchronous signature verification (Node.js only)
|
|
59
|
+
* Uses Node.js crypto module directly for hashing
|
|
60
|
+
*/
|
|
61
|
+
static verifySync(
|
|
62
|
+
message: string,
|
|
63
|
+
signature: string,
|
|
64
|
+
publicKey: string
|
|
65
|
+
): boolean {
|
|
66
|
+
if (!PlatformDetector.isNode()) {
|
|
67
|
+
throw new Error(
|
|
68
|
+
'verifySync should only be used in Node.js. Use verify() in other environments.'
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
try {
|
|
73
|
+
// eslint-disable-next-line @typescript-eslint/no-implied-eval
|
|
74
|
+
const getCrypto = new Function('return require("crypto")');
|
|
75
|
+
const crypto = getCrypto();
|
|
76
|
+
const key = ec.keyFromPublic(publicKey, 'hex');
|
|
77
|
+
const messageHash = crypto.createHash('sha256').update(message).digest('hex');
|
|
78
|
+
return key.verify(messageHash, signature);
|
|
79
|
+
} catch {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Verify an authentication challenge response
|
|
86
|
+
*
|
|
87
|
+
* @param publicKey - The user's public key
|
|
88
|
+
* @param challenge - The original challenge string
|
|
89
|
+
* @param signature - The signature of the auth message
|
|
90
|
+
* @param timestamp - The timestamp when the signature was created
|
|
91
|
+
* @param maxAgeMs - Maximum age of the signature in milliseconds
|
|
92
|
+
* @returns true if the challenge response is valid
|
|
93
|
+
*/
|
|
94
|
+
static async verifyChallengeResponse(
|
|
95
|
+
publicKey: string,
|
|
96
|
+
challenge: string,
|
|
97
|
+
signature: string,
|
|
98
|
+
timestamp: number,
|
|
99
|
+
maxAgeMs: number = CHALLENGE_TTL_MS
|
|
100
|
+
): Promise<boolean> {
|
|
101
|
+
// Check timestamp freshness
|
|
102
|
+
if (!isTimestampFresh(timestamp, maxAgeMs)) {
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Build the canonical message
|
|
107
|
+
const message = buildAuthMessage(publicKey, challenge, timestamp);
|
|
108
|
+
|
|
109
|
+
// Verify the signature
|
|
110
|
+
return this.verify(message, signature, publicKey);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Synchronous challenge response verification (Node.js only)
|
|
115
|
+
*/
|
|
116
|
+
static verifyChallengeResponseSync(
|
|
117
|
+
publicKey: string,
|
|
118
|
+
challenge: string,
|
|
119
|
+
signature: string,
|
|
120
|
+
timestamp: number,
|
|
121
|
+
maxAgeMs: number = CHALLENGE_TTL_MS
|
|
122
|
+
): boolean {
|
|
123
|
+
// Check timestamp freshness
|
|
124
|
+
if (!isTimestampFresh(timestamp, maxAgeMs)) {
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Build the canonical message
|
|
129
|
+
const message = buildAuthMessage(publicKey, challenge, timestamp);
|
|
130
|
+
|
|
131
|
+
// Verify the signature
|
|
132
|
+
return this.verifySync(message, signature, publicKey);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Verify a registration signature
|
|
137
|
+
* Signature format: oxy:register:{publicKey}:{timestamp}
|
|
138
|
+
*/
|
|
139
|
+
static async verifyRegistrationSignature(
|
|
140
|
+
publicKey: string,
|
|
141
|
+
signature: string,
|
|
142
|
+
timestamp: number,
|
|
143
|
+
maxAgeMs: number = MAX_SIGNATURE_AGE_MS
|
|
144
|
+
): Promise<boolean> {
|
|
145
|
+
// Check timestamp freshness
|
|
146
|
+
if (!isTimestampFresh(timestamp, maxAgeMs)) {
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Build the canonical message
|
|
151
|
+
const message = buildRegistrationMessage(publicKey, timestamp);
|
|
152
|
+
|
|
153
|
+
// Verify the signature
|
|
154
|
+
return this.verify(message, signature, publicKey);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Synchronous registration signature verification (Node.js only)
|
|
159
|
+
*/
|
|
160
|
+
static verifyRegistrationSignatureSync(
|
|
161
|
+
publicKey: string,
|
|
162
|
+
signature: string,
|
|
163
|
+
timestamp: number,
|
|
164
|
+
maxAgeMs: number = MAX_SIGNATURE_AGE_MS
|
|
165
|
+
): boolean {
|
|
166
|
+
// Check timestamp freshness
|
|
167
|
+
if (!isTimestampFresh(timestamp, maxAgeMs)) {
|
|
168
|
+
return false;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// Build the canonical message
|
|
172
|
+
const message = buildRegistrationMessage(publicKey, timestamp);
|
|
173
|
+
|
|
174
|
+
// Verify the signature
|
|
175
|
+
return this.verifySync(message, signature, publicKey);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Verify a signed request
|
|
180
|
+
* Used for authenticated API operations
|
|
181
|
+
*/
|
|
182
|
+
static async verifyRequestSignature(
|
|
183
|
+
publicKey: string,
|
|
184
|
+
data: Record<string, unknown>,
|
|
185
|
+
signature: string,
|
|
186
|
+
timestamp: number,
|
|
187
|
+
maxAgeMs: number = MAX_SIGNATURE_AGE_MS
|
|
188
|
+
): Promise<boolean> {
|
|
189
|
+
// Check timestamp freshness
|
|
190
|
+
if (!isTimestampFresh(timestamp, maxAgeMs)) {
|
|
191
|
+
return false;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// Build the canonical message
|
|
195
|
+
const message = buildRequestMessage(publicKey, timestamp, data);
|
|
196
|
+
|
|
197
|
+
// Verify the signature
|
|
198
|
+
return this.verify(message, signature, publicKey);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Synchronous request signature verification (Node.js only)
|
|
203
|
+
*/
|
|
204
|
+
static verifyRequestSignatureSync(
|
|
205
|
+
publicKey: string,
|
|
206
|
+
data: Record<string, unknown>,
|
|
207
|
+
signature: string,
|
|
208
|
+
timestamp: number,
|
|
209
|
+
maxAgeMs: number = MAX_SIGNATURE_AGE_MS
|
|
210
|
+
): boolean {
|
|
211
|
+
// Check timestamp freshness
|
|
212
|
+
if (!isTimestampFresh(timestamp, maxAgeMs)) {
|
|
213
|
+
return false;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// Build the canonical message
|
|
217
|
+
const message = buildRequestMessage(publicKey, timestamp, data);
|
|
218
|
+
|
|
219
|
+
// Verify the signature
|
|
220
|
+
return this.verifySync(message, signature, publicKey);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Validate that a string is a valid public key
|
|
225
|
+
*/
|
|
226
|
+
static isValidPublicKey(publicKey: string): boolean {
|
|
227
|
+
try {
|
|
228
|
+
ec.keyFromPublic(publicKey, 'hex');
|
|
229
|
+
return true;
|
|
230
|
+
} catch {
|
|
231
|
+
return false;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @oxyhq/shared
|
|
3
|
+
*
|
|
4
|
+
* Shared utilities, models, and crypto primitives for OxyHQ packages.
|
|
5
|
+
*
|
|
6
|
+
* This package provides:
|
|
7
|
+
* - Canonical data models (User, Session, ChallengePayload, etc.)
|
|
8
|
+
* - Unified signature verification across platforms
|
|
9
|
+
* - Platform-agnostic crypto adapters
|
|
10
|
+
* - Shared utility functions
|
|
11
|
+
* - Canonical message builders for signing
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
// Models
|
|
15
|
+
export * from './models/index';
|
|
16
|
+
|
|
17
|
+
// Crypto
|
|
18
|
+
export * from './crypto/signature';
|
|
19
|
+
export * from './crypto/messageBuilders';
|
|
20
|
+
export * from './crypto/platform';
|
|
21
|
+
export { getCryptoAdapter, PlatformDetector } from './crypto/platform';
|
|
22
|
+
|
|
23
|
+
// Utils
|
|
24
|
+
export * from './utils/index';
|
|
25
|
+
|
|
26
|
+
// Transport
|
|
27
|
+
export * from './transport/index';
|
|
28
|
+
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared Data Models
|
|
3
|
+
*
|
|
4
|
+
* Canonical TypeScript interfaces used across Accounts, Services SDK, and API packages.
|
|
5
|
+
* These models eliminate type drift and ensure consistency across the monorepo.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* User Model
|
|
10
|
+
*
|
|
11
|
+
* IMPORTANT:
|
|
12
|
+
* - id: MongoDB ObjectId (24 hex characters) - PRIMARY IDENTIFIER for all internal operations
|
|
13
|
+
* - publicKey: Cryptographic public key (130 hex characters) - LOOKUP KEY for authentication and identity operations
|
|
14
|
+
*
|
|
15
|
+
* Never use publicKey as an ID. Always use id (ObjectId) for:
|
|
16
|
+
* - Database queries
|
|
17
|
+
* - Session userId
|
|
18
|
+
* - Token userId
|
|
19
|
+
* - Socket room names
|
|
20
|
+
* - API route parameters (unless explicitly doing publicKey lookup)
|
|
21
|
+
*/
|
|
22
|
+
export interface User {
|
|
23
|
+
id: string; // MongoDB ObjectId - PRIMARY IDENTIFIER (always 24 hex chars)
|
|
24
|
+
publicKey: string; // Cryptographic public key - LOOKUP KEY (130 hex chars for secp256k1)
|
|
25
|
+
username: string;
|
|
26
|
+
email?: string;
|
|
27
|
+
avatar?: string; // Avatar file id (asset id)
|
|
28
|
+
privacySettings?: {
|
|
29
|
+
[key: string]: unknown;
|
|
30
|
+
};
|
|
31
|
+
name?: {
|
|
32
|
+
first?: string;
|
|
33
|
+
last?: string;
|
|
34
|
+
full?: string; // virtual, not stored in DB, returned by API
|
|
35
|
+
[key: string]: unknown;
|
|
36
|
+
};
|
|
37
|
+
bio?: string;
|
|
38
|
+
karma?: number;
|
|
39
|
+
location?: string;
|
|
40
|
+
website?: string;
|
|
41
|
+
createdAt?: string;
|
|
42
|
+
updatedAt?: string;
|
|
43
|
+
links?: Array<{
|
|
44
|
+
title?: string;
|
|
45
|
+
description?: string;
|
|
46
|
+
image?: string;
|
|
47
|
+
link: string;
|
|
48
|
+
}>;
|
|
49
|
+
_count?: {
|
|
50
|
+
followers?: number;
|
|
51
|
+
following?: number;
|
|
52
|
+
};
|
|
53
|
+
accountExpiresAfterInactivityDays?: number | null;
|
|
54
|
+
[key: string]: unknown;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Session Model
|
|
59
|
+
* Represents an authenticated session on a device
|
|
60
|
+
*/
|
|
61
|
+
export interface Session {
|
|
62
|
+
sessionId: string;
|
|
63
|
+
userId: string; // MongoDB ObjectId - PRIMARY IDENTIFIER
|
|
64
|
+
deviceId: string;
|
|
65
|
+
deviceInfo?: {
|
|
66
|
+
deviceName?: string;
|
|
67
|
+
deviceType?: string;
|
|
68
|
+
platform?: string;
|
|
69
|
+
browser?: string;
|
|
70
|
+
os?: string;
|
|
71
|
+
ipAddress?: string;
|
|
72
|
+
userAgent?: string;
|
|
73
|
+
location?: string;
|
|
74
|
+
fingerprint?: string;
|
|
75
|
+
lastActive?: string | Date;
|
|
76
|
+
};
|
|
77
|
+
isActive: boolean;
|
|
78
|
+
expiresAt: string | Date;
|
|
79
|
+
lastActive?: string | Date;
|
|
80
|
+
createdAt?: string | Date;
|
|
81
|
+
updatedAt?: string | Date;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Challenge Payload
|
|
86
|
+
* Used in challenge-response authentication
|
|
87
|
+
*/
|
|
88
|
+
export interface ChallengePayload {
|
|
89
|
+
challenge: string;
|
|
90
|
+
publicKey: string;
|
|
91
|
+
expiresAt: string | Date;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Signed Message
|
|
96
|
+
* Represents a message with cryptographic signature
|
|
97
|
+
*/
|
|
98
|
+
export interface SignedMessage {
|
|
99
|
+
message: string;
|
|
100
|
+
signature: string;
|
|
101
|
+
publicKey: string;
|
|
102
|
+
timestamp: number;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Auth Challenge Response
|
|
107
|
+
* Response to an authentication challenge
|
|
108
|
+
*/
|
|
109
|
+
export interface AuthChallengeResponse {
|
|
110
|
+
challenge: string;
|
|
111
|
+
publicKey: string;
|
|
112
|
+
signature: string;
|
|
113
|
+
timestamp: number;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Session Auth Response
|
|
118
|
+
* Response from session authorization (SSO flow)
|
|
119
|
+
*/
|
|
120
|
+
export interface SessionAuthResponse {
|
|
121
|
+
sessionToken: string;
|
|
122
|
+
status: 'pending' | 'authorized' | 'expired' | 'cancelled';
|
|
123
|
+
accessToken?: string;
|
|
124
|
+
refreshToken?: string;
|
|
125
|
+
user?: User;
|
|
126
|
+
expiresAt: string | Date;
|
|
127
|
+
createdAt?: string | Date;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Registration Request
|
|
132
|
+
* Used when registering a new identity
|
|
133
|
+
*/
|
|
134
|
+
export interface RegistrationRequest {
|
|
135
|
+
publicKey: string;
|
|
136
|
+
signature: string;
|
|
137
|
+
timestamp: number;
|
|
138
|
+
username?: string;
|
|
139
|
+
email?: string;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Login Response
|
|
144
|
+
* Response from successful authentication
|
|
145
|
+
*/
|
|
146
|
+
export interface LoginResponse {
|
|
147
|
+
accessToken?: string;
|
|
148
|
+
refreshToken?: string;
|
|
149
|
+
token?: string; // For backwards compatibility
|
|
150
|
+
user: User;
|
|
151
|
+
message?: string;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Pagination Info
|
|
156
|
+
* Standard pagination metadata
|
|
157
|
+
*/
|
|
158
|
+
export interface PaginationInfo {
|
|
159
|
+
total: number;
|
|
160
|
+
limit: number;
|
|
161
|
+
offset: number;
|
|
162
|
+
hasMore: boolean;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Search Profiles Response
|
|
167
|
+
* Response from profile search with pagination
|
|
168
|
+
*/
|
|
169
|
+
export interface SearchProfilesResponse {
|
|
170
|
+
data: User[];
|
|
171
|
+
pagination: PaginationInfo;
|
|
172
|
+
}
|
|
173
|
+
|