Harden auth/vault path sanitization and clean WeKnora docs
This commit is contained in:
@@ -209,13 +209,39 @@ export const createSidebarFileTreeOpenRuntime = (dependencies = {}) => {
|
||||
|| (/^思维导图/i.test(fileName) && /\.json$/i.test(fileName));
|
||||
}
|
||||
|
||||
function sanitizeWorkspaceRelativePath(rel) {
|
||||
var value = String(rel || '').trim().replace(/\\/g, '/');
|
||||
try {
|
||||
value = decodeURIComponent(value);
|
||||
} catch (_) {
|
||||
// keep raw
|
||||
}
|
||||
value = value.replace(/\\/g, '/').replace(/^\/+/, '');
|
||||
if (!value || value.indexOf('\0') >= 0) return '';
|
||||
var parts = [];
|
||||
value.split('/').forEach(function (seg) {
|
||||
if (!seg || seg === '.') return;
|
||||
if (seg === '..') {
|
||||
if (parts.length) parts.pop();
|
||||
return;
|
||||
}
|
||||
parts.push(seg);
|
||||
});
|
||||
return parts.join('/');
|
||||
}
|
||||
|
||||
function localFilePathFromAssetId(assetId) {
|
||||
var _rto_ = window.__mnoteResourceOpenRuntime;
|
||||
if (_rto_ && typeof _rto_.localFilePathFromAssetId === 'function') {
|
||||
return _rto_.localFilePathFromAssetId(assetId);
|
||||
return sanitizeWorkspaceRelativePath(_rto_.localFilePathFromAssetId(assetId));
|
||||
}
|
||||
var value = String(assetId || '').trim();
|
||||
return value.indexOf('local-file:') === 0 ? value.slice('local-file:'.length) : value.indexOf('local:asset:') === 0 ? value.slice('local:asset:'.length) : '';
|
||||
var raw = value.indexOf('local-file:') === 0
|
||||
? value.slice('local-file:'.length)
|
||||
: value.indexOf('local:asset:') === 0
|
||||
? value.slice('local:asset:'.length)
|
||||
: '';
|
||||
return sanitizeWorkspaceRelativePath(raw);
|
||||
}
|
||||
|
||||
function workspacePathFromDetail(detail) {
|
||||
@@ -249,15 +275,16 @@ export const createSidebarFileTreeOpenRuntime = (dependencies = {}) => {
|
||||
}
|
||||
|
||||
function buildLocalFileOpenUrl(relativePath, download) {
|
||||
var safePath = sanitizeWorkspaceRelativePath(relativePath);
|
||||
var _rto_ = window.__mnoteResourceOpenRuntime;
|
||||
if (_rto_ && typeof _rto_.buildLocalFileOpenUrl === 'function') {
|
||||
return _rto_.buildLocalFileOpenUrl(relativePath, download);
|
||||
return safePath ? _rto_.buildLocalFileOpenUrl(safePath, download) : '';
|
||||
}
|
||||
var rootUri = currentRootUri();
|
||||
if (!rootUri || !relativePath) return '';
|
||||
if (!rootUri || !safePath) return '';
|
||||
var url = new URL('/api/local-folder/files/open', window.location.origin);
|
||||
url.searchParams.set('rootUri', rootUri);
|
||||
url.searchParams.set('path', relativePath);
|
||||
url.searchParams.set('path', safePath);
|
||||
if (download) url.searchParams.set('download', 'true');
|
||||
return url.toString();
|
||||
}
|
||||
@@ -466,7 +493,7 @@ export const createSidebarFileTreeOpenRuntime = (dependencies = {}) => {
|
||||
}
|
||||
var documentId = String(detail && detail.documentId || '').trim();
|
||||
if (isMindmapAssetDetail(detail) && documentId) {
|
||||
if (typeof window.__mnoteDocumentPaneRuntime?.openResourceInActiveTab === 'function') {
|
||||
if (typeof window.__mnoteDocumentPaneRuntime?.openResourceInActiveTab === 'async function') {
|
||||
document.documentElement.setAttribute('data-mnote-last-mindmap-asset-open-mode', 'mindmap-resource-tab');
|
||||
document.documentElement.setAttribute('data-mnote-last-mindmap-asset-id', assetId);
|
||||
void window.__mnoteDocumentPaneRuntime.openResourceInActiveTab({
|
||||
@@ -493,7 +520,7 @@ export const createSidebarFileTreeOpenRuntime = (dependencies = {}) => {
|
||||
return;
|
||||
}
|
||||
document.documentElement.setAttribute('data-mnote-media-sign-retired', 'true');
|
||||
window.alert('旧 Convex Files 附件签名链已退役;local-first 附件请通过本地文件夹资源打开。');
|
||||
await window.mnote.alert('旧 Convex Files 附件签名链已退役;local-first 附件请通过本地文件夹资源打开。');
|
||||
}
|
||||
|
||||
window.addEventListener('tree.asset.open', function(event) {
|
||||
|
||||
Reference in New Issue
Block a user