mirror of
https://github.com/zadam/trilium.git
synced 2026-03-13 03:43:43 +01:00
refactor: avoid xss attack
This commit is contained in:
parent
df60e34072
commit
d504946de0
@ -180,7 +180,7 @@
|
||||
|
||||
---
|
||||
|
||||
### Step 6: 迁移"关闭弹窗"逻辑 + `attribute_detail.ts` 引用
|
||||
### Step 6: 迁移"关闭弹窗"逻辑 + `attribute_detail.ts` 引用 ✅ 完成
|
||||
**文件变更:**
|
||||
- `apps/client/src/services/dialog.ts` — 替换 `$(".aa-input").autocomplete("close")`
|
||||
- `apps/client/src/components/entrypoints.ts` — 替换 `$(".aa-input").autocomplete("close")`
|
||||
@ -188,12 +188,12 @@
|
||||
- `apps/client/src/widgets/attribute_widgets/attribute_detail.ts` — 更新 `.algolia-autocomplete` 选择器
|
||||
|
||||
**说明:**
|
||||
需要一个全局的"关闭所有 autocomplete"机制。方案:维护一个全局 `Set<AutocompleteApi>`,在各处调用时遍历关闭。可以放在 `note_autocomplete.ts` 中导出。
|
||||
引入了全局的 "关闭所有 headless autocomplete" 机制(通过 `closeAllHeadlessAutocompletes` 方法)。
|
||||
|
||||
**验证方式:**
|
||||
- autocomplete 弹窗打开时切换标签页 → 弹窗自动关闭
|
||||
- autocomplete 弹窗打开时打开对话框 → 弹窗自动关闭
|
||||
- 点击 autocomplete 下拉菜单时属性面板不应关闭
|
||||
- ✅ autocomplete 弹窗打开时切换标签页 → 弹窗自动关闭
|
||||
- ✅ autocomplete 弹窗打开时打开对话框 → 弹窗自动关闭
|
||||
- ✅ 点击 autocomplete 下拉菜单时属性面板不应关闭
|
||||
|
||||
---
|
||||
|
||||
|
||||
@ -82,14 +82,33 @@ function escapeHtml(text: string): string {
|
||||
}
|
||||
|
||||
function sanitizeHighlightedHtml(text: string, { allowBreaks = false }: { allowBreaks?: boolean } = {}): string {
|
||||
const sanitizedBreaks = allowBreaks
|
||||
? text.replace(/<br\b[^>]*\/?>/gi, "<br>")
|
||||
: text.replace(/<br\b[^>]*\/?>/gi, "");
|
||||
const parser = new DOMParser();
|
||||
const doc = parser.parseFromString(text, "text/html");
|
||||
const safeOutput = document.createDocumentFragment();
|
||||
|
||||
return sanitizedBreaks
|
||||
.replace(/<b\b[^>]*>/gi, "<b>")
|
||||
.replace(/<\/b\s*>/gi, "</b>")
|
||||
.replace(/<\/?[^>]+>/g, "");
|
||||
const processNode = (node: Node) => {
|
||||
if (node.nodeType === Node.TEXT_NODE) {
|
||||
safeOutput.appendChild(document.createTextNode(node.textContent || ""));
|
||||
} else if (node.nodeType === Node.ELEMENT_NODE) {
|
||||
const el = node as Element;
|
||||
if (el.tagName === "B") {
|
||||
const b = document.createElement("b");
|
||||
b.textContent = el.textContent; // Only extract text, stripping nested potential danger
|
||||
safeOutput.appendChild(b);
|
||||
} else if (el.tagName === "BR" && allowBreaks) {
|
||||
safeOutput.appendChild(document.createElement("br"));
|
||||
} else {
|
||||
// If the tag is not allowed, just extract its text content securely
|
||||
safeOutput.appendChild(document.createTextNode(el.textContent || ""));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
doc.body.childNodes.forEach(processNode);
|
||||
|
||||
const tmpDiv = document.createElement("div");
|
||||
tmpDiv.appendChild(safeOutput);
|
||||
return tmpDiv.innerHTML;
|
||||
}
|
||||
|
||||
function normalizeAttributeSnippet(snippet: string): string {
|
||||
@ -302,7 +321,7 @@ async function fetchResolvedSuggestions(term: string, options: Options = {}): Pr
|
||||
return commandSuggestions;
|
||||
}
|
||||
|
||||
const fastSearch = options.fastSearch === false ? false : true;
|
||||
const fastSearch = options.fastSearch !== false;
|
||||
if (fastSearch === false) {
|
||||
if (term.trim().length === 0) {
|
||||
return [];
|
||||
@ -804,9 +823,9 @@ function init() {
|
||||
$.fn.getSelectedNotePath = function () {
|
||||
if (!String($(this).val())?.trim()) {
|
||||
return "";
|
||||
} else {
|
||||
return $(this).attr(SELECTED_NOTE_PATH_KEY);
|
||||
}
|
||||
return $(this).attr(SELECTED_NOTE_PATH_KEY);
|
||||
|
||||
};
|
||||
|
||||
$.fn.getSelectedNoteId = function () {
|
||||
@ -830,9 +849,9 @@ function init() {
|
||||
$.fn.getSelectedExternalLink = function () {
|
||||
if (!String($(this).val())?.trim()) {
|
||||
return "";
|
||||
} else {
|
||||
return $(this).attr(SELECTED_EXTERNAL_LINK_KEY);
|
||||
}
|
||||
return $(this).attr(SELECTED_EXTERNAL_LINK_KEY);
|
||||
|
||||
};
|
||||
|
||||
$.fn.setSelectedExternalLink = function (externalLink: string | null) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user