mirror of
https://github.com/docmost/docmost.git
synced 2026-05-07 06:23:06 +08:00
fix: handle malformed URLs gracefully during import/export (#1868)
* Handling malformed URLs gracefully * Allow import of invalid URLs, but adding logging. --------- Co-authored-by: gpapp <gergely.papp@itworks.hu>
This commit is contained in:
@@ -118,7 +118,14 @@ export async function exportPage(data: IExportPageParams): Promise<void> {
|
||||
.split("filename=")[1]
|
||||
.replace(/"/g, "");
|
||||
|
||||
saveAs(req.data, decodeURIComponent(fileName));
|
||||
let decodedFileName = fileName;
|
||||
try {
|
||||
decodedFileName = decodeURIComponent(fileName);
|
||||
} catch (err) {
|
||||
// fallback to raw filename
|
||||
}
|
||||
|
||||
saveAs(req.data, decodedFileName);
|
||||
}
|
||||
|
||||
export async function importPage(file: File, spaceId: string) {
|
||||
|
||||
@@ -69,5 +69,12 @@ export async function exportSpace(data: IExportSpaceParams): Promise<void> {
|
||||
.split("filename=")[1]
|
||||
.replace(/"/g, "");
|
||||
|
||||
saveAs(req.data, decodeURIComponent(fileName));
|
||||
let decodedFileName = fileName;
|
||||
try {
|
||||
decodedFileName = decodeURIComponent(fileName);
|
||||
} catch (err) {
|
||||
// fallback to raw filename
|
||||
}
|
||||
|
||||
saveAs(req.data, decodedFileName);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { jsonToNode } from 'src/collaboration/collaboration.util';
|
||||
import { Logger } from '@nestjs/common';
|
||||
import { ExportFormat } from './dto/export-dto';
|
||||
import { Node } from '@tiptap/pm/model';
|
||||
import { validate as isValidUUID } from 'uuid';
|
||||
@@ -88,7 +89,7 @@ export function replaceInternalLinks(
|
||||
// if link and text are same, use page title
|
||||
if (markLink === node.text) {
|
||||
//@ts-expect-error
|
||||
node.text = getInternalLinkPageName(relativePath);
|
||||
node.text = getInternalLinkPageName(relativePath, currentPagePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -99,11 +100,20 @@ export function replaceInternalLinks(
|
||||
return doc.toJSON();
|
||||
}
|
||||
|
||||
export function getInternalLinkPageName(path: string): string {
|
||||
return decodeURIComponent(
|
||||
path?.split('/').pop().split('.').slice(0, -1).join('.'),
|
||||
export function getInternalLinkPageName(path: string, currentFilePath?: string): string {
|
||||
const name = path?.split('/').pop().split('.').slice(0, -1).join('.');
|
||||
try {
|
||||
return decodeURIComponent(name);
|
||||
} catch (err) {
|
||||
if (currentFilePath) {
|
||||
Logger.warn(
|
||||
`URI malformed in page ${currentFilePath}: ${name}. Falling back to raw name.`,
|
||||
'ExportUtils',
|
||||
);
|
||||
}
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
export function extractPageSlugId(input: string): string {
|
||||
if (!input) {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { getEmbedUrlAndProvider } from '@docmost/editor-ext';
|
||||
import { Logger } from '@nestjs/common';
|
||||
import * as path from 'path';
|
||||
import { v7 } from 'uuid';
|
||||
import { InsertableBacklink } from '@docmost/db/types/entity.types';
|
||||
@@ -280,8 +281,18 @@ export async function rewriteInternalLinksToMentionHtml(
|
||||
const $a = $(el);
|
||||
const raw = $a.attr('href')!;
|
||||
if (raw.startsWith('http') || raw.startsWith('/api/')) return;
|
||||
let decodedRaw = raw;
|
||||
try {
|
||||
decodedRaw = decodeURIComponent(raw);
|
||||
} catch (err) {
|
||||
Logger.warn(
|
||||
`URI malformed in page ${currentFilePath}: ${raw}. Falling back to raw path.`,
|
||||
'ImportFormatter',
|
||||
);
|
||||
}
|
||||
|
||||
const resolved = normalize(
|
||||
path.join(path.dirname(currentFilePath), decodeURIComponent(raw)),
|
||||
path.join(path.dirname(currentFilePath), decodedRaw),
|
||||
);
|
||||
const meta = filePathToPageMetaMap.get(resolved);
|
||||
if (!meta) return;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { Logger } from '@nestjs/common';
|
||||
import { promises as fs } from 'fs';
|
||||
import * as path from 'path';
|
||||
|
||||
@@ -30,8 +31,13 @@ export function resolveRelativeAttachmentPath(
|
||||
pageDir: string,
|
||||
attachmentCandidates: Map<string, string>,
|
||||
): string | null {
|
||||
const mainRel = decodeURIComponent(raw.replace(/^\.?\/+/, ''));
|
||||
const fallback = path.normalize(path.join(pageDir, mainRel));
|
||||
let mainRel = raw.replace(/^\.?\/+/, '');
|
||||
try {
|
||||
mainRel = decodeURIComponent(mainRel);
|
||||
} catch (err) {
|
||||
Logger.warn(`URI malformed for attachment path: ${mainRel}. Falling back to raw path.`, 'ImportUtils');
|
||||
}
|
||||
const fallback = path.normalize(path.join(pageDir, mainRel)).split(path.sep).join('/');
|
||||
|
||||
if (attachmentCandidates.has(mainRel)) {
|
||||
return mainRel;
|
||||
|
||||
Reference in New Issue
Block a user