feat: extendSessionOnUse to automatically renew Parse Sessions (#8505)
This commit is contained in:
50
src/Auth.js
50
src/Auth.js
@@ -3,6 +3,8 @@ import { isDeepStrictEqual } from 'util';
|
||||
import { getRequestObject, resolveError } from './triggers';
|
||||
import Deprecator from './Deprecator/Deprecator';
|
||||
import { logger } from './logger';
|
||||
import RestQuery from './RestQuery';
|
||||
import RestWrite from './RestWrite';
|
||||
|
||||
// An Auth object tells you who is requesting something and whether
|
||||
// the master key was used.
|
||||
@@ -66,6 +68,47 @@ function nobody(config) {
|
||||
return new Auth({ config, isMaster: false });
|
||||
}
|
||||
|
||||
const throttle = {};
|
||||
const renewSessionIfNeeded = async ({ config, session, sessionToken }) => {
|
||||
if (!config?.extendSessionOnUse) {
|
||||
return;
|
||||
}
|
||||
clearTimeout(throttle[sessionToken]);
|
||||
throttle[sessionToken] = setTimeout(async () => {
|
||||
try {
|
||||
if (!session) {
|
||||
const { results } = await new RestQuery(
|
||||
config,
|
||||
master(config),
|
||||
'_Session',
|
||||
{ sessionToken },
|
||||
{ limit: 1 }
|
||||
).execute();
|
||||
console.log({ results });
|
||||
session = results[0];
|
||||
}
|
||||
const lastUpdated = new Date(session?.updatedAt);
|
||||
const yesterday = new Date();
|
||||
yesterday.setDate(yesterday.getDate() - 1);
|
||||
if (lastUpdated > yesterday || !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);
|
||||
}
|
||||
}
|
||||
}, 500);
|
||||
};
|
||||
|
||||
// Returns a promise that resolves to an Auth object
|
||||
const getAuthForSessionToken = async function ({
|
||||
config,
|
||||
@@ -78,6 +121,7 @@ const getAuthForSessionToken = async function ({
|
||||
const userJSON = await cacheController.user.get(sessionToken);
|
||||
if (userJSON) {
|
||||
const cachedUser = Parse.Object.fromJSON(userJSON);
|
||||
renewSessionIfNeeded({ config, sessionToken });
|
||||
return Promise.resolve(
|
||||
new Auth({
|
||||
config,
|
||||
@@ -112,18 +156,20 @@ const getAuthForSessionToken = async function ({
|
||||
if (results.length !== 1 || !results[0]['user']) {
|
||||
throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN, 'Invalid session token');
|
||||
}
|
||||
const session = results[0];
|
||||
const now = new Date(),
|
||||
expiresAt = results[0].expiresAt ? new Date(results[0].expiresAt.iso) : undefined;
|
||||
expiresAt = session.expiresAt ? new Date(session.expiresAt.iso) : undefined;
|
||||
if (expiresAt < now) {
|
||||
throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN, 'Session token is expired.');
|
||||
}
|
||||
const obj = results[0]['user'];
|
||||
const obj = session.user;
|
||||
delete obj.password;
|
||||
obj['className'] = '_User';
|
||||
obj['sessionToken'] = sessionToken;
|
||||
if (cacheController) {
|
||||
cacheController.user.put(sessionToken, obj);
|
||||
}
|
||||
renewSessionIfNeeded({ config, session, sessionToken });
|
||||
const userObject = Parse.Object.fromJSON(obj);
|
||||
return new Auth({
|
||||
config,
|
||||
|
||||
Reference in New Issue
Block a user