Allow html tags for survey solutions, add sanitizer
Resolves MS-500
This commit is contained in:
parent
3278774876
commit
5af06069e8
|
|
@ -25,7 +25,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {sanitize} from '@/helpers/text';
|
import {sanitizeAsHtml} from '@/helpers/text';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: ['value'],
|
props: ['value'],
|
||||||
|
|
@ -38,8 +38,8 @@
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
sanitizedText() {
|
sanitizedText() {
|
||||||
return sanitize(this.value.text);
|
return sanitizeAsHtml(this.value.text);
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
|
@ -81,6 +81,7 @@
|
||||||
|
|
||||||
/deep/ ul {
|
/deep/ ul {
|
||||||
padding-left: $medium-spacing;
|
padding-left: $medium-spacing;
|
||||||
|
|
||||||
> li {
|
> li {
|
||||||
list-style: disc outside none;
|
list-style: disc outside none;
|
||||||
color: $color-silver-dark;
|
color: $color-silver-dark;
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,52 @@
|
||||||
|
// taken from https://gomakethings.com/how-to-sanitize-html-strings-with-vanilla-js-to-reduce-your-risk-of-xss-attacks/
|
||||||
|
const getDocument = html => new DOMParser().parseFromString(html, 'text/html');
|
||||||
|
|
||||||
|
const removeScripts = html => {
|
||||||
|
let scripts = html.querySelectorAll('script');
|
||||||
|
for (let script of scripts) {
|
||||||
|
script.remove();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// explicitly whitelist
|
||||||
|
// todo: do we need more attributes whitelisted
|
||||||
|
const isSafe = attr => {
|
||||||
|
return ['class'].includes(attr.name);
|
||||||
|
};
|
||||||
|
|
||||||
|
const removeAttributes = node => {
|
||||||
|
let attributes = [...node.attributes];
|
||||||
|
console.log(attributes);
|
||||||
|
for (const attr of attributes) {
|
||||||
|
if (isSafe(attr)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
node.removeAttribute(attr.name);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const clean = node => {
|
||||||
|
let nodes = node.children;
|
||||||
|
for (let node of nodes) {
|
||||||
|
removeAttributes(node);
|
||||||
|
clean(node);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
export const sanitize = html => {
|
export const sanitize = html => {
|
||||||
let doc = new DOMParser().parseFromString(html, 'text/html');
|
let doc = getDocument(html);
|
||||||
return doc.body.textContent || '';
|
return doc.body.textContent || '';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const sanitizeAsHtml = html => {
|
||||||
|
let doc = getDocument(html);
|
||||||
|
const body = doc.body || document.createElement('body');
|
||||||
|
removeScripts(body);
|
||||||
|
clean(body);
|
||||||
|
return body.innerHTML;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
export const newLineToParagraph = (text) => {
|
export const newLineToParagraph = (text) => {
|
||||||
return text
|
return text
|
||||||
.split(/\n+/)
|
.split(/\n+/)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue