2
0
Эх сурвалжийг харах

Add config setting `allow_non_roster_messaging`

- Add a test case.
- Don't allow passing of `attrs` to `chats.open`. Not sure yet of the
  implications of this.
JC Brand 8 жил өмнө
parent
commit
25d9880f9e

+ 1 - 0
docs/CHANGES.md

@@ -5,6 +5,7 @@
   be prioritized above other auth mechanisms. [jcbrand]
 - #755: create composer.json to add this project in packagist.org [fabiomontefuscolo]
 - #758: Bugfix. Render all resize drag handles for ChatRoomView. [LeoYReyes]
+- #762 Allow chatting with users not in your roster. [Ape, jcbrand]
 - Bugfix. Cancel button shown while registration form is being fetched wasn't working
   properly. [jcbrand]
 - Bugfix. Login form wasn't rendered after logging out (when `auto_reconnect` is `true`). [jcbrand]

+ 12 - 0
docs/source/configuration.rst

@@ -173,6 +173,18 @@ Allows users to be invited to join MUC chat rooms. An "Invite" widget will
 appear in the sidebar of the chat room where you can type in the JID of a user
 to invite into the chat room.
 
+allow_non_roster_messaging
+--------------------------
+
+* Default:  ``false``
+
+Determines whether you'll receive messages from users that are not in your
+roster. The XMPP specification allows for this (similar to email).
+Setting this to `true` increases your chances of receiving spam (when using a
+federated server), while setting it to `false` means that people not on your
+roster can't contact you unless one (or both) of you subscribe to one another's
+presence (i.e. adding as a roster contact).
+
 allow_otr
 ---------
 

+ 58 - 7
spec/chatbox.js

@@ -465,7 +465,7 @@
                         test_utils.openContactsPanel(converse);
 
                         spyOn(converse, 'emit');
-                        var message = 'converse is a received message';
+                        var message = 'This is a received message';
                         var sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
                         var msg = $msg({
                                 from: sender_jid,
@@ -506,6 +506,63 @@
                         });
                     }));
 
+                    describe("who is not on the roster", function () {
+                        it("will open a chatbox and be displayed inside it if allow_non_roster_messaging is true", mock.initConverse(function (converse) {
+                            converse.allow_non_roster_messaging = false;
+
+                            spyOn(converse, 'emit');
+                            var message = 'This is a received message from someone not on the roster';
+                            var sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
+                            var msg = $msg({
+                                    from: sender_jid,
+                                    to: converse.connection.jid,
+                                    type: 'chat',
+                                    id: (new Date()).getTime()
+                                }).c('body').t(message).up()
+                                .c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree();
+
+                            // We don't already have an open chatbox for this user
+                            expect(converse.chatboxes.get(sender_jid)).not.toBeDefined();
+
+                            runs(function () {
+                                // onMessage is a handler for received XMPP messages
+                                converse.chatboxes.onMessage(msg);
+                                expect(converse.emit).toHaveBeenCalledWith('message', msg);
+                            });
+                            waits(50);
+                            runs(function () {
+                                var chatbox = converse.chatboxes.get(sender_jid);
+                                expect(chatbox).not.toBeDefined();
+
+                                // onMessage is a handler for received XMPP messages
+                                converse.allow_non_roster_messaging =true;
+                                converse.chatboxes.onMessage(msg);
+                                expect(converse.emit).toHaveBeenCalledWith('message', msg);
+                            });
+                            waits(50);
+                            runs(function () {
+                                // Check that the chatbox and its view now exist
+                                var chatbox = converse.chatboxes.get(sender_jid);
+                                var chatboxview = converse.chatboxviews.get(sender_jid);
+                                expect(chatbox).toBeDefined();
+                                expect(chatboxview).toBeDefined();
+                                // Check that the message was received and check the message parameters
+                                expect(chatbox.messages.length).toEqual(1);
+                                var msg_obj = chatbox.messages.models[0];
+                                expect(msg_obj.get('message')).toEqual(message);
+                                expect(msg_obj.get('fullname')).toEqual(sender_jid);
+                                expect(msg_obj.get('sender')).toEqual('them');
+                                expect(msg_obj.get('delayed')).toEqual(false);
+                                // Now check that the message appears inside the chatbox in the DOM
+                                var $chat_content = chatboxview.$el.find('.chat-content');
+                                var msg_txt = $chat_content.find('.chat-message').find('.chat-msg-content').text();
+                                expect(msg_txt).toEqual(message);
+                                var sender_txt = $chat_content.find('span.chat-msg-them').text();
+                                expect(sender_txt.match(/^[0-9][0-9]:[0-9][0-9] /)).toBeTruthy();
+                            });
+                        }));
+                    });
+
                     describe("and for which then an error message is received from the server", function () {
                         afterEach(function () {
                             converse_api.user.logout();
@@ -719,12 +776,6 @@
                     }));
                 });
 
-                describe("when sent by the current user", function () {
-                    it("will always cause the chat area to be scrolled down", mock.initConverse(function (converse) {
-                        // TODO
-                    }));
-                });
-
                 it("is ignored if it's a malformed headline message", mock.initConverse(function (converse) {
                     test_utils.createContacts(converse, 'current');
                     test_utils.openControlBox();

+ 3 - 3
src/converse-api.js

@@ -106,20 +106,20 @@
             }
         },
         'chats': {
-            'open': function (jids, attrs) {
+            'open': function (jids) {
                 var chatbox;
                 if (typeof jids === "undefined") {
                     converse.log("chats.open: You need to provide at least one JID", "error");
                     return null;
                 } else if (typeof jids === "string") {
                     chatbox = converse.wrappedChatBox(
-                        converse.chatboxes.getChatBox(jids, true, attrs).trigger('show')
+                        converse.chatboxes.getChatBox(jids, true).trigger('show')
                     );
                     return chatbox;
                 }
                 return _.map(jids, function (jid) {
                     chatbox = converse.wrappedChatBox(
-                        converse.chatboxes.getChatBox(jid, true, attrs).trigger('show')
+                        converse.chatboxes.getChatBox(jid, true).trigger('show')
                     );
                     return chatbox;
                 });

+ 16 - 10
src/converse-core.js

@@ -208,6 +208,7 @@
         // ----------------------------
         this.default_settings = {
             allow_contact_requests: true,
+            allow_non_roster_messaging: false,
             animate: true,
             authentication: 'login', // Available values are "login", "prebind", "anonymous" and "external".
             auto_away: 0, // Seconds after which user status is set to 'away'
@@ -230,6 +231,7 @@
             keepalive: false,
             locked_domain: undefined,
             message_carbons: false, // Support for XEP-280
+            message_storage: 'session',
             password: undefined,
             prebind: false, // XXX: Deprecated, use "authentication" instead.
             prebind_url: null,
@@ -238,7 +240,6 @@
             show_only_online_users: false,
             sid: undefined,
             storage: 'session',
-            message_storage: 'session',
             strict_plugin_dependencies: false,
             synchronize_availability: true, // Set to false to not sync with other clients or with resource name of the particular client that it should synchronize with
             websocket_url: undefined,
@@ -1494,20 +1495,25 @@
                  * Parameters:
                  *    (String) jid - The JID of the user whose chat box we want
                  *    (Boolean) create - Should a new chat box be created if none exists?
+                 *    (Object) attrs - Optional chat box atributes.
                  */
                 jid = jid.toLowerCase();
                 var bare_jid = Strophe.getBareJidFromJid(jid);
                 var chatbox = this.get(bare_jid);
                 if (!chatbox && create) {
-                    var roster_info;
+                    var roster_info = {};
                     var roster_item = converse.roster.get(bare_jid);
-                    if (roster_item !== undefined) {
-                      roster_info = {
-                          'fullname': _.isEmpty(roster_item.get('fullname'))? jid: roster_item.get('fullname'),
-                          'image_type': roster_item.get('image_type'),
-                          'image': roster_item.get('image'),
-                          'url': roster_item.get('url'),
-                      };
+                    if (! _.isUndefined(roster_item)) {
+                        roster_info = {
+                            'fullname': _.isEmpty(roster_item.get('fullname'))? jid: roster_item.get('fullname'),
+                            'image_type': roster_item.get('image_type'),
+                            'image': roster_item.get('image'),
+                            'url': roster_item.get('url'),
+                        };
+                    } else if (!converse.allow_non_roster_messaging) {
+                        converse.log('Could not get roster item for JID '+bare_jid+
+                                    ' and allow_non_roster_messaging is set to false', 'error');
+                        return;
                     }
                     chatbox = this.create(_.extend({
                         'id': bare_jid,
@@ -1516,7 +1522,7 @@
                         'image_type': DEFAULT_IMAGE_TYPE,
                         'image': DEFAULT_IMAGE,
                         'url': '',
-                    }, roster_info || {}, attrs || {}));
+                    }, roster_info, attrs || {}));
                 }
                 return chatbox;
             }

+ 1 - 1
tests/mock.js

@@ -87,7 +87,7 @@
                 auto_login: true,
                 jid: 'dummy@localhost',
                 password: 'secret',
-                debug: true
+                debug: false
             }, settings || {}));
             converse.ChatBoxViews.prototype.trimChat = function () {};
             return func(converse);