fix: Using Parse Server option extendSessionOnUse does not correctly clear memory and functions as a debounce instead of a throttle (#8683)
This commit is contained in:
70
src/Auth.js
70
src/Auth.js
@@ -2,6 +2,7 @@ const Parse = require('parse/node');
|
||||
import { isDeepStrictEqual } from 'util';
|
||||
import { getRequestObject, resolveError } from './triggers';
|
||||
import { logger } from './logger';
|
||||
import { LRUCache as LRU } from 'lru-cache';
|
||||
import RestQuery from './RestQuery';
|
||||
import RestWrite from './RestWrite';
|
||||
|
||||
@@ -67,6 +68,10 @@ function nobody(config) {
|
||||
return new Auth({ config, isMaster: false });
|
||||
}
|
||||
|
||||
const throttle = new LRU({
|
||||
max: 10000,
|
||||
ttl: 500,
|
||||
});
|
||||
/**
|
||||
* Checks whether session should be updated based on last update time & session length.
|
||||
*/
|
||||
@@ -78,44 +83,45 @@ function shouldUpdateSessionExpiry(config, session) {
|
||||
return lastUpdated <= skipRange;
|
||||
}
|
||||
|
||||
const throttle = {};
|
||||
const renewSessionIfNeeded = async ({ config, session, sessionToken }) => {
|
||||
if (!config?.extendSessionOnUse) {
|
||||
return;
|
||||
}
|
||||
clearTimeout(throttle[sessionToken]);
|
||||
throttle[sessionToken] = setTimeout(async () => {
|
||||
try {
|
||||
if (!session) {
|
||||
const query = await RestQuery({
|
||||
method: RestQuery.Method.get,
|
||||
config,
|
||||
auth: master(config),
|
||||
runBeforeFind: false,
|
||||
className: '_Session',
|
||||
restWhere: { sessionToken },
|
||||
restOptions: { limit: 1 },
|
||||
});
|
||||
const { results } = await query.execute();
|
||||
session = results[0];
|
||||
}
|
||||
if (!shouldUpdateSessionExpiry(config, session) || !session) {
|
||||
return;
|
||||
}
|
||||
const expiresAt = config.generateSessionExpiresAt();
|
||||
await new RestWrite(
|
||||
if (throttle.get(sessionToken)) {
|
||||
return;
|
||||
}
|
||||
throttle.set(sessionToken, true);
|
||||
try {
|
||||
if (!session) {
|
||||
const query = await RestQuery({
|
||||
method: RestQuery.Method.get,
|
||||
config,
|
||||
master(config),
|
||||
'_Session',
|
||||
{ objectId: session.objectId },
|
||||
{ expiresAt: Parse._encode(expiresAt) }
|
||||
).execute();
|
||||
} catch (e) {
|
||||
if (e?.code !== Parse.Error.OBJECT_NOT_FOUND) {
|
||||
logger.error('Could not update session expiry: ', e);
|
||||
}
|
||||
auth: master(config),
|
||||
runBeforeFind: false,
|
||||
className: '_Session',
|
||||
restWhere: { sessionToken },
|
||||
restOptions: { limit: 1 },
|
||||
});
|
||||
const { results } = await query.execute();
|
||||
session = results[0];
|
||||
}
|
||||
}, 500);
|
||||
|
||||
if (!shouldUpdateSessionExpiry(config, session) || !session) {
|
||||
return;
|
||||
}
|
||||
const expiresAt = config.generateSessionExpiresAt();
|
||||
await new RestWrite(
|
||||
config,
|
||||
master(config),
|
||||
'_Session',
|
||||
{ objectId: session.objectId },
|
||||
{ expiresAt: Parse._encode(expiresAt) }
|
||||
).execute();
|
||||
} catch (e) {
|
||||
if (e?.code !== Parse.Error.OBJECT_NOT_FOUND) {
|
||||
logger.error('Could not update session expiry: ', e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Returns a promise that resolves to an Auth object
|
||||
|
||||
Reference in New Issue
Block a user