@oxyhq/services 5.9.2 → 5.9.3

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 (202) hide show
  1. package/README.md +1 -33
  2. package/lib/commonjs/core/OxyServices.js +159 -0
  3. package/lib/commonjs/core/OxyServices.js.map +1 -0
  4. package/lib/commonjs/core/OxyServicesMain.js +51 -0
  5. package/lib/commonjs/core/OxyServicesMain.js.map +1 -0
  6. package/lib/commonjs/core/analytics/AnalyticsService.js +67 -0
  7. package/lib/commonjs/core/analytics/AnalyticsService.js.map +1 -0
  8. package/lib/commonjs/core/auth/AuthService.js +526 -0
  9. package/lib/commonjs/core/auth/AuthService.js.map +1 -0
  10. package/lib/commonjs/core/devices/DeviceService.js +61 -0
  11. package/lib/commonjs/core/devices/DeviceService.js.map +1 -0
  12. package/lib/commonjs/core/files/FileService.js +176 -0
  13. package/lib/commonjs/core/files/FileService.js.map +1 -0
  14. package/lib/commonjs/core/index.js +103 -1701
  15. package/lib/commonjs/core/index.js.map +1 -1
  16. package/lib/commonjs/core/karma/KarmaService.js +100 -0
  17. package/lib/commonjs/core/karma/KarmaService.js.map +1 -0
  18. package/lib/commonjs/core/locations/LocationService.js +131 -0
  19. package/lib/commonjs/core/locations/LocationService.js.map +1 -0
  20. package/lib/commonjs/core/payments/PaymentService.js +124 -0
  21. package/lib/commonjs/core/payments/PaymentService.js.map +1 -0
  22. package/lib/commonjs/core/users/UserService.js +234 -0
  23. package/lib/commonjs/core/users/UserService.js.map +1 -0
  24. package/lib/commonjs/index.js +164 -3
  25. package/lib/commonjs/index.js.map +1 -1
  26. package/lib/commonjs/models/session.js +2 -0
  27. package/lib/commonjs/{types/middleware.js.map → models/session.js.map} +1 -1
  28. package/lib/commonjs/ui/context/OxyContext.js +28 -24
  29. package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
  30. package/lib/commonjs/ui/screens/AccountSwitcherScreen.js +2 -2
  31. package/lib/commonjs/ui/screens/AccountSwitcherScreen.js.map +1 -1
  32. package/lib/commonjs/ui/screens/FileManagementScreen.js +12 -12
  33. package/lib/commonjs/ui/screens/FileManagementScreen.js.map +1 -1
  34. package/lib/commonjs/ui/screens/ProfileScreen.js +2 -2
  35. package/lib/commonjs/ui/screens/ProfileScreen.js.map +1 -1
  36. package/lib/commonjs/ui/screens/SessionManagementScreen.js.map +1 -1
  37. package/lib/commonjs/ui/screens/SignInScreen.js +1 -1
  38. package/lib/commonjs/ui/screens/SignInScreen.js.map +1 -1
  39. package/lib/commonjs/ui/screens/karma/KarmaCenterScreen.js +1 -1
  40. package/lib/commonjs/ui/screens/karma/KarmaCenterScreen.js.map +1 -1
  41. package/lib/commonjs/ui/screens/karma/KarmaLeaderboardScreen.js +1 -1
  42. package/lib/commonjs/ui/screens/karma/KarmaLeaderboardScreen.js.map +1 -1
  43. package/lib/commonjs/ui/screens/karma/KarmaRulesScreen.js +1 -1
  44. package/lib/commonjs/ui/screens/karma/KarmaRulesScreen.js.map +1 -1
  45. package/lib/commonjs/ui/stores/followStore.js +4 -4
  46. package/lib/commonjs/ui/stores/followStore.js.map +1 -1
  47. package/lib/commonjs/utils/apiUtils.js +93 -0
  48. package/lib/commonjs/utils/apiUtils.js.map +1 -0
  49. package/lib/commonjs/utils/asyncUtils.js +219 -0
  50. package/lib/commonjs/utils/asyncUtils.js.map +1 -0
  51. package/lib/commonjs/utils/errorUtils.js +148 -0
  52. package/lib/commonjs/utils/errorUtils.js.map +1 -0
  53. package/lib/commonjs/utils/hookUtils.js +399 -0
  54. package/lib/commonjs/utils/hookUtils.js.map +1 -0
  55. package/lib/commonjs/utils/loggerUtils.js +160 -0
  56. package/lib/commonjs/utils/loggerUtils.js.map +1 -0
  57. package/lib/commonjs/utils/validationUtils.js +174 -0
  58. package/lib/commonjs/utils/validationUtils.js.map +1 -0
  59. package/lib/module/core/OxyServices.js +153 -0
  60. package/lib/module/core/OxyServices.js.map +1 -0
  61. package/lib/module/core/OxyServicesMain.js +47 -0
  62. package/lib/module/core/OxyServicesMain.js.map +1 -0
  63. package/lib/module/core/analytics/AnalyticsService.js +62 -0
  64. package/lib/module/core/analytics/AnalyticsService.js.map +1 -0
  65. package/lib/module/core/auth/AuthService.js +521 -0
  66. package/lib/module/core/auth/AuthService.js.map +1 -0
  67. package/lib/module/core/devices/DeviceService.js +57 -0
  68. package/lib/module/core/devices/DeviceService.js.map +1 -0
  69. package/lib/module/core/files/FileService.js +171 -0
  70. package/lib/module/core/files/FileService.js.map +1 -0
  71. package/lib/module/core/index.js +25 -1690
  72. package/lib/module/core/index.js.map +1 -1
  73. package/lib/module/core/karma/KarmaService.js +95 -0
  74. package/lib/module/core/karma/KarmaService.js.map +1 -0
  75. package/lib/module/core/locations/LocationService.js +127 -0
  76. package/lib/module/core/locations/LocationService.js.map +1 -0
  77. package/lib/module/core/payments/PaymentService.js +119 -0
  78. package/lib/module/core/payments/PaymentService.js.map +1 -0
  79. package/lib/module/core/users/UserService.js +230 -0
  80. package/lib/module/core/users/UserService.js.map +1 -0
  81. package/lib/module/index.js +8 -4
  82. package/lib/module/index.js.map +1 -1
  83. package/lib/module/models/session.js +2 -0
  84. package/lib/module/{types/middleware.js.map → models/session.js.map} +1 -1
  85. package/lib/module/ui/context/OxyContext.js +28 -24
  86. package/lib/module/ui/context/OxyContext.js.map +1 -1
  87. package/lib/module/ui/screens/AccountSwitcherScreen.js +2 -2
  88. package/lib/module/ui/screens/AccountSwitcherScreen.js.map +1 -1
  89. package/lib/module/ui/screens/FileManagementScreen.js +12 -12
  90. package/lib/module/ui/screens/FileManagementScreen.js.map +1 -1
  91. package/lib/module/ui/screens/ProfileScreen.js +2 -2
  92. package/lib/module/ui/screens/ProfileScreen.js.map +1 -1
  93. package/lib/module/ui/screens/SessionManagementScreen.js.map +1 -1
  94. package/lib/module/ui/screens/SignInScreen.js +1 -1
  95. package/lib/module/ui/screens/SignInScreen.js.map +1 -1
  96. package/lib/module/ui/screens/karma/KarmaCenterScreen.js +1 -1
  97. package/lib/module/ui/screens/karma/KarmaCenterScreen.js.map +1 -1
  98. package/lib/module/ui/screens/karma/KarmaLeaderboardScreen.js +1 -1
  99. package/lib/module/ui/screens/karma/KarmaLeaderboardScreen.js.map +1 -1
  100. package/lib/module/ui/screens/karma/KarmaRulesScreen.js +1 -1
  101. package/lib/module/ui/screens/karma/KarmaRulesScreen.js.map +1 -1
  102. package/lib/module/ui/stores/followStore.js +4 -4
  103. package/lib/module/ui/stores/followStore.js.map +1 -1
  104. package/lib/module/utils/apiUtils.js +85 -0
  105. package/lib/module/utils/apiUtils.js.map +1 -0
  106. package/lib/module/utils/asyncUtils.js +202 -0
  107. package/lib/module/utils/asyncUtils.js.map +1 -0
  108. package/lib/module/utils/errorUtils.js +139 -0
  109. package/lib/module/utils/errorUtils.js.map +1 -0
  110. package/lib/module/utils/hookUtils.js +381 -0
  111. package/lib/module/utils/hookUtils.js.map +1 -0
  112. package/lib/module/utils/loggerUtils.js +149 -0
  113. package/lib/module/utils/loggerUtils.js.map +1 -0
  114. package/lib/module/utils/validationUtils.js +154 -0
  115. package/lib/module/utils/validationUtils.js.map +1 -0
  116. package/lib/typescript/core/OxyServices.d.ts +64 -0
  117. package/lib/typescript/core/OxyServices.d.ts.map +1 -0
  118. package/lib/typescript/core/OxyServicesMain.d.ts +33 -0
  119. package/lib/typescript/core/OxyServicesMain.d.ts.map +1 -0
  120. package/lib/typescript/core/analytics/AnalyticsService.d.ts +26 -0
  121. package/lib/typescript/core/analytics/AnalyticsService.d.ts.map +1 -0
  122. package/lib/typescript/core/auth/AuthService.d.ts +165 -0
  123. package/lib/typescript/core/auth/AuthService.d.ts.map +1 -0
  124. package/lib/typescript/core/devices/DeviceService.d.ts +20 -0
  125. package/lib/typescript/core/devices/DeviceService.d.ts.map +1 -0
  126. package/lib/typescript/core/files/FileService.d.ts +59 -0
  127. package/lib/typescript/core/files/FileService.d.ts.map +1 -0
  128. package/lib/typescript/core/index.d.ts +19 -656
  129. package/lib/typescript/core/index.d.ts.map +1 -1
  130. package/lib/typescript/core/karma/KarmaService.d.ts +50 -0
  131. package/lib/typescript/core/karma/KarmaService.d.ts.map +1 -0
  132. package/lib/typescript/core/locations/LocationService.d.ts +39 -0
  133. package/lib/typescript/core/locations/LocationService.d.ts.map +1 -0
  134. package/lib/typescript/core/payments/PaymentService.d.ts +50 -0
  135. package/lib/typescript/core/payments/PaymentService.d.ts.map +1 -0
  136. package/lib/typescript/core/users/UserService.d.ts +111 -0
  137. package/lib/typescript/core/users/UserService.d.ts.map +1 -0
  138. package/lib/typescript/index.d.ts +7 -3
  139. package/lib/typescript/index.d.ts.map +1 -1
  140. package/lib/typescript/models/{secureSession.d.ts → session.d.ts} +4 -4
  141. package/lib/typescript/models/session.d.ts.map +1 -0
  142. package/lib/typescript/ui/context/OxyContext.d.ts +2 -2
  143. package/lib/typescript/ui/context/OxyContext.d.ts.map +1 -1
  144. package/lib/typescript/utils/apiUtils.d.ts +61 -0
  145. package/lib/typescript/utils/apiUtils.d.ts.map +1 -0
  146. package/lib/typescript/utils/asyncUtils.d.ts +64 -0
  147. package/lib/typescript/utils/asyncUtils.d.ts.map +1 -0
  148. package/lib/typescript/utils/errorUtils.d.ts +45 -0
  149. package/lib/typescript/utils/errorUtils.d.ts.map +1 -0
  150. package/lib/typescript/utils/hookUtils.d.ts +102 -0
  151. package/lib/typescript/utils/hookUtils.d.ts.map +1 -0
  152. package/lib/typescript/utils/loggerUtils.d.ts +49 -0
  153. package/lib/typescript/utils/loggerUtils.d.ts.map +1 -0
  154. package/lib/typescript/utils/validationUtils.d.ts +80 -0
  155. package/lib/typescript/utils/validationUtils.d.ts.map +1 -0
  156. package/package.json +2 -8
  157. package/src/core/OxyServices.ts +168 -0
  158. package/src/core/OxyServicesMain.ts +57 -0
  159. package/src/core/analytics/AnalyticsService.ts +64 -0
  160. package/src/core/auth/AuthService.ts +544 -0
  161. package/src/core/devices/DeviceService.ts +55 -0
  162. package/src/core/files/FileService.ts +194 -0
  163. package/src/core/index.ts +27 -1765
  164. package/src/core/karma/KarmaService.ts +104 -0
  165. package/src/core/locations/LocationService.ts +141 -0
  166. package/src/core/payments/PaymentService.ts +133 -0
  167. package/src/core/users/UserService.ts +241 -0
  168. package/src/index.ts +29 -8
  169. package/src/models/{secureSession.ts → session.ts} +5 -5
  170. package/src/ui/context/OxyContext.tsx +34 -30
  171. package/src/ui/screens/AccountSwitcherScreen.tsx +4 -4
  172. package/src/ui/screens/FileManagementScreen.tsx +12 -12
  173. package/src/ui/screens/ProfileScreen.tsx +3 -3
  174. package/src/ui/screens/SessionManagementScreen.tsx +2 -2
  175. package/src/ui/screens/SignInScreen.tsx +1 -1
  176. package/src/ui/screens/karma/KarmaCenterScreen.tsx +2 -2
  177. package/src/ui/screens/karma/KarmaLeaderboardScreen.tsx +3 -3
  178. package/src/ui/screens/karma/KarmaRulesScreen.tsx +3 -3
  179. package/src/ui/stores/followStore.ts +4 -4
  180. package/src/utils/apiUtils.ts +102 -0
  181. package/src/utils/asyncUtils.ts +265 -0
  182. package/src/utils/errorUtils.ts +172 -0
  183. package/src/utils/hookUtils.ts +397 -0
  184. package/src/utils/loggerUtils.ts +153 -0
  185. package/src/utils/validationUtils.ts +158 -0
  186. package/lib/commonjs/middleware.js +0 -17
  187. package/lib/commonjs/middleware.js.map +0 -1
  188. package/lib/commonjs/models/secureSession.js +0 -2
  189. package/lib/commonjs/models/secureSession.js.map +0 -1
  190. package/lib/commonjs/types/middleware.js +0 -6
  191. package/lib/module/middleware.js +0 -12
  192. package/lib/module/middleware.js.map +0 -1
  193. package/lib/module/models/secureSession.js +0 -2
  194. package/lib/module/models/secureSession.js.map +0 -1
  195. package/lib/module/types/middleware.js +0 -4
  196. package/lib/typescript/middleware.d.ts +0 -9
  197. package/lib/typescript/middleware.d.ts.map +0 -1
  198. package/lib/typescript/models/secureSession.d.ts.map +0 -1
  199. package/lib/typescript/types/middleware.d.ts +0 -19
  200. package/lib/typescript/types/middleware.d.ts.map +0 -1
  201. package/src/middleware.ts +0 -11
  202. package/src/types/middleware.ts +0 -20
@@ -4,20 +4,102 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  var _exportNames = {
7
- OXY_CLOUD_URL: true,
8
7
  OxyServices: true,
8
+ AuthService: true,
9
+ UserService: true,
10
+ PaymentService: true,
11
+ KarmaService: true,
12
+ FileService: true,
13
+ OXY_CLOUD_URL: true,
14
+ LocationService: true,
15
+ AnalyticsService: true,
16
+ DeviceService: true,
17
+ BaseOxyServices: true,
9
18
  DeviceManager: true
10
19
  };
20
+ Object.defineProperty(exports, "AnalyticsService", {
21
+ enumerable: true,
22
+ get: function () {
23
+ return _AnalyticsService.AnalyticsService;
24
+ }
25
+ });
26
+ Object.defineProperty(exports, "AuthService", {
27
+ enumerable: true,
28
+ get: function () {
29
+ return _AuthService.AuthService;
30
+ }
31
+ });
32
+ Object.defineProperty(exports, "BaseOxyServices", {
33
+ enumerable: true,
34
+ get: function () {
35
+ return _OxyServices.OxyServices;
36
+ }
37
+ });
11
38
  Object.defineProperty(exports, "DeviceManager", {
12
39
  enumerable: true,
13
40
  get: function () {
14
41
  return _deviceManager.DeviceManager;
15
42
  }
16
43
  });
17
- exports.default = exports.OxyServices = exports.OXY_CLOUD_URL = void 0;
18
- var _axios = _interopRequireDefault(require("axios"));
19
- var _jwtDecode = require("jwt-decode");
20
- var _deviceManager = require("../utils/deviceManager");
44
+ Object.defineProperty(exports, "DeviceService", {
45
+ enumerable: true,
46
+ get: function () {
47
+ return _DeviceService.DeviceService;
48
+ }
49
+ });
50
+ Object.defineProperty(exports, "FileService", {
51
+ enumerable: true,
52
+ get: function () {
53
+ return _FileService.FileService;
54
+ }
55
+ });
56
+ Object.defineProperty(exports, "KarmaService", {
57
+ enumerable: true,
58
+ get: function () {
59
+ return _KarmaService.KarmaService;
60
+ }
61
+ });
62
+ Object.defineProperty(exports, "LocationService", {
63
+ enumerable: true,
64
+ get: function () {
65
+ return _LocationService.LocationService;
66
+ }
67
+ });
68
+ Object.defineProperty(exports, "OXY_CLOUD_URL", {
69
+ enumerable: true,
70
+ get: function () {
71
+ return _FileService.OXY_CLOUD_URL;
72
+ }
73
+ });
74
+ Object.defineProperty(exports, "OxyServices", {
75
+ enumerable: true,
76
+ get: function () {
77
+ return _OxyServicesMain.OxyServicesMain;
78
+ }
79
+ });
80
+ Object.defineProperty(exports, "PaymentService", {
81
+ enumerable: true,
82
+ get: function () {
83
+ return _PaymentService.PaymentService;
84
+ }
85
+ });
86
+ Object.defineProperty(exports, "UserService", {
87
+ enumerable: true,
88
+ get: function () {
89
+ return _UserService.UserService;
90
+ }
91
+ });
92
+ exports.default = void 0;
93
+ var _OxyServicesMain = require("./OxyServicesMain");
94
+ var _AuthService = require("./auth/AuthService");
95
+ var _UserService = require("./users/UserService");
96
+ var _PaymentService = require("./payments/PaymentService");
97
+ var _KarmaService = require("./karma/KarmaService");
98
+ var _FileService = require("./files/FileService");
99
+ var _LocationService = require("./locations/LocationService");
100
+ var _AnalyticsService = require("./analytics/AnalyticsService");
101
+ var _DeviceService = require("./devices/DeviceService");
102
+ var _OxyServices = require("./OxyServices");
21
103
  var _interfaces = require("../models/interfaces");
22
104
  Object.keys(_interfaces).forEach(function (key) {
23
105
  if (key === "default" || key === "__esModule") return;
@@ -30,1712 +112,32 @@ Object.keys(_interfaces).forEach(function (key) {
30
112
  }
31
113
  });
32
114
  });
33
- var _secureSession = require("../models/secureSession");
34
- Object.keys(_secureSession).forEach(function (key) {
115
+ var _session = require("../models/session");
116
+ Object.keys(_session).forEach(function (key) {
35
117
  if (key === "default" || key === "__esModule") return;
36
118
  if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
37
- if (key in exports && exports[key] === _secureSession[key]) return;
119
+ if (key in exports && exports[key] === _session[key]) return;
38
120
  Object.defineProperty(exports, key, {
39
121
  enumerable: true,
40
122
  get: function () {
41
- return _secureSession[key];
123
+ return _session[key];
42
124
  }
43
125
  });
44
126
  });
45
- function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
46
- // Remove all FormData, form-data, and polyfill logic. Delete uploadFile and uploadFiles methods. Add a comment to use the new raw upload approach instead.
47
-
48
- // Import secure session types
49
-
50
- /**
51
- * Default cloud URL for Oxy services, cloud is where the user files are. (e.g. images, videos, etc.). Not the API.
52
- */
53
- const OXY_CLOUD_URL = exports.OXY_CLOUD_URL = 'https://cloud.oxy.so';
54
-
55
- // Export device management utilities
56
-
127
+ var _deviceManager = require("../utils/deviceManager");
57
128
  /**
58
- * OxyServices - Client library for interacting with the Oxy API
129
+ * OxyServices Core Module - Modular Architecture
59
130
  *
60
- * Note: For authentication status in UI components, use `isAuthenticated` from useOxy() context
61
- * instead of checking token status directly on this service.
131
+ * This module exports the main OxyServices class and all individual service modules
132
+ * for a clean, maintainable, and focused architecture.
62
133
  */
63
- class OxyServices {
64
- accessToken = null;
65
- refreshToken = null;
66
-
67
- /**
68
- * Creates a new instance of the OxyServices client
69
- * @param config - Configuration for the client
70
- */
71
- constructor(config) {
72
- this.client = _axios.default.create({
73
- baseURL: config.baseURL,
74
- timeout: 10000 // 10 second timeout
75
- });
76
-
77
- // Interceptor for adding auth header and handling token refresh
78
- this.client.interceptors.request.use(async req => {
79
- if (!this.accessToken) {
80
- return req;
81
- }
82
-
83
- // Check if token is expired and refresh if needed
84
- try {
85
- const decoded = (0, _jwtDecode.jwtDecode)(this.accessToken);
86
- const currentTime = Math.floor(Date.now() / 1000);
87
-
88
- // If token expires in less than 60 seconds, refresh it
89
- if (decoded.exp - currentTime < 60) {
90
- // For session-based tokens, get a new token from the session
91
- if (decoded.sessionId) {
92
- try {
93
- const res = await this.client.get(`/secure-session/token/${decoded.sessionId}`);
94
- this.accessToken = res.data.accessToken;
95
- } catch (refreshError) {
96
- // If refresh fails, clear tokens
97
- this.clearTokens();
98
- }
99
- }
100
- }
101
- } catch (error) {
102
- // If token can't be decoded, continue with request and let server handle it
103
- console.warn('Error decoding JWT token', error);
104
- }
105
- req.headers = req.headers || {};
106
- req.headers.Authorization = `Bearer ${this.accessToken}`;
107
- return req;
108
- });
109
-
110
- // Response interceptor for handling errors
111
- this.client.interceptors.response.use(response => response, async error => {
112
- const originalRequest = error.config;
113
- // If the error is due to an expired token and we haven't tried refreshing yet
114
- if (error.response?.status === 401 && this.accessToken && originalRequest && !originalRequest.headers?.['X-Retry-After-Refresh']) {
115
- try {
116
- // Check if token is session-based and try to refresh
117
- const decoded = (0, _jwtDecode.jwtDecode)(this.accessToken);
118
- if (decoded.sessionId) {
119
- const res = await this.client.get(`/secure-session/token/${decoded.sessionId}`);
120
- this.accessToken = res.data.accessToken;
121
-
122
- // Retry the original request with new token
123
- const newRequest = {
124
- ...originalRequest
125
- };
126
- if (newRequest.headers) {
127
- newRequest.headers.Authorization = `Bearer ${this.accessToken}`;
128
- newRequest.headers['X-Retry-After-Refresh'] = 'true';
129
- }
130
- return this.client(newRequest);
131
- }
132
- } catch (refreshError) {
133
- // If refresh fails, force user to login again
134
- this.clearTokens();
135
- return Promise.reject(refreshError);
136
- }
137
- }
138
-
139
- // Format error response
140
- const apiError = {
141
- message: error.response?.data?.error || error.response?.data?.message || 'An unknown error occurred',
142
- code: error.response?.data?.code || 'UNKNOWN_ERROR',
143
- status: error.response?.status || 500,
144
- details: error.response?.data
145
- };
146
-
147
- // If the error is an invalid session, clear tokens
148
- if (apiError.code === 'INVALID_SESSION' || apiError.message === 'Invalid session') {
149
- this.clearTokens();
150
- }
151
- return Promise.reject(apiError);
152
- });
153
- }
154
-
155
- /**
156
- * Gets the base URL configured for this OxyServices instance
157
- * @returns The base URL
158
- */
159
- getBaseURL() {
160
- return this.client.defaults.baseURL || '';
161
- }
162
-
163
- /**
164
- * Set authentication tokens manually
165
- * @param accessToken - The access token
166
- * @param refreshToken - The refresh token (optional for session-based auth)
167
- */
168
- setTokens(accessToken, refreshToken = '') {
169
- this.accessToken = accessToken;
170
- this.refreshToken = refreshToken;
171
- }
172
-
173
- /**
174
- * Clear stored authentication tokens
175
- */
176
- clearTokens() {
177
- this.accessToken = null;
178
- this.refreshToken = null;
179
- }
180
-
181
- /**
182
- * Get the current user ID from the stored token
183
- * @returns User ID or null if not authenticated
184
- */
185
- getCurrentUserId() {
186
- if (!this.accessToken) return null;
187
- try {
188
- const decoded = (0, _jwtDecode.jwtDecode)(this.accessToken);
189
- return decoded.userId || decoded.id || null;
190
- } catch (error) {
191
- return null;
192
- }
193
- }
194
-
195
- /**
196
- * Internal method to check if we have an access token
197
- * @private
198
- * @returns Boolean indicating if access token exists
199
- * @internal - Use `isAuthenticated` from useOxy() context in UI components instead
200
- */
201
- hasAccessToken() {
202
- return this.accessToken !== null;
203
- }
204
-
205
- /**
206
- * Validate current access token
207
- * @returns Boolean indicating if the token is valid
208
- */
209
- async validate() {
210
- try {
211
- // Check if token contains sessionId (new session-based system)
212
- if (this.accessToken) {
213
- try {
214
- const decoded = (0, _jwtDecode.jwtDecode)(this.accessToken);
215
- if (decoded.sessionId) {
216
- // Use session-based validation
217
- const res = await this.client.get(`/secure-session/validate/${decoded.sessionId}`);
218
- return res.data.valid;
219
- }
220
- } catch (decodeError) {
221
- // If token can't be decoded, fall back to old validation
222
- console.warn('Error decoding JWT token for session validation:', decodeError);
223
- }
224
- }
225
-
226
- // Fall back to old validation method
227
- const res = await this.client.get('/auth/validate');
228
- return res.data.valid;
229
- } catch (error) {
230
- return false;
231
- }
232
- }
233
-
234
- /* Session Management Methods */
235
-
236
- /**
237
- * Get device sessions for a specific session ID
238
- * @param sessionId - The session ID to get device sessions for
239
- * @param deviceId - Optional device ID filter
240
- * @returns Array of device sessions
241
- */
242
- async getDeviceSessions(sessionId, deviceId) {
243
- try {
244
- const params = deviceId ? {
245
- deviceId
246
- } : {};
247
- const res = await this.client.get(`/secure-session/device/sessions/${sessionId}`, {
248
- params
249
- });
250
-
251
- // Map backend response to frontend interface
252
- return (res.data.sessions || []).map(session => ({
253
- sessionId: session.sessionId,
254
- deviceId: res.data.deviceId || '',
255
- deviceName: session.deviceInfo?.deviceName || 'Unknown Device',
256
- isActive: true,
257
- // All returned sessions are active
258
- lastActive: session.lastActive,
259
- expiresAt: session.expiresAt || new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString(),
260
- isCurrent: session.sessionId === sessionId,
261
- user: session.user,
262
- createdAt: session.createdAt
263
- }));
264
- } catch (error) {
265
- throw this.handleError(error);
266
- }
267
- }
268
-
269
- /**
270
- * Logout all device sessions for a specific device
271
- * @param sessionId - The session ID
272
- * @param deviceId - Optional device ID (uses current session's device if not provided)
273
- * @param excludeCurrent - Whether to exclude the current session from logout
274
- * @returns Logout response
275
- */
276
- async logoutAllDeviceSessions(sessionId, deviceId, excludeCurrent) {
277
- try {
278
- const data = {};
279
- if (deviceId) data.deviceId = deviceId;
280
- if (excludeCurrent !== undefined) data.excludeCurrent = excludeCurrent;
281
- const res = await this.client.post(`/secure-session/device/logout-all/${sessionId}`, data);
282
- return res.data;
283
- } catch (error) {
284
- throw this.handleError(error);
285
- }
286
- }
287
-
288
- /**
289
- * Update device name for a session
290
- * @param sessionId - The session ID
291
- * @param deviceName - The new device name
292
- * @returns Update response
293
- */
294
- async updateDeviceName(sessionId, deviceName) {
295
- try {
296
- const res = await this.client.put(`/secure-session/device/name/${sessionId}`, {
297
- deviceName
298
- });
299
- return res.data;
300
- } catch (error) {
301
- throw this.handleError(error);
302
- }
303
- }
304
-
305
- /* Profile Methods */
306
-
307
- /**
308
- * Fetch profile by username
309
- * @param username - The username to look up
310
- * @returns User profile data
311
- */
312
- async getProfileByUsername(username) {
313
- try {
314
- const res = await this.client.get(`/profiles/username/${username}`);
315
- return res.data;
316
- } catch (error) {
317
- throw this.handleError(error);
318
- }
319
- }
320
-
321
- /**
322
- * Search profiles
323
- * @param query - Search query string
324
- * @param limit - Maximum number of results to return
325
- * @param offset - Number of results to skip for pagination
326
- * @returns Array of matching user profiles
327
- */
328
- async searchProfiles(query, limit, offset) {
329
- try {
330
- const params = {
331
- query
332
- };
333
- if (limit !== undefined) params.limit = limit;
334
- if (offset !== undefined) params.offset = offset;
335
- const res = await this.client.get('/profiles/search', {
336
- params
337
- });
338
- return res.data;
339
- } catch (error) {
340
- throw this.handleError(error);
341
- }
342
- }
343
-
344
- /**
345
- * Get recommended profiles for the authenticated user
346
- * @returns Array of recommended profiles
347
- */
348
- async getProfileRecommendations() {
349
- try {
350
- const res = await this.client.get('/profiles/recommendations');
351
- return res.data;
352
- } catch (error) {
353
- throw this.handleError(error);
354
- }
355
- }
356
-
357
- /* User Methods */
358
-
359
- /**
360
- * Get general user by ID
361
- * @param userId - The user ID to look up
362
- * @returns User data
363
- */
364
- async getUserById(userId) {
365
- try {
366
- const res = await this.client.get(`/users/${userId}`);
367
- return res.data;
368
- } catch (error) {
369
- throw this.handleError(error);
370
- }
371
- }
372
-
373
- /**
374
- * Get the currently authenticated user's profile
375
- * @returns User data for the current user
376
- */
377
- async getCurrentUser() {
378
- try {
379
- console.log('OxyServices: Fetching current user...');
380
- const res = await this.client.get('/users/me');
381
- console.log('OxyServices: Current user response:', {
382
- hasUser: !!res.data,
383
- userLinksMetadata: res.data?.linksMetadata,
384
- userLinks: res.data?.links,
385
- userWebsite: res.data?.website
386
- });
387
- return res.data;
388
- } catch (error) {
389
- console.error('OxyServices: Error fetching current user:', error);
390
- throw this.handleError(error);
391
- }
392
- }
393
-
394
- /**
395
- * Update the authenticated user's profile
396
- * @param updates - Object containing fields to update
397
- * @returns Updated user data
398
- */
399
- async updateProfile(updates) {
400
- try {
401
- console.log('OxyServices: Updating profile with:', updates);
402
- const res = await this.client.put('/users/me', updates);
403
- console.log('OxyServices: Profile update response:', res.data);
404
- return res.data;
405
- } catch (error) {
406
- console.error('OxyServices: Error updating profile:', error);
407
- throw this.handleError(error);
408
- }
409
- }
410
-
411
- /**
412
- * Update user profile (requires auth)
413
- * @param userId - User ID to update (must match authenticated user or have admin rights)
414
- * @param updates - Object containing fields to update
415
- * @returns Updated user data
416
- */
417
- async updateUser(userId, updates) {
418
- try {
419
- const res = await this.client.put(`/users/${userId}`, updates);
420
- return res.data;
421
- } catch (error) {
422
- throw this.handleError(error);
423
- }
424
- }
425
-
426
- /**
427
- * Follow a user
428
- * @param userId - User ID to follow
429
- * @returns Status of the follow operation
430
- */
431
- async followUser(userId) {
432
- try {
433
- const res = await this.client.post(`/users/${userId}/follow`);
434
- return res.data;
435
- } catch (error) {
436
- throw this.handleError(error);
437
- }
438
- }
439
-
440
- /**
441
- * Unfollow a user
442
- * @param userId - User ID to unfollow
443
- * @returns Status of the unfollow operation
444
- */
445
- async unfollowUser(userId) {
446
- try {
447
- const res = await this.client.delete(`/users/${userId}/follow`);
448
- return res.data;
449
- } catch (error) {
450
- throw this.handleError(error);
451
- }
452
- }
453
-
454
- /**
455
- * Get follow status for a user
456
- * @param userId - User ID to check follow status for
457
- * @returns Whether the current user is following the specified user
458
- */
459
- async getFollowStatus(userId) {
460
- try {
461
- const res = await this.client.get(`/users/${userId}/following-status`);
462
- return res.data;
463
- } catch (error) {
464
- throw this.handleError(error);
465
- }
466
- }
467
-
468
- /**
469
- * Get all followers of a user
470
- * @param userId - User ID to get followers for
471
- * @param limit - Maximum number of followers to return
472
- * @param offset - Number of followers to skip for pagination
473
- * @returns Array of users who follow the specified user and pagination info
474
- */
475
- async getUserFollowers(userId, limit, offset) {
476
- try {
477
- const params = {};
478
- if (limit !== undefined) params.limit = limit;
479
- if (offset !== undefined) params.offset = offset;
480
- const res = await this.client.get(`/users/${userId}/followers`, {
481
- params
482
- });
483
- return res.data;
484
- } catch (error) {
485
- throw this.handleError(error);
486
- }
487
- }
488
-
489
- /**
490
- * Get all users that a user is following
491
- * @param userId - User ID to get following list for
492
- * @param limit - Maximum number of users to return
493
- * @param offset - Number of users to skip for pagination
494
- * @returns Array of users the specified user follows and pagination info
495
- */
496
- async getUserFollowing(userId, limit, offset) {
497
- try {
498
- const params = {};
499
- if (limit !== undefined) params.limit = limit;
500
- if (offset !== undefined) params.offset = offset;
501
- const res = await this.client.get(`/users/${userId}/following`, {
502
- params
503
- });
504
- return res.data;
505
- } catch (error) {
506
- throw this.handleError(error);
507
- }
508
- }
509
-
510
- /* Notification Methods */
511
-
512
- /**
513
- * Fetch all notifications for the authenticated user
514
- * @returns Array of notifications
515
- */
516
- async getNotifications() {
517
- try {
518
- const res = await this.client.get('/notifications');
519
- return res.data;
520
- } catch (error) {
521
- throw this.handleError(error);
522
- }
523
- }
524
-
525
- /**
526
- * Get count of unread notifications
527
- * @returns Number of unread notifications
528
- */
529
- async getUnreadCount() {
530
- try {
531
- const res = await this.client.get('/notifications/unread-count');
532
- return res.data;
533
- } catch (error) {
534
- throw this.handleError(error);
535
- }
536
- }
537
-
538
- /**
539
- * Create a new notification (admin use)
540
- * @param data - Notification data
541
- * @returns Created notification
542
- */
543
- async createNotification(data) {
544
- try {
545
- const res = await this.client.post('/notifications', data);
546
- return res.data;
547
- } catch (error) {
548
- throw this.handleError(error);
549
- }
550
- }
551
-
552
- /**
553
- * Mark a single notification as read
554
- * @param notificationId - ID of notification to mark as read
555
- */
556
- async markNotificationAsRead(notificationId) {
557
- try {
558
- await this.client.put(`/notifications/${notificationId}/read`);
559
- } catch (error) {
560
- throw this.handleError(error);
561
- }
562
- }
563
-
564
- /**
565
- * Mark all notifications as read
566
- */
567
- async markAllNotificationsAsRead() {
568
- try {
569
- await this.client.put('/notifications/read-all');
570
- } catch (error) {
571
- throw this.handleError(error);
572
- }
573
- }
574
-
575
- /**
576
- * Delete a notification
577
- * @param notificationId - ID of notification to delete
578
- */
579
- async deleteNotification(notificationId) {
580
- try {
581
- await this.client.delete(`/notifications/${notificationId}`);
582
- } catch (error) {
583
- throw this.handleError(error);
584
- }
585
- }
586
-
587
- /* Payment Methods */
588
-
589
- /**
590
- * Process a payment
591
- * @param data - Payment data including user ID, plan, and payment method
592
- * @returns Payment result with transaction ID
593
- */
594
- async processPayment(data) {
595
- try {
596
- const res = await this.client.post('/payments/process', data);
597
- return res.data;
598
- } catch (error) {
599
- throw this.handleError(error);
600
- }
601
- }
602
-
603
- /**
604
- * Validate a payment method
605
- * @param paymentMethod - Payment method to validate
606
- * @returns Object indicating if the payment method is valid
607
- */
608
- async validatePaymentMethod(paymentMethod) {
609
- try {
610
- const res = await this.client.post('/payments/validate', {
611
- paymentMethod
612
- });
613
- return res.data;
614
- } catch (error) {
615
- throw this.handleError(error);
616
- }
617
- }
618
-
619
- /**
620
- * Get saved payment methods for a user
621
- * @param userId - User ID to get payment methods for
622
- * @returns Array of payment methods
623
- */
624
- async getPaymentMethods(userId) {
625
- try {
626
- const res = await this.client.get(`/payments/methods/${userId}`);
627
- return res.data;
628
- } catch (error) {
629
- throw this.handleError(error);
630
- }
631
- }
632
-
633
- /* Analytics Methods */
634
-
635
- /**
636
- * Get analytics data
637
- * @param userId - User ID to get analytics for
638
- * @param period - Time period for analytics (e.g., "day", "week", "month")
639
- * @returns Analytics data
640
- */
641
- async getAnalytics(userId, period) {
642
- try {
643
- const params = {
644
- userID: userId
645
- };
646
- if (period) params.period = period;
647
- const res = await this.client.get('/analytics', {
648
- params
649
- });
650
- return res.data;
651
- } catch (error) {
652
- throw this.handleError(error);
653
- }
654
- }
655
-
656
- /**
657
- * Update analytics (internal use)
658
- * @param userId - User ID to update analytics for
659
- * @param type - Type of analytics to update
660
- * @param data - Analytics data to update
661
- * @returns Message indicating success
662
- */
663
- async updateAnalytics(userId, type, data) {
664
- try {
665
- const res = await this.client.post('/analytics/update', {
666
- userID: userId,
667
- type,
668
- data
669
- });
670
- return res.data;
671
- } catch (error) {
672
- throw this.handleError(error);
673
- }
674
- }
675
-
676
- /**
677
- * Get content viewers analytics
678
- * @param userId - User ID to get viewer data for
679
- * @param period - Time period for analytics
680
- * @returns Array of content viewer data
681
- */
682
- async getContentViewers(userId, period) {
683
- try {
684
- const params = {
685
- userID: userId
686
- };
687
- if (period) params.period = period;
688
- const res = await this.client.get('/analytics/viewers', {
689
- params
690
- });
691
- return res.data;
692
- } catch (error) {
693
- throw this.handleError(error);
694
- }
695
- }
696
-
697
- /**
698
- * Get follower analytics details
699
- * @param userId - User ID to get follower data for
700
- * @param period - Time period for follower data
701
- * @returns Follower details
702
- */
703
- async getFollowerDetails(userId, period) {
704
- try {
705
- const params = {
706
- userID: userId
707
- };
708
- if (period) params.period = period;
709
- const res = await this.client.get('/analytics/followers', {
710
- params
711
- });
712
- return res.data;
713
- } catch (error) {
714
- throw this.handleError(error);
715
- }
716
- }
717
-
718
- /* Wallet Methods */
719
-
720
- /**
721
- * Get wallet info
722
- * @param userId - User ID to get wallet for
723
- * @returns Wallet data
724
- */
725
- async getWallet(userId) {
726
- try {
727
- const res = await this.client.get(`/wallet/${userId}`);
728
- return res.data;
729
- } catch (error) {
730
- throw this.handleError(error);
731
- }
732
- }
733
-
734
- /**
735
- * Get transaction history
736
- * @param userId - User ID to get transactions for
737
- * @param limit - Maximum number of transactions to return
738
- * @param offset - Number of transactions to skip for pagination
739
- * @returns Array of transactions and pagination info
740
- */
741
- async getTransactionHistory(userId, limit, offset) {
742
- try {
743
- const params = {};
744
- if (limit !== undefined) params.limit = limit;
745
- if (offset !== undefined) params.offset = offset;
746
- const res = await this.client.get(`/wallet/transactions/${userId}`, {
747
- params
748
- });
749
- return res.data;
750
- } catch (error) {
751
- throw this.handleError(error);
752
- }
753
- }
754
-
755
- /**
756
- * Get a specific transaction
757
- * @param transactionId - ID of transaction to retrieve
758
- * @returns Transaction data
759
- */
760
- async getTransaction(transactionId) {
761
- try {
762
- const res = await this.client.get(`/wallet/transaction/${transactionId}`);
763
- return res.data;
764
- } catch (error) {
765
- throw this.handleError(error);
766
- }
767
- }
768
-
769
- /**
770
- * Transfer funds between users
771
- * @param data - Transfer details including source, destination, and amount
772
- * @returns Transaction response
773
- */
774
- async transferFunds(data) {
775
- try {
776
- const res = await this.client.post('/wallet/transfer', data);
777
- return res.data;
778
- } catch (error) {
779
- throw this.handleError(error);
780
- }
781
- }
782
-
783
- /**
784
- * Process a purchase
785
- * @param data - Purchase details including user, item, and amount
786
- * @returns Transaction response
787
- */
788
- async processPurchase(data) {
789
- try {
790
- const res = await this.client.post('/wallet/purchase', data);
791
- return res.data;
792
- } catch (error) {
793
- throw this.handleError(error);
794
- }
795
- }
796
-
797
- /**
798
- * Request a withdrawal
799
- * @param data - Withdrawal details including user, amount, and address
800
- * @returns Transaction response
801
- */
802
- async requestWithdrawal(data) {
803
- try {
804
- const res = await this.client.post('/wallet/withdraw', data);
805
- return res.data;
806
- } catch (error) {
807
- throw this.handleError(error);
808
- }
809
- }
810
-
811
- /* Karma Methods */
812
-
813
- /**
814
- * Get karma leaderboard
815
- * @returns Array of karma leaderboard entries
816
- */
817
- async getKarmaLeaderboard() {
818
- try {
819
- const res = await this.client.get('/karma/leaderboard');
820
- return res.data;
821
- } catch (error) {
822
- throw this.handleError(error);
823
- }
824
- }
825
-
826
- /**
827
- * Get karma rules
828
- * @returns Array of karma rules
829
- */
830
- async getKarmaRules() {
831
- try {
832
- const res = await this.client.get('/karma/rules');
833
- return res.data;
834
- } catch (error) {
835
- throw this.handleError(error);
836
- }
837
- }
838
-
839
- /**
840
- * Get total karma for a user
841
- * @param userId - User ID to get karma for
842
- * @returns Object with total karma points
843
- */
844
- async getUserKarmaTotal(userId) {
845
- try {
846
- const res = await this.client.get(`/karma/${userId}/total`);
847
- return res.data;
848
- } catch (error) {
849
- throw this.handleError(error);
850
- }
851
- }
852
-
853
- /**
854
- * Get karma history for a user
855
- * @param userId - User ID to get karma history for
856
- * @param limit - Maximum number of history entries to return
857
- * @param offset - Number of entries to skip for pagination
858
- * @returns Karma history entries and pagination info
859
- */
860
- async getUserKarmaHistory(userId, limit, offset) {
861
- try {
862
- const params = {};
863
- if (limit !== undefined) params.limit = limit;
864
- if (offset !== undefined) params.offset = offset;
865
- const res = await this.client.get(`/karma/${userId}/history`, {
866
- params
867
- });
868
- return res.data;
869
- } catch (error) {
870
- throw this.handleError(error);
871
- }
872
- }
873
-
874
- /**
875
- * Award karma points to a user
876
- * @param data - Karma award details
877
- * @returns Karma award response
878
- */
879
- async awardKarma(data) {
880
- try {
881
- const res = await this.client.post('/karma/award', data);
882
- return res.data;
883
- } catch (error) {
884
- throw this.handleError(error);
885
- }
886
- }
887
-
888
- /**
889
- * Deduct karma points from a user
890
- * @param data - Karma deduction details
891
- * @returns Karma deduction response
892
- */
893
- async deductKarma(data) {
894
- try {
895
- const res = await this.client.post('/karma/deduct', data);
896
- return res.data;
897
- } catch (error) {
898
- throw this.handleError(error);
899
- }
900
- }
901
-
902
- /**
903
- * Create or update karma rule (admin)
904
- * @param data - Karma rule data
905
- * @returns Created or updated karma rule
906
- */
907
- async createOrUpdateKarmaRule(data) {
908
- try {
909
- const res = await this.client.post('/karma/rules', data);
910
- return res.data;
911
- } catch (error) {
912
- throw this.handleError(error);
913
- }
914
- }
915
-
916
- /* File Management Methods */
917
-
918
- /**
919
- * Upload a file using GridFS
920
- * @param file - The file to upload (File or Blob in browser, Buffer in Node.js)
921
- * @param filename - The name of the file
922
- * @param metadata - Optional metadata to associate with the file
923
- * @returns File metadata including ID and download URL
924
- */
925
- async uploadFile(file,
926
- // Use 'any' to handle Buffer type in cross-platform scenarios
927
- filename, metadata) {
928
- // This method is deprecated. Use uploadFilesRaw instead.
929
- // For now, we'll throw an error as the underlying logic is removed.
930
- throw new Error('uploadFile is deprecated. Use uploadFilesRaw instead.');
931
- }
932
-
933
- /**
934
- * Upload multiple files using GridFS
935
- * @param files - Array of files to upload
936
- * @param filenames - Array of filenames (must match files array length)
937
- * @param metadata - Optional metadata to associate with all files
938
- * @returns Array of file metadata
939
- */
940
- async uploadFiles(files, filenames, metadata) {
941
- // This method is deprecated. Use uploadFilesRaw instead.
942
- // For now, we'll throw an error as the underlying logic is removed.
943
- throw new Error('uploadFiles is deprecated. Use uploadFilesRaw instead.');
944
- }
945
-
946
- /**
947
- * Get file metadata by ID
948
- * @param fileId - ID of the file to retrieve metadata for
949
- * @returns File metadata
950
- */
951
- async getFileMetadata(fileId) {
952
- try {
953
- const res = await this.client.get(`/files/${fileId}/metadata`);
954
- return res.data;
955
- } catch (error) {
956
- throw this.handleError(error);
957
- }
958
- }
959
-
960
- /**
961
- * Update file metadata
962
- * @param fileId - ID of the file to update
963
- * @param updates - Metadata updates to apply
964
- * @returns Updated file metadata
965
- */
966
- async updateFileMetadata(fileId, updates) {
967
- try {
968
- const res = await this.client.put(`/files/${fileId}/metadata`, updates);
969
- return res.data;
970
- } catch (error) {
971
- throw this.handleError(error);
972
- }
973
- }
974
-
975
- /**
976
- * Delete a file by ID
977
- * @param fileId - ID of the file to delete
978
- * @returns Status of the delete operation
979
- */
980
- async deleteFile(fileId) {
981
- try {
982
- console.log('Deleting file with ID:', fileId);
983
- const res = await this.client.delete(`/files/${fileId}`);
984
- console.log('Delete response:', res.data);
985
- return res.data;
986
- } catch (error) {
987
- console.error('Delete file error:', error);
988
- console.error('Error response:', error.response?.data);
989
- console.error('Error status:', error.response?.status);
990
-
991
- // Provide more specific error messages based on status code
992
- if (error.response?.status === 404) {
993
- throw new Error('File not found or already deleted');
994
- } else if (error.response?.status === 403) {
995
- throw new Error('You do not have permission to delete this file');
996
- } else if (error.response?.status === 400) {
997
- throw new Error('Invalid file ID format');
998
- }
999
- throw this.handleError(error);
1000
- }
1001
- }
1002
-
1003
- /**
1004
- * Get download URL for a file
1005
- * @param fileId - ID of the file to get download URL for
1006
- * @returns Full URL to download the file
1007
- */
1008
- getFileDownloadUrl(fileId) {
1009
- return `${this.client.defaults.baseURL}/files/${fileId}`;
1010
- }
1011
-
1012
- /**
1013
- * Stream a file (useful for playing audio/video without full download)
1014
- * @param fileId - ID of the file to stream
1015
- * @returns Full URL to stream the file
1016
- */
1017
- getFileStreamUrl(fileId) {
1018
- return `${this.client.defaults.baseURL}/files/${fileId}`;
1019
- }
1020
-
1021
- /**
1022
- * List files for a specific user
1023
- * @param userId - User ID to list files for
1024
- * @param limit - Maximum number of files to return
1025
- * @param offset - Number of files to skip for pagination
1026
- * @param filters - Optional filters for the file list (e.g., contentType)
1027
- * @returns Array of file metadata and pagination info
1028
- */
1029
- async listUserFiles(userId, limit, offset, filters) {
1030
- try {
1031
- const params = {};
1032
- if (limit !== undefined) params.limit = limit;
1033
- if (offset !== undefined) params.offset = offset;
1034
- if (filters) Object.assign(params, filters);
1035
- const res = await this.client.get(`/files/list/${userId}`, {
1036
- params
1037
- });
1038
-
1039
- // Handle backend response format: backend returns FileMetadata[] directly
1040
- // but interface expects { files: FileMetadata[], total: number, hasMore: boolean }
1041
- const rawFiles = Array.isArray(res.data) ? res.data : res.data.files || [];
1042
-
1043
- // Transform GridFS files to match FileMetadata interface (map _id to id)
1044
- const filesArray = rawFiles.map(file => ({
1045
- ...file,
1046
- id: file._id?.toString() || file.id,
1047
- uploadDate: file.uploadDate?.toISOString ? file.uploadDate.toISOString() : file.uploadDate
1048
- }));
1049
- return {
1050
- files: filesArray,
1051
- total: filesArray.length,
1052
- hasMore: false // No pagination in current backend implementation
1053
- };
1054
- } catch (error) {
1055
- throw this.handleError(error);
1056
- }
1057
- }
1058
-
1059
- /**
1060
- * Sign up a new user and create a session
1061
- * @param username - Desired username
1062
- * @param email - User's email address
1063
- * @param password - User's password
1064
- * @returns Object containing the message, token and user data
1065
- */
1066
- async signUp(username, email, password) {
1067
- try {
1068
- // First, create the user account
1069
- const res = await this.client.post('/secure-session/register', {
1070
- username,
1071
- email,
1072
- password
1073
- });
1074
- const {
1075
- message,
1076
- user
1077
- } = res.data;
1078
-
1079
- // Then log them in to create a session
1080
- const loginRes = await this.secureLogin(username, password);
1081
-
1082
- // Get the access token for the session
1083
- const tokenRes = await this.getTokenBySession(loginRes.sessionId);
1084
- return {
1085
- message,
1086
- token: tokenRes.accessToken,
1087
- user: loginRes.user
1088
- };
1089
- } catch (error) {
1090
- throw this.handleError(error);
1091
- }
1092
- }
1093
-
1094
- /**
1095
- * Secure login that creates a device-based session
1096
- * @param username - User's username or email
1097
- * @param password - User's password
1098
- * @param deviceName - Optional device name
1099
- * @param deviceFingerprint - Optional device fingerprint
1100
- * @returns Login response with session data
1101
- */
1102
- async secureLogin(username, password, deviceName, deviceFingerprint) {
1103
- try {
1104
- const payload = {
1105
- username,
1106
- password,
1107
- deviceName
1108
- };
1109
- if (deviceFingerprint) {
1110
- payload.deviceFingerprint = deviceFingerprint;
1111
- }
1112
- const res = await this.client.post('/secure-session/login', payload);
1113
- return res.data;
1114
- } catch (error) {
1115
- throw this.handleError(error);
1116
- }
1117
- }
1118
-
1119
- /**
1120
- * Get full user data by session ID
1121
- * @param sessionId - The session ID
1122
- * @returns Full user data
1123
- */
1124
- async getUserBySession(sessionId) {
1125
- try {
1126
- const res = await this.client.get(`/secure-session/user/${sessionId}`);
1127
- return res.data.user;
1128
- } catch (error) {
1129
- throw this.handleError(error);
1130
- }
1131
- }
1132
-
1133
- /**
1134
- * Get access token by session ID (for API calls)
1135
- * @param sessionId - The session ID
1136
- * @returns Access token and expiry info
1137
- */
1138
- async getTokenBySession(sessionId) {
1139
- try {
1140
- const res = await this.client.get(`/secure-session/token/${sessionId}`);
1141
- // Set the token for subsequent API calls
1142
- this.accessToken = res.data.accessToken;
1143
- return res.data;
1144
- } catch (error) {
1145
- throw this.handleError(error);
1146
- }
1147
- }
1148
-
1149
- /**
1150
- * Get all active sessions for current user
1151
- * @param sessionId - Current session ID
1152
- * @returns Array of user sessions
1153
- */
1154
- async getSessionsBySessionId(sessionId) {
1155
- console.log('getSessionsBySessionId called with sessionId:', sessionId);
1156
- try {
1157
- const res = await this.client.get(`/secure-session/sessions/${sessionId}`);
1158
- console.log('getSessionsBySessionId response:', res.data);
1159
- return res.data.sessions;
1160
- } catch (error) {
1161
- console.error('getSessionsBySessionId error:', error);
1162
- throw this.handleError(error);
1163
- }
1164
- }
1165
-
1166
- /**
1167
- * Logout specific session
1168
- * @param sessionId - Current session ID
1169
- * @param targetSessionId - Optional target session to logout (defaults to current)
1170
- */
1171
- async logoutSecureSession(sessionId, targetSessionId) {
1172
- try {
1173
- await this.client.post(`/secure-session/logout/${sessionId}`, {
1174
- targetSessionId
1175
- });
1176
-
1177
- // If we're logging out the current session, clear the access token
1178
- if (!targetSessionId || targetSessionId === sessionId) {
1179
- this.accessToken = null;
1180
- this.refreshToken = null;
1181
- }
1182
- } catch (error) {
1183
- throw this.handleError(error);
1184
- }
1185
- }
1186
-
1187
- /**
1188
- * Logout all sessions for current user
1189
- * @param sessionId - Current session ID
1190
- */
1191
- async logoutAllSecureSessions(sessionId) {
1192
- console.log('logoutAllSecureSessions called with sessionId:', sessionId);
1193
- console.log('API client defaults:', this.client.defaults);
1194
- try {
1195
- const response = await this.client.post(`/secure-session/logout-all/${sessionId}`);
1196
- console.log('logoutAllSecureSessions response:', response.status, response.data);
1197
-
1198
- // Clear tokens since all sessions are logged out
1199
- this.accessToken = null;
1200
- this.refreshToken = null;
1201
- console.log('Tokens cleared successfully');
1202
- } catch (error) {
1203
- console.error('logoutAllSecureSessions error:', error);
1204
- if (error && typeof error === 'object' && 'response' in error) {
1205
- const axiosError = error;
1206
- console.error('Error response data:', axiosError.response?.data);
1207
- console.error('Error response status:', axiosError.response?.status);
1208
- }
1209
- throw this.handleError(error);
1210
- }
1211
- }
1212
-
1213
- /**
1214
- * Validate session
1215
- * @param sessionId - The session ID to validate
1216
- * @returns Session validation status with user data
1217
- */
1218
- async validateSession(sessionId) {
1219
- try {
1220
- const res = await this.client.get(`/secure-session/validate/${sessionId}`);
1221
- return res.data;
1222
- } catch (error) {
1223
- throw this.handleError(error);
1224
- }
1225
- }
1226
-
1227
- /**
1228
- * Validate session using x-session-id header
1229
- * @param sessionId - The session ID to validate (sent as header)
1230
- * @param deviceFingerprint - Optional device fingerprint for enhanced security
1231
- * @returns Session validation status with user data
1232
- */
1233
- async validateSessionFromHeader(sessionId, deviceFingerprint) {
1234
- try {
1235
- const headers = {
1236
- 'x-session-id': sessionId
1237
- };
1238
- if (deviceFingerprint) {
1239
- headers['x-device-fingerprint'] = deviceFingerprint;
1240
- }
1241
- const res = await this.client.get('/secure-session/validate-header', {
1242
- headers
1243
- });
1244
- return res.data;
1245
- } catch (error) {
1246
- throw this.handleError(error);
1247
- }
1248
- }
1249
-
1250
- /**
1251
- * Validate session using automatic header detection
1252
- * The validateSession endpoint will automatically read from x-session-id header
1253
- * @param sessionId - The session ID to validate (sent as header)
1254
- * @param deviceFingerprint - Optional device fingerprint for enhanced security
1255
- * @returns Session validation status with user data
1256
- */
1257
- async validateSessionAuto(sessionId, deviceFingerprint) {
1258
- try {
1259
- const headers = {
1260
- 'x-session-id': sessionId
1261
- };
1262
- if (deviceFingerprint) {
1263
- headers['x-device-fingerprint'] = deviceFingerprint;
1264
- }
1265
-
1266
- // Call the regular validateSession endpoint which now auto-reads from headers
1267
- // Use 'auto' as placeholder since the controller reads from header
1268
- const res = await this.client.get('/secure-session/validate/auto', {
1269
- headers
1270
- });
1271
- return res.data;
1272
- } catch (error) {
1273
- throw this.handleError(error);
1274
- }
1275
- }
1276
-
1277
- /**
1278
- * Create authentication middleware for Express.js applications
1279
- * This is the recommended way to protect routes in server applications
1280
- * @returns Express middleware function
1281
- */
1282
- createAuthMiddleware() {
1283
- return async (req, res, next) => {
1284
- try {
1285
- const authHeader = req.headers.authorization;
1286
- if (!authHeader?.startsWith('Bearer ')) {
1287
- return res.status(401).json({
1288
- error: 'Authentication required',
1289
- message: 'Invalid or missing authorization header'
1290
- });
1291
- }
1292
- const token = authHeader.split(' ')[1];
1293
-
1294
- // Use the authenticateToken method
1295
- const result = await this.authenticateToken(token);
1296
- if (!result.valid) {
1297
- return res.status(401).json({
1298
- error: 'Invalid token',
1299
- message: result.error || 'The provided authentication token is invalid'
1300
- });
1301
- }
1302
-
1303
- // Set user information on request object
1304
- req.userId = result.userId || undefined;
1305
- req.accessToken = token;
1306
- if (result.user) {
1307
- req.user = result.user;
1308
- } else if (result.userId) {
1309
- req.user = {
1310
- id: result.userId
1311
- };
1312
- }
1313
- next();
1314
- } catch (error) {
1315
- console.error('Auth middleware error:', error);
1316
- return res.status(500).json({
1317
- error: 'Server error',
1318
- message: 'An error occurred while authenticating your request'
1319
- });
1320
- }
1321
- };
1322
- }
1323
-
1324
- /**
1325
- * Helper method for validating tokens without Express middleware
1326
- * Useful for standalone token validation in various contexts
1327
- * @param token - The access token to validate
1328
- * @returns Object with validation result and user information
1329
- */
1330
- async authenticateToken(token) {
1331
- try {
1332
- if (!token) {
1333
- return {
1334
- valid: false,
1335
- error: 'Token is required'
1336
- };
1337
- }
1338
-
1339
- // Check if token contains sessionId (new session-based system)
1340
- try {
1341
- const decoded = (0, _jwtDecode.jwtDecode)(token);
1342
- const userId = decoded.userId || decoded.id;
1343
- if (decoded.sessionId) {
1344
- // Use session-based validation
1345
- const tempOxyServices = new OxyServices({
1346
- baseURL: this.client.defaults.baseURL || ''
1347
- });
1348
- tempOxyServices.setTokens(token, '');
1349
- const validation = await tempOxyServices.validateSession(decoded.sessionId);
1350
- if (validation.valid) {
1351
- return {
1352
- valid: true,
1353
- userId,
1354
- user: validation.user
1355
- };
1356
- } else {
1357
- return {
1358
- valid: false,
1359
- error: 'Invalid or expired session'
1360
- };
1361
- }
1362
- } else {
1363
- // Use old validation method
1364
- const tempOxyServices = new OxyServices({
1365
- baseURL: this.client.defaults.baseURL || ''
1366
- });
1367
- tempOxyServices.setTokens(token, '');
1368
- const isValid = await tempOxyServices.validate();
1369
- if (!isValid) {
1370
- return {
1371
- valid: false,
1372
- error: 'Invalid or expired token'
1373
- };
1374
- }
1375
- if (!userId) {
1376
- return {
1377
- valid: false,
1378
- error: 'Invalid token payload'
1379
- };
1380
- }
1381
-
1382
- // Try to get user profile
1383
- let user;
1384
- try {
1385
- user = await tempOxyServices.getUserById(userId);
1386
- } catch (error) {
1387
- // Continue without full user data
1388
- user = {
1389
- id: userId
1390
- };
1391
- }
1392
- return {
1393
- valid: true,
1394
- userId,
1395
- user
1396
- };
1397
- }
1398
- } catch (decodeError) {
1399
- return {
1400
- valid: false,
1401
- error: 'Invalid token payload'
1402
- };
1403
- }
1404
- } catch (error) {
1405
- return {
1406
- valid: false,
1407
- error: error instanceof Error ? error.message : 'Token validation failed'
1408
- };
1409
- }
1410
- }
1411
-
1412
- /**
1413
- * Centralized error handling
1414
- * @private
1415
- * @param error - Error object from API call
1416
- * @returns Formatted API error
1417
- */
1418
- handleError(error) {
1419
- if (error && error.code && error.status) {
1420
- // Already formatted as ApiError
1421
- return error;
1422
- }
1423
- const apiError = {
1424
- message: error?.message || error?.response?.data?.message || 'Unknown error occurred',
1425
- code: error?.response?.data?.code || 'UNKNOWN_ERROR',
1426
- status: error?.response?.status || 500,
1427
- details: error?.response?.data
1428
- };
1429
- return apiError;
1430
- }
1431
-
1432
- /**
1433
- * Check if a username is available
1434
- * @param username - The username to check
1435
- * @returns Promise with availability status
1436
- */
1437
- async checkUsernameAvailability(username) {
1438
- try {
1439
- const res = await this.client.get(`/auth/check-username/${username}`);
1440
- return res.data;
1441
- } catch (error) {
1442
- // If the endpoint doesn't exist, fall back to basic validation
1443
- if (error.response?.status === 404) {
1444
- console.warn('Username validation endpoint not found, using fallback validation');
1445
- return {
1446
- available: true,
1447
- message: 'Username validation not available'
1448
- };
1449
- }
1450
-
1451
- // If it's a validation error (400), return the error message
1452
- if (error.response?.status === 400) {
1453
- return error.response.data;
1454
- }
1455
-
1456
- // For other errors, log and return a fallback
1457
- console.error('Username validation error:', error);
1458
- return {
1459
- available: true,
1460
- message: 'Unable to validate username'
1461
- };
1462
- }
1463
- }
1464
-
1465
- /**
1466
- * Check if an email is available
1467
- * @param email - The email to check
1468
- * @returns Promise with availability status
1469
- */
1470
- async checkEmailAvailability(email) {
1471
- try {
1472
- const res = await this.client.post('/auth/check-email', {
1473
- email
1474
- });
1475
- return res.data;
1476
- } catch (error) {
1477
- // If the endpoint doesn't exist, fall back to basic validation
1478
- if (error.response?.status === 404) {
1479
- console.warn('Email validation endpoint not found, using fallback validation');
1480
- return {
1481
- available: true,
1482
- message: 'Email validation not available'
1483
- };
1484
- }
1485
-
1486
- // If it's a validation error (400), return the error message
1487
- if (error.response?.status === 400) {
1488
- return error.response.data;
1489
- }
1490
-
1491
- // For other errors, log and return a fallback
1492
- console.error('Email validation error:', error);
1493
- return {
1494
- available: true,
1495
- message: 'Unable to validate email'
1496
- };
1497
- }
1498
- }
1499
-
1500
- /**
1501
- * Get user profile by username
1502
- * @param username - The username to look up
1503
- * @returns Promise with user profile
1504
- */
1505
- async getUserProfileByUsername(username) {
1506
- try {
1507
- const res = await this.client.get(`/profiles/username/${username}`);
1508
- return res.data;
1509
- } catch (error) {
1510
- throw this.handleError(error);
1511
- }
1512
- }
1513
-
1514
- /**
1515
- * Health check endpoint to verify API connectivity
1516
- * @returns Health status and basic server info
1517
- */
1518
- async healthCheck() {
1519
- try {
1520
- const res = await this.client.get('/');
1521
- return res.data;
1522
- } catch (error) {
1523
- throw this.handleError(error);
1524
- }
1525
- }
1526
-
1527
- /**
1528
- * Download file content using authenticated request
1529
- * @param fileId - The file ID to download
1530
- * @returns Response object for further processing
1531
- */
1532
- async downloadFileContent(fileId) {
1533
- try {
1534
- const downloadUrl = this.getFileDownloadUrl(fileId);
1535
- const response = await fetch(downloadUrl);
1536
- if (!response.ok) {
1537
- throw new Error(`Download failed: ${response.status} ${response.statusText}`);
1538
- }
1539
- return response;
1540
- } catch (error) {
1541
- throw this.handleError(error);
1542
- }
1543
- }
1544
-
1545
- /**
1546
- * Get file content as text using authenticated request
1547
- * @param fileId - The file ID to get content for
1548
- * @returns File content as string
1549
- */
1550
- async getFileContentAsText(fileId) {
1551
- try {
1552
- const response = await this.downloadFileContent(fileId);
1553
- return await response.text();
1554
- } catch (error) {
1555
- throw this.handleError(error);
1556
- }
1557
- }
1558
-
1559
- /**
1560
- * Get file content as blob using authenticated request
1561
- * @param fileId - The file ID to get content for
1562
- * @returns File content as blob
1563
- */
1564
- async getFileContentAsBlob(fileId) {
1565
- try {
1566
- const response = await this.downloadFileContent(fileId);
1567
- return await response.blob();
1568
- } catch (error) {
1569
- throw this.handleError(error);
1570
- }
1571
- }
1572
-
1573
- /**
1574
- * Fetch metadata for a URL (title, description, image)
1575
- * @param url - The URL to fetch metadata for
1576
- * @returns Promise with metadata object
1577
- */
1578
- async fetchLinkMetadata(url) {
1579
- try {
1580
- const response = await this.client.post('/link-metadata/fetch-metadata', {
1581
- url
1582
- });
1583
- return response.data;
1584
- } catch (error) {
1585
- throw this.handleError(error);
1586
- }
1587
- }
1588
-
1589
- /**
1590
- * Search for locations using the enhanced location search API
1591
- * @param query - Search query string
1592
- * @param limit - Maximum number of results (default: 5)
1593
- * @param countrycodes - Optional country codes filter (e.g., "us,ca")
1594
- * @returns Promise with array of location results
1595
- */
1596
- async searchLocations(query, limit = 5, countrycodes) {
1597
- try {
1598
- const params = new URLSearchParams({
1599
- query,
1600
- limit: limit.toString()
1601
- });
1602
- if (countrycodes) {
1603
- params.append('countrycodes', countrycodes);
1604
- }
1605
- const res = await this.client.get(`/location-search/search?${params.toString()}`);
1606
- return res.data.results;
1607
- } catch (error) {
1608
- throw this.handleError(error);
1609
- }
1610
- }
1611
-
1612
- /**
1613
- * Get detailed information about a specific location by coordinates
1614
- * @param lat - Latitude
1615
- * @param lon - Longitude
1616
- * @returns Promise with detailed location information
1617
- */
1618
- async getLocationDetails(lat, lon) {
1619
- try {
1620
- const res = await this.client.get(`/location-search/details?lat=${lat}&lon=${lon}`);
1621
- return res.data.result;
1622
- } catch (error) {
1623
- throw this.handleError(error);
1624
- }
1625
- }
1626
-
1627
- /**
1628
- * Find locations near a point using geospatial queries
1629
- * @param lat - Latitude
1630
- * @param lon - Longitude
1631
- * @param maxDistance - Maximum distance in meters (default: 10000)
1632
- * @param limit - Maximum number of results (default: 10)
1633
- * @param skip - Number of results to skip (default: 0)
1634
- * @returns Promise with nearby locations
1635
- */
1636
- async findLocationsNear(lat, lon, maxDistance = 10000, limit = 10, skip = 0) {
1637
- try {
1638
- const params = new URLSearchParams({
1639
- lat: lat.toString(),
1640
- lon: lon.toString(),
1641
- maxDistance: maxDistance.toString(),
1642
- limit: limit.toString(),
1643
- skip: skip.toString()
1644
- });
1645
- const res = await this.client.get(`/location-search/near?${params.toString()}`);
1646
- return res.data;
1647
- } catch (error) {
1648
- throw this.handleError(error);
1649
- }
1650
- }
1651
-
1652
- /**
1653
- * Search locations in database by text
1654
- * @param query - Search query
1655
- * @param limit - Maximum number of results (default: 10)
1656
- * @param skip - Number of results to skip (default: 0)
1657
- * @param type - Filter by location type
1658
- * @param country - Filter by country
1659
- * @param city - Filter by city
1660
- * @returns Promise with search results
1661
- */
1662
- async searchLocationsInDB(query, limit = 10, skip = 0, type, country, city) {
1663
- try {
1664
- const params = new URLSearchParams({
1665
- query,
1666
- limit: limit.toString(),
1667
- skip: skip.toString()
1668
- });
1669
- if (type) params.append('type', type);
1670
- if (country) params.append('country', country);
1671
- if (city) params.append('city', city);
1672
- const res = await this.client.get(`/location-search/db-search?${params.toString()}`);
1673
- return res.data;
1674
- } catch (error) {
1675
- throw this.handleError(error);
1676
- }
1677
- }
1678
-
1679
- /**
1680
- * Get location statistics
1681
- * @returns Promise with location statistics
1682
- */
1683
- async getLocationStats() {
1684
- try {
1685
- const res = await this.client.get('/location-search/stats');
1686
- return res.data.stats;
1687
- } catch (error) {
1688
- throw this.handleError(error);
1689
- }
1690
- }
1691
-
1692
- /**
1693
- * Get cache statistics
1694
- * @returns Promise with cache statistics
1695
- */
1696
- async getLocationCacheStats() {
1697
- try {
1698
- const res = await this.client.get('/location-search/cache/stats');
1699
- return res.data.stats;
1700
- } catch (error) {
1701
- throw this.handleError(error);
1702
- }
1703
- }
1704
-
1705
- /**
1706
- * Clear location cache
1707
- * @returns Promise with success status
1708
- */
1709
- async clearLocationCache() {
1710
- try {
1711
- const res = await this.client.delete('/location-search/cache');
1712
- return res.data;
1713
- } catch (error) {
1714
- throw this.handleError(error);
1715
- }
1716
- }
1717
-
1718
- /**
1719
- * Get performance statistics
1720
- * @returns Promise with performance statistics
1721
- */
1722
- async getLocationPerformanceStats() {
1723
- try {
1724
- const res = await this.client.get('/location-search/performance');
1725
- return res.data;
1726
- } catch (error) {
1727
- throw this.handleError(error);
1728
- }
1729
- }
1730
- }
1731
-
134
+ // Main OxyServices class (backward compatible)
135
+ // Individual service classes for focused usage
136
+ // Base class for custom service extensions
137
+ // Constants
138
+ // Re-export all models and types for convenience
139
+ // Export device management utilities
140
+ // Import the main class for default export
1732
141
  // Default export for backward compatibility
1733
- exports.OxyServices = OxyServices;
1734
- var _default = exports.default = OxyServices; // Re-export all models and types for convenience
1735
- // Clean middleware exports - these will be available for server-side use
1736
- // Note: These require Express.js and are only for server-side applications
1737
-
1738
- if (typeof FormData === 'undefined') {
1739
- console.warn('[OxyHQ/Services] FormData is not available. If you are using Hermes, add "import \'react-native-url-polyfill/auto\'" at the top of your app entry file.');
1740
- }
142
+ var _default = exports.default = _OxyServicesMain.OxyServicesMain;
1741
143
  //# sourceMappingURL=index.js.map