fix: code review — security fixes, dedup, cleanup

- setup: validate roles against users.VALID_ROLES (Supervisor was missing)
- files: fix path traversal prefix-match edge case (is_relative_to),
  dedupe path validation into resolve_upload_path(), use logging not print
- measurements: extract shared _build_measurement_filters() helper
- client app: prevent open redirect via Referer on /set-language
- maker: guard resp.json() in parse-technical-sheet proxy
- measure/maker: extract shared file proxy into services/file_proxy.py
- measure: localize supervisor validation error messages
- annotation-editor: remove global keydown listener in destroy()

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Adriano Dal Pastro
2026-06-11 12:16:29 +00:00
parent 25a788f430
commit fd571c479e
8 changed files with 141 additions and 134 deletions
@@ -956,7 +956,7 @@ function annotationEditor() {
setupKeyboard() {
var self = this;
document.addEventListener('keydown', function (e) {
this._onKeyDown = function (e) {
// Skip when typing in form fields
var tag = e.target.tagName;
if (tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT') return;
@@ -970,7 +970,8 @@ function annotationEditor() {
self.canvas.discardActiveObject();
self.canvas.renderAll();
}
});
};
document.addEventListener('keydown', this._onKeyDown);
},
// ----------------------------------------------------------------
@@ -1289,6 +1290,9 @@ function annotationEditor() {
if (this._onImageLoaded) {
window.removeEventListener('image-loaded', this._onImageLoaded);
}
if (this._onKeyDown) {
document.removeEventListener('keydown', this._onKeyDown);
}
if (this.canvas) {
this.canvas.dispose();
this.canvas = null;