Commit cf8e1da2 authored by Jérome Perrin's avatar Jérome Perrin

officejs_support_request_ui: use a handlbars template for comments

This prevents html injection for Mr. <script>
parent a5fcbc4f
......@@ -10,10 +10,32 @@
<script src="renderjs.js" type="text/javascript"></script>
<!-- custom script -->
<script src="handlebars.js" type="text/javascript"></script>
<script src="gadget_erp5_global.js" type="text/javascript"></script>
<script src="gadget_erp5_pt_form_view_discussable.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="gadget_erp5_pt_form_view_discussable.css">
<!-- templates -->
<script id="template-document-list" type="text/x-handlebars-template">
{{#if comments }}
{{#each comments }}
<li>By <strong>{{ user }}</strong> -
<time datetime="{{ date }}" title="{{ date_formatted }}">{{ date_relative }}</time>
<br/>
{{{ text }}}
{{#if attachment_link }}
<br/>
<strong>Attachment: </strong>
<a href="{{attachment_link}}">{{ attachment_name }}</a>
{{/if}}
<hr id="post_item">
</li>
{{/each }}
{{else }}
<p><em>No comment yet.</em></p><hr id="post_item">
{{/if }}
</script>
</head>
<body>
<!-- XXX this is a form replacement -->
......
......@@ -252,7 +252,7 @@
</tuple>
<state>
<tuple>
<float>1538971816.32</float>
<float>1539136980.8</float>
<string>GMT+9</string>
</tuple>
</state>
......
/*global window, rJS, RSVP, calculatePageTitle, FormData, URI, jIO, moment */
/*global window, rJS, RSVP, calculatePageTitle, FormData, URI, jIO, moment, Handlebars */
/*jslint nomen: true, indent: 2, maxerr: 3 */
(function (window, rJS, RSVP, calculatePageTitle, moment) {
(function (window, rJS, RSVP, calculatePageTitle, moment, Handlebars) {
"use strict";
var gadget_klass = rJS(window),
comment_list_template = Handlebars.compile(
gadget_klass.__template_element.getElementById("template-document-list").innerHTML
);
rJS(window)
gadget_klass
/////////////////////////////////////////////////////////////////
// Acquired methods
/////////////////////////////////////////////////////////////////
......@@ -68,11 +72,9 @@
});
})
.onStateChange(function () {
/** @type {GadgetInstance} */
var gadget = this;
// render the erp5 form
return this.getDeclaredGadget("erp5_form")
return gadget.getDeclaredGadget("erp5_form")
.push(function (erp5_form) {
return gadget.getDeclaredGadget("editor")
.push(function (editor) {
......@@ -166,55 +168,37 @@
);
})
.push(function (post_list) {
var queue_list = [], i = 0;
if (post_list.length) {
for (i = 0; i < post_list.length; i += 1) {
if (post_list[i].attachment_link !== null && post_list[i].attachment_link.indexOf("image_module") !== -1) {
queue_list.push(gadget.getImageUrl(post_list[i].attachment_link));
} else if (post_list[i].attachment_link !== null && post_list[i].attachment_link.indexOf("document_module") !== -1) {
queue_list.push(gadget.getDocumentUrl(post_list[i].attachment_link));
} else {
queue_list.push(null);
}
}
}
queue_list.push(post_list);
return RSVP.all(queue_list);
})
.push(function (result_list) {
var s = '', i, comments = gadget.element.querySelector("#post_list"),
plain_content, post_list = result_list.pop();
if (post_list.length) {
for (i = 0; i < post_list.length; i += 1) {
s += '<li>' +
'By <strong>' + post_list[i].user + '</strong>' +
' - <time datetime="' + post_list[i].date + '" title="' + moment(post_list[i].date).format('LLLL') + '">' + moment(post_list[i].date).fromNow() + '</time><br/>';
if (post_list[i].attachment_link !== null && result_list[i] !== null) {
post_list[i].attachment_link = result_list[i];
function getPostWithLinkAndLocalDate(post) {
post.date_formatted = moment(post.date).format('LLLL');
post.date_relative = moment(post.date).fromNow();
if (post.attachment_link === null) {
return post;
}
if (post_list[i].text) {
plain_content = post_list[i].text;
if (post_list[i].attachment_link) {
s += plain_content + '<strong>Attachment: </strong>' +
'<a href=\"' +
post_list[i].attachment_link + '\">' + post_list[i].attachment_name +
'</a>';
} else {
s += plain_content;
if (post.attachment_link.indexOf("image_module") !== -1) {
return gadget.getImageUrl(post.attachment_link).push(
function (attachment_link) {
post.attachment_link = attachment_link;
return post;
}
} else {
if (post_list[i].attachment_link) {
s += '<strong>Attachment: </strong>' + '<a href=\"' +
post_list[i].attachment_link + '\">' + post_list[i].attachment_name +
'</a>';
);
}
return gadget.getDocumentUrl(post.attachment_link).push(
function (attachment_link) {
post.attachment_link = attachment_link;
return post;
}
s += '<hr id=post_item>'; // XXX XSS attack!
);
}
comments.innerHTML = s;
} else {
comments.innerHTML = "<p><em>No comment yet.</em></p><hr id=post_item>";
// build links with attachments and localized dates
var queue_list = [], i = 0;
for (i = 0; i < post_list.length; i += 1) {
queue_list.push(getPostWithLinkAndLocalDate(post_list[i]));
}
return RSVP.all(queue_list);
})
.push(function (comment_list) {
var comments = gadget.element.querySelector("#post_list");
comments.innerHTML = comment_list_template({comments: comment_list});
});
})
.declareJob('submitPostComment', function () {
......@@ -276,4 +260,4 @@
.onEvent('submit', function () {
this.submitPostComment();
});
}(window, rJS, RSVP, calculatePageTitle, moment));
\ No newline at end of file
}(window, rJS, RSVP, calculatePageTitle, moment, Handlebars));
\ No newline at end of file
......@@ -252,7 +252,7 @@
</tuple>
<state>
<tuple>
<float>1539135182.86</float>
<float>1539140577.69</float>
<string>GMT+9</string>
</tuple>
</state>
......
......@@ -72,6 +72,22 @@
<td>//ol[@id="post_list"]//li[1]/p</td>
<td>Post test 1</td>
</tr>
<tr>
<td>waitForText</td>
<td>//ol[@id="post_list"]//li[1]/p</td>
<td>Post test 1</td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//ol[@id="post_list"]//li[1]/strong</td>
<td></td>
</tr>
<tr>
<td>assertText</td>
<td>//ol[@id="post_list"]//li[1]/time</td>
<td>a few seconds ago</td>
</tr>
<!-- The "just posted" message is available because it is retrieved from memcached,
eventhough it's not ingested yet. But this works only for one message, so to first message
posted when opening the SR and the second one posted as a comment, we need to flush
......@@ -120,6 +136,17 @@ displayed
<td>//ol[@id="post_list"]//li[1]/p</td>
<td>Post test 1</td>
</tr>
<tr>
<td>assertText</td>
<td>//ol[@id="post_list"]//li[1]/strong</td>
<td>A1 Corporation</td>
</tr>
<tr>
<td>assertText</td>
<td>//ol[@id="post_list"]//li[1]/time</td>
<td>a few seconds ago</td>
</tr>
<!-- flush activities and post one more message, to exercice ingesting post
posted from support request comment, which uses a different code path than
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment