Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions spec/Auth.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ describe('Auth', () => {
updatedAt: updatedAt.toISOString(),
}
);
Parse.Server.cacheController.clear();
await new Promise(resolve => setTimeout(resolve, 1000));
await session.fetch();
await new Promise(resolve => setTimeout(resolve, 1000));
await session.fetch();
Expand Down
70 changes: 38 additions & 32 deletions src/Auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down Expand Up @@ -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.
*/
Expand All @@ -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];
}

if (!shouldUpdateSessionExpiry(config, session) || !session) {
return;
}
}, 500);
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
Expand Down
Loading