feat(cms): optimistic locking against stale-tab overwrites
CI Pipeline with Test Management / 🧪 Run Tests & Generate Reports (push) Waiting to run
CI Pipeline with Test Management / 🐳 Docker Integration Tests (push) Blocked by required conditions
CI Pipeline with Test Management / 🏗️ Build Docker Image (push) Blocked by required conditions
CI Pipeline with Test Management / 📊 Generate Test Summary (push) Blocked by required conditions
Test Reporting & Gherkin Analysis / 🧪 Run Tests & Generate Reports (push) Waiting to run
Test Reporting & Gherkin Analysis / 📊 Analyze Test Coverage (push) Blocked by required conditions
Test Reporting & Gherkin Analysis / 🔄 Sync with Linear (push) Blocked by required conditions
Test Reporting & Gherkin Analysis / ⚡ Performance Monitoring (push) Blocked by required conditions
CI Pipeline with Test Management / 🧪 Run Tests & Generate Reports (push) Waiting to run
CI Pipeline with Test Management / 🐳 Docker Integration Tests (push) Blocked by required conditions
CI Pipeline with Test Management / 🏗️ Build Docker Image (push) Blocked by required conditions
CI Pipeline with Test Management / 📊 Generate Test Summary (push) Blocked by required conditions
Test Reporting & Gherkin Analysis / 🧪 Run Tests & Generate Reports (push) Waiting to run
Test Reporting & Gherkin Analysis / 📊 Analyze Test Coverage (push) Blocked by required conditions
Test Reporting & Gherkin Analysis / 🔄 Sync with Linear (push) Blocked by required conditions
Test Reporting & Gherkin Analysis / ⚡ Performance Monitoring (push) Blocked by required conditions
A Content Editor tab left open across a deploy (or a save from another tab) held the pre-deploy content; one Save would silently overwrite the newer file. The editor page now embeds a SHA-256 fingerprint of the file content at load time, /save requires it back in X-Content-Hash and compares against the current file: mismatch (or a missing header) answers 409 with an explanatory message and writes nothing. The client offers a reload on 409. Integration test covers: matching hash saves, stale hash rejected with the file untouched, missing hash rejected, retry with the fresh hash succeeds. Closes MITHOME-61
This commit is contained in:
@@ -233,10 +233,16 @@ async function save() {
|
||||
const data = collect();
|
||||
const res = await fetch('/save?file=' + FILE, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': CSRF_TOKEN },
|
||||
headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': CSRF_TOKEN, 'X-Content-Hash': CONTENT_HASH },
|
||||
body: JSON.stringify(data, null, 2)
|
||||
});
|
||||
if (res.status === 401) { location.href = '/login'; return; }
|
||||
if (res.status === 409) {
|
||||
if (confirm('A tartalom megváltozott, mióta ez a lap megnyílt (pl. deploy vagy másik fül mentett).\n\nOK = lap frissítése az új tartalommal (a szerkesztésed elvész)\nMégse = maradsz ezen a lapon, a mentés nem történt meg.')) {
|
||||
location.reload();
|
||||
}
|
||||
return;
|
||||
}
|
||||
const json = await res.json();
|
||||
const status = document.getElementById('saveStatus');
|
||||
if (json.ok) {
|
||||
|
||||
Reference in New Issue
Block a user