UNPKG

nowjs-core

Version:

NowCanDo Javascript Core [nowjs-core] is a library written by TypeScript code maintains under Apache 2.0 licence

126 lines (125 loc) 3.93 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const index_1 = require("../index"); const DEFAULT_ALLOWED_TAGS = [ 'h3', 'h4', 'h5', 'h6', 'blockquote', 'p', 'a', 'ul', 'ol', 'nl', 'li', 'b', 'i', 'strong', 'em', 'strike', 'code', 'hr', 'br', 'div', 'table', 'thead', 'caption', 'tbody', 'tr', 'th', 'td', 'pre', ]; const DEFAULT_ALLOWED_ATTRIBUTES = { a: ['href', 'name', 'target'], img: ['src'], }; const DEFAULT_SELFCLOSING = ['img', 'br', 'hr', 'area', 'base', 'basefont', 'input', 'link', 'meta']; const DEFAULT_ALLOWED_SCHEMAS = ['http', 'https', 'ftp', 'mailto']; const HTML_TAG_REGEX = /^\<.+\>/gim; const HTML_TAG_ATTRIBUTE_REGEX = /(([a-zA-Z0-9]+)\=\"([a-zA-Z0-9]+)\")+/gim; class HtmlSanitizer extends index_1.SanitizerBase { constructor(options) { super('HtmlSanitizer'); this.options = options; this.options = this.options || {}; this.options.AllowedAttributes = this.options.AllowedAttributes || DEFAULT_ALLOWED_ATTRIBUTES; this.options.AllowedTags = this.options.AllowedTags || DEFAULT_ALLOWED_TAGS; this.options.AllowedSchemes = this.options.AllowedSchemes || DEFAULT_ALLOWED_SCHEMAS; } sanitize(value) { if (!value) { return Promise.resolve(value); } const allowedTags = (this.options.AllowedTags || DEFAULT_ALLOWED_TAGS).join('|'); const selfcloseTags = (this.options.SelfClosingTags || DEFAULT_SELFCLOSING).join('|'); this.tagRegex = new RegExp(`^((\<(${allowedTags})\\s*([a-zA-Z0-9\"\=\\s]*\\s*)\>)(.*)\<\/(${allowedTags})\\s*\>)|(<!--[\\s\\S]*?-->)|((\<(${selfcloseTags})\\s*\/\>))$`, 'gmi'); if (this.options.AllowedAttributes) { this.tagAttrRegex = {}; } for (const item in this.options.AllowedAttributes) { const attrs = this.options.AllowedAttributes[item]; this.tagAttrRegex[item] = []; } return Promise.resolve(this.sanitizeInnerText(value, '')); } sanitizeInnerText(value, parentValue) { const results = []; const tags = this.getTagParts(value); if (!tags) { return this.hasTag(value) ? '' : value; } if (tags[3] && tags[3] === tags[6]) { let tagst = ''; if (tags[4]) { tagst = `<${tags[3]} ${this.sanitizeTagAttributes(tags[3], tags[4])} >`; } else { tagst = `<${tags[3]}>`; } const innerText = this.sanitizeInnerText(tags[5], tags[2]); const tagText = `${tagst}${innerText}</${tags[6]}>`; results.push(tagText); } return results.join(''); } hasTag(value) { return HTML_TAG_REGEX.test(value); } sanitizeTagAttributes(value, tag) { const results = []; HTML_TAG_ATTRIBUTE_REGEX.lastIndex = 0; let attrs; while ((attrs = this.getTagAttributeParts(value, tag))) { results.push(attrs[1]); } return results.join(' '); } getTagAttributeParts(tag, value) { if (this.tagAttrRegex && tag && this.tagAttrRegex[tag]) { return this.tagAttrRegex[tag].exec(value); } else if (tag && HTML_TAG_ATTRIBUTE_REGEX) { return HTML_TAG_ATTRIBUTE_REGEX.exec(value); } else { return []; } } getTagParts(value) { this.tagRegex.lastIndex = 0; return this.tagRegex.exec(value); } escapeHtml(s) { if (typeof s !== 'string') { s = s + ''; } return s .replace(/\&/g, '&amp;') .replace(/</g, '&lt;') .replace(/\>/g, '&gt;') .replace(/\"/g, '&quot;'); } } exports.HtmlSanitizer = HtmlSanitizer;