diff --git a/lib/models/note.js b/lib/models/note.js index 7f19f751..70ee6c52 100644 --- a/lib/models/note.js +++ b/lib/models/note.js @@ -13,7 +13,8 @@ var async = require('async') var moment = require('moment') var DiffMatchPatch = require('@hackmd/diff-match-patch') var dmp = new DiffMatchPatch() -var S = require('string') + +const {stripTags} = require('../../utils/string') // core var config = require('../config') @@ -338,7 +339,7 @@ module.exports = function (sequelize, DataTypes) { title = meta.title } else { var h1s = $('h1') - if (h1s.length > 0 && h1s.first().text().split('\n').length === 1) { title = S(h1s.first().text()).stripTags().s } + if (h1s.length > 0 && h1s.first().text().split('\n').length === 1) { title = stripTags(h1s.first().text()) } } if (!title) title = 'Untitled' return title @@ -368,7 +369,7 @@ module.exports = function (sequelize, DataTypes) { if (/^tags/gmi.test($(value).text())) { var codes = $(value).find('code') for (let i = 0; i < codes.length; i++) { - var text = S($(codes[i]).text().trim()).stripTags().s + var text = stripTags($(codes[i]).text().trim()) if (text) rawtags.push(text) } } diff --git a/package.json b/package.json index f92fede3..7d36f60d 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "CodiMD", + "name": "codimd", "version": "1.3.1", "description": "Realtime collaborative markdown notes on all platforms.", "main": "app.js", @@ -19,7 +19,7 @@ "@hackmd/codemirror": "^5.41.2", "@hackmd/diff-match-patch": "^1.1.1", "@hackmd/idle-js": "^1.0.1", - "@hackmd/imgur": "^0.4.0", + "@hackmd/imgur": "^0.4.1", "@hackmd/js-sequence-diagrams": "^0.0.1-alpha.2", "@passport-next/passport-openid": "^1.0.0", "archiver": "^2.1.1", @@ -117,7 +117,6 @@ "spin.js": "^2.3.2", "sqlite3": "^4.0.1", "store": "^2.0.12", - "string": "^3.3.3", "tedious": "^1.14.0", "toobusy-js": "^0.5.1", "turndown": "^5.0.1", @@ -184,7 +183,7 @@ "html-webpack-plugin": "4.0.0-beta.2", "imports-loader": "^0.8.0", "jsonlint": "^1.6.2", - "less": "^2.7.1", + "less": "^3.9.0", "less-loader": "^4.1.0", "mini-css-extract-plugin": "^0.4.1", "mocha": "^5.2.0", diff --git a/public/js/cover.js b/public/js/cover.js index 79fb3a2a..3324e556 100644 --- a/public/js/cover.js +++ b/public/js/cover.js @@ -30,7 +30,7 @@ import { import { saveAs } from 'file-saver' import List from 'list.js' -import S from 'string' +import unescapeHTML from 'lodash/unescape' const options = { valueNames: ['id', 'text', 'timestamp', 'fromNow', 'time', 'tags', 'pinned'], @@ -397,7 +397,7 @@ function buildTagsFilter (tags) { for (let i = 0; i < tags.length; i++) { tags[i] = { id: i, - text: S(tags[i]).unescapeHTML().s + text: unescapeHTML(tags[i]) } } filtertags = tags diff --git a/public/js/extra.js b/public/js/extra.js index b80290d1..a8430c68 100644 --- a/public/js/extra.js +++ b/public/js/extra.js @@ -13,9 +13,13 @@ require('prismjs/components/prism-gherkin') import Prism from 'prismjs' import hljs from 'highlight.js' import PDFObject from 'pdfobject' -import S from 'string' import { saveAs } from 'file-saver' +import escapeHTML from 'lodash/escape' +import unescapeHTML from 'lodash/unescape' + +import {stripTags} from '../../utils/string' + require('./lib/common/login') require('../vendor/md-toc') var Viz = require('viz.js') @@ -157,7 +161,7 @@ export function renderTags (view) { function slugifyWithUTF8 (text) { // remove html tags and trim spaces - let newText = S(text).trim().stripTags().s + let newText = stripTags(text.toString().trim()) // replace all spaces in between to dashes newText = newText.replace(/\s+/g, '-') // slugify string to make it valid for attribute @@ -492,22 +496,22 @@ export function finishView (view) { value: code } } else if (reallang === 'haskell' || reallang === 'go' || reallang === 'typescript' || reallang === 'jsx' || reallang === 'gherkin') { - code = S(code).unescapeHTML().s + code = unescapeHTML(code) result = { value: Prism.highlight(code, Prism.languages[reallang]) } } else if (reallang === 'tiddlywiki' || reallang === 'mediawiki') { - code = S(code).unescapeHTML().s + code = unescapeHTML(code) result = { value: Prism.highlight(code, Prism.languages.wiki) } } else if (reallang === 'cmake') { - code = S(code).unescapeHTML().s + code = unescapeHTML(code) result = { value: Prism.highlight(code, Prism.languages.makefile) } } else { - code = S(code).unescapeHTML().s + code = unescapeHTML(code) const languages = hljs.listLanguages() if (!languages.includes(reallang)) { result = hljs.highlightAuto(code) @@ -902,7 +906,7 @@ export function scrollToHash () { function highlightRender (code, lang) { if (!lang || /no(-?)highlight|plain|text/.test(lang)) { return } - code = S(code).escapeHTML().s + code = escapeHTML(code) if (lang === 'sequence') { return `
${code}
` } else if (lang === 'flow') { diff --git a/public/js/history.js b/public/js/history.js index d9beedf4..b085a19a 100644 --- a/public/js/history.js +++ b/public/js/history.js @@ -2,9 +2,10 @@ /* global serverurl, moment */ import store from 'store' -import S from 'string' import LZString from 'lz-string' +import escapeHTML from 'lodash/escape' + import wurl from 'wurl' import { @@ -276,8 +277,8 @@ function parseToHistory (list, notehistory, callback) { notehistory[i].fromNow = timestamp.fromNow() notehistory[i].time = timestamp.format('llll') // prevent XSS - notehistory[i].text = S(notehistory[i].text).escapeHTML().s - notehistory[i].tags = (notehistory[i].tags && notehistory[i].tags.length > 0) ? S(notehistory[i].tags).escapeHTML().s.split(',') : [] + notehistory[i].text = escapeHTML(notehistory[i].text) + notehistory[i].tags = (notehistory[i].tags && notehistory[i].tags.length > 0) ? escapeHTML(notehistory[i].tags).split(',') : [] // add to list if (notehistory[i].id && list.get('id', notehistory[i].id).length === 0) { list.add(notehistory[i]) } } diff --git a/utils/string.js b/utils/string.js new file mode 100644 index 00000000..53894d04 --- /dev/null +++ b/utils/string.js @@ -0,0 +1,7 @@ +'use strict' + +function stripTags(s) { + return s.replace(RegExp(`]*>`, 'gi'), '') +} + +exports.stripTags = stripTags diff --git a/yarn.lock b/yarn.lock index 92f46ded..94955170 100644 --- a/yarn.lock +++ b/yarn.lock @@ -33,10 +33,10 @@ resolved "https://registry.yarnpkg.com/@hackmd/idle-js/-/idle-js-1.0.1.tgz#89079a76d9c7bda87029660a708e72fbb2be3605" integrity sha512-yuv9BBdA5rk4TpmSrsdNgkLIyRt73hWyBEs7PhWhIozFcNv66JfUzXqA0eT3ToXX0163aVnbpHeJZRvcYy5Seg== -"@hackmd/imgur@^0.4.0": - version "0.4.0" - resolved "https://registry.yarnpkg.com/@hackmd/imgur/-/imgur-0.4.0.tgz#e5716f6a7a12e8011ceb57f46369fcc958623e19" - integrity sha512-519G+fXIDu1LUwPU32nerot4wuP2pSDEBysOj9nX6IYL5qom/lo6vmp3bp0bg7SbtHWvmjZEDOermCrlqR18xw== +"@hackmd/imgur@^0.4.1": + version "0.4.1" + resolved "https://registry.yarnpkg.com/@hackmd/imgur/-/imgur-0.4.1.tgz#9d51dafc4fd0baf36a8fb7a8a5c23f2f660d3ad2" + integrity sha512-zvAt/4drM+nZG/yM12hJ7/DtkPffw/fzvr8oDp6twg5a04/HBoGha28vYrZP4fV/a5ZAAnRzxRRbeADxRfsGfA== dependencies: glob "^7.1.3" request "^2.88.0" @@ -1976,7 +1976,7 @@ cliui@^4.0.0: strip-ansi "^4.0.0" wrap-ansi "^2.0.0" -clone@^2.1.1: +clone@^2.1.1, clone@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" integrity sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18= @@ -5414,19 +5414,21 @@ less-loader@^4.1.0: loader-utils "^1.1.0" pify "^3.0.0" -less@^2.7.1: - version "2.7.3" - resolved "https://registry.yarnpkg.com/less/-/less-2.7.3.tgz#cc1260f51c900a9ec0d91fb6998139e02507b63b" - integrity sha512-KPdIJKWcEAb02TuJtaLrhue0krtRLoRoo7x6BNJIBelO00t/CCdJQUnHW5V34OnHMWzIktSalJxRO+FvytQlCQ== +less@^3.9.0: + version "3.9.0" + resolved "https://registry.yarnpkg.com/less/-/less-3.9.0.tgz#b7511c43f37cf57dc87dffd9883ec121289b1474" + integrity sha512-31CmtPEZraNUtuUREYjSqRkeETFdyEHSEPAGq4erDlUXtda7pzNmctdljdIagSb589d/qXGWiiP31R5JVf+v0w== + dependencies: + clone "^2.1.2" optionalDependencies: errno "^0.1.1" graceful-fs "^4.1.2" image-size "~0.5.0" - mime "^1.2.11" + mime "^1.4.1" mkdirp "^0.5.0" promise "^7.1.1" - request "2.81.0" - source-map "^0.5.3" + request "^2.83.0" + source-map "~0.6.0" levn@^0.3.0, levn@~0.3.0: version "0.3.0" @@ -5982,7 +5984,7 @@ mime@1.4.1: resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" integrity sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ== -mime@^1.2.11: +mime@^1.4.1: version "1.6.0" resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== @@ -8046,7 +8048,7 @@ request-promise-native@^1.0.5: stealthy-require "^1.1.1" tough-cookie "^2.3.3" -request@2.81.0, request@2.x, request@^2.61.0, request@^2.81.0, request@^2.86.0, request@^2.87.0, request@^2.88.0: +request@2.x, request@^2.61.0, request@^2.81.0, request@^2.83.0, request@^2.86.0, request@^2.87.0, request@^2.88.0: version "2.88.0" resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef" integrity sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg== @@ -8829,11 +8831,6 @@ string-width@^3.0.0: is-fullwidth-code-point "^2.0.0" strip-ansi "^5.1.0" -string@^3.3.3: - version "3.3.3" - resolved "https://registry.yarnpkg.com/string/-/string-3.3.3.tgz#5ea211cd92d228e184294990a6cc97b366a77cb0" - integrity sha1-XqIRzZLSKOGEKUmQpsyXs2anfLA= - string_decoder@^1.0.0, string_decoder@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.2.0.tgz#fe86e738b19544afe70469243b2a1ee9240eae8d"