diff --git a/.claude/session-state.json b/.claude/session-state.json index 9aa992c2..b94acaa2 100644 --- a/.claude/session-state.json +++ b/.claude/session-state.json @@ -43,8 +43,8 @@ "last_deliberation": null }, "FileEditHook": { - "timestamp": "2025-10-24T03:32:50.799Z", - "file": "/home/theflow/projects/tractatus/public/js/admin/submission-modal-enhanced.js", + "timestamp": "2025-10-24T03:42:14.478Z", + "file": "/home/theflow/projects/tractatus/src/middleware/csrf-protection.middleware.js", "result": "passed" }, "FileWriteHook": { @@ -58,25 +58,25 @@ "tokens": 30000 }, "alerts": [], - "last_updated": "2025-10-24T03:32:50.799Z", + "last_updated": "2025-10-24T03:42:14.478Z", "initialized": true, "framework_components": { "CrossReferenceValidator": { "message": 0, "tokens": 0, - "timestamp": "2025-10-24T03:35:34.228Z", - "last_validation": "2025-10-24T03:35:34.228Z", - "validations_performed": 951 + "timestamp": "2025-10-24T03:42:14.476Z", + "last_validation": "2025-10-24T03:42:14.476Z", + "validations_performed": 957 }, "BashCommandValidator": { "message": 0, "tokens": 0, "timestamp": null, - "last_validation": "2025-10-24T03:35:34.229Z", - "validations_performed": 584, - "blocks_issued": 62 + "last_validation": "2025-10-24T03:42:26.291Z", + "validations_performed": 589, + "blocks_issued": 66 } }, - "action_count": 584, + "action_count": 589, "auto_compact_events": [] } \ No newline at end of file diff --git a/public/js/blog.js b/public/js/blog.js index ca82d788..ad3e830c 100644 --- a/public/js/blog.js +++ b/public/js/blog.js @@ -571,10 +571,17 @@ function setupNewsletterModal() { submitBtn.textContent = 'Subscribing...'; try { + // Get CSRF token from cookie + const csrfToken = document.cookie + .split('; ') + .find(row => row.startsWith('csrf-token=')) + ?.split('=')[1]; + const response = await fetch('/api/newsletter/subscribe', { method: 'POST', headers: { - 'Content-Type': 'application/json' + 'Content-Type': 'application/json', + 'X-CSRF-Token': csrfToken || '' }, body: JSON.stringify({ email, diff --git a/src/middleware/csrf-protection.middleware.js b/src/middleware/csrf-protection.middleware.js index 4da885a1..2a9a9e12 100644 --- a/src/middleware/csrf-protection.middleware.js +++ b/src/middleware/csrf-protection.middleware.js @@ -79,7 +79,7 @@ function setCsrfToken(req, res, next) { const isSecure = req.secure || req.headers['x-forwarded-proto'] === 'https'; res.cookie('csrf-token', token, { - httpOnly: true, + httpOnly: false, // Must be false for double-submit pattern (client needs to read it) secure: isSecure && process.env.NODE_ENV === 'production', sameSite: 'strict', maxAge: 24 * 60 * 60 * 1000 // 24 hours