Merge branch 'master' into 0.8
Conflicts: bower.json converse.js docs/CHANGES.rst spec/chatbox.js tests/utils.js tests_main.js
This commit is contained in:
commit
9849daacf9
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "converse",
|
||||
"version": "0.7.3",
|
||||
"version": "0.7.4",
|
||||
"devDependencies": {
|
||||
"jasmine": "https://github.com/jcbrand/jasmine.git#1_3_x",
|
||||
"otr": "0.2.7",
|
||||
|
4
builds/converse-no-locales-no-otr.min.js
vendored
4
builds/converse-no-locales-no-otr.min.js
vendored
File diff suppressed because one or more lines are too long
4
builds/converse-no-otr.min.js
vendored
4
builds/converse-no-otr.min.js
vendored
File diff suppressed because one or more lines are too long
4
builds/converse.min.js
vendored
4
builds/converse.min.js
vendored
File diff suppressed because one or more lines are too long
@ -43,7 +43,8 @@
|
||||
if (list) {
|
||||
for (i=0; i<list.length; i++) {
|
||||
var prot = list[i].indexOf('http://') === 0 || list[i].indexOf('https://') === 0 ? '' : 'http://';
|
||||
x = x.replace(list[i], "<a target='_blank' href='" + prot + list[i] + "'>"+ list[i] + "</a>" );
|
||||
var escaped_url = encodeURI(decodeURI(list[i])).replace(/[!'()]/g, escape).replace(/\*/g, "%2A");
|
||||
x = x.replace(list[i], "<a target='_blank' href='" + prot + escaped_url + "'>"+ list[i] + "</a>" );
|
||||
}
|
||||
}
|
||||
$(obj).html(x);
|
||||
@ -942,15 +943,16 @@
|
||||
msg_date = msg_dict.time ? converse.parseISO8601(msg_dict.time) : new Date(),
|
||||
text = msg_dict.message,
|
||||
match = text.match(/^\/(.*?)(?: (.*))?$/),
|
||||
fullname = msg_dict.fullname || this.model.get('fullname'),
|
||||
template, username;
|
||||
|
||||
if ((match) && (match[1] === 'me')) {
|
||||
text = text.replace(/^\/me/, '');
|
||||
template = converse.templates.action_template;
|
||||
username = msg_dict.fullname;
|
||||
username = fullname;
|
||||
} else {
|
||||
template = converse.templates.message;
|
||||
username = msg_dict.sender === 'me' && __('me') || msg_dict.fullname || this.model.get('fullname');
|
||||
username = msg_dict.sender === 'me' && __('me') || fullname;
|
||||
}
|
||||
$el.find('div.chat-event').remove();
|
||||
var message = template({
|
||||
|
@ -7,6 +7,16 @@ Changelog
|
||||
* Chat boxes and rooms can now be resized vertically. [jcbrand]
|
||||
* Chat boxes and rooms can be minimized. [jcbrand]
|
||||
|
||||
0.7.4 (2014-03-05)
|
||||
------------------
|
||||
|
||||
.. note:: This release contains an important security fix.
|
||||
Thanks to Renaud Dubourguais from `Synacktiv http://synacktiv.com`_ for reporting the vulnerability.
|
||||
|
||||
* #125 Bugfix: crypto dependencies loaded in wrong order [jcbrand]
|
||||
* Bugfix: action messages (i.e. /me) didn't work in OTR mode. [jcbrand]
|
||||
* Security fix: Ensure that message URLs are properly encoded. [jcbrand]
|
||||
|
||||
0.7.3 (2014-02-23)
|
||||
------------------
|
||||
|
||||
@ -22,11 +32,12 @@ Changelog
|
||||
------------------
|
||||
|
||||
.. note:: This release contains an important security fix.
|
||||
Thanks to hejsan for reporting the vulnerability.
|
||||
|
||||
* #48 Add event emitter support and emit events. [jcbrand]
|
||||
* #97 Wrong number of online contacts shown with config option ``show_only_online_users``. [jcbrand]
|
||||
* #100 Make the fetching of vCards optional (enabled by default). [jcbrand]
|
||||
* Sanitize message text to avoid Javascript injection attacks. Thanks to hejsan for reporting. [jcbrand]
|
||||
* Sanitize message text to avoid Javascript injection attacks. [jcbrand]
|
||||
|
||||
0.7.1 (2013-11-17)
|
||||
------------------
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Sphinx build info version 1
|
||||
# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
|
||||
config: 738ca7b60aed811ee1668ad08d26eabb
|
||||
config: 0660e50cf30718622673fcf0e779dfd4
|
||||
tags: fbb0d17656682115ca4d033fb2f83ba1
|
||||
|
@ -9,7 +9,7 @@
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
|
||||
<title>Index — Converse.js 0.7.3 documentation</title>
|
||||
<title>Index — Converse.js 0.7.4 documentation</title>
|
||||
|
||||
<link rel="stylesheet" href="_static/stylesheet.css" type="text/css" />
|
||||
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
|
||||
@ -17,7 +17,7 @@
|
||||
<script type="text/javascript">
|
||||
var DOCUMENTATION_OPTIONS = {
|
||||
URL_ROOT: '',
|
||||
VERSION: '0.7.3',
|
||||
VERSION: '0.7.4',
|
||||
COLLAPSE_INDEX: false,
|
||||
FILE_SUFFIX: '.html',
|
||||
HAS_SOURCE: true
|
||||
@ -26,7 +26,7 @@
|
||||
<script type="text/javascript" src="_static/jquery.js"></script>
|
||||
<script type="text/javascript" src="_static/underscore.js"></script>
|
||||
<script type="text/javascript" src="_static/doctools.js"></script>
|
||||
<link rel="top" title="Converse.js 0.7.3 documentation" href="index.html" />
|
||||
<link rel="top" title="Converse.js 0.7.4 documentation" href="index.html" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="header_wrap" class="outer">
|
||||
@ -51,7 +51,7 @@
|
||||
<li class="right" style="margin-right: 10px">
|
||||
<a href="#" title="General Index"
|
||||
accesskey="I">index</a></li>
|
||||
<li><a href="index.html">Converse.js 0.7.3 documentation</a> »</li>
|
||||
<li><a href="index.html">Converse.js 0.7.4 documentation</a> »</li>
|
||||
</ul>
|
||||
</div>
|
||||
<section id="main_content" class="inner">
|
||||
@ -80,7 +80,7 @@
|
||||
<li class="right" style="margin-right: 10px">
|
||||
<a href="#" title="General Index"
|
||||
>index</a></li>
|
||||
<li><a href="index.html">Converse.js 0.7.3 documentation</a> »</li>
|
||||
<li><a href="index.html">Converse.js 0.7.4 documentation</a> »</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -7,7 +7,7 @@
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
|
||||
<title>Quickstart (to get a demo up and running) — Converse.js 0.7.3 documentation</title>
|
||||
<title>Quickstart (to get a demo up and running) — Converse.js 0.7.4 documentation</title>
|
||||
|
||||
<link rel="stylesheet" href="_static/stylesheet.css" type="text/css" />
|
||||
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
|
||||
@ -15,7 +15,7 @@
|
||||
<script type="text/javascript">
|
||||
var DOCUMENTATION_OPTIONS = {
|
||||
URL_ROOT: '',
|
||||
VERSION: '0.7.3',
|
||||
VERSION: '0.7.4',
|
||||
COLLAPSE_INDEX: false,
|
||||
FILE_SUFFIX: '.html',
|
||||
HAS_SOURCE: true
|
||||
@ -24,7 +24,7 @@
|
||||
<script type="text/javascript" src="_static/jquery.js"></script>
|
||||
<script type="text/javascript" src="_static/underscore.js"></script>
|
||||
<script type="text/javascript" src="_static/doctools.js"></script>
|
||||
<link rel="top" title="Converse.js 0.7.3 documentation" href="#" />
|
||||
<link rel="top" title="Converse.js 0.7.4 documentation" href="#" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="header_wrap" class="outer">
|
||||
@ -49,7 +49,7 @@
|
||||
<li class="right" style="margin-right: 10px">
|
||||
<a href="genindex.html" title="General Index"
|
||||
accesskey="I">index</a></li>
|
||||
<li><a href="#">Converse.js 0.7.3 documentation</a> »</li>
|
||||
<li><a href="#">Converse.js 0.7.4 documentation</a> »</li>
|
||||
</ul>
|
||||
</div>
|
||||
<section id="main_content" class="inner">
|
||||
@ -1045,7 +1045,7 @@ The query string will be included in the request with <tt class="docutils litera
|
||||
<li class="right" style="margin-right: 10px">
|
||||
<a href="genindex.html" title="General Index"
|
||||
>index</a></li>
|
||||
<li><a href="#">Converse.js 0.7.3 documentation</a> »</li>
|
||||
<li><a href="#">Converse.js 0.7.4 documentation</a> »</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,6 +1,6 @@
|
||||
# Sphinx inventory version 2
|
||||
# Project: Converse.js
|
||||
# Version: 0.7.3
|
||||
# Version: 0.7.4
|
||||
# The remainder of this file is compressed using zlib.
|
||||
xÚmÎÁ
|
||||
à à{Ÿ"°³ƒ]÷;
|
||||
|
@ -7,7 +7,7 @@
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
|
||||
<title>Search — Converse.js 0.7.3 documentation</title>
|
||||
<title>Search — Converse.js 0.7.4 documentation</title>
|
||||
|
||||
<link rel="stylesheet" href="_static/stylesheet.css" type="text/css" />
|
||||
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
|
||||
@ -15,7 +15,7 @@
|
||||
<script type="text/javascript">
|
||||
var DOCUMENTATION_OPTIONS = {
|
||||
URL_ROOT: '',
|
||||
VERSION: '0.7.3',
|
||||
VERSION: '0.7.4',
|
||||
COLLAPSE_INDEX: false,
|
||||
FILE_SUFFIX: '.html',
|
||||
HAS_SOURCE: true
|
||||
@ -25,7 +25,7 @@
|
||||
<script type="text/javascript" src="_static/underscore.js"></script>
|
||||
<script type="text/javascript" src="_static/doctools.js"></script>
|
||||
<script type="text/javascript" src="_static/searchtools.js"></script>
|
||||
<link rel="top" title="Converse.js 0.7.3 documentation" href="index.html" />
|
||||
<link rel="top" title="Converse.js 0.7.4 documentation" href="index.html" />
|
||||
<script type="text/javascript">
|
||||
jQuery(function() { Search.loadIndex("searchindex.js"); });
|
||||
</script>
|
||||
@ -55,7 +55,7 @@
|
||||
<li class="right" style="margin-right: 10px">
|
||||
<a href="genindex.html" title="General Index"
|
||||
accesskey="I">index</a></li>
|
||||
<li><a href="index.html">Converse.js 0.7.3 documentation</a> »</li>
|
||||
<li><a href="index.html">Converse.js 0.7.4 documentation</a> »</li>
|
||||
</ul>
|
||||
</div>
|
||||
<section id="main_content" class="inner">
|
||||
@ -100,7 +100,7 @@
|
||||
<li class="right" style="margin-right: 10px">
|
||||
<a href="genindex.html" title="General Index"
|
||||
>index</a></li>
|
||||
<li><a href="index.html">Converse.js 0.7.3 documentation</a> »</li>
|
||||
<li><a href="index.html">Converse.js 0.7.4 documentation</a> »</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
File diff suppressed because one or more lines are too long
@ -48,9 +48,9 @@ copyright = u'2013, JC Brand'
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = '0.7.3'
|
||||
version = '0.7.4'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '0.7.3'
|
||||
release = '0.7.4'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
|
@ -4,7 +4,7 @@
|
||||
<meta charset='utf-8' />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
|
||||
<meta name="description" content="Converse.js: Open Source Browser-Based Instant Messaging" />
|
||||
<meta name="description" content="Converse.js: A chat client for your website" />
|
||||
<link rel="stylesheet" type="text/css" media="screen" href="stylesheets/stylesheet.css">
|
||||
<link rel="stylesheet" type="text/css" media="screen" href="converse.css">
|
||||
<script data-main="main" src="components/requirejs/require.js"></script>
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "converse.js",
|
||||
"version": "0.7.3",
|
||||
"version": "0.7.4",
|
||||
"description": "Browser based XMPP instant messaging client",
|
||||
"main": "main.js",
|
||||
"directories": {
|
||||
|
@ -465,42 +465,99 @@
|
||||
var view = this.chatboxviews.get(contact_jid);
|
||||
var message = 'This message is sent from this chatbox';
|
||||
spyOn(view, 'sendMessage').andCallThrough();
|
||||
view.$el.find('.chat-textarea').text(message);
|
||||
view.$el.find('textarea.chat-textarea').trigger($.Event('keypress', {keyCode: 13}));
|
||||
utils.sendMessage(view, message);
|
||||
expect(view.sendMessage).toHaveBeenCalled();
|
||||
expect(view.model.messages.length, 2);
|
||||
expect(converse.emit.callCount).toEqual(3);
|
||||
expect(converse.emit.mostRecentCall.args, ['onMessageSend', message]);
|
||||
var txt = view.$el.find('.chat-content').find('.chat-message').last().find('.chat-message-content').text();
|
||||
expect(txt).toEqual(message);
|
||||
expect(view.$el.find('.chat-content').find('.chat-message').last().find('.chat-message-content').text()).toEqual(message);
|
||||
}.bind(converse));
|
||||
}, converse));
|
||||
|
||||
it("are sanitized to prevent Javascript injection attacks", $.proxy(function () {
|
||||
it("is sanitized to prevent Javascript injection attacks", $.proxy(function () {
|
||||
var contact_jid = mock.cur_names[0].replace(' ','.').toLowerCase() + '@localhost';
|
||||
utils.openChatBoxFor(contact_jid);
|
||||
var view = this.chatboxviews.get(contact_jid);
|
||||
var message = 'This message contains <b>markup</b>';
|
||||
var message = '<p>This message contains <em>some</em> <b>markup</b></p>';
|
||||
spyOn(view, 'sendMessage').andCallThrough();
|
||||
view.$el.find('.chat-textarea').text(message);
|
||||
view.$el.find('textarea.chat-textarea').trigger($.Event('keypress', {keyCode: 13}));
|
||||
utils.sendMessage(view, message);
|
||||
expect(view.sendMessage).toHaveBeenCalled();
|
||||
var txt = view.$el.find('.chat-content').find('.chat-message').last().find('.chat-message-content').text();
|
||||
expect(txt).toEqual(message);
|
||||
var msg = view.$el.find('.chat-content').find('.chat-message').last().find('.chat-message-content');
|
||||
expect(msg.text()).toEqual(message);
|
||||
expect(msg.html()).toEqual('<p>This message contains <em>some</em> <b>markup</b></p>');
|
||||
}, converse));
|
||||
|
||||
it("can contain hyperlinks, which will be clickable", $.proxy(function () {
|
||||
var contact_jid = mock.cur_names[0].replace(' ','.').toLowerCase() + '@localhost';
|
||||
utils.openChatBoxFor(contact_jid);
|
||||
var view = this.chatboxviews.get(contact_jid);
|
||||
var message = 'This message contains a hyperlink: www.opkode.com';
|
||||
spyOn(view, 'sendMessage').andCallThrough();
|
||||
utils.sendMessage(view, message);
|
||||
expect(view.sendMessage).toHaveBeenCalled();
|
||||
var msg = view.$el.find('.chat-content').find('.chat-message').last().find('.chat-message-content');
|
||||
expect(msg.text()).toEqual(message);
|
||||
expect(msg.html()).toEqual('This message contains a hyperlink: <a target="_blank" href="http://www.opkode.com">www.opkode.com</a>');
|
||||
}, converse));
|
||||
|
||||
it("will have properly escaped URLs", $.proxy(function () {
|
||||
var contact_jid = mock.cur_names[0].replace(' ','.').toLowerCase() + '@localhost';
|
||||
utils.openChatBoxFor(contact_jid);
|
||||
var view = this.chatboxviews.get(contact_jid);
|
||||
spyOn(view, 'sendMessage').andCallThrough();
|
||||
|
||||
var message = "http://www.opkode.com/'onmouseover='alert(1)'whatever";
|
||||
utils.sendMessage(view, message);
|
||||
expect(view.sendMessage).toHaveBeenCalled();
|
||||
var msg = view.$el.find('.chat-content').find('.chat-message').last().find('.chat-message-content');
|
||||
expect(msg.text()).toEqual(message);
|
||||
expect(msg.html()).toEqual('<a target="_blank" href="http://www.opkode.com/%27onmouseover=%27alert%281%29%27whatever">http://www.opkode.com/\'onmouseover=\'alert(1)\'whatever</a>');
|
||||
|
||||
message = 'http://www.opkode.com/"onmouseover="alert(1)"whatever';
|
||||
utils.sendMessage(view, message);
|
||||
expect(view.sendMessage).toHaveBeenCalled();
|
||||
msg = view.$el.find('.chat-content').find('.chat-message').last().find('.chat-message-content');
|
||||
expect(msg.text()).toEqual(message);
|
||||
expect(msg.html()).toEqual('<a target="_blank" href="http://www.opkode.com/%22onmouseover=%22alert%281%29%22whatever">http://www.opkode.com/"onmouseover="alert(1)"whatever</a>');
|
||||
|
||||
message = "https://en.wikipedia.org/wiki/Ender's_Game";
|
||||
utils.sendMessage(view, message);
|
||||
expect(view.sendMessage).toHaveBeenCalled();
|
||||
msg = view.$el.find('.chat-content').find('.chat-message').last().find('.chat-message-content');
|
||||
expect(msg.text()).toEqual(message);
|
||||
expect(msg.html()).toEqual('<a target="_blank" href="https://en.wikipedia.org/wiki/Ender%27s_Game">https://en.wikipedia.org/wiki/Ender\'s_Game</a>');
|
||||
|
||||
message = "https://en.wikipedia.org/wiki/Ender%27s_Game";
|
||||
utils.sendMessage(view, message);
|
||||
expect(view.sendMessage).toHaveBeenCalled();
|
||||
msg = view.$el.find('.chat-content').find('.chat-message').last().find('.chat-message-content');
|
||||
expect(msg.text()).toEqual(message);
|
||||
expect(msg.html()).toEqual('<a target="_blank" href="https://en.wikipedia.org/wiki/Ender%27s_Game">https://en.wikipedia.org/wiki/Ender%27s_Game</a>');
|
||||
}, converse));
|
||||
|
||||
}, converse));
|
||||
}, converse));
|
||||
|
||||
describe("Special Messages", $.proxy(function () {
|
||||
beforeEach(function () {
|
||||
utils.closeAllChatBoxes();
|
||||
utils.removeControlBox();
|
||||
converse.roster.localStorage._clear();
|
||||
utils.initConverse();
|
||||
utils.createCurrentContacts();
|
||||
utils.openControlBox();
|
||||
utils.openContactsPanel();
|
||||
});
|
||||
|
||||
it("'/clear' can be used to clear messages in a conversation", $.proxy(function () {
|
||||
spyOn(converse, 'emit');
|
||||
var contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
|
||||
utils.openChatBoxFor(contact_jid);
|
||||
var view = this.chatboxviews.get(contact_jid);
|
||||
var message = 'This message is another sent from this chatbox';
|
||||
// Lets make sure there is at least one message already
|
||||
// (e.g for when this test is run on its own).
|
||||
view.$el.find('.chat-textarea').val(message).text(message);
|
||||
view.$el.find('textarea.chat-textarea').trigger($.Event('keypress', {keyCode: 13}));
|
||||
utils.sendMessage(view, message);
|
||||
expect(view.model.messages.length > 0).toBeTruthy();
|
||||
expect(view.model.messages.localStorage.records.length > 0).toBeTruthy();
|
||||
expect(converse.emit).toHaveBeenCalledWith('onMessageSend', message);
|
||||
@ -508,8 +565,7 @@
|
||||
message = '/clear';
|
||||
var old_length = view.model.messages.length;
|
||||
spyOn(view, 'sendMessage').andCallThrough();
|
||||
view.$el.find('.chat-textarea').val(message).text(message);
|
||||
view.$el.find('textarea.chat-textarea').trigger($.Event('keypress', {keyCode: 13}));
|
||||
utils.sendMessage(view, message);
|
||||
expect(view.sendMessage).toHaveBeenCalled();
|
||||
expect(view.model.messages.length, 0); // The messages must be removed from the modal
|
||||
expect(view.model.messages.localStorage.records.length, 0); // And also from localStorage
|
||||
|
@ -33,8 +33,8 @@
|
||||
"bigint": "src/bigint",
|
||||
"crypto.core": "components/otr/vendor/cryptojs/core",
|
||||
"crypto.enc-base64": "components/otr/vendor/cryptojs/enc-base64",
|
||||
"crypto.md5": "components/crypto-js/src/md5",
|
||||
"crypto.evpkdf": "components/crypto-js/src/evpkdf",
|
||||
"crypto.md5": "components/crypto-js-evanvosberg/src/md5",
|
||||
"crypto.evpkdf": "components/crypto-js-evanvosberg/src/evpkdf",
|
||||
"crypto.cipher-core": "components/otr/vendor/cryptojs/cipher-core",
|
||||
"crypto.aes": "components/otr/vendor/cryptojs/aes",
|
||||
"crypto.sha1": "components/otr/vendor/cryptojs/sha1",
|
||||
|
@ -3,7 +3,7 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Converse.js Tests</title>
|
||||
<meta name="description" content="Converse.js: Open Source Browser-Based Instant Messaging" />
|
||||
<meta name="description" content="Converse.js: A chat client for your website" />
|
||||
<link rel="shortcut icon" type="image/png" href="components/jasmine/images/jasmine_favicon.png">
|
||||
<link rel="stylesheet" type="text/css" href="components/jasmine/src/html/jasmine.css">
|
||||
<link rel="stylesheet" type="text/css" media="screen" href="stylesheets/stylesheet.css">
|
||||
|
@ -110,5 +110,10 @@
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
utils.sendMessage = function (chatboxview, message) {
|
||||
chatboxview.$el.find('.chat-textarea').val(message);
|
||||
chatboxview.$el.find('textarea.chat-textarea').trigger($.Event('keypress', {keyCode: 13}));
|
||||
};
|
||||
return utils;
|
||||
}));
|
||||
|
Loading…
Reference in New Issue
Block a user