Harden auth/vault path sanitization and clean WeKnora docs

This commit is contained in:
Agent Board
2026-07-28 17:04:27 +08:00
parent 2deaf59f7b
commit 26ff1a9c9a
190 changed files with 13454 additions and 4987 deletions
@@ -148,10 +148,10 @@ export const createSidebarFileTreeCommandRuntime = (dependencies = {}) => {
}).then(function(){
if (!localFolderSource && documentId) updateTitleEverywhere(documentId, commandTitle);
});
void work.then(close).catch(function(error) {
void work.then(close).catch(async function(error) {
committing = false;
input.disabled = false;
window.alert(error && error.message ? error.message : '重命名失败');
await window.mnote.alert(error && error.message ? error.message : '重命名失败');
});
};
input.addEventListener('click', function(event) { event.stopPropagation(); });
@@ -298,7 +298,7 @@ export const createSidebarFileTreeCommandRuntime = (dependencies = {}) => {
return url.toString();
}
function convertToPreviousSiblingChild(trigger, detail) {
async function convertToPreviousSiblingChild(trigger, detail) {
var documentId = detail.documentId || '';
var row = document.querySelector('#sidebar-tree-root .tree-row[data-node-id="' + cssEscape(documentId) + '"]');
if (!(row instanceof HTMLElement)) return;
@@ -308,7 +308,7 @@ export const createSidebarFileTreeCommandRuntime = (dependencies = {}) => {
});
var index = siblings.indexOf(row);
if (index <= 0) {
window.alert('当前页面前面没有同级页面。');
await window.mnote.alert('当前页面前面没有同级页面。');
return;
}
var previous = siblings[index - 1];
@@ -369,9 +369,21 @@ export const createSidebarFileTreeCommandRuntime = (dependencies = {}) => {
function joinLocalAbsolutePath(rootUri, relativePath) {
var rootPath = localRootPathFromRootUri(rootUri);
var normalized = decodeLocalEncodedPath(relativePath).replace(/^\/+/, '');
var normalized = decodeLocalEncodedPath(relativePath).replace(/^\/+/, '').replace(/\\/g, '/');
if (!rootPath || !normalized) return rootPath || normalized;
return rootPath.replace(/\/+$/g, '') + '/' + normalized;
// Collapse . / empty and resolve .. without climbing above workspace root.
var parts = [];
normalized.split('/').forEach(function (seg) {
if (!seg || seg === '.') return;
if (seg === '..') {
if (parts.length) parts.pop();
return;
}
parts.push(seg);
});
var safeRel = parts.join('/');
if (!safeRel) return rootPath.replace(/\/+$/g, '');
return rootPath.replace(/\/+$/g, '') + '/' + safeRel;
}
function fileTreeCopyLocalAbsolutePath(detail, trigger) {
@@ -488,7 +500,7 @@ export const createSidebarFileTreeCommandRuntime = (dependencies = {}) => {
return payload;
}
function handleTreeContextMenuAction(action, detail, trigger) {
async function handleTreeContextMenuAction(action, detail, trigger) {
closeTreeContextMenu();
detail = detail || {};
if (action === 'knowledge-rag-index') {
@@ -499,13 +511,13 @@ export const createSidebarFileTreeCommandRuntime = (dependencies = {}) => {
if (window.mnote && window.mnote.toast) {
window.mnote.toast('已加入知识库', { kind: 'success' });
}
}).catch(function(error) {
}).catch(async function(error) {
var msg = error && error.message ? error.message : '知识库索引失败';
recordFileTreeActionStatus('failed', Object.assign({}, detail, { fallback: 'alert' }));
if (window.mnote && window.mnote.toast) {
window.mnote.toast(msg, { kind: 'error' });
} else {
window.alert(msg);
await window.mnote.alert(msg);
}
});
return;
@@ -584,7 +596,7 @@ export const createSidebarFileTreeCommandRuntime = (dependencies = {}) => {
return;
}
if (isAsset && action === 'open-edit-mode') {
withOfficeEditModeGuard(function() {
withOfficeEditModeGuard(async function() {
recordFileTreeAction('open-edit-mode', detail);
void openConvexAssetFromFileTree({ ...detail, openTarget: 'edit-mode' });
});
@@ -635,15 +647,15 @@ export const createSidebarFileTreeCommandRuntime = (dependencies = {}) => {
}
}
if (action === 'delete-trash' && isAsset) {
if (!window.confirm('确定要将“' + title + '”删除到垃圾桶吗?')) return;
if (!(await window.mnote.confirm('确定要将“' + title + '”删除到垃圾桶吗?'))) return;
recordFileTreeAction('delete-trash', detail);
recordFileTreeActionStatus('pending', detail);
void deleteSingleFileTreeAsset(detail, trigger).then(function() {
recordFileTreeActionStatus('archived', Object.assign({}, detail, { undo: 'trash-modal' }));
if (currentSourceKind() === 'local_folder') void refreshLocalFolderSidebarSnapshot();
}).catch(function(error) {
}).catch(async function(error) {
recordFileTreeActionStatus('failed', Object.assign({}, detail, { fallback: 'alert' }));
window.alert(error && error.message ? error.message : '资源删除失败');
await window.mnote.alert(error && error.message ? error.message : '资源删除失败');
});
return;
}
@@ -655,9 +667,9 @@ export const createSidebarFileTreeCommandRuntime = (dependencies = {}) => {
recordFileTreeAction('new-folder', detail);
void createFileTreeFolder(trigger || document.body, fileTreeMenuTargetParentId(detail, trigger) || null).then(function(ok) {
recordFileTreeActionStatus(ok ? 'created' : 'skipped', detail);
}).catch(function(error) {
}).catch(async function(error) {
recordFileTreeActionStatus('failed', Object.assign({}, detail, { fallback: 'alert' }));
window.alert(error && error.message ? error.message : '新建文件夹失败');
await window.mnote.alert(error && error.message ? error.message : '新建文件夹失败');
});
return;
}
@@ -690,9 +702,9 @@ export const createSidebarFileTreeCommandRuntime = (dependencies = {}) => {
recordFileTreeAction('paste-into', detail);
void pasteSidebarFileTreeClipboard(pasteRow).then(function(ok) {
recordFileTreeActionStatus(ok ? 'applied' : 'skipped', detail);
}).catch(function(error) {
}).catch(async function(error) {
recordFileTreeActionStatus('failed', Object.assign({}, detail, { fallback: 'alert' }));
window.alert(error && error.message ? error.message : '粘贴失败');
await window.mnote.alert(error && error.message ? error.message : '粘贴失败');
});
return;
}
@@ -738,7 +750,7 @@ export const createSidebarFileTreeCommandRuntime = (dependencies = {}) => {
workspaceId: workspaceId,
documentId: documentId,
title: nextTitle.trim()
}).then(function(){ updateTitleEverywhere(documentId, nextTitle.trim()); });
}).then(async function(){ updateTitleEverywhere(documentId, nextTitle.trim()); });
}
return;
}
@@ -747,12 +759,12 @@ export const createSidebarFileTreeCommandRuntime = (dependencies = {}) => {
return;
}
if (action === 'convert-child') {
convertToPreviousSiblingChild(trigger, detail);
void convertToPreviousSiblingChild(trigger, detail);
return;
}
var deleteTargetId = documentId || String(detail.rowId || '').trim();
if (action === 'delete-trash' && deleteTargetId) {
if (!window.confirm('确定要将“' + title + '”删除到垃圾桶吗?')) return;
if (!(await window.mnote.confirm('确定要将“' + title + '”删除到垃圾桶吗?'))) return;
recordFileTreeAction('delete-trash', detail);
recordFileTreeActionStatus('pending', detail);
void dispatchTreeCommand(trigger || document.body, {
@@ -762,9 +774,9 @@ export const createSidebarFileTreeCommandRuntime = (dependencies = {}) => {
}).then(function() {
recordFileTreeActionStatus('archived', Object.assign({}, detail, { undo: 'trash-modal' }));
if (currentSourceKind() === 'local_folder') void refreshLocalFolderSidebarSnapshot();
}).catch(function(error) {
}).catch(async function(error) {
recordFileTreeActionStatus('failed', Object.assign({}, detail, { fallback: 'alert' }));
window.alert(error && error.message ? error.message : '删除失败');
await window.mnote.alert(error && error.message ? error.message : '删除失败');
});
}
}
@@ -967,7 +979,7 @@ export const createSidebarFileTreeCommandRuntime = (dependencies = {}) => {
document.head.appendChild(style);
}
// ── 知识库列表获取:只读 MNote 后端 registry/status避免前端直连 WeKnora service key。 ──
// ── 知识库列表获取:只读 MNote 后端 registry/status不直连外部知识库 service key。 ──
function fetchKnowledgeBaseList(detail) {
var rootUri = knowledgeRagRootUri(detail, null);
if (!rootUri) return Promise.resolve([]);
@@ -2125,7 +2137,7 @@ export const createSidebarFileTreeCommandRuntime = (dependencies = {}) => {
window.dispatchEvent(new CustomEvent('tree:local-command-batch-complete', { detail: { batchId: batchId, action: 'move', failed: failures.length, count: movableRows.length } }));
if (failures.length > 0) {
recordFileTreeActionStatus('failed', { documentId: targetParentId, fallback: 'alert', batchId: batchId });
window.alert('部分对象移动失败:' + failures.join(''));
await window.mnote.alert('部分对象移动失败:' + failures.join(''));
return false;
}
recordFileTreeActionStatus('applied', { documentId: targetParentId, batchId: batchId });
@@ -2159,7 +2171,7 @@ export const createSidebarFileTreeCommandRuntime = (dependencies = {}) => {
var plan = buildSidebarFileTreeDeletePlan(rows);
var total = plan.docRows.length + plan.folderRows.length + plan.fileAssetRows.length + plan.mindmapRows.length + plan.tableRows.length;
if (total === 0) return false;
if (!window.confirm(sidebarFileTreeDeleteConfirmText(plan))) return false;
if (!(await window.mnote.confirm(sidebarFileTreeDeleteConfirmText(plan)))) return false;
var batchId = nextFileTreeOperationBatchId('bulk-delete');
document.documentElement.setAttribute('data-mnote-filetree-bulk-delete-batch-id', batchId);
recordFileTreeAction('bulk-delete', { rowId: trigger instanceof HTMLElement ? trigger.getAttribute('data-row-id') || '' : '', count: total, batchId: batchId });
@@ -2264,7 +2276,7 @@ export const createSidebarFileTreeCommandRuntime = (dependencies = {}) => {
if (failures.length > 0) {
window.dispatchEvent(new CustomEvent('tree:local-command-batch-complete', { detail: { batchId: batchId, action: 'bulk-delete', failed: failures.length, count: total } }));
recordFileTreeActionStatus('failed', { count: total, failures: failures.slice(0, 20), fallback: 'alert', batchId: batchId });
window.alert('部分对象删除失败:' + failures.slice(0, 5).join(', ') + (failures.length > 5 ? '…' : ''));
await window.mnote.alert('部分对象删除失败:' + failures.slice(0, 5).join(', ') + (failures.length > 5 ? '…' : ''));
return false;
}
document.documentElement.setAttribute('data-mnote-filetree-bulk-delete-applied', 'true');