From 9975eb3b625943da2dbc93542e1886544640f35b Mon Sep 17 00:00:00 2001 From: lumi Date: Thu, 21 Feb 2019 02:46:29 +0100 Subject: [PATCH 1/2] Don't send a paticipant's real jid in the mention if we are a moderator in a semi-anonymous or anonymous MUC. Always add the "uri" attribute, as it is required according to the XEP. --- CHANGES.md | 2 ++ spec/messages.js | 28 ++++++++++++++++++++++++++++ src/headless/converse-muc.js | 15 +++++++++++---- 3 files changed, 41 insertions(+), 4 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 30b2d57456..f68f32e9af 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -5,6 +5,8 @@ - Bugfix. Prevent duplicate messages by comparing MAM archive id to XEP-0359 stanza ids. - Bugfix. Open groupchats not shown when logging in after disconnection. - #1406: `TypeError: e.devicelists is undefined` when unchecking the "trusted device" checkbox +- Bugfix. Don't send real jids in mentions in a semi-anonymous or anonymous room when we are a moderator. +- Bugfix. Always set the "uri" field in reference tags, as required by the XEP. ## 4.1.1 (2019-02-18) diff --git a/spec/messages.js b/spec/messages.js index d46ddb155b..331c534bb8 100644 --- a/spec/messages.js +++ b/spec/messages.js @@ -2800,6 +2800,34 @@ done(); })); + it("will not leak the real JIDs of participants in XEP-0372 references", + mock.initConverse( + null, ['rosterGroupsFetched'], {}, + async function (done, _converse) { + + await test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy'); + const view = _converse.chatboxviews.get('lounge@localhost'); + view.model.features.save({'nonanonymous': false, 'semianonymous': true}); + const textarea = view.el.querySelector('.chat-textarea'); + textarea.value = "Meow @dummy!"; + spyOn(_converse.connection, 'send'); + const enter_event = { + 'target': textarea, + 'preventDefault': _.noop, + 'stopPropagation': _.noop, + 'keyCode': 13 // Enter + }; + view.keyPressed(enter_event); + await new Promise((resolve, reject) => view.once('messageInserted', resolve)); + const msg = _converse.connection.send.calls.all()[0].args[0]; + const selector = `message[to="lounge@localhost"] reference[xmlns="urn:xmpp:reference:0"]`; + const node = msg.nodeTree.querySelector(selector); + const refUri = node.getAttribute('uri'); + expect(refUri).toBe('xmpp:lounge@localhost/dummy'); + + done(); + })); + it("includes XEP-0372 references to that person", mock.initConverse( null, ['rosterGroupsFetched'], {}, diff --git a/src/headless/converse-muc.js b/src/headless/converse-muc.js index cf968f2969..642c39c54d 100644 --- a/src/headless/converse-muc.js +++ b/src/headless/converse-muc.js @@ -356,15 +356,22 @@ converse.plugins.add('converse-muc', { if (!occupant) { return null; } + const roomJid = this.get('jid'); + const nonanon = this.features.get('nonanonymous'); + let uri; + if (occupant.get('jid') && nonanon) { + uri = `xmpp:${occupant.get('jid')}`; + } + else { + uri = `xmpp:${roomJid}/${occupant.get('nick')}`; + } const obj = { 'begin': index, 'end': index + longest_match.length, 'value': longest_match, - 'type': 'mention' + 'type': 'mention', + 'uri': uri, }; - if (occupant.get('jid')) { - obj.uri = `xmpp:${occupant.get('jid')}` - } return obj; }, From b1a54583ad5270654a0c1823a4f1d677dc3da007 Mon Sep 17 00:00:00 2001 From: lumi Date: Thu, 21 Feb 2019 18:03:17 +0100 Subject: [PATCH 2/2] Fix the tests to reflect the changes in XEP-0372 reference handling. --- spec/messages.js | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/spec/messages.js b/spec/messages.js index 331c534bb8..a8a0c3ca4a 100644 --- a/spec/messages.js +++ b/spec/messages.js @@ -2686,6 +2686,9 @@ }))); }); + // This room is not anonymous, so real JIDs can be used. + view.model.features.save({'nonanonymous': true, 'semianonymous': false}); + // Run a few unit tests for the parseTextForReferences method let [text, references] = view.model.parseTextForReferences('hello z3r0') expect(references.length).toBe(0); @@ -2694,15 +2697,17 @@ [text, references] = view.model.parseTextForReferences('hello @z3r0') expect(references.length).toBe(1); expect(text).toBe('hello z3r0'); - expect(JSON.stringify(references)) - .toBe('[{"begin":6,"end":10,"value":"z3r0","type":"mention","uri":"xmpp:z3r0@localhost"}]'); + expect(references) + .toEqual([{"begin":6,"end":10,"value":"z3r0","type":"mention","uri":"xmpp:z3r0@localhost"}]); [text, references] = view.model.parseTextForReferences('hello @some1 @z3r0 @gibson @mr.robot, how are you?') expect(text).toBe('hello @some1 z3r0 gibson mr.robot, how are you?'); - expect(JSON.stringify(references)) - .toBe('[{"begin":13,"end":17,"value":"z3r0","type":"mention","uri":"xmpp:z3r0@localhost"},'+ - '{"begin":18,"end":24,"value":"gibson","type":"mention","uri":"xmpp:gibson@localhost"},'+ - '{"begin":25,"end":33,"value":"mr.robot","type":"mention","uri":"xmpp:mr.robot@localhost"}]'); + expect(references) + .toEqual([ + {"begin":13,"end":17,"value":"z3r0","type":"mention","uri":"xmpp:z3r0@localhost"}, + {"begin":18,"end":24,"value":"gibson","type":"mention","uri":"xmpp:gibson@localhost"}, + {"begin":25,"end":33,"value":"mr.robot","type":"mention","uri":"xmpp:mr.robot@localhost"} + ]); [text, references] = view.model.parseTextForReferences('yo @gib') expect(text).toBe('yo @gib'); @@ -2715,14 +2720,14 @@ [text, references] = view.model.parseTextForReferences('@gibson') expect(text).toBe('gibson'); expect(references.length).toBe(1); - expect(JSON.stringify(references)) - .toBe('[{"begin":0,"end":6,"value":"gibson","type":"mention","uri":"xmpp:gibson@localhost"}]'); + expect(references) + .toEqual([{"begin":0,"end":6,"value":"gibson","type":"mention","uri":"xmpp:gibson@localhost"}]); [text, references] = view.model.parseTextForReferences('hi @Link Mauve how are you?') expect(text).toBe('hi Link Mauve how are you?'); expect(references.length).toBe(1); - expect(JSON.stringify(references)) - .toBe('[{"begin":3,"end":13,"value":"Link Mauve","type":"mention","uri":"xmpp:Link-Mauve@localhost"}]'); + expect(references) + .toEqual([{"begin":3,"end":13,"value":"Link Mauve","type":"mention","uri":"xmpp:Link-Mauve@localhost"}]); done(); })); @@ -2747,6 +2752,9 @@ }))); }); + // This room is not anonymous, so real JIDs can be used. + view.model.features.save({'nonanonymous': true, 'semianonymous': false}); + const textarea = view.el.querySelector('textarea.chat-textarea'); textarea.value = 'hello @z3r0 @gibson @mr.robot, how are you?' const enter_event = { @@ -2850,6 +2858,9 @@ }))); }); + // This room is not anonymous, so real JIDs can be used. + view.model.features.save({'nonanonymous': true, 'semianonymous': false}); + spyOn(_converse.connection, 'send'); const textarea = view.el.querySelector('textarea.chat-textarea'); textarea.value = 'hello @z3r0 @gibson @mr.robot, how are you?'