#!/usr/bin/env python3 """ Precise Cache-Busting Patch for server.py Applies all modifications correctly """ import re def apply_patch(): server_file = "/home/uroma/obsidian-web-interface/server.js" with open(server_file, 'r') as f: content = f.read() # 1. Add cache-busting configuration after SESSION_SECRET content = re.sub( r"(const SESSION_SECRET = 'obsidian-web-secret-' \+ Math\.random\(\)\.toString\(36\)\.substring\(2\);)", r"""\1 // ============================================================ // CACHE-BUSTING CONFIGURATION // ============================================================ // Build timestamp forces browser to reload all assets on server restart const BUILD_TIMESTAMP = Date.now(); const ASSET_VERSION = `v=${BUILD_TIMESTAMP}`; console.log(`[CACHE-BUSTING] Build timestamp initialized: ${BUILD_TIMESTAMP}`); console.log(`[CACHE-BUSTING] All JavaScript files will be served with ?${ASSET_VERSION}`);""", content ) # 2. Add middleware import after database import content = re.sub( r"(const \{ db \} = require\('\./services/database'\);)", r"""\1 // Cache-busting middleware const { createCacheBustingMiddleware } = require('./cache-bust-middleware');""", content ) # 3. Apply middleware after session configuration content = re.sub( r"( name: 'connect\.sid'\n)\})(\);)", r"""\1 })); // Apply cache-busting middleware to HTML responses app.use(createCacheBustingMiddleware(ASSET_VERSION));\2""", content ) # 4. Enhance static file configuration content = re.sub( r"(// Serve static files \(must come after specific routes\)\n)(// Disable caching for JS files to prevent browser from serving stale code\n)(app\.use\('/claude', express\.static\(path\.join\(__dirname, 'public'\), \{\n etag: false,\n lastModified: false,\n setHeaders: \(res, filePath\) => \{\n if \(filePath\.endsWith\('\.js'\)\) \{\n res\.setHeader\('Cache-Control', 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0'\);\n res\.setHeader\('Pragma', 'no-cache'\);\n res\.setHeader\('Expires', '0'\);\n \}\n \}\n)\}\);)", r"""\1\2// CRITICAL: Cache-busting via query parameters (ASSET_VERSION) ensures fresh content \3 setHeaders: (res, filePath) => { // Disable caching for all JavaScript and CSS files if (filePath.endsWith('.js') || filePath.endsWith('.css')) { res.setHeader('Cache-Control', 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0'); res.setHeader('Pragma', 'no-cache'); res.setHeader('Expires', '0'); res.removeHeader('ETag'); } } });""", content ) with open(server_file, 'w') as f: f.write(content) return True if __name__ == "__main__": print("[CACHE-BUSTING] Applying patch...") try: if apply_patch(): print("[CACHE-BUSTING] ✓ Patch applied successfully") except Exception as e: print(f"[CACHE-BUSTING] ✗ Error: {e}") import traceback traceback.print_exc()