feat: add wildcard token support for allowed extensions and access token CLI commands

Introduce WILDCARD_TOKENS set in attachments.py to treat "*", ".*", "*.*" as wildcards that fall back to ALLOWED_UPLOAD_TYPES. Add cmd_token_issue and cmd_token_list CLI commands for issuing and listing DevPlace access tokens. Register access_tokens table in SOFT_DELETE_TABLES and initialize its columns and indexes in init_db. Replace Form() with Depends(json_or_form(...)) in admin backup, container, notification, settings, and user routers to support both JSON and form data.
This commit is contained in:
2026-06-17 17:10:52 +00:00
parent 217210e02f
commit 9598a1b867
45 changed files with 436 additions and 284 deletions
+28 -2
View File
@@ -14,9 +14,11 @@ export class AppUpload extends Component {
this.uidsName = this.attr("name", "attachment_uids");
this.maxBytes = this.intAttr("max-size", 10) * 1024 * 1024;
this.maxFiles = this.intAttr("max-files", 10);
this.allowedTypes = this.attr("allowed-types", "")
const declaredTypes = this.attr("allowed-types", "")
.split(",").map((t) => t.trim().toLowerCase()).filter(Boolean);
this.showChips = !this.boolAttr("hide-chips");
const wildcard = declaredTypes.some((t) => t === "*" || t === ".*" || t === "*.*");
this.allowedTypes = wildcard ? [] : declaredTypes;
this.showChips = this.boolAttr("show-chips");
this.extraFields = {};
this.items = [];
this.busyCount = 0;
@@ -84,6 +86,21 @@ export class AppUpload extends Component {
this.uidsInput.name = this.uidsName;
this.append(this.uidsInput);
}
this.pendingSubmitForm = null;
const form = this.closest("form");
if (form) {
form.addEventListener("submit", (event) => {
if (this.busyCount > 0) {
event.preventDefault();
event.stopImmediatePropagation();
this.pendingSubmitForm = form;
if (window.app && window.app.toast) {
window.app.toast.show("Waiting for upload to finish...", { type: "info" });
}
}
}, true);
}
}
open() {
@@ -188,6 +205,15 @@ export class AppUpload extends Component {
}
this._lastBusy = active;
this.emit("busy", { busy: active });
if (!active && this.pendingSubmitForm) {
const form = this.pendingSubmitForm;
this.pendingSubmitForm = null;
if (form.requestSubmit) {
form.requestSubmit();
} else {
form.submit();
}
}
}
setFieldFiles(files) {