@oxyhq/services 5.16.35 → 5.16.37

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (232) hide show
  1. package/README.md +8 -26
  2. package/lib/commonjs/core/OxyServices.base.js.map +1 -1
  3. package/lib/commonjs/core/mixins/OxyServices.user.js.map +1 -1
  4. package/lib/commonjs/core/mixins/OxyServices.utility.js.map +1 -1
  5. package/lib/commonjs/crypto/README.md +142 -0
  6. package/lib/commonjs/crypto/core.js +147 -0
  7. package/lib/commonjs/crypto/core.js.map +1 -0
  8. package/lib/commonjs/crypto/index.js +16 -0
  9. package/lib/commonjs/crypto/index.js.map +1 -1
  10. package/lib/commonjs/crypto/keyManager.js +19 -22
  11. package/lib/commonjs/crypto/keyManager.js.map +1 -1
  12. package/lib/commonjs/crypto/signatureService.js +116 -28
  13. package/lib/commonjs/crypto/signatureService.js.map +1 -1
  14. package/lib/commonjs/index.js +0 -12
  15. package/lib/commonjs/index.js.map +1 -1
  16. package/lib/commonjs/models/interfaces.js +10 -11
  17. package/lib/commonjs/models/interfaces.js.map +1 -1
  18. package/lib/commonjs/node/index.js +10 -1
  19. package/lib/commonjs/node/index.js.map +1 -1
  20. package/lib/commonjs/node/signatureService.js +107 -0
  21. package/lib/commonjs/node/signatureService.js.map +1 -0
  22. package/lib/commonjs/ui/context/OxyContext.js +23 -0
  23. package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
  24. package/lib/commonjs/ui/context/hooks/useAuthOperations.js +29 -2
  25. package/lib/commonjs/ui/context/hooks/useAuthOperations.js.map +1 -1
  26. package/lib/commonjs/ui/context/hooks/useLanguageManagement.js.map +1 -1
  27. package/lib/commonjs/ui/hooks/useLanguageManagement.js.map +1 -1
  28. package/lib/commonjs/ui/hooks/useSessionManagement.js.map +1 -1
  29. package/lib/commonjs/ui/index.js +0 -2
  30. package/lib/commonjs/ui/index.js.map +1 -1
  31. package/lib/commonjs/ui/screens/AccountSettingsScreen.js.map +1 -1
  32. package/lib/commonjs/ui/screens/OxyAuthScreen.js +11 -2
  33. package/lib/commonjs/ui/screens/OxyAuthScreen.js.map +1 -1
  34. package/lib/module/core/OxyServices.base.js.map +1 -1
  35. package/lib/module/core/mixins/OxyServices.user.js.map +1 -1
  36. package/lib/module/core/mixins/OxyServices.utility.js.map +1 -1
  37. package/lib/module/crypto/README.md +142 -0
  38. package/lib/module/crypto/core.js +133 -0
  39. package/lib/module/crypto/core.js.map +1 -0
  40. package/lib/module/crypto/index.js +3 -9
  41. package/lib/module/crypto/index.js.map +1 -1
  42. package/lib/module/crypto/keyManager.js +19 -22
  43. package/lib/module/crypto/keyManager.js.map +1 -1
  44. package/lib/module/crypto/signatureService.js +113 -23
  45. package/lib/module/crypto/signatureService.js.map +1 -1
  46. package/lib/module/index.js +0 -2
  47. package/lib/module/index.js.map +1 -1
  48. package/lib/module/models/interfaces.js +10 -11
  49. package/lib/module/models/interfaces.js.map +1 -1
  50. package/lib/module/node/index.js +3 -0
  51. package/lib/module/node/index.js.map +1 -1
  52. package/lib/module/node/signatureService.js +101 -0
  53. package/lib/module/node/signatureService.js.map +1 -0
  54. package/lib/module/ui/context/OxyContext.js +23 -0
  55. package/lib/module/ui/context/OxyContext.js.map +1 -1
  56. package/lib/module/ui/context/hooks/useAuthOperations.js +29 -2
  57. package/lib/module/ui/context/hooks/useAuthOperations.js.map +1 -1
  58. package/lib/module/ui/context/hooks/useLanguageManagement.js.map +1 -1
  59. package/lib/module/ui/hooks/useLanguageManagement.js.map +1 -1
  60. package/lib/module/ui/hooks/useSessionManagement.js.map +1 -1
  61. package/lib/module/ui/index.js +0 -1
  62. package/lib/module/ui/index.js.map +1 -1
  63. package/lib/module/ui/screens/AccountSettingsScreen.js.map +1 -1
  64. package/lib/module/ui/screens/OxyAuthScreen.js +11 -2
  65. package/lib/module/ui/screens/OxyAuthScreen.js.map +1 -1
  66. package/lib/typescript/core/OxyServices.base.d.ts.map +1 -1
  67. package/lib/typescript/core/mixins/OxyServices.analytics.d.ts.map +1 -1
  68. package/lib/typescript/core/mixins/OxyServices.assets.d.ts.map +1 -1
  69. package/lib/typescript/core/mixins/OxyServices.auth.d.ts +1 -1
  70. package/lib/typescript/core/mixins/OxyServices.auth.d.ts.map +1 -1
  71. package/lib/typescript/core/mixins/OxyServices.developer.d.ts.map +1 -1
  72. package/lib/typescript/core/mixins/OxyServices.devices.d.ts.map +1 -1
  73. package/lib/typescript/core/mixins/OxyServices.karma.d.ts.map +1 -1
  74. package/lib/typescript/core/mixins/OxyServices.language.d.ts.map +1 -1
  75. package/lib/typescript/core/mixins/OxyServices.location.d.ts.map +1 -1
  76. package/lib/typescript/core/mixins/OxyServices.payment.d.ts.map +1 -1
  77. package/lib/typescript/core/mixins/OxyServices.privacy.d.ts.map +1 -1
  78. package/lib/typescript/core/mixins/OxyServices.security.d.ts.map +1 -1
  79. package/lib/typescript/core/mixins/OxyServices.user.d.ts +1 -2
  80. package/lib/typescript/core/mixins/OxyServices.user.d.ts.map +1 -1
  81. package/lib/typescript/core/mixins/OxyServices.utility.d.ts.map +1 -1
  82. package/lib/typescript/core/mixins/index.d.ts +13 -13
  83. package/lib/typescript/core/mixins/index.d.ts.map +1 -1
  84. package/lib/typescript/core/services/SessionService.d.ts +1 -1
  85. package/lib/typescript/core/services/SessionService.d.ts.map +1 -1
  86. package/lib/typescript/crypto/core.d.ts +56 -0
  87. package/lib/typescript/crypto/core.d.ts.map +1 -0
  88. package/lib/typescript/crypto/index.d.ts +1 -9
  89. package/lib/typescript/crypto/index.d.ts.map +1 -1
  90. package/lib/typescript/crypto/keyManager.d.ts +13 -1
  91. package/lib/typescript/crypto/keyManager.d.ts.map +1 -1
  92. package/lib/typescript/crypto/signatureService.d.ts +15 -9
  93. package/lib/typescript/crypto/signatureService.d.ts.map +1 -1
  94. package/lib/typescript/index.d.ts +1 -2
  95. package/lib/typescript/index.d.ts.map +1 -1
  96. package/lib/typescript/models/interfaces.d.ts +68 -15
  97. package/lib/typescript/models/interfaces.d.ts.map +1 -1
  98. package/lib/typescript/node/index.d.ts +1 -0
  99. package/lib/typescript/node/index.d.ts.map +1 -1
  100. package/lib/typescript/node/signatureService.d.ts +55 -0
  101. package/lib/typescript/node/signatureService.d.ts.map +1 -0
  102. package/lib/typescript/ui/context/OxyContext.d.ts +1 -2
  103. package/lib/typescript/ui/context/OxyContext.d.ts.map +1 -1
  104. package/lib/typescript/ui/context/hooks/useAuthOperations.d.ts +1 -2
  105. package/lib/typescript/ui/context/hooks/useAuthOperations.d.ts.map +1 -1
  106. package/lib/typescript/ui/context/hooks/useLanguageManagement.d.ts +1 -2
  107. package/lib/typescript/ui/context/hooks/useLanguageManagement.d.ts.map +1 -1
  108. package/lib/typescript/ui/hooks/mutations/useAccountMutations.d.ts +1 -1
  109. package/lib/typescript/ui/hooks/mutations/useAccountMutations.d.ts.map +1 -1
  110. package/lib/typescript/ui/hooks/queries/useAccountQueries.d.ts +1 -1
  111. package/lib/typescript/ui/hooks/queries/useAccountQueries.d.ts.map +1 -1
  112. package/lib/typescript/ui/hooks/useLanguageManagement.d.ts +1 -2
  113. package/lib/typescript/ui/hooks/useLanguageManagement.d.ts.map +1 -1
  114. package/lib/typescript/ui/hooks/useSessionManagement.d.ts +1 -2
  115. package/lib/typescript/ui/hooks/useSessionManagement.d.ts.map +1 -1
  116. package/lib/typescript/ui/index.d.ts +1 -1
  117. package/lib/typescript/ui/index.d.ts.map +1 -1
  118. package/lib/typescript/ui/screens/OxyAuthScreen.d.ts.map +1 -1
  119. package/lib/typescript/ui/stores/authStore.d.ts +1 -1
  120. package/lib/typescript/ui/stores/authStore.d.ts.map +1 -1
  121. package/lib/typescript/ui/utils/avatarUtils.d.ts +1 -1
  122. package/lib/typescript/ui/utils/avatarUtils.d.ts.map +1 -1
  123. package/package.json +6 -1
  124. package/src/core/OxyServices.base.ts +1 -2
  125. package/src/core/mixins/OxyServices.auth.ts +1 -1
  126. package/src/core/mixins/OxyServices.user.ts +1 -2
  127. package/src/core/mixins/OxyServices.utility.ts +1 -2
  128. package/src/core/services/SessionService.ts +1 -1
  129. package/src/crypto/README.md +142 -0
  130. package/src/crypto/__tests__/core.test.ts +203 -0
  131. package/src/crypto/core.ts +142 -0
  132. package/src/crypto/index.ts +3 -10
  133. package/src/crypto/keyManager.ts +25 -21
  134. package/src/crypto/signatureService.ts +137 -36
  135. package/src/index.ts +2 -3
  136. package/src/models/interfaces.ts +73 -21
  137. package/src/node/index.ts +3 -0
  138. package/src/node/signatureService.ts +126 -0
  139. package/src/ui/context/OxyContext.tsx +26 -2
  140. package/src/ui/context/hooks/useAuthOperations.ts +33 -4
  141. package/src/ui/context/hooks/useLanguageManagement.ts +1 -2
  142. package/src/ui/hooks/auth/index.ts +2 -0
  143. package/src/ui/hooks/mutations/useAccountMutations.ts +1 -1
  144. package/src/ui/hooks/mutations/useServicesMutations.ts +1 -1
  145. package/src/ui/hooks/queries/useAccountQueries.ts +1 -1
  146. package/src/ui/hooks/useLanguageManagement.ts +1 -2
  147. package/src/ui/hooks/useSessionManagement.ts +1 -2
  148. package/src/ui/index.ts +1 -2
  149. package/src/ui/screens/AccountSettingsScreen.tsx +6 -6
  150. package/src/ui/screens/AccountSwitcherScreen.tsx +1 -1
  151. package/src/ui/screens/OxyAuthScreen.tsx +11 -2
  152. package/src/ui/screens/ProfileScreen.tsx +1 -1
  153. package/src/ui/stores/authStore.ts +1 -1
  154. package/src/ui/types/navigation.ts +1 -1
  155. package/src/ui/utils/avatarUtils.ts +1 -1
  156. package/lib/commonjs/core/services/AuthService.js +0 -156
  157. package/lib/commonjs/core/services/AuthService.js.map +0 -1
  158. package/lib/commonjs/core/services/SessionTransportService.js +0 -64
  159. package/lib/commonjs/core/services/SessionTransportService.js.map +0 -1
  160. package/lib/commonjs/core/services/UserService.js +0 -123
  161. package/lib/commonjs/core/services/UserService.js.map +0 -1
  162. package/lib/commonjs/core/services/index.js +0 -34
  163. package/lib/commonjs/core/services/index.js.map +0 -1
  164. package/lib/commonjs/shared/crypto/messageBuilders.js +0 -79
  165. package/lib/commonjs/shared/crypto/messageBuilders.js.map +0 -1
  166. package/lib/commonjs/shared/crypto/platform.js +0 -118
  167. package/lib/commonjs/shared/crypto/platform.js.map +0 -1
  168. package/lib/commonjs/shared/crypto/signature.js +0 -191
  169. package/lib/commonjs/shared/crypto/signature.js.map +0 -1
  170. package/lib/commonjs/shared/index.js +0 -94
  171. package/lib/commonjs/shared/index.js.map +0 -1
  172. package/lib/commonjs/shared/models/index.js +0 -2
  173. package/lib/commonjs/shared/models/index.js.map +0 -1
  174. package/lib/commonjs/shared/transport/index.js +0 -260
  175. package/lib/commonjs/shared/transport/index.js.map +0 -1
  176. package/lib/commonjs/shared/utils/index.js +0 -82
  177. package/lib/commonjs/shared/utils/index.js.map +0 -1
  178. package/lib/module/core/services/AuthService.js +0 -151
  179. package/lib/module/core/services/AuthService.js.map +0 -1
  180. package/lib/module/core/services/SessionTransportService.js +0 -59
  181. package/lib/module/core/services/SessionTransportService.js.map +0 -1
  182. package/lib/module/core/services/UserService.js +0 -118
  183. package/lib/module/core/services/UserService.js.map +0 -1
  184. package/lib/module/core/services/index.js +0 -16
  185. package/lib/module/core/services/index.js.map +0 -1
  186. package/lib/module/shared/crypto/messageBuilders.js +0 -70
  187. package/lib/module/shared/crypto/messageBuilders.js.map +0 -1
  188. package/lib/module/shared/crypto/platform.js +0 -112
  189. package/lib/module/shared/crypto/platform.js.map +0 -1
  190. package/lib/module/shared/crypto/signature.js +0 -186
  191. package/lib/module/shared/crypto/signature.js.map +0 -1
  192. package/lib/module/shared/index.js +0 -30
  193. package/lib/module/shared/index.js.map +0 -1
  194. package/lib/module/shared/models/index.js +0 -2
  195. package/lib/module/shared/models/index.js.map +0 -1
  196. package/lib/module/shared/transport/index.js +0 -254
  197. package/lib/module/shared/transport/index.js.map +0 -1
  198. package/lib/module/shared/utils/index.js +0 -74
  199. package/lib/module/shared/utils/index.js.map +0 -1
  200. package/lib/typescript/core/services/AuthService.d.ts +0 -50
  201. package/lib/typescript/core/services/AuthService.d.ts.map +0 -1
  202. package/lib/typescript/core/services/SessionTransportService.d.ts +0 -31
  203. package/lib/typescript/core/services/SessionTransportService.d.ts.map +0 -1
  204. package/lib/typescript/core/services/UserService.d.ts +0 -39
  205. package/lib/typescript/core/services/UserService.d.ts.map +0 -1
  206. package/lib/typescript/core/services/index.d.ts +0 -13
  207. package/lib/typescript/core/services/index.d.ts.map +0 -1
  208. package/lib/typescript/shared/crypto/messageBuilders.d.ts +0 -38
  209. package/lib/typescript/shared/crypto/messageBuilders.d.ts.map +0 -1
  210. package/lib/typescript/shared/crypto/platform.d.ts +0 -54
  211. package/lib/typescript/shared/crypto/platform.d.ts.map +0 -1
  212. package/lib/typescript/shared/crypto/signature.d.ts +0 -72
  213. package/lib/typescript/shared/crypto/signature.d.ts.map +0 -1
  214. package/lib/typescript/shared/index.d.ts +0 -20
  215. package/lib/typescript/shared/index.d.ts.map +0 -1
  216. package/lib/typescript/shared/models/index.d.ts +0 -163
  217. package/lib/typescript/shared/models/index.d.ts.map +0 -1
  218. package/lib/typescript/shared/transport/index.d.ts +0 -73
  219. package/lib/typescript/shared/transport/index.d.ts.map +0 -1
  220. package/lib/typescript/shared/utils/index.d.ts +0 -28
  221. package/lib/typescript/shared/utils/index.d.ts.map +0 -1
  222. package/src/core/services/AuthService.ts +0 -153
  223. package/src/core/services/SessionTransportService.ts +0 -69
  224. package/src/core/services/UserService.ts +0 -125
  225. package/src/core/services/index.ts +0 -14
  226. package/src/shared/crypto/messageBuilders.ts +0 -89
  227. package/src/shared/crypto/platform.ts +0 -140
  228. package/src/shared/crypto/signature.ts +0 -235
  229. package/src/shared/index.ts +0 -28
  230. package/src/shared/models/index.ts +0 -173
  231. package/src/shared/transport/index.ts +0 -349
  232. package/src/shared/utils/index.ts +0 -73
@@ -1,125 +0,0 @@
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
-
@@ -1,14 +0,0 @@
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
-
@@ -1,89 +0,0 @@
1
- /**
2
- * Canonical Message Builders
3
- *
4
- * Creates standardized, canonical message formats for signing.
5
- * These formats are used consistently across Accounts, Services SDK, and API.
6
- */
7
-
8
- import type { SignedMessage, AuthChallengeResponse } from '../models/index';
9
-
10
- /**
11
- * Build authentication message for challenge-response
12
- * Format: auth:{publicKey}:{challenge}:{timestamp}
13
- */
14
- export function buildAuthMessage(
15
- publicKey: string,
16
- challenge: string,
17
- timestamp: number
18
- ): string {
19
- return `auth:${publicKey}:${challenge}:${timestamp}`;
20
- }
21
-
22
- /**
23
- * Build registration message
24
- * Format: oxy:register:{publicKey}:{timestamp}
25
- */
26
- export function buildRegistrationMessage(
27
- publicKey: string,
28
- timestamp: number
29
- ): string {
30
- return `oxy:register:${publicKey}:${timestamp}`;
31
- }
32
-
33
- /**
34
- * Build request signing message
35
- * Format: request:{publicKey}:{timestamp}:{canonicalData}
36
- */
37
- export function buildRequestMessage(
38
- publicKey: string,
39
- timestamp: number,
40
- data: Record<string, unknown>
41
- ): string {
42
- // Create canonical string representation
43
- const sortedKeys = Object.keys(data).sort();
44
- const canonicalParts = sortedKeys.map(key => `${key}:${JSON.stringify(data[key])}`);
45
- const canonicalString = canonicalParts.join('|');
46
-
47
- return `request:${publicKey}:${timestamp}:${canonicalString}`;
48
- }
49
-
50
- /**
51
- * Create canonical data representation for signing
52
- * Sorts keys and creates a consistent string representation
53
- */
54
- export function canonicalizeData(data: Record<string, unknown>): string {
55
- const sortedKeys = Object.keys(data).sort();
56
- const canonicalParts = sortedKeys.map(key => `${key}:${JSON.stringify(data[key])}`);
57
- return canonicalParts.join('|');
58
- }
59
-
60
- /**
61
- * Build auth challenge response payload
62
- * Helper to construct the signed challenge response
63
- */
64
- export function buildAuthChallengeResponse(
65
- publicKey: string,
66
- challenge: string,
67
- signature: string,
68
- timestamp: number
69
- ): AuthChallengeResponse {
70
- return {
71
- challenge,
72
- publicKey,
73
- signature,
74
- timestamp,
75
- };
76
- }
77
-
78
- /**
79
- * Validate timestamp freshness
80
- * Ensures signed messages are not too old
81
- */
82
- export function isTimestampFresh(
83
- timestamp: number,
84
- maxAgeMs: number = 5 * 60 * 1000 // 5 minutes default
85
- ): boolean {
86
- const now = Date.now();
87
- return (now - timestamp) <= maxAgeMs && timestamp <= now;
88
- }
89
-
@@ -1,140 +0,0 @@
1
- /**
2
- * Platform Detection and Adapters
3
- *
4
- * Provides environment detection and platform-specific crypto adapters
5
- * to support Node.js, React Native, and Web environments.
6
- */
7
-
8
- /**
9
- * Platform types
10
- */
11
- export type Platform = 'node' | 'react-native' | 'web';
12
-
13
- /**
14
- * Platform detection utilities
15
- */
16
- export const PlatformDetector = {
17
- /**
18
- * Detect current platform
19
- */
20
- detect(): Platform {
21
- if (typeof window === 'undefined' && typeof process !== 'undefined' && process.versions?.node) {
22
- return 'node';
23
- }
24
- if (typeof navigator !== 'undefined' && navigator.product === 'ReactNative') {
25
- return 'react-native';
26
- }
27
- return 'web';
28
- },
29
-
30
- /**
31
- * Check if running in Node.js
32
- */
33
- isNode(): boolean {
34
- return this.detect() === 'node';
35
- },
36
-
37
- /**
38
- * Check if running in React Native
39
- */
40
- isReactNative(): boolean {
41
- return this.detect() === 'react-native';
42
- },
43
-
44
- /**
45
- * Check if running in Web browser
46
- */
47
- isWeb(): boolean {
48
- return this.detect() === 'web';
49
- },
50
- };
51
-
52
- /**
53
- * Crypto adapter interface
54
- * Platform-specific implementations must implement this interface
55
- */
56
- export interface CryptoAdapter {
57
- /**
58
- * Generate random bytes
59
- */
60
- randomBytes(size: number): Promise<Uint8Array>;
61
-
62
- /**
63
- * Compute SHA-256 hash
64
- */
65
- sha256(message: string): Promise<string>;
66
-
67
- /**
68
- * Synchronous SHA-256 hash (Node.js only)
69
- */
70
- sha256Sync?(message: string): string;
71
- }
72
-
73
- /**
74
- * Get the appropriate crypto adapter for the current platform
75
- */
76
- export async function getCryptoAdapter(): Promise<CryptoAdapter> {
77
- const platform = PlatformDetector.detect();
78
-
79
- if (platform === 'node') {
80
- // eslint-disable-next-line @typescript-eslint/no-implied-eval
81
- const getCrypto = new Function('return require("crypto")');
82
- const crypto = getCrypto();
83
-
84
- return {
85
- async randomBytes(size: number): Promise<Uint8Array> {
86
- return new Uint8Array(crypto.randomBytes(size));
87
- },
88
- async sha256(message: string): Promise<string> {
89
- return crypto.createHash('sha256').update(message).digest('hex');
90
- },
91
- sha256Sync(message: string): string {
92
- return crypto.createHash('sha256').update(message).digest('hex');
93
- },
94
- };
95
- }
96
-
97
- if (platform === 'react-native') {
98
- // Lazy load expo-crypto (peer dependency)
99
- try {
100
- // @ts-ignore - expo-crypto is an optional peer dependency
101
- const ExpoCrypto = await import('expo-crypto');
102
-
103
- return {
104
- async randomBytes(size: number): Promise<Uint8Array> {
105
- const bytes = await ExpoCrypto.getRandomBytesAsync(size);
106
- return new Uint8Array(bytes);
107
- },
108
- async sha256(message: string): Promise<string> {
109
- return ExpoCrypto.digestStringAsync(
110
- ExpoCrypto.CryptoDigestAlgorithm.SHA256,
111
- message
112
- );
113
- },
114
- };
115
- } catch (error) {
116
- throw new Error(
117
- `expo-crypto is required in React Native environment: ${error instanceof Error ? error.message : String(error)}`
118
- );
119
- }
120
- }
121
-
122
- // Web platform - use Web Crypto API
123
- if (typeof window !== 'undefined' && window.crypto) {
124
- return {
125
- async randomBytes(size: number): Promise<Uint8Array> {
126
- return window.crypto.getRandomValues(new Uint8Array(size));
127
- },
128
- async sha256(message: string): Promise<string> {
129
- const encoder = new TextEncoder();
130
- const data = encoder.encode(message);
131
- const hashBuffer = await window.crypto.subtle.digest('SHA-256', data);
132
- const hashArray = Array.from(new Uint8Array(hashBuffer));
133
- return hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
134
- },
135
- };
136
- }
137
-
138
- throw new Error('No suitable crypto implementation found for current platform');
139
- }
140
-
@@ -1,235 +0,0 @@
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
-
@@ -1,28 +0,0 @@
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
-