@oxyhq/services 5.8.11 → 5.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/commonjs/core/index.js +207 -283
- package/lib/commonjs/core/index.js.map +1 -1
- package/lib/commonjs/node/index.js +0 -9
- package/lib/commonjs/node/index.js.map +1 -1
- package/lib/commonjs/ui/components/OxyProvider.js +3 -9
- package/lib/commonjs/ui/components/OxyProvider.js.map +1 -1
- package/lib/commonjs/ui/screens/FeedbackScreen.js +0 -4
- package/lib/commonjs/ui/screens/FeedbackScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/RecoverAccountScreen.js +0 -4
- package/lib/commonjs/ui/screens/RecoverAccountScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/SignInScreen.js +16 -27
- package/lib/commonjs/ui/screens/SignInScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/SignUpScreen.js +4 -18
- package/lib/commonjs/ui/screens/SignUpScreen.js.map +1 -1
- package/lib/commonjs/ui/styles/authStyles.js +1 -2
- package/lib/commonjs/ui/styles/authStyles.js.map +1 -1
- package/lib/module/core/index.js +207 -283
- package/lib/module/core/index.js.map +1 -1
- package/lib/module/node/index.js +0 -4
- package/lib/module/node/index.js.map +1 -1
- package/lib/module/ui/components/OxyProvider.js +3 -9
- package/lib/module/ui/components/OxyProvider.js.map +1 -1
- package/lib/module/ui/screens/FeedbackScreen.js +0 -4
- package/lib/module/ui/screens/FeedbackScreen.js.map +1 -1
- package/lib/module/ui/screens/RecoverAccountScreen.js +0 -4
- package/lib/module/ui/screens/RecoverAccountScreen.js.map +1 -1
- package/lib/module/ui/screens/SignInScreen.js +16 -27
- package/lib/module/ui/screens/SignInScreen.js.map +1 -1
- package/lib/module/ui/screens/SignUpScreen.js +4 -18
- package/lib/module/ui/screens/SignUpScreen.js.map +1 -1
- package/lib/module/ui/styles/authStyles.js +1 -2
- package/lib/module/ui/styles/authStyles.js.map +1 -1
- package/lib/typescript/core/index.d.ts +29 -79
- package/lib/typescript/core/index.d.ts.map +1 -1
- package/lib/typescript/node/index.d.ts +0 -2
- package/lib/typescript/node/index.d.ts.map +1 -1
- package/lib/typescript/ui/components/OxyProvider.d.ts.map +1 -1
- package/lib/typescript/ui/screens/FeedbackScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/RecoverAccountScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/SignInScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/SignUpScreen.d.ts.map +1 -1
- package/lib/typescript/ui/styles/authStyles.d.ts +0 -1
- package/lib/typescript/ui/styles/authStyles.d.ts.map +1 -1
- package/package.json +6 -6
- package/src/core/index.ts +213 -254
- package/src/node/index.ts +0 -4
- package/src/ui/components/OxyProvider.tsx +3 -9
- package/src/ui/screens/FeedbackScreen.tsx +0 -4
- package/src/ui/screens/RecoverAccountScreen.tsx +0 -4
- package/src/ui/screens/SignInScreen.tsx +16 -20
- package/src/ui/screens/SignUpScreen.tsx +4 -14
- package/src/ui/styles/authStyles.ts +0 -1
- package/lib/commonjs/node/createAuth.js +0 -95
- package/lib/commonjs/node/createAuth.js.map +0 -1
- package/lib/module/node/createAuth.js +0 -90
- package/lib/module/node/createAuth.js.map +0 -1
- package/lib/typescript/node/createAuth.d.ts +0 -7
- package/lib/typescript/node/createAuth.d.ts.map +0 -1
- package/src/node/createAuth.ts +0 -116
|
@@ -63,7 +63,6 @@ const OXY_CLOUD_URL = exports.OXY_CLOUD_URL = 'https://cloud.oxy.so';
|
|
|
63
63
|
class OxyServices {
|
|
64
64
|
accessToken = null;
|
|
65
65
|
refreshToken = null;
|
|
66
|
-
refreshPromise = null;
|
|
67
66
|
|
|
68
67
|
/**
|
|
69
68
|
* Creates a new instance of the OxyServices client
|
|
@@ -79,14 +78,25 @@ class OxyServices {
|
|
|
79
78
|
this.client.interceptors.request.use(async req => {
|
|
80
79
|
if (!this.accessToken) {
|
|
81
80
|
return req;
|
|
82
|
-
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Check if token is expired and refresh if needed
|
|
83
84
|
try {
|
|
84
85
|
const decoded = (0, _jwtDecode.jwtDecode)(this.accessToken);
|
|
85
86
|
const currentTime = Math.floor(Date.now() / 1000);
|
|
86
87
|
|
|
87
88
|
// If token expires in less than 60 seconds, refresh it
|
|
88
89
|
if (decoded.exp - currentTime < 60) {
|
|
89
|
-
|
|
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
|
+
}
|
|
90
100
|
}
|
|
91
101
|
} catch (error) {
|
|
92
102
|
// If token can't be decoded, continue with request and let server handle it
|
|
@@ -101,18 +111,24 @@ class OxyServices {
|
|
|
101
111
|
this.client.interceptors.response.use(response => response, async error => {
|
|
102
112
|
const originalRequest = error.config;
|
|
103
113
|
// If the error is due to an expired token and we haven't tried refreshing yet
|
|
104
|
-
if (error.response?.status === 401 && this.
|
|
114
|
+
if (error.response?.status === 401 && this.accessToken && originalRequest && !originalRequest.headers?.['X-Retry-After-Refresh']) {
|
|
105
115
|
try {
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
newRequest
|
|
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);
|
|
114
131
|
}
|
|
115
|
-
return this.client(newRequest);
|
|
116
132
|
} catch (refreshError) {
|
|
117
133
|
// If refresh fails, force user to login again
|
|
118
134
|
this.clearTokens();
|
|
@@ -145,43 +161,17 @@ class OxyServices {
|
|
|
145
161
|
}
|
|
146
162
|
|
|
147
163
|
/**
|
|
148
|
-
*
|
|
149
|
-
* @
|
|
150
|
-
|
|
151
|
-
getCurrentUserId() {
|
|
152
|
-
if (!this.accessToken) return null;
|
|
153
|
-
try {
|
|
154
|
-
const decoded = (0, _jwtDecode.jwtDecode)(this.accessToken);
|
|
155
|
-
|
|
156
|
-
// Check for both userId (preferred) and id (fallback) for compatibility
|
|
157
|
-
return decoded.userId || decoded.id || null;
|
|
158
|
-
} catch (error) {
|
|
159
|
-
return null;
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
/**
|
|
164
|
-
* Internal method to check if we have an access token
|
|
165
|
-
* @private
|
|
166
|
-
* @returns Boolean indicating if access token exists
|
|
167
|
-
* @internal - Use `isAuthenticated` from useOxy() context in UI components instead
|
|
164
|
+
* Set authentication tokens manually
|
|
165
|
+
* @param accessToken - The access token
|
|
166
|
+
* @param refreshToken - The refresh token (optional for session-based auth)
|
|
168
167
|
*/
|
|
169
|
-
|
|
170
|
-
return this.accessToken !== null;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
/**
|
|
174
|
-
* Sets authentication tokens directly (useful for initializing from storage)
|
|
175
|
-
* @param accessToken - JWT access token
|
|
176
|
-
* @param refreshToken - Refresh token for getting new access tokens
|
|
177
|
-
*/
|
|
178
|
-
setTokens(accessToken, refreshToken) {
|
|
168
|
+
setTokens(accessToken, refreshToken = '') {
|
|
179
169
|
this.accessToken = accessToken;
|
|
180
170
|
this.refreshToken = refreshToken;
|
|
181
171
|
}
|
|
182
172
|
|
|
183
173
|
/**
|
|
184
|
-
*
|
|
174
|
+
* Clear stored authentication tokens
|
|
185
175
|
*/
|
|
186
176
|
clearTokens() {
|
|
187
177
|
this.accessToken = null;
|
|
@@ -189,120 +179,27 @@ class OxyServices {
|
|
|
189
179
|
}
|
|
190
180
|
|
|
191
181
|
/**
|
|
192
|
-
*
|
|
193
|
-
* @
|
|
194
|
-
* @param email - User's email address
|
|
195
|
-
* @param password - User's password
|
|
196
|
-
* @returns Object containing the message, token and user data
|
|
197
|
-
*/
|
|
198
|
-
async signUp(username, email, password) {
|
|
199
|
-
try {
|
|
200
|
-
const res = await this.client.post('/auth/signup', {
|
|
201
|
-
username,
|
|
202
|
-
email,
|
|
203
|
-
password
|
|
204
|
-
});
|
|
205
|
-
const {
|
|
206
|
-
message,
|
|
207
|
-
token,
|
|
208
|
-
user
|
|
209
|
-
} = res.data;
|
|
210
|
-
this.accessToken = token;
|
|
211
|
-
return {
|
|
212
|
-
message,
|
|
213
|
-
token,
|
|
214
|
-
user
|
|
215
|
-
};
|
|
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, password) {
|
|
228
|
-
try {
|
|
229
|
-
const res = await this.client.post('/auth/login', {
|
|
230
|
-
username,
|
|
231
|
-
password
|
|
232
|
-
});
|
|
233
|
-
const {
|
|
234
|
-
accessToken,
|
|
235
|
-
refreshToken,
|
|
236
|
-
user
|
|
237
|
-
} = res.data;
|
|
238
|
-
this.accessToken = accessToken;
|
|
239
|
-
this.refreshToken = refreshToken;
|
|
240
|
-
return {
|
|
241
|
-
accessToken,
|
|
242
|
-
refreshToken,
|
|
243
|
-
user
|
|
244
|
-
};
|
|
245
|
-
} catch (error) {
|
|
246
|
-
throw this.handleError(error);
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
/**
|
|
251
|
-
* Log out user
|
|
182
|
+
* Get the current user ID from the stored token
|
|
183
|
+
* @returns User ID or null if not authenticated
|
|
252
184
|
*/
|
|
253
|
-
|
|
254
|
-
if (!this.
|
|
185
|
+
getCurrentUserId() {
|
|
186
|
+
if (!this.accessToken) return null;
|
|
255
187
|
try {
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
});
|
|
188
|
+
const decoded = (0, _jwtDecode.jwtDecode)(this.accessToken);
|
|
189
|
+
return decoded.userId || decoded.id || null;
|
|
259
190
|
} catch (error) {
|
|
260
|
-
|
|
261
|
-
} finally {
|
|
262
|
-
this.accessToken = null;
|
|
263
|
-
this.refreshToken = null;
|
|
191
|
+
return null;
|
|
264
192
|
}
|
|
265
193
|
}
|
|
266
194
|
|
|
267
195
|
/**
|
|
268
|
-
*
|
|
269
|
-
* @
|
|
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
|
|
270
200
|
*/
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
throw new Error('No refresh token available');
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
// If a refresh is already in progress, return that promise
|
|
277
|
-
if (this.refreshPromise) {
|
|
278
|
-
return this.refreshPromise;
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
// Create a new refresh promise
|
|
282
|
-
this.refreshPromise = (async () => {
|
|
283
|
-
try {
|
|
284
|
-
const res = await this.client.post('/auth/refresh', {
|
|
285
|
-
refreshToken: this.refreshToken
|
|
286
|
-
});
|
|
287
|
-
const {
|
|
288
|
-
accessToken,
|
|
289
|
-
refreshToken
|
|
290
|
-
} = res.data;
|
|
291
|
-
this.accessToken = accessToken;
|
|
292
|
-
this.refreshToken = refreshToken;
|
|
293
|
-
return {
|
|
294
|
-
accessToken,
|
|
295
|
-
refreshToken
|
|
296
|
-
};
|
|
297
|
-
} catch (error) {
|
|
298
|
-
this.accessToken = null;
|
|
299
|
-
this.refreshToken = null;
|
|
300
|
-
throw this.handleError(error);
|
|
301
|
-
} finally {
|
|
302
|
-
this.refreshPromise = null;
|
|
303
|
-
}
|
|
304
|
-
})();
|
|
305
|
-
return this.refreshPromise;
|
|
201
|
+
hasAccessToken() {
|
|
202
|
+
return this.accessToken !== null;
|
|
306
203
|
}
|
|
307
204
|
|
|
308
205
|
/**
|
|
@@ -311,6 +208,22 @@ class OxyServices {
|
|
|
311
208
|
*/
|
|
312
209
|
async validate() {
|
|
313
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
|
|
314
227
|
const res = await this.client.get('/auth/validate');
|
|
315
228
|
return res.data.valid;
|
|
316
229
|
} catch (error) {
|
|
@@ -320,59 +233,6 @@ class OxyServices {
|
|
|
320
233
|
|
|
321
234
|
/* Session Management Methods */
|
|
322
235
|
|
|
323
|
-
/**
|
|
324
|
-
* Get active sessions for the authenticated user
|
|
325
|
-
* @returns Array of active session objects
|
|
326
|
-
*/
|
|
327
|
-
async getUserSessions() {
|
|
328
|
-
try {
|
|
329
|
-
const res = await this.client.get('/sessions');
|
|
330
|
-
return res.data;
|
|
331
|
-
} catch (error) {
|
|
332
|
-
throw this.handleError(error);
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
/**
|
|
337
|
-
* Logout from a specific session
|
|
338
|
-
* @param sessionId - The session ID to logout from
|
|
339
|
-
* @returns Success status
|
|
340
|
-
*/
|
|
341
|
-
async logoutSession(sessionId) {
|
|
342
|
-
try {
|
|
343
|
-
const res = await this.client.delete(`/sessions/${sessionId}`);
|
|
344
|
-
return res.data;
|
|
345
|
-
} catch (error) {
|
|
346
|
-
throw this.handleError(error);
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
/**
|
|
351
|
-
* Logout from all other sessions (keep current session active)
|
|
352
|
-
* @returns Success status
|
|
353
|
-
*/
|
|
354
|
-
async logoutOtherSessions() {
|
|
355
|
-
try {
|
|
356
|
-
const res = await this.client.post('/sessions/logout-others');
|
|
357
|
-
return res.data;
|
|
358
|
-
} catch (error) {
|
|
359
|
-
throw this.handleError(error);
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
/**
|
|
364
|
-
* Logout from all sessions
|
|
365
|
-
* @returns Success status
|
|
366
|
-
*/
|
|
367
|
-
async logoutAllSessions() {
|
|
368
|
-
try {
|
|
369
|
-
const res = await this.client.post('/sessions/logout-all');
|
|
370
|
-
return res.data;
|
|
371
|
-
} catch (error) {
|
|
372
|
-
throw this.handleError(error);
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
|
|
376
236
|
/**
|
|
377
237
|
* Get device sessions for a specific session ID
|
|
378
238
|
* @param sessionId - The session ID to get device sessions for
|
|
@@ -1197,12 +1057,47 @@ class OxyServices {
|
|
|
1197
1057
|
}
|
|
1198
1058
|
|
|
1199
1059
|
/**
|
|
1200
|
-
*
|
|
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
|
|
1201
1096
|
* @param username - User's username or email
|
|
1202
1097
|
* @param password - User's password
|
|
1203
|
-
* @param deviceName - Optional device name
|
|
1204
|
-
* @param deviceFingerprint -
|
|
1205
|
-
* @returns
|
|
1098
|
+
* @param deviceName - Optional device name
|
|
1099
|
+
* @param deviceFingerprint - Optional device fingerprint
|
|
1100
|
+
* @returns Login response with session data
|
|
1206
1101
|
*/
|
|
1207
1102
|
async secureLogin(username, password, deviceName, deviceFingerprint) {
|
|
1208
1103
|
try {
|
|
@@ -1410,34 +1305,42 @@ class OxyServices {
|
|
|
1410
1305
|
});
|
|
1411
1306
|
}
|
|
1412
1307
|
|
|
1413
|
-
//
|
|
1414
|
-
|
|
1415
|
-
baseURL: this.client.defaults.baseURL || ''
|
|
1416
|
-
});
|
|
1417
|
-
tempOxyServices.setTokens(token, ''); // Set access token
|
|
1418
|
-
|
|
1419
|
-
// Validate token using the validate method
|
|
1420
|
-
const isValid = await tempOxyServices.validate();
|
|
1421
|
-
if (!isValid) {
|
|
1422
|
-
const error = {
|
|
1423
|
-
message: 'Invalid or expired token',
|
|
1424
|
-
code: 'INVALID_TOKEN',
|
|
1425
|
-
status: 403
|
|
1426
|
-
};
|
|
1427
|
-
if (onError) {
|
|
1428
|
-
return onError(error);
|
|
1429
|
-
}
|
|
1430
|
-
return res.status(403).json({
|
|
1431
|
-
message: 'Invalid or expired token',
|
|
1432
|
-
code: 'INVALID_TOKEN'
|
|
1433
|
-
});
|
|
1434
|
-
}
|
|
1435
|
-
|
|
1436
|
-
// Get user ID from token using JWT decode instead of relying on getCurrentUserId
|
|
1308
|
+
// Check if token contains sessionId (new session-based system)
|
|
1309
|
+
let isValid = false;
|
|
1437
1310
|
let userId = null;
|
|
1438
1311
|
try {
|
|
1439
1312
|
const decoded = (0, _jwtDecode.jwtDecode)(token);
|
|
1440
1313
|
userId = decoded.userId || decoded.id;
|
|
1314
|
+
if (decoded.sessionId) {
|
|
1315
|
+
// Use session-based validation
|
|
1316
|
+
const tempOxyServices = new OxyServices({
|
|
1317
|
+
baseURL: this.client.defaults.baseURL || ''
|
|
1318
|
+
});
|
|
1319
|
+
tempOxyServices.setTokens(token, '');
|
|
1320
|
+
const validation = await tempOxyServices.validateSession(decoded.sessionId);
|
|
1321
|
+
isValid = validation.valid;
|
|
1322
|
+
if (isValid && loadFullUser) {
|
|
1323
|
+
req.user = validation.user;
|
|
1324
|
+
}
|
|
1325
|
+
} else {
|
|
1326
|
+
// Use old validation method
|
|
1327
|
+
const tempOxyServices = new OxyServices({
|
|
1328
|
+
baseURL: this.client.defaults.baseURL || ''
|
|
1329
|
+
});
|
|
1330
|
+
tempOxyServices.setTokens(token, '');
|
|
1331
|
+
isValid = await tempOxyServices.validate();
|
|
1332
|
+
if (isValid && loadFullUser) {
|
|
1333
|
+
try {
|
|
1334
|
+
const userProfile = await tempOxyServices.getUserById(userId);
|
|
1335
|
+
req.user = userProfile;
|
|
1336
|
+
} catch (userError) {
|
|
1337
|
+
// If we can't load user, continue with just ID
|
|
1338
|
+
req.user = {
|
|
1339
|
+
id: userId
|
|
1340
|
+
};
|
|
1341
|
+
}
|
|
1342
|
+
}
|
|
1343
|
+
}
|
|
1441
1344
|
} catch (decodeError) {
|
|
1442
1345
|
const error = {
|
|
1443
1346
|
message: 'Invalid token payload',
|
|
@@ -1452,6 +1355,20 @@ class OxyServices {
|
|
|
1452
1355
|
code: 'INVALID_PAYLOAD'
|
|
1453
1356
|
});
|
|
1454
1357
|
}
|
|
1358
|
+
if (!isValid) {
|
|
1359
|
+
const error = {
|
|
1360
|
+
message: 'Invalid or expired token',
|
|
1361
|
+
code: 'INVALID_TOKEN',
|
|
1362
|
+
status: 403
|
|
1363
|
+
};
|
|
1364
|
+
if (onError) {
|
|
1365
|
+
return onError(error);
|
|
1366
|
+
}
|
|
1367
|
+
return res.status(403).json({
|
|
1368
|
+
message: 'Invalid or expired token',
|
|
1369
|
+
code: 'INVALID_TOKEN'
|
|
1370
|
+
});
|
|
1371
|
+
}
|
|
1455
1372
|
if (!userId) {
|
|
1456
1373
|
const error = {
|
|
1457
1374
|
message: 'Invalid token payload',
|
|
@@ -1471,18 +1388,8 @@ class OxyServices {
|
|
|
1471
1388
|
req.userId = userId;
|
|
1472
1389
|
req.accessToken = token;
|
|
1473
1390
|
|
|
1474
|
-
//
|
|
1475
|
-
if (
|
|
1476
|
-
try {
|
|
1477
|
-
const userProfile = await tempOxyServices.getUserById(userId);
|
|
1478
|
-
req.user = userProfile;
|
|
1479
|
-
} catch (userError) {
|
|
1480
|
-
// If we can't load user, continue with just ID
|
|
1481
|
-
req.user = {
|
|
1482
|
-
id: userId
|
|
1483
|
-
};
|
|
1484
|
-
}
|
|
1485
|
-
} else {
|
|
1391
|
+
// Set user object if not already set by session validation
|
|
1392
|
+
if (!req.user) {
|
|
1486
1393
|
req.user = {
|
|
1487
1394
|
id: userId
|
|
1488
1395
|
};
|
|
@@ -1516,54 +1423,71 @@ class OxyServices {
|
|
|
1516
1423
|
};
|
|
1517
1424
|
}
|
|
1518
1425
|
|
|
1519
|
-
//
|
|
1520
|
-
const tempOxyServices = new OxyServices({
|
|
1521
|
-
baseURL: this.client.defaults.baseURL || ''
|
|
1522
|
-
});
|
|
1523
|
-
tempOxyServices.setTokens(token, '');
|
|
1524
|
-
|
|
1525
|
-
// Validate token
|
|
1526
|
-
const isValid = await tempOxyServices.validate();
|
|
1527
|
-
if (!isValid) {
|
|
1528
|
-
return {
|
|
1529
|
-
valid: false,
|
|
1530
|
-
error: 'Invalid or expired token'
|
|
1531
|
-
};
|
|
1532
|
-
}
|
|
1533
|
-
|
|
1534
|
-
// Get user ID from token using JWT decode
|
|
1535
|
-
let userId = null;
|
|
1426
|
+
// Check if token contains sessionId (new session-based system)
|
|
1536
1427
|
try {
|
|
1537
1428
|
const decoded = (0, _jwtDecode.jwtDecode)(token);
|
|
1538
|
-
userId = decoded.userId || decoded.id;
|
|
1429
|
+
const userId = decoded.userId || decoded.id;
|
|
1430
|
+
if (decoded.sessionId) {
|
|
1431
|
+
// Use session-based validation
|
|
1432
|
+
const tempOxyServices = new OxyServices({
|
|
1433
|
+
baseURL: this.client.defaults.baseURL || ''
|
|
1434
|
+
});
|
|
1435
|
+
tempOxyServices.setTokens(token, '');
|
|
1436
|
+
const validation = await tempOxyServices.validateSession(decoded.sessionId);
|
|
1437
|
+
if (validation.valid) {
|
|
1438
|
+
return {
|
|
1439
|
+
valid: true,
|
|
1440
|
+
userId,
|
|
1441
|
+
user: validation.user
|
|
1442
|
+
};
|
|
1443
|
+
} else {
|
|
1444
|
+
return {
|
|
1445
|
+
valid: false,
|
|
1446
|
+
error: 'Invalid or expired session'
|
|
1447
|
+
};
|
|
1448
|
+
}
|
|
1449
|
+
} else {
|
|
1450
|
+
// Use old validation method
|
|
1451
|
+
const tempOxyServices = new OxyServices({
|
|
1452
|
+
baseURL: this.client.defaults.baseURL || ''
|
|
1453
|
+
});
|
|
1454
|
+
tempOxyServices.setTokens(token, '');
|
|
1455
|
+
const isValid = await tempOxyServices.validate();
|
|
1456
|
+
if (!isValid) {
|
|
1457
|
+
return {
|
|
1458
|
+
valid: false,
|
|
1459
|
+
error: 'Invalid or expired token'
|
|
1460
|
+
};
|
|
1461
|
+
}
|
|
1462
|
+
if (!userId) {
|
|
1463
|
+
return {
|
|
1464
|
+
valid: false,
|
|
1465
|
+
error: 'Invalid token payload'
|
|
1466
|
+
};
|
|
1467
|
+
}
|
|
1468
|
+
|
|
1469
|
+
// Try to get user profile
|
|
1470
|
+
let user;
|
|
1471
|
+
try {
|
|
1472
|
+
user = await tempOxyServices.getUserById(userId);
|
|
1473
|
+
} catch (error) {
|
|
1474
|
+
// Continue without full user data
|
|
1475
|
+
user = {
|
|
1476
|
+
id: userId
|
|
1477
|
+
};
|
|
1478
|
+
}
|
|
1479
|
+
return {
|
|
1480
|
+
valid: true,
|
|
1481
|
+
userId,
|
|
1482
|
+
user
|
|
1483
|
+
};
|
|
1484
|
+
}
|
|
1539
1485
|
} catch (decodeError) {
|
|
1540
1486
|
return {
|
|
1541
1487
|
valid: false,
|
|
1542
1488
|
error: 'Invalid token payload'
|
|
1543
1489
|
};
|
|
1544
1490
|
}
|
|
1545
|
-
if (!userId) {
|
|
1546
|
-
return {
|
|
1547
|
-
valid: false,
|
|
1548
|
-
error: 'Invalid token payload'
|
|
1549
|
-
};
|
|
1550
|
-
}
|
|
1551
|
-
|
|
1552
|
-
// Try to get user profile
|
|
1553
|
-
let user;
|
|
1554
|
-
try {
|
|
1555
|
-
user = await tempOxyServices.getUserById(userId);
|
|
1556
|
-
} catch (error) {
|
|
1557
|
-
// Continue without full user data
|
|
1558
|
-
user = {
|
|
1559
|
-
id: userId
|
|
1560
|
-
};
|
|
1561
|
-
}
|
|
1562
|
-
return {
|
|
1563
|
-
valid: true,
|
|
1564
|
-
userId,
|
|
1565
|
-
user
|
|
1566
|
-
};
|
|
1567
1491
|
} catch (error) {
|
|
1568
1492
|
return {
|
|
1569
1493
|
valid: false,
|