diff --git a/src/middleware/auth.ts b/src/middleware/auth.ts index a72cb1c..81c5af9 100644 --- a/src/middleware/auth.ts +++ b/src/middleware/auth.ts @@ -33,7 +33,7 @@ export function issueSessionCookie( export function makeRequireAuth(config: Config) { return async function requireAuth(request: FastifyRequest, reply: FastifyReply): Promise { try { - const payload = await request.jwtVerify(); + const payload = await request.jwtVerify(); slideSessionIfNeeded(request, reply, payload, request.server, config.cookieSecure); } catch { const isApi = request.url.startsWith('/api/'); diff --git a/src/middleware/session-renewal.ts b/src/middleware/session-renewal.ts index b6878b9..f3ebd4b 100644 --- a/src/middleware/session-renewal.ts +++ b/src/middleware/session-renewal.ts @@ -7,7 +7,7 @@ import { issueSessionCookie } from './auth.ts'; export function slideSessionIfNeeded( request: FastifyRequest, reply: FastifyReply, - payload: JwtPayload & { iat?: number }, + payload: JwtPayload, server: FastifyInstance, cookieSecure: boolean, ): void { diff --git a/tests/unit/session-renewal.test.ts b/tests/unit/session-renewal.test.ts index abd789a..ad88141 100644 --- a/tests/unit/session-renewal.test.ts +++ b/tests/unit/session-renewal.test.ts @@ -3,18 +3,13 @@ import Fastify, { type FastifyInstance } from 'fastify'; import fastifyCookie from '@fastify/cookie'; import fastifyJwt from '@fastify/jwt'; import { slideSessionIfNeeded } from '../../src/middleware/session-renewal.ts'; +import type { JwtPayload } from '../../src/types.ts'; import { SESSION_COOKIE_NAME, SESSION_RENEW_THRESHOLD_SECONDS, SESSION_TTL_SECONDS, } from '../../src/constants.ts'; -interface TestPayload { - sub: number; - username: string; - iat?: number; -} - async function buildTestServer(): Promise { const app = Fastify(); await app.register(fastifyCookie); @@ -60,7 +55,7 @@ describe('slideSessionIfNeeded', () => { it('re-issues cookie when now - iat >= SESSION_RENEW_THRESHOLD_SECONDS', () => { const reply = fakeReply(); - const payload: TestPayload = { + const payload: JwtPayload = { sub: 1, username: 'alice', iat: NOW_SEC - SESSION_RENEW_THRESHOLD_SECONDS, @@ -73,7 +68,7 @@ describe('slideSessionIfNeeded', () => { it('skips re-issue when now - iat < SESSION_RENEW_THRESHOLD_SECONDS', () => { const reply = fakeReply(); - const payload: TestPayload = { + const payload: JwtPayload = { sub: 1, username: 'alice', iat: NOW_SEC - (SESSION_RENEW_THRESHOLD_SECONDS - 1), @@ -84,35 +79,35 @@ describe('slideSessionIfNeeded', () => { it('skips re-issue on /logout path', () => { const reply = fakeReply(); - const payload: TestPayload = { sub: 1, username: 'alice', iat: 0 }; // ancient + const payload: JwtPayload = { sub: 1, username: 'alice', iat: 0 }; // ancient slideSessionIfNeeded(fakeRequest('/logout') as never, reply as never, payload, app, false); expect(reply.setCookieCalls.length).toBe(0); }); it('skips re-issue on /api/v1/auth/logout path', () => { const reply = fakeReply(); - const payload: TestPayload = { sub: 1, username: 'alice', iat: 0 }; + const payload: JwtPayload = { sub: 1, username: 'alice', iat: 0 }; slideSessionIfNeeded(fakeRequest('/api/v1/auth/logout') as never, reply as never, payload, app, false); expect(reply.setCookieCalls.length).toBe(0); }); it('skips re-issue when /logout has a query string', () => { const reply = fakeReply(); - const payload: TestPayload = { sub: 1, username: 'alice', iat: 0 }; + const payload: JwtPayload = { sub: 1, username: 'alice', iat: 0 }; slideSessionIfNeeded(fakeRequest('/logout?redirect=foo') as never, reply as never, payload, app, false); expect(reply.setCookieCalls.length).toBe(0); }); it('treats missing iat as 0 (forces refresh)', () => { const reply = fakeReply(); - const payload: TestPayload = { sub: 1, username: 'alice' }; + const payload: JwtPayload = { sub: 1, username: 'alice' }; slideSessionIfNeeded(fakeRequest('/upload') as never, reply as never, payload, app, false); expect(reply.setCookieCalls.length).toBe(1); }); it('produces a cookie carrying Max-Age=SESSION_TTL_SECONDS', () => { const reply = fakeReply(); - const payload: TestPayload = { sub: 1, username: 'alice', iat: 0 }; + const payload: JwtPayload = { sub: 1, username: 'alice', iat: 0 }; slideSessionIfNeeded(fakeRequest('/upload') as never, reply as never, payload, app, true); expect(reply.setCookieCalls[0].opts.maxAge).toBe(SESSION_TTL_SECONDS); expect(reply.setCookieCalls[0].opts.secure).toBe(true);