Merge pull request #3481 from SillyTavern/cache-buster Add cache buster middleware to clear browser cache on server restart
Signed| @@ -60,6 +60,7 @@ import basicAuthMiddleware from './src/middleware/basicAuth.js'; | |||
| 60 | import whitelistMiddleware from './src/middleware/whitelist.js'; | 60 | import whitelistMiddleware from './src/middleware/whitelist.js'; |
| 61 | import multerMonkeyPatch from './src/middleware/multerMonkeyPatch.js'; | 61 | import multerMonkeyPatch from './src/middleware/multerMonkeyPatch.js'; |
| 62 | import initRequestProxy from './src/request-proxy.js'; | 62 | import initRequestProxy from './src/request-proxy.js'; |
| 63 | import getCacheBusterMiddleware from './src/middleware/cacheBuster.js'; | ||
| 63 | import { | 64 | import { |
| 64 | getVersion, | 65 | getVersion, |
| 65 | getConfigValue, | 66 | getConfigValue, |
| @@ -515,7 +516,7 @@ if (!disableCsrf) { | |||
| 515 | 516 | ||
| 516 | // Static files | 517 | // Static files |
| 517 | // Host index page | 518 | // Host index page |
| 518 | app.get('/', (request, response) => { | 519 | app.get('/', getCacheBusterMiddleware(), (request, response) => { |
| 519 | if (shouldRedirectToLogin(request)) { | 520 | if (shouldRedirectToLogin(request)) { |
| 520 | const query = request.url.split('?')[1]; | 521 | const query = request.url.split('?')[1]; |
| 521 | const redirectUrl = query ? `/login?${query}` : '/login'; | 522 | const redirectUrl = query ? `/login?${query}` : '/login'; |
| @@ -0,0 +1,28 @@ | |||
| 1 | import crypto from 'node:crypto'; | ||
| 2 | import { DEFAULT_USER } from '../constants.js'; | ||
| 3 | |||
| 4 | /** | ||
| 5 | * Middleware to bust the browser cache for the current user. | ||
| 6 | * @returns {import('express').RequestHandler} | ||
| 7 | */ | ||
| 8 | export default function getCacheBusterMiddleware() { | ||
| 9 | /** | ||
| 10 | * @type {Set<string>} Handles/User-Agents that have already been busted. | ||
| 11 | */ | ||
| 12 | const keys = new Set(); | ||
| 13 | |||
| 14 | return (request, response, next) => { | ||
| 15 | const handle = request.user?.profile?.handle || DEFAULT_USER.handle; | ||
| 16 | const userAgent = request.headers['user-agent'] || ''; | ||
| 17 | const hash = crypto.createHash('sha256').update(userAgent).digest('hex'); | ||
| 18 | const key = `${handle}-${hash}`; | ||
| 19 | |||
| 20 | if (keys.has(key)) { | ||
| 21 | return next(); | ||
| 22 | } | ||
| 23 | |||
| 24 | keys.add(key); | ||
| 25 | response.setHeader('Clear-Site-Data', '"cache"'); | ||
| 26 | next(); | ||
| 27 | }; | ||
| 28 | } | ||