#!/usr/bin/env python3 """ Cache-Busting Patch for server.js This script adds dynamic asset versioning to force browser cache invalidation """ import re import sys def patch_server_js(): server_file = "/home/uroma/obsidian-web-interface/server.js" with open(server_file, 'r') as f: lines = f.readlines() modified_lines = [] modifications = [] # Track if we've added cache-busting config cache_busting_added = False middleware_imported = False middleware_applied = False static_config_updated = False i = 0 while i < len(lines): line = lines[i] # 1. Add cache-busting configuration after SESSION_SECRET if not cache_busting_added and "const SESSION_SECRET = 'obsidian-web-secret-'" in line: modified_lines.append(line) # Add cache-busting configuration cache_busting_config = """ // ============================================================ // 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}`); """ modified_lines.append(cache_busting_config) modifications.append("✓ Added cache-busting configuration") cache_busting_added = True i += 1 continue # 2. Add cache-busting middleware import if not middleware_imported and "const { db } = require('./services/database');" in line: modified_lines.append(line) # Check if next line is "const app = express();" if i + 1 < len(lines) and "const app = express();" in lines[i + 1]: modified_lines.append("// Cache-busting middleware\n") modified_lines.append("const { createCacheBustingMiddleware } = require('./cache-bust-middleware');\n") modifications.append("✓ Added cache-busting middleware import") middleware_imported = True i += 1 continue # 3. Apply cache-busting middleware after session middleware if not middleware_applied and "name: 'connect.sid'" in line: modified_lines.append(line) # Skip closing brace and add middleware i += 1 if i < len(lines) and "});" in lines[i]: modified_lines.append(lines[i]) # Add the }); modified_lines.append("\n") modified_lines.append("// Apply cache-busting middleware to HTML responses\n") modified_lines.append(f"app.use(createCacheBustingMiddleware(ASSET_VERSION));\n") modifications.append("✓ Applied cache-busting middleware") middleware_applied = True i += 1 continue i += 1 continue # 4. Update static file configuration if not static_config_updated and "// Serve static files (must come after specific routes)" in line: # Skip the old configuration lines until we reach the closing }); modified_lines.append(line) i += 1 # Add new enhanced configuration static_config = """// Disable caching for JS files to prevent browser from serving stale code // CRITICAL: Cache-busting via query parameters (ASSET_VERSION) ensures fresh content app.use('/claude', express.static(path.join(__dirname, 'public'), { etag: false, lastModified: false, 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'); } } })); """ modified_lines.append(static_config) # Skip old static config lines until we find the end while i < len(lines) and "});" not in lines[i]: i += 1 i += 1 # Skip the }); modifications.append("✓ Enhanced static file cache headers") static_config_updated = True continue modified_lines.append(line) i += 1 # Write the modified content with open(server_file, 'w') as f: f.writelines(modified_lines) return modifications if __name__ == "__main__": print("[CACHE-BUSTING] Patching server.js...") try: modifications = patch_server_js() print("[CACHE-BUSTING] Successfully applied the following modifications:") for mod in modifications: print(f" {mod}") print("[CACHE-BUSTING] Patch complete!") except Exception as e: print(f"[CACHE-BUSTING] ERROR: {e}", file=sys.stderr) sys.exit(1)