@oxyhq/services 5.8.11 → 5.9.1

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 (73) hide show
  1. package/lib/commonjs/core/index.js +192 -346
  2. package/lib/commonjs/core/index.js.map +1 -1
  3. package/lib/commonjs/index.js +6 -0
  4. package/lib/commonjs/index.js.map +1 -1
  5. package/lib/commonjs/node/index.js +0 -9
  6. package/lib/commonjs/node/index.js.map +1 -1
  7. package/lib/commonjs/types/middleware.js +6 -0
  8. package/lib/commonjs/types/middleware.js.map +1 -0
  9. package/lib/commonjs/ui/components/OxyProvider.js +3 -9
  10. package/lib/commonjs/ui/components/OxyProvider.js.map +1 -1
  11. package/lib/commonjs/ui/screens/FeedbackScreen.js +0 -4
  12. package/lib/commonjs/ui/screens/FeedbackScreen.js.map +1 -1
  13. package/lib/commonjs/ui/screens/RecoverAccountScreen.js +0 -4
  14. package/lib/commonjs/ui/screens/RecoverAccountScreen.js.map +1 -1
  15. package/lib/commonjs/ui/screens/SignInScreen.js +16 -27
  16. package/lib/commonjs/ui/screens/SignInScreen.js.map +1 -1
  17. package/lib/commonjs/ui/screens/SignUpScreen.js +4 -18
  18. package/lib/commonjs/ui/screens/SignUpScreen.js.map +1 -1
  19. package/lib/commonjs/ui/styles/authStyles.js +1 -2
  20. package/lib/commonjs/ui/styles/authStyles.js.map +1 -1
  21. package/lib/module/core/index.js +190 -345
  22. package/lib/module/core/index.js.map +1 -1
  23. package/lib/module/index.js +4 -0
  24. package/lib/module/index.js.map +1 -1
  25. package/lib/module/node/index.js +0 -4
  26. package/lib/module/node/index.js.map +1 -1
  27. package/lib/module/types/middleware.js +4 -0
  28. package/lib/module/types/middleware.js.map +1 -0
  29. package/lib/module/ui/components/OxyProvider.js +3 -9
  30. package/lib/module/ui/components/OxyProvider.js.map +1 -1
  31. package/lib/module/ui/screens/FeedbackScreen.js +0 -4
  32. package/lib/module/ui/screens/FeedbackScreen.js.map +1 -1
  33. package/lib/module/ui/screens/RecoverAccountScreen.js +0 -4
  34. package/lib/module/ui/screens/RecoverAccountScreen.js.map +1 -1
  35. package/lib/module/ui/screens/SignInScreen.js +16 -27
  36. package/lib/module/ui/screens/SignInScreen.js.map +1 -1
  37. package/lib/module/ui/screens/SignUpScreen.js +4 -18
  38. package/lib/module/ui/screens/SignUpScreen.js.map +1 -1
  39. package/lib/module/ui/styles/authStyles.js +1 -2
  40. package/lib/module/ui/styles/authStyles.js.map +1 -1
  41. package/lib/typescript/core/index.d.ts +34 -86
  42. package/lib/typescript/core/index.d.ts.map +1 -1
  43. package/lib/typescript/index.d.ts +2 -0
  44. package/lib/typescript/index.d.ts.map +1 -1
  45. package/lib/typescript/node/index.d.ts +0 -2
  46. package/lib/typescript/node/index.d.ts.map +1 -1
  47. package/lib/typescript/types/middleware.d.ts +19 -0
  48. package/lib/typescript/types/middleware.d.ts.map +1 -0
  49. package/lib/typescript/ui/components/OxyProvider.d.ts.map +1 -1
  50. package/lib/typescript/ui/screens/FeedbackScreen.d.ts.map +1 -1
  51. package/lib/typescript/ui/screens/RecoverAccountScreen.d.ts.map +1 -1
  52. package/lib/typescript/ui/screens/SignInScreen.d.ts.map +1 -1
  53. package/lib/typescript/ui/screens/SignUpScreen.d.ts.map +1 -1
  54. package/lib/typescript/ui/styles/authStyles.d.ts +0 -1
  55. package/lib/typescript/ui/styles/authStyles.d.ts.map +1 -1
  56. package/package.json +6 -6
  57. package/src/core/index.ts +196 -328
  58. package/src/index.ts +4 -0
  59. package/src/node/index.ts +0 -4
  60. package/src/types/middleware.ts +20 -0
  61. package/src/ui/components/OxyProvider.tsx +3 -9
  62. package/src/ui/screens/FeedbackScreen.tsx +0 -4
  63. package/src/ui/screens/RecoverAccountScreen.tsx +0 -4
  64. package/src/ui/screens/SignInScreen.tsx +16 -20
  65. package/src/ui/screens/SignUpScreen.tsx +4 -14
  66. package/src/ui/styles/authStyles.ts +0 -1
  67. package/lib/commonjs/node/createAuth.js +0 -95
  68. package/lib/commonjs/node/createAuth.js.map +0 -1
  69. package/lib/module/node/createAuth.js +0 -90
  70. package/lib/module/node/createAuth.js.map +0 -1
  71. package/lib/typescript/node/createAuth.d.ts +0 -7
  72. package/lib/typescript/node/createAuth.d.ts.map +0 -1
  73. package/src/node/createAuth.ts +0 -116
package/src/core/index.ts CHANGED
@@ -66,7 +66,6 @@ export class OxyServices {
66
66
  private client: AxiosInstance;
67
67
  private accessToken: string | null = null;
68
68
  private refreshToken: string | null = null;
69
- private refreshPromise: Promise<{ accessToken: string; refreshToken: string }> | null = null;
70
69
 
71
70
  /**
72
71
  * Creates a new instance of the OxyServices client
@@ -82,14 +81,25 @@ export class OxyServices {
82
81
  this.client.interceptors.request.use(async (req: InternalAxiosRequestConfig) => {
83
82
  if (!this.accessToken) {
84
83
  return req;
85
- } // Check if token is expired and refresh if needed
86
- try {
87
- const decoded = jwtDecode<JwtPayload>(this.accessToken);
88
- const currentTime = Math.floor(Date.now() / 1000);
89
-
84
+ }
85
+
86
+ // Check if token is expired and refresh if needed
87
+ try {
88
+ const decoded = jwtDecode<JwtPayload>(this.accessToken);
89
+ const currentTime = Math.floor(Date.now() / 1000);
90
+
90
91
  // If token expires in less than 60 seconds, refresh it
91
92
  if (decoded.exp - currentTime < 60) {
92
- await this.refreshTokens();
93
+ // For session-based tokens, get a new token from the session
94
+ if (decoded.sessionId) {
95
+ try {
96
+ const res = await this.client.get(`/secure-session/token/${decoded.sessionId}`);
97
+ this.accessToken = res.data.accessToken;
98
+ } catch (refreshError) {
99
+ // If refresh fails, clear tokens
100
+ this.clearTokens();
101
+ }
102
+ }
93
103
  }
94
104
  } catch (error) {
95
105
  // If token can't be decoded, continue with request and let server handle it
@@ -109,19 +119,25 @@ export class OxyServices {
109
119
  // If the error is due to an expired token and we haven't tried refreshing yet
110
120
  if (
111
121
  error.response?.status === 401 &&
112
- this.refreshToken &&
122
+ this.accessToken &&
113
123
  originalRequest &&
114
124
  !originalRequest.headers?.['X-Retry-After-Refresh']
115
125
  ) {
116
126
  try {
117
- await this.refreshTokens();
118
- // Retry the original request with new token
119
- const newRequest = { ...originalRequest };
120
- if (newRequest.headers) {
121
- newRequest.headers.Authorization = `Bearer ${this.accessToken}`;
122
- newRequest.headers['X-Retry-After-Refresh'] = 'true';
127
+ // Check if token is session-based and try to refresh
128
+ const decoded = jwtDecode<JwtPayload>(this.accessToken);
129
+ if (decoded.sessionId) {
130
+ const res = await this.client.get(`/secure-session/token/${decoded.sessionId}`);
131
+ this.accessToken = res.data.accessToken;
132
+
133
+ // Retry the original request with new token
134
+ const newRequest = { ...originalRequest };
135
+ if (newRequest.headers) {
136
+ newRequest.headers.Authorization = `Bearer ${this.accessToken}`;
137
+ newRequest.headers['X-Retry-After-Refresh'] = 'true';
138
+ }
139
+ return this.client(newRequest);
123
140
  }
124
- return this.client(newRequest);
125
141
  } catch (refreshError) {
126
142
  // If refresh fails, force user to login again
127
143
  this.clearTokens();
@@ -156,44 +172,17 @@ export class OxyServices {
156
172
  }
157
173
 
158
174
  /**
159
- * Gets the currently authenticated user ID from the token
160
- * @returns The user ID or null if not authenticated
161
- */
162
- public getCurrentUserId(): string | null {
163
- if (!this.accessToken) return null;
164
-
165
- try {
166
- const decoded = jwtDecode<JwtPayload>(this.accessToken);
167
-
168
- // Check for both userId (preferred) and id (fallback) for compatibility
169
- return decoded.userId || (decoded as any).id || null;
170
- } catch (error) {
171
- return null;
172
- }
173
- }
174
-
175
- /**
176
- * Internal method to check if we have an access token
177
- * @private
178
- * @returns Boolean indicating if access token exists
179
- * @internal - Use `isAuthenticated` from useOxy() context in UI components instead
180
- */
181
- private hasAccessToken(): boolean {
182
- return this.accessToken !== null;
183
- }
184
-
185
- /**
186
- * Sets authentication tokens directly (useful for initializing from storage)
187
- * @param accessToken - JWT access token
188
- * @param refreshToken - Refresh token for getting new access tokens
175
+ * Set authentication tokens manually
176
+ * @param accessToken - The access token
177
+ * @param refreshToken - The refresh token (optional for session-based auth)
189
178
  */
190
- public setTokens(accessToken: string, refreshToken: string): void {
179
+ public setTokens(accessToken: string, refreshToken: string = ''): void {
191
180
  this.accessToken = accessToken;
192
181
  this.refreshToken = refreshToken;
193
182
  }
194
-
183
+
195
184
  /**
196
- * Clears all authentication tokens
185
+ * Clear stored authentication tokens
197
186
  */
198
187
  public clearTokens(): void {
199
188
  this.accessToken = null;
@@ -201,89 +190,28 @@ export class OxyServices {
201
190
  }
202
191
 
203
192
  /**
204
- * Sign up a new user
205
- * @param username - Desired username
206
- * @param email - User's email address
207
- * @param password - User's password
208
- * @returns Object containing the message, token and user data
209
- */
210
- async signUp(username: string, email: string, password: string): Promise<{ message: string; token: string; user: User }> {
211
- try {
212
- const res = await this.client.post('/auth/signup', { username, email, password });
213
- const { message, token, user } = res.data;
214
- this.accessToken = token;
215
- return { message, token, user };
216
- } catch (error) {
217
- throw this.handleError(error);
218
- }
219
- }
220
-
221
- /**
222
- * Log in and store tokens
223
- * @param username - User's username or email
224
- * @param password - User's password
225
- * @returns Login response containing tokens and user data
226
- */
227
- async login(username: string, password: string): Promise<LoginResponse> {
228
- try {
229
- const res = await this.client.post('/auth/login', { username, password });
230
- const { accessToken, refreshToken, user } = res.data;
231
- this.accessToken = accessToken;
232
- this.refreshToken = refreshToken;
233
- return { accessToken, refreshToken, user };
234
- } catch (error) {
235
- throw this.handleError(error);
236
- }
237
- }
238
-
239
- /**
240
- * Log out user
193
+ * Get the current user ID from the stored token
194
+ * @returns User ID or null if not authenticated
241
195
  */
242
- async logout(): Promise<void> {
243
- if (!this.refreshToken) return;
196
+ public getCurrentUserId(): string | null {
197
+ if (!this.accessToken) return null;
244
198
 
245
199
  try {
246
- await this.client.post('/auth/logout', { refreshToken: this.refreshToken });
200
+ const decoded = jwtDecode<JwtPayload>(this.accessToken);
201
+ return decoded.userId || decoded.id || null;
247
202
  } catch (error) {
248
- console.warn('Error during logout', error);
249
- } finally {
250
- this.accessToken = null;
251
- this.refreshToken = null;
203
+ return null;
252
204
  }
253
205
  }
254
-
206
+
255
207
  /**
256
- * Refresh access and refresh tokens
257
- * @returns New tokens
208
+ * Internal method to check if we have an access token
209
+ * @private
210
+ * @returns Boolean indicating if access token exists
211
+ * @internal - Use `isAuthenticated` from useOxy() context in UI components instead
258
212
  */
259
- async refreshTokens(): Promise<{ accessToken: string; refreshToken: string }> {
260
- if (!this.refreshToken) {
261
- throw new Error('No refresh token available');
262
- }
263
-
264
- // If a refresh is already in progress, return that promise
265
- if (this.refreshPromise) {
266
- return this.refreshPromise;
267
- }
268
-
269
- // Create a new refresh promise
270
- this.refreshPromise = (async () => {
271
- try {
272
- const res = await this.client.post('/auth/refresh', { refreshToken: this.refreshToken });
273
- const { accessToken, refreshToken } = res.data;
274
- this.accessToken = accessToken;
275
- this.refreshToken = refreshToken;
276
- return { accessToken, refreshToken };
277
- } catch (error) {
278
- this.accessToken = null;
279
- this.refreshToken = null;
280
- throw this.handleError(error);
281
- } finally {
282
- this.refreshPromise = null;
283
- }
284
- })();
285
-
286
- return this.refreshPromise;
213
+ private hasAccessToken(): boolean {
214
+ return this.accessToken !== null;
287
215
  }
288
216
 
289
217
  /**
@@ -292,6 +220,22 @@ export class OxyServices {
292
220
  */
293
221
  async validate(): Promise<boolean> {
294
222
  try {
223
+ // Check if token contains sessionId (new session-based system)
224
+ if (this.accessToken) {
225
+ try {
226
+ const decoded = jwtDecode<JwtPayload>(this.accessToken);
227
+ if (decoded.sessionId) {
228
+ // Use session-based validation
229
+ const res = await this.client.get(`/secure-session/validate/${decoded.sessionId}`);
230
+ return res.data.valid;
231
+ }
232
+ } catch (decodeError) {
233
+ // If token can't be decoded, fall back to old validation
234
+ console.warn('Error decoding JWT token for session validation:', decodeError);
235
+ }
236
+ }
237
+
238
+ // Fall back to old validation method
295
239
  const res = await this.client.get('/auth/validate');
296
240
  return res.data.valid;
297
241
  } catch (error) {
@@ -301,59 +245,6 @@ export class OxyServices {
301
245
 
302
246
  /* Session Management Methods */
303
247
 
304
- /**
305
- * Get active sessions for the authenticated user
306
- * @returns Array of active session objects
307
- */
308
- async getUserSessions(): Promise<any[]> {
309
- try {
310
- const res = await this.client.get('/sessions');
311
- return res.data;
312
- } catch (error) {
313
- throw this.handleError(error);
314
- }
315
- }
316
-
317
- /**
318
- * Logout from a specific session
319
- * @param sessionId - The session ID to logout from
320
- * @returns Success status
321
- */
322
- async logoutSession(sessionId: string): Promise<{ success: boolean; message: string }> {
323
- try {
324
- const res = await this.client.delete(`/sessions/${sessionId}`);
325
- return res.data;
326
- } catch (error) {
327
- throw this.handleError(error);
328
- }
329
- }
330
-
331
- /**
332
- * Logout from all other sessions (keep current session active)
333
- * @returns Success status
334
- */
335
- async logoutOtherSessions(): Promise<{ success: boolean; message: string }> {
336
- try {
337
- const res = await this.client.post('/sessions/logout-others');
338
- return res.data;
339
- } catch (error) {
340
- throw this.handleError(error);
341
- }
342
- }
343
-
344
- /**
345
- * Logout from all sessions
346
- * @returns Success status
347
- */
348
- async logoutAllSessions(): Promise<{ success: boolean; message: string }> {
349
- try {
350
- const res = await this.client.post('/sessions/logout-all');
351
- return res.data;
352
- } catch (error) {
353
- throw this.handleError(error);
354
- }
355
- }
356
-
357
248
  /**
358
249
  * Get device sessions for a specific session ID
359
250
  * @param sessionId - The session ID to get device sessions for
@@ -1177,12 +1068,41 @@ export class OxyServices {
1177
1068
  }
1178
1069
 
1179
1070
  /**
1180
- * Secure login that returns only session data (no tokens stored locally)
1071
+ * Sign up a new user and create a session
1072
+ * @param username - Desired username
1073
+ * @param email - User's email address
1074
+ * @param password - User's password
1075
+ * @returns Object containing the message, token and user data
1076
+ */
1077
+ async signUp(username: string, email: string, password: string): Promise<{ message: string; token: string; user: User }> {
1078
+ try {
1079
+ // First, create the user account
1080
+ const res = await this.client.post('/secure-session/register', { username, email, password });
1081
+ const { message, user } = res.data;
1082
+
1083
+ // Then log them in to create a session
1084
+ const loginRes = await this.secureLogin(username, password);
1085
+
1086
+ // Get the access token for the session
1087
+ const tokenRes = await this.getTokenBySession(loginRes.sessionId);
1088
+
1089
+ return {
1090
+ message,
1091
+ token: tokenRes.accessToken,
1092
+ user: loginRes.user as User
1093
+ };
1094
+ } catch (error) {
1095
+ throw this.handleError(error);
1096
+ }
1097
+ }
1098
+
1099
+ /**
1100
+ * Secure login that creates a device-based session
1181
1101
  * @param username - User's username or email
1182
1102
  * @param password - User's password
1183
- * @param deviceName - Optional device name for session tracking
1184
- * @param deviceFingerprint - Device fingerprint for enhanced security
1185
- * @returns Secure login response with session data
1103
+ * @param deviceName - Optional device name
1104
+ * @param deviceFingerprint - Optional device fingerprint
1105
+ * @returns Login response with session data
1186
1106
  */
1187
1107
  async secureLogin(username: string, password: string, deviceName?: string, deviceFingerprint?: any): Promise<SecureLoginResponse> {
1188
1108
  try {
@@ -1362,132 +1282,50 @@ export class OxyServices {
1362
1282
  }
1363
1283
 
1364
1284
  /**
1365
- * Utility method to help implement authentication middleware in Express.js applications
1366
- * This creates a function that can be used as Express middleware to validate tokens
1367
- * @param options - Configuration options for the middleware
1285
+ * Create authentication middleware for Express.js applications
1286
+ * This is the recommended way to protect routes in server applications
1368
1287
  * @returns Express middleware function
1369
1288
  */
1370
- public createAuthenticateTokenMiddleware(options: {
1371
- loadFullUser?: boolean; // Whether to load full user object or just user ID
1372
- onError?: (error: ApiError) => any; // Custom error handler
1373
- } = {}) {
1374
- const { loadFullUser = true, onError } = options;
1375
-
1289
+ public createAuthMiddleware() {
1376
1290
  return async (req: any, res: any, next: any) => {
1377
1291
  try {
1378
- const authHeader = req.headers['authorization'];
1379
- const token = authHeader && authHeader.split(' ')[1]; // Bearer TOKEN
1292
+ const authHeader = req.headers.authorization;
1380
1293
 
1381
- if (!token) {
1382
- const error = {
1383
- message: 'Access token required',
1384
- code: 'MISSING_TOKEN',
1385
- status: 401
1386
- };
1387
-
1388
- if (onError) {
1389
- return onError(error);
1390
- }
1391
-
1392
- return res.status(401).json({
1393
- message: 'Access token required',
1394
- code: 'MISSING_TOKEN'
1395
- });
1396
- }
1397
-
1398
- // Create a temporary OxyServices instance with the token to validate it
1399
- const tempOxyServices = new OxyServices({
1400
- baseURL: this.client.defaults.baseURL || ''
1401
- });
1402
- tempOxyServices.setTokens(token, ''); // Set access token
1403
-
1404
- // Validate token using the validate method
1405
- const isValid = await tempOxyServices.validate();
1406
-
1407
- if (!isValid) {
1408
- const error = {
1409
- message: 'Invalid or expired token',
1410
- code: 'INVALID_TOKEN',
1411
- status: 403
1412
- };
1413
-
1414
- if (onError) {
1415
- return onError(error);
1416
- }
1417
-
1418
- return res.status(403).json({
1419
- message: 'Invalid or expired token',
1420
- code: 'INVALID_TOKEN'
1294
+ if (!authHeader?.startsWith('Bearer ')) {
1295
+ return res.status(401).json({
1296
+ error: 'Authentication required',
1297
+ message: 'Invalid or missing authorization header'
1421
1298
  });
1422
1299
  }
1300
+
1301
+ const token = authHeader.split(' ')[1];
1423
1302
 
1424
- // Get user ID from token using JWT decode instead of relying on getCurrentUserId
1425
- let userId: string | null = null;
1426
- try {
1427
- const decoded = jwtDecode<JwtPayload>(token);
1428
- userId = decoded.userId || decoded.id;
1429
- } catch (decodeError) {
1430
- const error = {
1431
- message: 'Invalid token payload',
1432
- code: 'INVALID_PAYLOAD',
1433
- status: 403
1434
- };
1435
-
1436
- if (onError) {
1437
- return onError(error);
1438
- }
1439
-
1440
- return res.status(403).json({
1441
- message: 'Invalid token payload',
1442
- code: 'INVALID_PAYLOAD'
1443
- });
1444
- }
1303
+ // Use the authenticateToken method
1304
+ const result = await this.authenticateToken(token);
1445
1305
 
1446
- if (!userId) {
1447
- const error = {
1448
- message: 'Invalid token payload',
1449
- code: 'INVALID_PAYLOAD',
1450
- status: 403
1451
- };
1452
-
1453
- if (onError) {
1454
- return onError(error);
1455
- }
1456
-
1457
- return res.status(403).json({
1458
- message: 'Invalid token payload',
1459
- code: 'INVALID_PAYLOAD'
1306
+ if (!result.valid) {
1307
+ return res.status(401).json({
1308
+ error: 'Invalid token',
1309
+ message: result.error || 'The provided authentication token is invalid'
1460
1310
  });
1461
1311
  }
1462
1312
 
1463
1313
  // Set user information on request object
1464
- req.userId = userId;
1314
+ req.userId = result.userId || undefined;
1465
1315
  req.accessToken = token;
1466
1316
 
1467
- // Optionally load full user data
1468
- if (loadFullUser) {
1469
- try {
1470
- const userProfile = await tempOxyServices.getUserById(userId);
1471
- req.user = userProfile;
1472
- } catch (userError) {
1473
- // If we can't load user, continue with just ID
1474
- req.user = { id: userId };
1475
- }
1476
- } else {
1477
- req.user = { id: userId };
1317
+ if (result.user) {
1318
+ req.user = result.user;
1319
+ } else if (result.userId) {
1320
+ req.user = { id: result.userId };
1478
1321
  }
1479
1322
 
1480
1323
  next();
1481
1324
  } catch (error) {
1482
- const apiError = this.handleError(error);
1483
-
1484
- if (onError) {
1485
- return onError(apiError);
1486
- }
1487
-
1488
- return res.status(apiError.status || 500).json({
1489
- message: apiError.message,
1490
- code: apiError.code
1325
+ console.error('Auth middleware error:', error);
1326
+ return res.status(500).json({
1327
+ error: 'Server error',
1328
+ message: 'An error occurred while authenticating your request'
1491
1329
  });
1492
1330
  }
1493
1331
  };
@@ -1513,55 +1351,76 @@ export class OxyServices {
1513
1351
  };
1514
1352
  }
1515
1353
 
1516
- // Create a temporary OxyServices instance with the token
1517
- const tempOxyServices = new OxyServices({
1518
- baseURL: this.client.defaults.baseURL || ''
1519
- });
1520
- tempOxyServices.setTokens(token, '');
1521
-
1522
- // Validate token
1523
- const isValid = await tempOxyServices.validate();
1524
-
1525
- if (!isValid) {
1526
- return {
1527
- valid: false,
1528
- error: 'Invalid or expired token'
1529
- };
1530
- }
1531
-
1532
- // Get user ID from token using JWT decode
1533
- let userId: string | null = null;
1354
+ // Check if token contains sessionId (new session-based system)
1534
1355
  try {
1535
1356
  const decoded = jwtDecode<JwtPayload>(token);
1536
- userId = decoded.userId || decoded.id;
1357
+ const userId = decoded.userId || decoded.id;
1358
+
1359
+ if (decoded.sessionId) {
1360
+ // Use session-based validation
1361
+ const tempOxyServices = new OxyServices({
1362
+ baseURL: this.client.defaults.baseURL || ''
1363
+ });
1364
+ tempOxyServices.setTokens(token, '');
1365
+
1366
+ const validation = await tempOxyServices.validateSession(decoded.sessionId);
1367
+
1368
+ if (validation.valid) {
1369
+ return {
1370
+ valid: true,
1371
+ userId,
1372
+ user: validation.user
1373
+ };
1374
+ } else {
1375
+ return {
1376
+ valid: false,
1377
+ error: 'Invalid or expired session'
1378
+ };
1379
+ }
1380
+ } else {
1381
+ // Use old validation method
1382
+ const tempOxyServices = new OxyServices({
1383
+ baseURL: this.client.defaults.baseURL || ''
1384
+ });
1385
+ tempOxyServices.setTokens(token, '');
1386
+
1387
+ const isValid = await tempOxyServices.validate();
1388
+
1389
+ if (!isValid) {
1390
+ return {
1391
+ valid: false,
1392
+ error: 'Invalid or expired token'
1393
+ };
1394
+ }
1395
+
1396
+ if (!userId) {
1397
+ return {
1398
+ valid: false,
1399
+ error: 'Invalid token payload'
1400
+ };
1401
+ }
1402
+
1403
+ // Try to get user profile
1404
+ let user;
1405
+ try {
1406
+ user = await tempOxyServices.getUserById(userId);
1407
+ } catch (error) {
1408
+ // Continue without full user data
1409
+ user = { id: userId };
1410
+ }
1411
+
1412
+ return {
1413
+ valid: true,
1414
+ userId,
1415
+ user
1416
+ };
1417
+ }
1537
1418
  } catch (decodeError) {
1538
1419
  return {
1539
1420
  valid: false,
1540
1421
  error: 'Invalid token payload'
1541
1422
  };
1542
1423
  }
1543
-
1544
- if (!userId) {
1545
- return {
1546
- valid: false,
1547
- error: 'Invalid token payload'
1548
- };
1549
- }
1550
-
1551
- // Try to get user profile
1552
- let user;
1553
- try {
1554
- user = await tempOxyServices.getUserById(userId);
1555
- } catch (error) {
1556
- // Continue without full user data
1557
- user = { id: userId };
1558
- }
1559
-
1560
- return {
1561
- valid: true,
1562
- userId,
1563
- user
1564
- };
1565
1424
  } catch (error) {
1566
1425
  return {
1567
1426
  valid: false,
@@ -1909,6 +1768,15 @@ export default OxyServices;
1909
1768
  export * from '../models/interfaces';
1910
1769
  export * from '../models/secureSession';
1911
1770
 
1771
+ // Clean middleware exports - these will be available for server-side use
1772
+ // Note: These require Express.js and are only for server-side applications
1773
+ export type { AuthRequest, SimpleAuthRequest } from '../types/middleware';
1774
+
1775
+ // Export a simple function to create auth middleware
1776
+ export const createAuthMiddleware = (oxyServices: OxyServices) => {
1777
+ return oxyServices.createAuthMiddleware();
1778
+ };
1779
+
1912
1780
  if (typeof FormData === 'undefined') {
1913
1781
  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.');
1914
1782
  }
package/src/index.ts CHANGED
@@ -10,6 +10,10 @@
10
10
  export { OxyServices } from './core';
11
11
  export { OXY_CLOUD_URL } from './core';
12
12
 
13
+ // Middleware exports (for server-side use)
14
+ export type { AuthRequest, SimpleAuthRequest } from './types/middleware';
15
+ export { createAuthMiddleware } from './core';
16
+
13
17
  // React context
14
18
  export {
15
19
  OxyContextProvider, // Backward compatibility
package/src/node/index.ts CHANGED
@@ -4,15 +4,11 @@
4
4
 
5
5
  // ------------- Core Imports -------------
6
6
  import { OxyServices, OXY_CLOUD_URL } from '../core'; // Adjusted path
7
- import { createAuth } from './createAuth';
8
7
  import * as Models from '../models/interfaces'; // Adjusted path
9
8
 
10
9
  // ------------- Core Exports -------------
11
10
  export { OxyServices, OXY_CLOUD_URL };
12
11
 
13
- // Zero-config auth and session router
14
- export { createAuth };
15
-
16
12
  // ------------- Model Exports -------------
17
13
  export { Models }; // Export all models as a namespace
18
14
  export * from '../models/interfaces'; // Export all models directly