feat/security
All checks were successful
Build and Publish Docker Image / deploy (push) Successful in 1m44s

Reviewed-on: #2
This commit was merged in pull request #2.
This commit is contained in:
2026-05-04 00:00:36 +03:00
parent dd8dd7cdc2
commit fbeff3f6c0
43 changed files with 3268 additions and 299 deletions

View File

@@ -373,6 +373,35 @@
}
}
async function runCleanupAction() {
try {
const response = await fetch("/admin/boxes/actions", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ action: "cleanup_expired", box_ids: [] })
});
const payload = await response.json();
if (!response.ok) {
const message = payload.error || payload.message || "Cleanup failed";
showToast(message, "error", 3200);
return;
}
state.boxes = Array.isArray(payload.boxes) ? payload.boxes : state.boxes;
state.selected.clear();
if (state.activeId && !state.boxes.some((box) => box.id === state.activeId)) {
state.activeId = null;
}
renderTable();
let message = payload.message || "Expired cleanup completed";
if (Array.isArray(payload.warnings) && payload.warnings.length) {
message += ` (${payload.warnings.length} warning${payload.warnings.length === 1 ? "" : "s"})`;
}
showToast(message, Array.isArray(payload.warnings) && payload.warnings.length ? "warning" : "success", 3200);
} catch (_) {
showToast("Network error while running cleanup", "error", 3200);
}
}
function selectedIDsOrActive() {
if (state.selected.size) return Array.from(state.selected);
const active = currentActiveBox();
@@ -419,6 +448,10 @@
if (!window.confirm("Delete selected boxes? This removes stored files.")) return;
await runBulkAction("delete", selectedIDsOrActive());
return;
case "cleanup-expired":
if (!window.confirm("Run cleanup for expired boxes now?")) return;
await runCleanupAction();
return;
case "help-scope":
showToast("Ownership filter waits for account + box owner data in backend", "info", 3400);
return;