forked from retoor/devplacepy
fix: correct audit event names, attachment deletion, redirect safety, and add account deactivation check
- Fix audit event names in CLI prune/clear commands from `cli.seo.*` to `cli.seo_meta.*`
- Refactor `_delete_attachment_file` to accept full attachment dict instead of storage_path string, using directory and stored_name fields with ATTACHMENTS_DIR
- Add `safe_next` validation for referer header in validation error redirect and media redirect
- Add `is_active` check in login router to reject deactivated accounts with "Account is deactivated" error
- Replace raw `request.headers.get("Referer")` with `redirect_back()` utility in bookmarks, polls, reactions, and votes routers
- Move `mark_conversation_read` call from `get_conversation_messages` to `messages_page` to avoid side effects during message retrieval
- Fix poll audit link to use `option.get("label")` instead of `option.get("text")`
- Add `VOTABLE` set validation in votes router to reject invalid target types with 400 response
- Strip control characters (0x00-0x20) from URLs in `_safe_url` instead of simple strip
- Add `__getattr__` fallback in services `__init__.py` for dynamic attribute access
This commit is contained in:
@@ -13,7 +13,13 @@ export class ContainerManager {
|
||||
}
|
||||
|
||||
init() {
|
||||
const data = JSON.parse(this.root.querySelector("#cm-data").textContent || "{}");
|
||||
const dataNode = this.root.querySelector("#cm-data");
|
||||
let data = {};
|
||||
try {
|
||||
data = JSON.parse((dataNode && dataNode.textContent) || "{}");
|
||||
} catch (error) {
|
||||
data = {};
|
||||
}
|
||||
this.instances = data.instances || [];
|
||||
this.bind();
|
||||
this.renderInstances();
|
||||
@@ -61,7 +67,12 @@ export class ContainerManager {
|
||||
const link = document.createElement("a");
|
||||
link.className = "cm-item-link";
|
||||
link.href = `/admin/containers/${inst.uid}`;
|
||||
link.innerHTML = `<span>${inst.name}</span> <span class="cm-badge cm-${inst.status}">${inst.status}</span>`;
|
||||
const nameEl = document.createElement("span");
|
||||
nameEl.textContent = inst.name;
|
||||
const badge = document.createElement("span");
|
||||
badge.className = `cm-badge cm-${String(inst.status || "").replace(/[^a-z0-9_-]/gi, "")}`;
|
||||
badge.textContent = inst.status;
|
||||
link.append(nameEl, document.createTextNode(" "), badge);
|
||||
li.appendChild(link);
|
||||
list.appendChild(li);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ export class Poller {
|
||||
this._interval = intervalMs;
|
||||
this._pauseHidden = !!options.pauseHidden;
|
||||
this._timer = null;
|
||||
this._busy = false;
|
||||
if (options.immediate !== false) this.tick();
|
||||
this.start();
|
||||
}
|
||||
@@ -24,10 +25,14 @@ export class Poller {
|
||||
|
||||
async tick() {
|
||||
if (this._pauseHidden && document.hidden) return;
|
||||
if (this._busy) return;
|
||||
this._busy = true;
|
||||
try {
|
||||
await this._fn();
|
||||
} catch (error) {
|
||||
return;
|
||||
} finally {
|
||||
this._busy = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user