diff --git a/src/routes/api/image.js b/src/routes/api/image.js index 83f8d41f9..ed2d0ea43 100644 --- a/src/routes/api/image.js +++ b/src/routes/api/image.js @@ -18,7 +18,7 @@ async function returnImage(req, res) { res.set('Content-Type', 'image/png'); return res.send(fs.readFileSync(RESOURCE_DIR + '/db/image-deleted.png')); } - image.mime = image.mime.replace("image/svg", "image/svg+xml"); + res.set('Content-Type', image.mime); res.send(await image.getContent()); diff --git a/src/services/image.js b/src/services/image.js index 1693a04cb..bee9f69c2 100644 --- a/src/services/image.js +++ b/src/services/image.js @@ -44,6 +44,12 @@ function getImageType(buffer) { } } +function getImageMimeFromExtension(ext) { + ext = ext.toLowerCase(); + + return 'image/' + (ext === 'svg' ? 'svg+xml' : ext); +} + async function updateImage(noteId, uploadBuffer, originalName) { const {buffer, imageFormat} = await processImage(uploadBuffer, originalName, true); @@ -51,7 +57,7 @@ async function updateImage(noteId, uploadBuffer, originalName) { await noteRevisionService.createNoteRevision(note); - note.mime = 'image/' + imageFormat.ext.toLowerCase(); + note.mime = getImageMimeFromExtension(imageFormat.ext); await note.setContent(buffer); @@ -72,7 +78,7 @@ async function saveImage(parentNoteId, uploadBuffer, originalName, shrinkImageSw title: fileName, content: buffer, type: 'image', - mime: 'image/' + imageFormat.ext.toLowerCase(), + mime: getImageMimeFromExtension(imageFormat.ext), isProtected: parentNote.isProtected && protectedSessionService.isProtectedSessionAvailable() }); diff --git a/src/services/notes.js b/src/services/notes.js index cb95b7641..95081eea7 100644 --- a/src/services/notes.js +++ b/src/services/notes.js @@ -280,11 +280,13 @@ async function downloadImage(noteId, imageUrl) { const downloadImagePromises = {}; function replaceUrl(content, url, imageNote) { - return content.replace(new RegExp(url, "g"), `api/images/${imageNote.noteId}/${imageNote.title}`); + const quoted = url.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); + + return content.replace(new RegExp(quoted, "g"), `api/images/${imageNote.noteId}/${imageNote.title}`); } async function downloadImages(noteId, content) { - const re = /]+)['"]/ig; + const re = /]+)['"]/ig; let match; while (match = re.exec(content)) { @@ -323,7 +325,7 @@ async function downloadImages(noteId, content) { } } - await Promise.all(Object.values(downloadImagePromises)).then(() => { + Promise.all(Object.values(downloadImagePromises)).then(() => { setTimeout(async () => { const imageNotes = await repository.getNotes(Object.values(imageUrlToNoteIdMapping)); @@ -344,6 +346,8 @@ async function downloadImages(noteId, content) { } }, 5000); }); + + return content; } async function saveLinks(note, content) { @@ -363,7 +367,7 @@ async function saveLinks(note, content) { content = findExternalLinks(content, foundLinks); content = findIncludeNoteLinks(content, foundLinks); - downloadImages(note.noteId, content); + content = await downloadImages(note.noteId, content); } else if (note.type === 'relation-map') { findRelationMapLinks(content, foundLinks); diff --git a/src/services/utils.js b/src/services/utils.js index e8be08396..4a7a5bd32 100644 --- a/src/services/utils.js +++ b/src/services/utils.js @@ -158,7 +158,7 @@ function getContentDisposition(filename) { return `file; filename="${sanitizedFilename}"; filename*=UTF-8''${sanitizedFilename}`; } -const STRING_MIME_TYPES = ["application/x-javascript", "image/svg"]; +const STRING_MIME_TYPES = ["application/x-javascript", "image/svg+xml"]; function isStringNote(type, mime) { return ["text", "code", "relation-map", "search"].includes(type)