feat(editor): harden photo editor security and interactions

This commit is contained in:
Alexandre Teixeira
2026-10-28 17:37:10 +00:00
parent 0b8176b11e
commit c237a1cb9c
68 changed files with 3630 additions and 426 deletions
+23 -1
View File
@@ -1,4 +1,5 @@
import json
import os
from pathlib import Path
import subprocess
@@ -27,10 +28,22 @@ def test_action_names_and_unknown_steps_are_literal_text():
const panel = createActionsPanel();
document.body.append(panel.element);
panel.setSteps([attack]);
const input = panel.element.querySelector('.ge-actions-name');
input.value = attack + '<svg onload="window.__actionsXss=true">';
input.parentElement.querySelector('button').click();
const savedName = input.value;
const savedButton = Array.from(panel.element.querySelectorAll('.ge-actions-saved-row button'))
.find(button => button.textContent === savedName);
savedButton.click();
return {
images: panel.element.querySelectorAll('img').length,
svgs: panel.element.querySelectorAll('svg').length,
saved: panel.element.querySelector('.ge-actions-saved-row button').textContent,
step: panel.element.querySelector('.ge-actions-step-label').textContent,
option: Array.from(panel.element.querySelector('.ge-actions-batch-select').options)
.find(option => option.value === savedName)?.textContent,
persisted: JSON.parse(localStorage.getItem('ge-actions'))[savedName],
savedName,
executed: Boolean(window.__actionsXss),
attack,
};
@@ -39,12 +52,21 @@ def test_action_names_and_unknown_steps_are_literal_text():
} finally { await browser.close(); }
})().catch(error => { console.error(error); process.exit(1); });
'''
env = os.environ.copy()
if 'PLAYWRIGHT_BROWSERS_PATH' not in env:
for candidate in [Path.home() / '.cache/ms-playwright', Path('/home/alteixeira20/.cache/ms-playwright')]:
if candidate.exists():
env['PLAYWRIGHT_BROWSERS_PATH'] = str(candidate)
break
result = subprocess.run(
['node', '-e', script, str(ROOT / 'static/js/editor/actions-panel.js')],
cwd=ROOT, capture_output=True, text=True, timeout=30,
cwd=ROOT, capture_output=True, text=True, timeout=30, env=env,
)
assert result.returncode == 0, result.stderr
observed = json.loads(result.stdout)
assert observed['images'] == 0
assert observed['svgs'] == 0
assert observed['saved'] == observed['step'] == observed['attack']
assert observed['option'] == observed['savedName']
assert observed['persisted'] == [observed['attack']]
assert not observed['executed']