Skip to content

Commit b98ff5a

Browse files
authored
refactor: improve auth session persistence (#3790)
1 parent 36c59c5 commit b98ff5a

6 files changed

Lines changed: 49 additions & 15 deletions

File tree

.infra/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,14 +102,14 @@ const redis = new Redis(`${name}-redis`, {
102102
isAdhocEnv,
103103
name: `${name}-redis`,
104104
tier: 'BASIC',
105-
memorySizeGb: 1,
105+
memorySizeGb: 2,
106106
region: location,
107107
authEnabled: true,
108108
redisVersion: 'REDIS_7_2',
109109
labels: { app: name },
110110
redisConfigs: {
111111
'maxmemory-policy': 'volatile-ttl',
112-
'maxmemory-gb': '0.95',
112+
'maxmemory-gb': '1.9',
113113
},
114114
maintenancePolicy: {
115115
weeklyMaintenanceWindows: [

__tests__/boot.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -710,6 +710,37 @@ describe('logged in boot', () => {
710710
});
711711
});
712712

713+
it('should boot logged in user and refresh jwt when token expires within 3 minutes', async () => {
714+
const accessToken = await signJwt(
715+
{
716+
userId: '1',
717+
roles: [],
718+
},
719+
2 * 60 * 1000,
720+
);
721+
const key = app.signCookie(accessToken.token);
722+
const res = await request(app.server)
723+
.get(BASE_PATH)
724+
.set('User-Agent', TEST_UA)
725+
.set('Cookie', `${cookies.auth.key}=${key};`)
726+
.expect(200);
727+
728+
expect(res.body).toEqual({
729+
...LOGGED_IN_BODY,
730+
user: {
731+
...LOGGED_IN_BODY.user,
732+
canSubmitArticle:
733+
LOGGED_IN_BODY.user.reputation >= submitArticleThreshold,
734+
},
735+
});
736+
737+
const authCookie = setCookieParser.parse(res, { map: true })[
738+
cookies.auth.key
739+
];
740+
expect(authCookie?.value).toBeTruthy();
741+
expect(authCookie?.value).not.toEqual(key);
742+
});
743+
713744
it('should not re-issue JWT token when isPlus in payload is same as user', async () => {
714745
await saveFixtures(con, User, [
715746
{

__tests__/routes/betterAuth.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,12 @@ describe('betterAuth routes', () => {
6161
expect(options.account).toMatchObject({
6262
modelName: 'ba_account',
6363
});
64+
expect(options.session).toMatchObject({
65+
modelName: 'ba_session',
66+
storeSessionInDatabase: true,
67+
expiresIn: 30 * 24 * 60 * 60,
68+
updateAge: 24 * 60 * 60,
69+
});
6470
});
6571

6672
it('should forward native callback routes to BetterAuth handler', async () => {

src/betterAuth.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { triggerTypedEvent } from './common/typedPubsub';
1212
import { sendEmail, CioTransactionalMessageTemplateId } from './common/mailing';
1313
import { handleRegex } from './common/object';
1414
import { validateAndTransformHandle } from './common/handles';
15-
import { ONE_DAY_IN_SECONDS } from './common/constants';
15+
import { ONE_DAY_IN_SECONDS, ONE_MONTH_IN_SECONDS } from './common/constants';
1616
import { singleRedisClient } from './redis';
1717
import { User } from './entity/user/User';
1818
import { cookies, extractRootDomain } from './cookies';
@@ -398,7 +398,7 @@ export const getBetterAuthOptions = (pool: Pool): BetterAuthOptions => {
398398
session: {
399399
modelName: 'ba_session',
400400
storeSessionInDatabase: true,
401-
expiresIn: 7 * ONE_DAY_IN_SECONDS,
401+
expiresIn: ONE_MONTH_IN_SECONDS,
402402
updateAge: ONE_DAY_IN_SECONDS,
403403
},
404404
account: {

src/cookies.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { CookieSerializeOptions } from '@fastify/cookie';
22
import { FastifyReply, FastifyRequest } from 'fastify';
3+
import { ONE_MONTH_IN_SECONDS } from './common/constants';
34
import { generateTrackingId } from './ids';
45
import { setTrackingId } from './tracking';
56
import { counters } from './telemetry';
@@ -62,7 +63,7 @@ export const cookies: {
6263
authSession: {
6364
key: env === 'production' ? '__Secure-dast' : 'dast',
6465
opts: {
65-
maxAge: 60 * 60 * 24 * 7,
66+
maxAge: ONE_MONTH_IN_SECONDS,
6667
signed: false,
6768
httpOnly: true,
6869
secure: env === 'production',

src/routes/boot.ts

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -919,6 +919,9 @@ export const getBootData = async (
919919
middleware?: BootMiddleware,
920920
): Promise<AnonymousBoot | LoggedInBoot> => {
921921
const referrer = getBootReferrer(req);
922+
const shouldRefreshJwt =
923+
!req.accessToken?.expiresIn ||
924+
differenceInMinutes(req.accessToken.expiresIn, new Date()) <= 3;
922925

923926
const baSessionCookie = req.cookies[cookies.authSession.key];
924927
if (baSessionCookie) {
@@ -933,14 +936,11 @@ export const getBootData = async (
933936
req.userId = session.user.id;
934937
req.trackingId = req.userId;
935938
setTrackingId(req, res, req.trackingId);
936-
const jwtValid =
937-
req.accessToken?.expiresIn &&
938-
differenceInMinutes(req.accessToken.expiresIn, new Date()) > 3;
939939
return loggedInBoot({
940940
con,
941941
req,
942942
res,
943-
refreshToken: !jwtValid,
943+
refreshToken: shouldRefreshJwt,
944944
middleware,
945945
userId: req.userId,
946946
});
@@ -957,16 +957,12 @@ export const getBootData = async (
957957
setCookie(req, res, 'authSession', undefined);
958958
}
959959

960-
if (
961-
req.userId &&
962-
req.accessToken?.expiresIn &&
963-
differenceInMinutes(req.accessToken?.expiresIn, new Date()) > 3
964-
) {
960+
if (req.userId && req.accessToken?.expiresIn) {
965961
return loggedInBoot({
966962
con,
967963
req,
968964
res,
969-
refreshToken: false,
965+
refreshToken: shouldRefreshJwt,
970966
middleware,
971967
userId: req.userId,
972968
});

0 commit comments

Comments
 (0)