Harden auth/vault path sanitization and clean WeKnora docs
This commit is contained in:
@@ -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');
|
||||
|
||||
Reference in New Issue
Block a user