Auto-link urls in message bodies

And watch out for xss.

Closes #187
This commit is contained in:
lilia 2015-03-06 17:01:04 -08:00
parent 8ee282b1aa
commit dc1b09f59d
3 changed files with 32 additions and 10 deletions

View file

@ -31,7 +31,6 @@
}
});
var ContentMessageView = Whisper.View.extend({
tagName: 'div',
template: $('#message').html(),
@ -45,6 +44,9 @@
renderDelivered: function() {
if (this.model.get('delivered')) { this.$el.addClass('delivered'); }
},
autoLink: function(text) {
return text.replace(/(^|[\s\n]|<br\/?>)((?:https?|ftp):\/\/[\-A-Z0-9+\u0026\u2019@#\/%?=()~_|!:,.;]*[\-A-Z0-9+\u0026@#\/%=~()_|])/gi, "$1<a href='$2' target='_blank'>$2</a>");
},
render: function() {
this.$el.html(
Mustache.render(this.template, {
@ -54,6 +56,9 @@
})
);
var content = this.$el.find('.content');
content.html(this.autoLink(content.html()));
this.renderDelivered();
this.$el.find('.attachments').append(

View file

@ -47,16 +47,13 @@
<script type='text/x-tmpl-mustache' id='message'>
<div class='sender'>{{ sender }}</div>
<img class='avatar' src='{{ contact_avatar }}'>
<div class='bubble bubble_context {{ bubble_class }}'>
<ul class='volley'>
<li class='message'>
{{ message }}
<div class="bubble">
<p class="content">{{ message }}</p>
<div class='attachments'></div>
<div class='meta'>
<span class='timestamp'>{{ timestamp }}</span>
</li>
</ul>
{{#attachments}}
<img src={{.}}>
{{/attachments}}
<span class='checkmark hide'></span>
</div>
</div>
</script>
<script type='text/x-tmpl-mustache' id='contact'>

View file

@ -44,4 +44,24 @@ describe('MessageView', function() {
message.destroy();
assert.strictEqual(div.find(view.$el).length, 0);
});
it('allows links', function() {
var url = 'http://example.com';
message.set('body', url);
var view = new Whisper.MessageView({model: message});
view.render();
var link = view.$el.find('.content a');
assert.strictEqual(link.length, 1);
assert.strictEqual(link.text(), url);
assert.strictEqual(link.attr('href'), url);
});
it('disallows xss', function() {
var xss = '<script>alert("pwnd")</script>';
message.set('body', xss);
var view = new Whisper.MessageView({model: message});
view.render();
assert.include(view.$el.text(), xss); // should appear as escaped text
assert.strictEqual(view.$el.find('script').length, 0); // should not appear as html
});
});