diff --git a/src/routes/api/sender.js b/src/routes/api/sender.js index 4d26407ae..404eb4a9b 100644 --- a/src/routes/api/sender.js +++ b/src/routes/api/sender.js @@ -4,6 +4,7 @@ const imageType = require('image-type'); const imageService = require('../../services/image'); const dateNoteService = require('../../services/date_notes'); const noteService = require('../../services/notes'); +const attributeService = require('../../services/attributes'); function uploadImage(req) { const file = req.file; @@ -37,7 +38,7 @@ function saveNote(req) { if (req.body.labels) { for (const {name, value} of req.body.labels) { - note.setLabel(name, value); + note.setLabel(attributeService.sanitizeAttributeName(name), value); } } diff --git a/src/services/attributes.js b/src/services/attributes.js index d3e583fe2..d0383cbaa 100644 --- a/src/services/attributes.js +++ b/src/services/attributes.js @@ -2,7 +2,6 @@ const repository = require('./repository'); const sql = require('./sql'); -const utils = require('./utils'); const Attribute = require('../entities/attribute'); const ATTRIBUTE_TYPES = [ 'label', 'relation' ]; @@ -146,6 +145,20 @@ function getBuiltinAttributeNames() { ]); } +function sanitizeAttributeName(origName) { + let fixedName; + + if (origName === '') { + fixedName = "unnamed"; + } + else { + // any not allowed character should be replaced with underscore + fixedName = origName.replace(/[^\p{L}\p{N}_:]/ug, "_"); + } + + return fixedName; +} + module.exports = { getNotesWithLabel, getNotesWithLabels, @@ -156,5 +169,6 @@ module.exports = { getAttributeNames, isAttributeType, isAttributeDangerous, - getBuiltinAttributeNames + getBuiltinAttributeNames, + sanitizeAttributeName }; diff --git a/src/services/consistency_checks.js b/src/services/consistency_checks.js index c36a02591..07c6d9679 100644 --- a/src/services/consistency_checks.js +++ b/src/services/consistency_checks.js @@ -11,6 +11,7 @@ const entityChangesService = require('./entity_changes.js'); const optionsService = require('./options'); const Branch = require('../entities/branch'); const dateUtils = require('./date_utils'); +const attributeService = require('./attributes'); class ConsistencyChecks { constructor(autoFix) { @@ -607,20 +608,10 @@ class ConsistencyChecks { findWronglyNamedAttributes() { const attrNames = sql.getColumn(`SELECT DISTINCT name FROM attributes`); - const attrNameMatcher = new RegExp("^[\\p{L}\\p{N}_:]+$", "u"); - for (const origName of attrNames) { - if (!attrNameMatcher.test(origName)) { - let fixedName; - - if (origName === '') { - fixedName = "unnamed"; - } - else { - // any not allowed character should be replaced with underscore - fixedName = origName.replace(/[^\p{L}\p{N}_:]/ug, "_"); - } + const fixedName = attributeService.sanitizeAttributeName(origName); + if (fixedName !== origName) { if (this.autoFix) { // there isn't a good way to update this: // - just SQL query will fix it in DB but not notify frontend (or other caches) that it has been fixed diff --git a/src/services/image.js b/src/services/image.js index 9420245e3..1fe432f5b 100644 --- a/src/services/image.js +++ b/src/services/image.js @@ -37,7 +37,7 @@ function getImageType(buffer) { } } else { - return imageType(buffer); + return imageType(buffer) || "jpg"; // optimistic JPG default } } diff --git a/src/services/import/enex.js b/src/services/import/enex.js index e80224af0..25171978d 100644 --- a/src/services/import/enex.js +++ b/src/services/import/enex.js @@ -7,6 +7,7 @@ const noteService = require("../notes"); const imageService = require("../image"); const protectedSessionService = require('../protected_session'); const htmlSanitizer = require("../html_sanitizer"); +const attributeService = require("../attributes"); // date format is e.g. 20181121T193703Z function parseDate(text) { @@ -105,9 +106,17 @@ function importEnex(taskContext, file, parentNote) { const previousTag = getPreviousTag(); if (previousTag === 'note-attributes') { + let labelName = currentTag; + + if (labelName === 'source-url') { + labelName = 'sourceUrl'; + } + + labelName = attributeService.sanitizeAttributeName(labelName); + note.attributes.push({ type: 'label', - name: currentTag, + name: labelName, value: text }); } @@ -149,7 +158,7 @@ function importEnex(taskContext, file, parentNote) { } else if (currentTag === 'tag') { note.attributes.push({ type: 'label', - name: text, + name: attributeService.sanitizeAttributeName(text), value: '' }) } @@ -227,6 +236,10 @@ function importEnex(taskContext, file, parentNote) { taskContext.increaseProgressCount(); for (const resource of resources) { + if (!resource.content) { + continue; + } + const hash = utils.md5(resource.content); const mediaRegex = new RegExp(`]*>`, 'g');