Add own device to the server-stored devicelist

updates #497
This commit is contained in:
JC Brand 2018-05-13 14:12:53 +02:00
parent 281865d9b1
commit 9645641505
4 changed files with 100 additions and 44 deletions

View File

@ -6,38 +6,6 @@
var $iq = converse.env.$iq; var $iq = converse.env.$iq;
var _ = converse.env._; var _ = converse.env._;
window.libsignal = {
'KeyHelper': {
'generateIdentityKeyPair': function () {
return Promise.resolve({
'pubKey': 1234,
'privKey': 4321
});
},
'generateRegistrationId': function () {
return '31415';
},
'generatePreKey': function (keyid) {
return Promise.resolve({
'keyId': keyid,
'keyPair': {
'pubKey': 1234,
'privKey': 4321
}
});
},
'generateSignedPreKey': function (identity_keypair, keyid) {
return Promise.resolve({
'keyId': keyid,
'keyPair': {
'pubKey': 1234,
'privKey': 4321
}
});
}
}
};
describe("The OMEMO module", function() { describe("The OMEMO module", function() {
it("will add processing hints to sent out encrypted <message> stanzas", it("will add processing hints to sent out encrypted <message> stanzas",
@ -114,6 +82,31 @@
expect(devicelist.devices.at(0).get('id')).toBe('482886413b977930064a5888b92134fe'); expect(devicelist.devices.at(0).get('id')).toBe('482886413b977930064a5888b92134fe');
test_utils.openChatBoxFor(_converse, contact_jid); test_utils.openChatBoxFor(_converse, contact_jid);
return test_utils.waitUntil(() => {
return _.filter(_converse.connection.IQ_stanzas, function (iq) {
const node = iq.nodeTree.querySelector('publish[xmlns="eu.siacs.conversations.axolotl.devicelist"]');
if (node) { iq_stanza = iq.nodeTree; }
return node;
}).length;
});
}).then(function () {
expect(iq_stanza.outerHTML).toBe(
'<iq from="dummy@localhost" type="set" xmlns="jabber:client" id="'+iq_stanza.getAttribute('id')+'">'+
'<pubsub xmlns="http://jabber.org/protocol/pubsub">'+
'<publish xmlns="eu.siacs.conversations.axolotl.devicelist">'+
'<item>'+
'<list xmlns="eu.siacs.conversations.axolotl"/>'+
'<device id="482886413b977930064a5888b92134fe"/>'+
'</item>'+
'</publish>'+
'</pubsub>'+
'</iq>');
const stanza = $iq({
'from': _converse.bare_jid,
'id': iq_stanza.getAttribute('id'),
'to': _converse.bare_jid,
'type': 'result'});
_converse.connection._dataRecv(test_utils.createRequest(stanza));
return test_utils.waitUntil(() => { return test_utils.waitUntil(() => {
return _.filter( return _.filter(
_converse.connection.IQ_stanzas, _converse.connection.IQ_stanzas,

View File

@ -47,7 +47,7 @@
"<presence xmlns='jabber:client'>"+ "<presence xmlns='jabber:client'>"+
"<status>Hello world</status>"+ "<status>Hello world</status>"+
"<priority>0</priority>"+ "<priority>0</priority>"+
"<c xmlns='http://jabber.org/protocol/caps' hash='sha-1' node='https://conversejs.org' ver='1J7kq1MEvnB6ea6vKcgCsSE37gw='/>"+ "<c xmlns='http://jabber.org/protocol/caps' hash='sha-1' node='https://conversejs.org' ver='3RLZIW6Gu1JDLZXCD6HFV9MiDQ4='/>"+
"</presence>" "</presence>"
); );
_converse.priority = 2; _converse.priority = 2;
@ -57,7 +57,7 @@
"<show>away</show>"+ "<show>away</show>"+
"<status>Going jogging</status>"+ "<status>Going jogging</status>"+
"<priority>2</priority>"+ "<priority>2</priority>"+
"<c xmlns='http://jabber.org/protocol/caps' hash='sha-1' node='https://conversejs.org' ver='1J7kq1MEvnB6ea6vKcgCsSE37gw='/>"+ "<c xmlns='http://jabber.org/protocol/caps' hash='sha-1' node='https://conversejs.org' ver='3RLZIW6Gu1JDLZXCD6HFV9MiDQ4='/>"+
"</presence>" "</presence>"
); );
@ -68,7 +68,7 @@
"<show>dnd</show>"+ "<show>dnd</show>"+
"<status>Doing taxes</status>"+ "<status>Doing taxes</status>"+
"<priority>0</priority>"+ "<priority>0</priority>"+
"<c xmlns='http://jabber.org/protocol/caps' hash='sha-1' node='https://conversejs.org' ver='1J7kq1MEvnB6ea6vKcgCsSE37gw='/>"+ "<c xmlns='http://jabber.org/protocol/caps' hash='sha-1' node='https://conversejs.org' ver='3RLZIW6Gu1JDLZXCD6HFV9MiDQ4='/>"+
"</presence>" "</presence>"
); );
})); }));
@ -97,7 +97,7 @@
.toBe("<presence xmlns='jabber:client'>"+ .toBe("<presence xmlns='jabber:client'>"+
"<status>My custom status</status>"+ "<status>My custom status</status>"+
"<priority>0</priority>"+ "<priority>0</priority>"+
"<c xmlns='http://jabber.org/protocol/caps' hash='sha-1' node='https://conversejs.org' ver='1J7kq1MEvnB6ea6vKcgCsSE37gw='/>"+ "<c xmlns='http://jabber.org/protocol/caps' hash='sha-1' node='https://conversejs.org' ver='3RLZIW6Gu1JDLZXCD6HFV9MiDQ4='/>"+
"</presence>") "</presence>")
return test_utils.waitUntil(function () { return test_utils.waitUntil(function () {
@ -113,7 +113,7 @@
modal.el.querySelector('[type="submit"]').click(); modal.el.querySelector('[type="submit"]').click();
expect(_converse.connection.send.calls.mostRecent().args[0].toLocaleString()) expect(_converse.connection.send.calls.mostRecent().args[0].toLocaleString())
.toBe("<presence xmlns='jabber:client'><show>dnd</show><status>My custom status</status><priority>0</priority>"+ .toBe("<presence xmlns='jabber:client'><show>dnd</show><status>My custom status</status><priority>0</priority>"+
"<c xmlns='http://jabber.org/protocol/caps' hash='sha-1' node='https://conversejs.org' ver='1J7kq1MEvnB6ea6vKcgCsSE37gw='/>"+ "<c xmlns='http://jabber.org/protocol/caps' hash='sha-1' node='https://conversejs.org' ver='3RLZIW6Gu1JDLZXCD6HFV9MiDQ4='/>"+
"</presence>") "</presence>")
done(); done();
}); });

View File

@ -188,6 +188,27 @@
reject, reject,
_converse.IQ_TIMEOUT); _converse.IQ_TIMEOUT);
}); });
},
addDeviceToList () {
/* Add this device to our list of devices stored on the
* server.
* https://xmpp.org/extensions/xep-0384.html#usecases-announcing
*/
return new Promise((resolve, reject) => {
const stanza = $iq({
'from': _converse.bare_jid,
'type': 'set'
}).c('pubsub', {'xmlns': Strophe.NS.PUBSUB})
.c('publish', {'xmlns': Strophe.NS.OMEMO_DEVICELIST})
.c('item')
.c('list', {'xmlns': Strophe.NS.OMEMO}).up()
this.devices.each((device) => {
stanza.c('device', {'id': device.get('id')}).up();
});
_converse.connection.sendIQ(stanza, resolve, reject, _converse.IQ_TIMEOUT);
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.ERROR));
} }
}); });
@ -226,10 +247,7 @@
return new Promise((resolve, reject) => _converse.devicelists.fetch({'success': resolve})); return new Promise((resolve, reject) => _converse.devicelists.fetch({'success': resolve}));
} }
function updateOwnDeviceList () { function fetchOwnDevices () {
/* If our own device is not on the list, add it.
* Also, deduplicate devices if necessary.
*/
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
fetchDeviceLists().then(() => { fetchDeviceLists().then(() => {
let own_devicelist = _converse.devicelists.get(_converse.bare_jid); let own_devicelist = _converse.devicelists.get(_converse.bare_jid);
@ -237,12 +255,23 @@
own_devicelist = _converse.devicelists.create({'jid': _converse.bare_jid}); own_devicelist = _converse.devicelists.create({'jid': _converse.bare_jid});
} }
own_devicelist.fetchDevices().then(resolve).catch(reject); own_devicelist.fetchDevices().then(resolve).catch(reject);
// TODO: if our own device is not onthe list, add it.
// TODO: deduplicate
}); });
}); });
} }
function updateOwnDeviceList () {
/* If our own device is not on the list, add it.
* Also, deduplicate devices if necessary.
*/
return new Promise((resolve, reject) => {
const devicelist = _converse.devicelists.get(_converse.bare_jid);
if (!devicelist.devices.findWhere({'id': _converse.omemo_store.get('device_id')})) {
return devicelist.addDeviceToList().then(resolve).catch(reject);
}
resolve();
});
}
function updateDevicesFromStanza (stanza) { function updateDevicesFromStanza (stanza) {
// TODO: check whether our own device_id is still on the list, // TODO: check whether our own device_id is still on the list,
// otherwise we need to update it. // otherwise we need to update it.
@ -268,6 +297,7 @@
_converse.connection.addHandler((message) => { _converse.connection.addHandler((message) => {
if (message.querySelector('event[xmlns="'+Strophe.NS.PUBSUB+'#event"]')) { if (message.querySelector('event[xmlns="'+Strophe.NS.PUBSUB+'#event"]')) {
updateDevicesFromStanza(message); updateDevicesFromStanza(message);
updateOwnDeviceList();
} }
}, null, 'message', 'headline', null, _converse.bare_jid); }, null, 'message', 'headline', null, _converse.bare_jid);
} }
@ -298,6 +328,7 @@
); );
restoreOMEMOSession() restoreOMEMOSession()
.then(() => publishBundle()) .then(() => publishBundle())
.then(() => fetchOwnDevices())
.then(() => updateOwnDeviceList()) .then(() => updateOwnDeviceList())
.then(() => _converse.emit('OMEMOInitialized')) .then(() => _converse.emit('OMEMOInitialized'))
.catch(_.partial(_converse.log, _, Strophe.LogLevel.ERROR)); .catch(_.partial(_converse.log, _, Strophe.LogLevel.ERROR));

View File

@ -5,8 +5,40 @@
var Promise = converse.env.Promise; var Promise = converse.env.Promise;
var Strophe = converse.env.Strophe; var Strophe = converse.env.Strophe;
var $iq = converse.env.$iq; var $iq = converse.env.$iq;
var mock = {};
window.libsignal = {
'KeyHelper': {
'generateIdentityKeyPair': function () {
return Promise.resolve({
'pubKey': 1234,
'privKey': 4321
});
},
'generateRegistrationId': function () {
return '31415';
},
'generatePreKey': function (keyid) {
return Promise.resolve({
'keyId': keyid,
'keyPair': {
'pubKey': 1234,
'privKey': 4321
}
});
},
'generateSignedPreKey': function (identity_keypair, keyid) {
return Promise.resolve({
'keyId': keyid,
'keyPair': {
'pubKey': 1234,
'privKey': 4321
}
});
}
}
};
var mock = {};
mock.view_mode = 'overlayed'; mock.view_mode = 'overlayed';
// Names from http://www.fakenamegenerator.com/ // Names from http://www.fakenamegenerator.com/