propro-utils 1.7.30 → 1.7.32
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/package.json +1 -1
- package/src/server/index.js +52 -4
package/package.json
CHANGED
package/src/server/index.js
CHANGED
|
@@ -188,9 +188,11 @@ class AuthMiddleware {
|
|
|
188
188
|
const refreshToken =
|
|
189
189
|
req.cookies['x-refresh-token'] || req.headers['x-refresh-token'];
|
|
190
190
|
if (!refreshToken) {
|
|
191
|
+
console.error('Refresh token missing in request');
|
|
191
192
|
return res.status(401).json({
|
|
192
193
|
redirectUrl: this.constructRedirectUrl(),
|
|
193
194
|
error: 'No refresh token provided',
|
|
195
|
+
message: 'Authentication required. Please log in.',
|
|
194
196
|
});
|
|
195
197
|
}
|
|
196
198
|
|
|
@@ -198,16 +200,25 @@ class AuthMiddleware {
|
|
|
198
200
|
const lockKey = refreshToken;
|
|
199
201
|
if (this.refreshLocks.has(lockKey)) {
|
|
200
202
|
// Wait for the in-flight request to complete
|
|
203
|
+
console.log('Waiting for in-flight refresh request to complete...');
|
|
201
204
|
try {
|
|
202
205
|
const result = await this.refreshLocks.get(lockKey);
|
|
206
|
+
console.log('Reusing result from in-flight refresh request');
|
|
203
207
|
return res.status(200).json(result);
|
|
204
208
|
} catch (error) {
|
|
205
|
-
|
|
209
|
+
console.error('In-flight refresh request failed:', error);
|
|
210
|
+
return res.status(401).json({
|
|
211
|
+
error: 'Failed to refresh token',
|
|
212
|
+
message: 'Session refresh failed. Please log in again.',
|
|
213
|
+
});
|
|
206
214
|
}
|
|
207
215
|
}
|
|
208
216
|
|
|
209
217
|
// Create a promise for this refresh operation
|
|
210
218
|
const refreshPromise = (async () => {
|
|
219
|
+
console.log('Starting refresh token operation...');
|
|
220
|
+
const startTime = Date.now();
|
|
221
|
+
|
|
211
222
|
try {
|
|
212
223
|
const response = await this.refreshTokens(refreshToken);
|
|
213
224
|
const { account, access, refresh } = response.data;
|
|
@@ -216,10 +227,13 @@ class AuthMiddleware {
|
|
|
216
227
|
throw new Error('Invalid or expired refresh token');
|
|
217
228
|
}
|
|
218
229
|
|
|
230
|
+
console.log(`Token refresh successful for account: ${account.accountId}`);
|
|
231
|
+
|
|
219
232
|
const user = await checkIfUserExists(account.accountId);
|
|
220
233
|
|
|
221
234
|
const { returnTokens } = req.query;
|
|
222
235
|
if (returnTokens === 'true') {
|
|
236
|
+
console.log(`Refresh completed in ${Date.now() - startTime}ms (returning tokens)`);
|
|
223
237
|
return { account, user, access, refresh };
|
|
224
238
|
}
|
|
225
239
|
|
|
@@ -231,11 +245,24 @@ class AuthMiddleware {
|
|
|
231
245
|
this.options.appUrl
|
|
232
246
|
);
|
|
233
247
|
|
|
234
|
-
|
|
248
|
+
console.log(`Refresh completed in ${Date.now() - startTime}ms (cookies set)`);
|
|
249
|
+
return {
|
|
250
|
+
message: 'Token refreshed successfully',
|
|
251
|
+
account: { accountId: account.accountId, email: account.email },
|
|
252
|
+
};
|
|
253
|
+
} catch (error) {
|
|
254
|
+
const status = error?.response?.status;
|
|
255
|
+
console.error(`Token refresh failed after ${Date.now() - startTime}ms (status: ${status}):`, error.message);
|
|
256
|
+
|
|
257
|
+
// Immediately clean up lock on failure to prevent blocking
|
|
258
|
+
this.refreshLocks.delete(lockKey);
|
|
259
|
+
|
|
260
|
+
throw error;
|
|
235
261
|
} finally {
|
|
236
|
-
// Clean up lock after 30 seconds
|
|
262
|
+
// Clean up lock after 30 seconds for successful requests
|
|
237
263
|
setTimeout(() => {
|
|
238
264
|
this.refreshLocks.delete(lockKey);
|
|
265
|
+
console.log('Refresh lock cleaned up (delayed)');
|
|
239
266
|
}, 30000);
|
|
240
267
|
}
|
|
241
268
|
})();
|
|
@@ -248,7 +275,28 @@ class AuthMiddleware {
|
|
|
248
275
|
res.status(200).json(result);
|
|
249
276
|
} catch (error) {
|
|
250
277
|
console.error('Error refreshing token:', error);
|
|
251
|
-
|
|
278
|
+
|
|
279
|
+
const status = error?.response?.status || 401;
|
|
280
|
+
const errorMessage = error?.response?.data?.message || error?.message || 'Failed to refresh token';
|
|
281
|
+
|
|
282
|
+
// Pass through rate limit status
|
|
283
|
+
if (status === 429) {
|
|
284
|
+
const retryAfter = error?.response?.headers?.['retry-after'];
|
|
285
|
+
return res.status(429).json({
|
|
286
|
+
error: 'Too many requests',
|
|
287
|
+
message: 'Rate limit exceeded. Please try again later.',
|
|
288
|
+
retryAfter: retryAfter ? parseInt(retryAfter) : 900,
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
// Handle 401 unauthorized
|
|
293
|
+
res.status(status).json({
|
|
294
|
+
error: 'Failed to refresh token',
|
|
295
|
+
message: errorMessage,
|
|
296
|
+
details: status === 401
|
|
297
|
+
? 'Your session has expired. Please log in again.'
|
|
298
|
+
: 'Your session could not be refreshed. Please log in again.',
|
|
299
|
+
});
|
|
252
300
|
}
|
|
253
301
|
};
|
|
254
302
|
|