Commit 4c5ea34a authored by JC Brand's avatar JC Brand

New build

parent 3eb5e93f
...@@ -63144,8 +63144,8 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_ ...@@ -63144,8 +63144,8 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
const result = this.getMessageAttributesFromStanza(message, original_stanza); const result = this.getMessageAttributesFromStanza(message, original_stanza);
if (result instanceof Promise) { if (typeof result.then === "function") {
return new Promise((resolve, reject) => result.then(attrs => resolve(_create(attrs))).catch(reject)); return new Promise((resolve, reject) => result.then(attrs => resolve(_create(attrs))));
} else { } else {
const message = _create(result); const message = _create(result);
...@@ -69805,13 +69805,7 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_ ...@@ -69805,13 +69805,7 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
'id': id 'id': id
}) })
}); });
this.toggleview.model.browserStorage = new Backbone.BrowserStorage[storage](id);
try {
this.toggleview.model.browserStorage = new Backbone.BrowserStorage[storage](id);
} catch (e) {
debugger;
}
this.toggleview.model.fetch(); this.toggleview.model.fetch();
}, },
...@@ -74126,6 +74120,7 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_ ...@@ -74126,6 +74120,7 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
this.devicelist.devices.on('change:bundle', this.debouncedRender, this); this.devicelist.devices.on('change:bundle', this.debouncedRender, this);
this.devicelist.devices.on('reset', this.debouncedRender, this); this.devicelist.devices.on('reset', this.debouncedRender, this);
this.devicelist.devices.on('remove', this.debouncedRender, this); this.devicelist.devices.on('remove', this.debouncedRender, this);
this.devicelist.devices.on('add', this.debouncedRender, this);
return this.__super__.initialize.apply(this, arguments); return this.__super__.initialize.apply(this, arguments);
}, },
...@@ -74183,6 +74178,7 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_ ...@@ -74183,6 +74178,7 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
this.devicelist.devices.on('change:bundle', this.render, this); this.devicelist.devices.on('change:bundle', this.render, this);
this.devicelist.devices.on('change:trusted', this.render, this); this.devicelist.devices.on('change:trusted', this.render, this);
this.devicelist.devices.on('remove', this.render, this); this.devicelist.devices.on('remove', this.render, this);
this.devicelist.devices.on('add', this.render, this);
this.devicelist.devices.on('reset', this.render, this); this.devicelist.devices.on('reset', this.render, this);
return this.__super__.initialize.apply(this, arguments); return this.__super__.initialize.apply(this, arguments);
}, },
...@@ -74197,29 +74193,26 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_ ...@@ -74197,29 +74193,26 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
ChatBox: { ChatBox: {
getBundlesAndBuildSessions() { getBundlesAndBuildSessions() {
const _converse = this.__super__._converse; const _converse = this.__super__._converse;
return new Promise((resolve, reject) => { let devices;
_converse.getDevicesForContact(this.get('jid')).then(their_devices => { return _converse.getDevicesForContact(this.get('jid')).then(their_devices => {
const device_id = _converse.omemo_store.get('device_id'), const device_id = _converse.omemo_store.get('device_id'),
devicelist = _converse.devicelists.get(_converse.bare_jid), devicelist = _converse.devicelists.get(_converse.bare_jid),
own_devices = devicelist.devices.filter(device => device.get('id') !== device_id), own_devices = devicelist.devices.filter(device => device.get('id') !== device_id);
devices = _.concat(own_devices, their_devices.models);
devices = _.concat(own_devices, their_devices.models);
Promise.all(devices.map(device => device.getBundle())).then(() => this.buildSessions(devices)).then(() => resolve(devices)).catch(_.partial(_converse.log, _, Strophe.LogLevel.ERROR)); return Promise.all(devices.map(device => device.getBundle()));
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.ERROR)); }).then(() => this.buildSessions(devices));
});
}, },
buildSession(device) { buildSession(device) {
const _converse = this.__super__._converse; const _converse = this.__super__._converse,
const bundle = device.get('bundle'),
address = new libsignal.SignalProtocolAddress(device.get('jid'), device.get('id')), address = new libsignal.SignalProtocolAddress(device.get('jid'), device.get('id')),
sessionBuilder = new libsignal.SessionBuilder(_converse.omemo_store, address), sessionBuilder = new libsignal.SessionBuilder(_converse.omemo_store, address),
prekey = device.getRandomPreKey(); prekey = device.getRandomPreKey();
return device.getBundle().then(bundle => {
try {
return sessionBuilder.processPreKey({ return sessionBuilder.processPreKey({
'registrationId': parseInt(_converse.omemo_store.get('device_id'), 10), 'registrationId': parseInt(device.get('id'), 10),
'identityKey': u.base64ToArrayBuffer(_converse.omemo_store.get('identity_key')), 'identityKey': u.base64ToArrayBuffer(bundle.identity_key),
'signedPreKey': { 'signedPreKey': {
'keyId': bundle.signed_prekey.id, 'keyId': bundle.signed_prekey.id,
// <Number> // <Number>
...@@ -74232,13 +74225,19 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_ ...@@ -74232,13 +74225,19 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
'publicKey': u.base64ToArrayBuffer(prekey.key) 'publicKey': u.base64ToArrayBuffer(prekey.key)
} }
}); });
} catch (e) { });
_converse.log(`Error: could not build session for device ${device.get('id')}`, Strophe.LogLevel.ERROR); },
_converse.log(e.message, Strophe.LogLevel.ERROR);
return Promise.resolve(); getSession(device) {
} const _converse = this.__super__._converse,
address = new libsignal.SignalProtocolAddress(device.get('jid'), device.get('id'));
return _converse.omemo_store.loadSession(address.toString()).then(session => {
if (session) {
return Promise.resolve();
} else {
return this.buildSession(device);
}
});
}, },
getKeyAndTag(string) { getKeyAndTag(string) {
...@@ -74266,68 +74265,85 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_ ...@@ -74266,68 +74265,85 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
'tagLength': TAG_LENGTH 'tagLength': TAG_LENGTH
}; };
return window.crypto.subtle.decrypt(algo, key_obj, u.base64ToArrayBuffer(obj.payload)); return window.crypto.subtle.decrypt(algo, key_obj, u.base64ToArrayBuffer(obj.payload));
}).then(out => new TextDecoder().decode(out)).catch(e => _converse.log(e.toString(), Strophe.LogLevel.ERROR)); }).then(out => new TextDecoder().decode(out));
}, },
decryptFromKeyAndTag(key_and_tag, obj) { reportDecryptionError(e) {
const aes_data = this.getKeyAndTag(u.arrayBufferToString(key_and_tag)); const _converse = this.__super__._converse,
return this.decryptMessage(_.extend(obj, { __ = _converse.__;
'key': aes_data.key, this.messages.create({
'tag': aes_data.tag 'message': __("Sorry, could not decrypt a received OMEMO message due to an error.") + `${e.name} ${e.message}`,
})); 'type': 'error'
},
handlePreKeyMessage(attrs) {
// TODO
const _converse = this.__super__._converse; // If this is the case, a new session is built from this received element. The client
// SHOULD then republish their bundle information, replacing the used PreKey, such
// that it won't be used again by a different client. If the client already has a session
// with the sender's device, it MUST replace this session with the newly built session.
// The client MUST delete the private key belonging to the PreKey after use.
const address = new libsignal.SignalProtocolAddress(attrs.from, attrs.encrypted.device_id),
session_cipher = new window.libsignal.SessionCipher(_converse.omemo_store, address),
libsignal_payload = JSON.parse(atob(attrs.encrypted.key));
return session_cipher.decryptPreKeyWhisperMessage(libsignal_payload.body, 'binary').then(key_and_tag => this.decryptFromKeyAndTag(key_and_tag, attrs.encrypted)).then(f => {// TODO handle new key...
// _converse.omemo.publishBundle()
}); });
_converse.log(e, Strophe.LogLevel.ERROR);
}, },
decrypt(attrs) { decrypt(attrs) {
if (attrs.prekey === 'true') {
return this.handlePreKeyMessage(attrs);
}
const _converse = this.__super__._converse, const _converse = this.__super__._converse,
address = new libsignal.SignalProtocolAddress(attrs.from, attrs.encrypted.device_id), devicelist = _converse.devicelists.get(attrs.from),
device = devicelist.devices.get(attrs.encrypted.device_id),
address = new libsignal.SignalProtocolAddress(attrs.from, parseInt(attrs.encrypted.device_id, 10)),
session_cipher = new window.libsignal.SessionCipher(_converse.omemo_store, address), session_cipher = new window.libsignal.SessionCipher(_converse.omemo_store, address),
libsignal_payload = JSON.parse(atob(attrs.encrypted.key)); libsignal_payload = JSON.parse(atob(attrs.encrypted.key));
return new Promise((resolve, reject) => {
session_cipher.decryptWhisperMessage(libsignal_payload.body, 'binary').then(key_and_tag => this.decryptFromKeyAndTag(key_and_tag, attrs.encrypted)).then(resolve).catch(reject); if (attrs.encrypted.prekey === 'true') {
}); // If this is the case, a new session is built from this received element. The client
// SHOULD then republish their bundle information, replacing the used PreKey, such
// that it won't be used again by a different client. If the client already has a session
// with the sender's device, it MUST replace this session with the newly built session.
// The client MUST delete the private key belonging to the PreKey after use.
return session_cipher.decryptPreKeyWhisperMessage(libsignal_payload.body, 'binary').then(key_and_tag => {
const aes_data = this.getKeyAndTag(u.arrayBufferToString(key_and_tag));
return this.decryptMessage(_.extend(attrs.encrypted, {
'key': aes_data.key,
'tag': aes_data.tag
}));
}).then(plaintext => {
// TODO remove newly used key before republishing
_converse.omemo.publishBundle();
return _.extend(attrs, {
'plaintext': plaintext
});
}).catch(e => {
this.reportDecryptionError(e);
return attrs;
});
} else {
return session_cipher.decryptWhisperMessage(libsignal_payload.body, 'binary').then(key_and_tag => {
const aes_data = this.getKeyAndTag(u.arrayBufferToString(key_and_tag));
return this.decryptMessage(_.extend(attrs.encrypted, {
'key': aes_data.key,
'tag': aes_data.tag
}));
}).then(plaintext => _.extend(attrs, {
'plaintext': plaintext
})).catch(e => {
this.reportDecryptionError(e);
return attrs;
});
}
}, },
getEncryptionAttributesfromStanza(stanza, original_stanza, attrs) { getEncryptionAttributesfromStanza(stanza, original_stanza, attrs) {
const _converse = this.__super__._converse, const _converse = this.__super__._converse,
encrypted = sizzle(`encrypted[xmlns="${Strophe.NS.OMEMO}"]`, original_stanza).pop(); encrypted = sizzle(`encrypted[xmlns="${Strophe.NS.OMEMO}"]`, original_stanza).pop(),
return new Promise((resolve, reject) => { header = encrypted.querySelector('header'),
const _converse = this.__super__._converse, key = sizzle(`key[rid="${_converse.omemo_store.get('device_id')}"]`, encrypted).pop();
header = encrypted.querySelector('header'),
key = sizzle(`key[rid="${_converse.omemo_store.get('device_id')}"]`, encrypted).pop(); if (key) {
attrs['encrypted'] = {
if (key) { 'device_id': header.getAttribute('sid'),
attrs['encrypted'] = { 'iv': header.querySelector('iv').textContent,
'device_id': header.getAttribute('sid'), 'key': key.textContent,
'iv': header.querySelector('iv').textContent, 'payload': _.get(encrypted.querySelector('payload'), 'textContent', null),
'key': key.textContent, 'prekey': key.getAttribute('prekey')
'payload': _.get(encrypted.querySelector('payload'), 'textContent', null), };
'prekey': key.getAttribute('prekey') return this.decrypt(attrs);
}; } else {
this.decrypt(attrs).then(plaintext => resolve(_.extend(attrs, { return Promise.resolve(attrs);
'plaintext': plaintext }
}))).catch(reject);
}
});
}, },
getMessageAttributesFromStanza(stanza, original_stanza) { getMessageAttributesFromStanza(stanza, original_stanza) {
...@@ -74343,7 +74359,7 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_ ...@@ -74343,7 +74359,7 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
}, },
buildSessions(devices) { buildSessions(devices) {
return Promise.all(devices.map(device => this.buildSession(device))); return Promise.all(devices.map(device => this.getSession(device))).then(() => devices);
}, },
encryptMessage(plaintext) { encryptMessage(plaintext) {
...@@ -74364,12 +74380,10 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_ ...@@ -74364,12 +74380,10 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
}).then(ciphertext => { }).then(ciphertext => {
return window.crypto.subtle.exportKey("jwk", key).then(key_obj => { return window.crypto.subtle.exportKey("jwk", key).then(key_obj => {
const tag = u.arrayBufferToBase64(ciphertext.slice(ciphertext.byteLength - (TAG_LENGTH + 7 >> 3))); const tag = u.arrayBufferToBase64(ciphertext.slice(ciphertext.byteLength - (TAG_LENGTH + 7 >> 3)));
console.log('XXXX: Base64 TAG is ' + tag);
console.log('YYY: KEY is ' + key_obj.k);
return Promise.resolve({ return Promise.resolve({
'key': key_obj.k, 'key': key_obj.k,
'tag': tag, 'tag': tag,
'key_and_tag': btoa(key_obj.k + tag), 'key_and_tag': key_obj.k + tag,
'payload': u.arrayBufferToBase64(ciphertext), 'payload': u.arrayBufferToBase64(ciphertext),
'iv': u.arrayBufferToBase64(iv) 'iv': u.arrayBufferToBase64(iv)
}); });
...@@ -74379,14 +74393,12 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_ ...@@ -74379,14 +74393,12 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
encryptKey(plaintext, device) { encryptKey(plaintext, device) {
const _converse = this.__super__._converse, const _converse = this.__super__._converse,
address = new libsignal.SignalProtocolAddress(this.get('jid'), device.get('id')), address = new libsignal.SignalProtocolAddress(device.get('jid'), device.get('id')),
session_cipher = new window.libsignal.SessionCipher(_converse.omemo_store, address); session_cipher = new window.libsignal.SessionCipher(_converse.omemo_store, address);
return new Promise((resolve, reject) => { return session_cipher.encrypt(plaintext).then(payload => ({
session_cipher.encrypt(plaintext).then(payload => resolve({ 'payload': payload,
'payload': payload, 'device': device
'device': device }));
})).catch(_.partial(_converse.log, _, Strophe.LogLevel.ERROR));
});
}, },
addKeysToMessageStanza(stanza, dicts, iv) { addKeysToMessageStanza(stanza, dicts, iv) {
...@@ -74422,6 +74434,10 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_ ...@@ -74422,6 +74434,10 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
const body = __("This is an OMEMO encrypted message which your client doesn’t seem to support. " + "Find more information on https://conversations.im/omemo"); const body = __("This is an OMEMO encrypted message which your client doesn’t seem to support. " + "Find more information on https://conversations.im/omemo");
if (!message.get('message')) {
throw new Error("No message body to encrypt!");
}
const stanza = $msg({ const stanza = $msg({
'from': _converse.connection.jid, 'from': _converse.connection.jid,
'to': this.get('jid'), 'to': this.get('jid'),
...@@ -74438,7 +74454,7 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_ ...@@ -74438,7 +74454,7 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
}).c('header', { }).c('header', {
'sid': _converse.omemo_store.get('device_id') 'sid': _converse.omemo_store.get('device_id')
}); });
return this.encryptMessage(message).then(obj => { return this.encryptMessage(message.get('message')).then(obj => {
// The 16 bytes key and the GCM authentication tag (The tag // The 16 bytes key and the GCM authentication tag (The tag
// SHOULD have at least 128 bit) are concatenated and for each // SHOULD have at least 128 bit) are concatenated and for each
// intended recipient device, i.e. both own devices as well as // intended recipient device, i.e. both own devices as well as
...@@ -74446,16 +74462,24 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_ ...@@ -74446,16 +74462,24 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
// concatenation is encrypted using the corresponding // concatenation is encrypted using the corresponding
// long-standing SignalProtocol session. // long-standing SignalProtocol session.
const promises = devices.filter(device => device.get('trusted') != UNTRUSTED).map(device => this.encryptKey(obj.key_and_tag, device)); const promises = devices.filter(device => device.get('trusted') != UNTRUSTED).map(device => this.encryptKey(obj.key_and_tag, device));
return Promise.all(promises).then(dicts => this.addKeysToMessageStanza(stanza, dicts, obj.iv)).then(stanza => stanza.c('payload').t(obj.payload)).catch(_.partial(_converse.log, _, Strophe.LogLevel.ERROR)); return Promise.all(promises).then(dicts => this.addKeysToMessageStanza(stanza, dicts, obj.iv)).then(stanza => stanza.c('payload').t(obj.payload));
}); });
}, },
sendMessage(attrs) { sendMessage(attrs) {
const _converse = this.__super__._converse; const _converse = this.__super__._converse,
__ = _converse.__;
if (this.get('omemo_active')) { if (this.get('omemo_active') && attrs.message) {
const message = this.messages.create(attrs); const message = this.messages.create(attrs);
this.getBundlesAndBuildSessions().then(devices => this.createOMEMOMessageStanza(message, devices)).then(stanza => this.sendMessageStanza(stanza)).catch(_.partial(_converse.log, _, Strophe.LogLevel.ERROR)); this.getBundlesAndBuildSessions().then(devices => this.createOMEMOMessageStanza(message, devices)).then(stanza => this.sendMessageStanza(stanza)).catch(e => {
this.messages.create({
'message': __("Sorry, could not send the message due to an error.") + ` ${e.message}`,
'type': 'error'
});
_converse.log(e, Strophe.LogLevel.ERROR);
});
} else { } else {
return this.__super__.sendMessage.apply(this, arguments); return this.__super__.sendMessage.apply(this, arguments);
} }
...@@ -74567,11 +74591,15 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_ ...@@ -74567,11 +74591,15 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
}, },
getIdentityKeyPair() { getIdentityKeyPair() {
return Promise.resolve(this.get('identity_keypair')); const keypair = this.get('identity_keypair');
return Promise.resolve({
'privKey': u.base64ToArrayBuffer(keypair.privKey),
'pubKey': u.base64ToArrayBuffer(keypair.pubKey)
});
}, },
getLocalRegistrationId() { getLocalRegistrationId() {
return Promise.resolve(this.get('device_id')); return Promise.resolve(parseInt(this.get('device_id'), 10));
}, },
isTrustedIdentity(identifier, identity_key, direction) { isTrustedIdentity(identifier, identity_key, direction) {
...@@ -74589,7 +74617,7 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_ ...@@ -74589,7 +74617,7 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
return Promise.resolve(true); return Promise.resolve(true);
} }
return Promise.resolve(u.arrayBufferToString(identity_key) === u.arrayBufferToString(trusted)); return Promise.resolve(u.arrayBufferToBase64(identity_key) === trusted);
}, },
loadIdentityKey(identifier) { loadIdentityKey(identifier) {
...@@ -74597,7 +74625,7 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_ ...@@ -74597,7 +74625,7 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
throw new Error("Can't load identity_key for invalid identifier"); throw new Error("Can't load identity_key for invalid identifier");
} }
return Promise.resolve(this.get('identity_key' + identifier)); return Promise.resolve(u.base64ToArrayBuffer(this.get('identity_key' + identifier)));
}, },
saveIdentity(identifier, identity_key) { saveIdentity(identifier, identity_key) {
...@@ -74607,9 +74635,10 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_ ...@@ -74607,9 +74635,10 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
const address = new libsignal.SignalProtocolAddress.fromString(identifier), const address = new libsignal.SignalProtocolAddress.fromString(identifier),
existing = this.get('identity_key' + address.getName()); existing = this.get('identity_key' + address.getName());
this.save('identity_key' + address.getName(), identity_key); const b64_idkey = u.arrayBufferToBase64(identity_key);
this.save('identity_key' + address.getName(), b64_idkey);
if (existing && u.arrayBufferToString(identity_key) !== u.arrayBufferToString(existing)) { if (existing && b64_idkey !== existing) {
return Promise.resolve(true); return Promise.resolve(true);
} else { } else {
return Promise.resolve(false); return Promise.resolve(false);
...@@ -74619,10 +74648,10 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_ ...@@ -74619,10 +74648,10 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
loadPreKey(keyId) { loadPreKey(keyId) {
let res = this.get('25519KeypreKey' + keyId); let res = this.get('25519KeypreKey' + keyId);
if (_.isUndefined(res)) { if (res) {
res = { res = {
'pubKey': res.pubKey, 'privKey': u.base64ToArrayBuffer(res.privKey),
'privKey': res.privKey 'pubKey': u.base64ToArrayBuffer(res.pubKey)
}; };
} }
...@@ -74630,7 +74659,11 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_ ...@@ -74630,7 +74659,11 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
}, },
storePreKey(keyId, keyPair) { storePreKey(keyId, keyPair) {
return Promise.resolve(this.save('25519KeypreKey' + keyId, keyPair)); this.save('25519KeypreKey' + keyId, {
'privKey': u.arrayBufferToBase64(keyPair.privKey),
'pubKey': u.arrayBufferToBase64(keyPair.pubKey)
});
return Promise.resolve();
}, },
removePreKey(keyId) { removePreKey(keyId) {
...@@ -74640,10 +74673,10 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_ ...@@ -74640,10 +74673,10 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
loadSignedPreKey(keyId) { loadSignedPreKey(keyId) {
let res = this.get('25519KeysignedKey' + keyId); let res = this.get('25519KeysignedKey' + keyId);
if (res !== undefined) { if (res) {
res = { res = {
'pubKey': res.pubKey, 'privKey': u.base64ToArrayBuffer(res.privKey),
'privKey': res.privKey 'pubKey': u.base64ToArrayBuffer(res.pubKey)
}; };
} }
...@@ -74651,7 +74684,11 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_ ...@@ -74651,7 +74684,11 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
}, },
storeSignedPreKey(keyId, keyPair) { storeSignedPreKey(keyId, keyPair) {
return Promise.resolve(this.save('25519KeysignedKey' + keyId, keyPair)); this.save('25519KeysignedKey' + keyId, {
'privKey': u.arrayBufferToBase64(keyPair.privKey),
'pubKey': u.arrayBufferToBase64(keyPair.pubKey)
});
return Promise.resolve();
}, },
removeSignedPreKey(keyId) { removeSignedPreKey(keyId) {
...@@ -74698,18 +74735,39 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_ ...@@ -74698,18 +74735,39 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
'device_id': generateDeviceID() 'device_id': generateDeviceID()
}; };
return libsignal.KeyHelper.generateIdentityKeyPair().then(identity_keypair => { return libsignal.KeyHelper.generateIdentityKeyPair().then(identity_keypair => {
data['identity_keypair'] = identity_keypair; const identity_key = u.arrayBufferToBase64(identity_keypair.pubKey);
data['identity_key'] = u.arrayBufferToBase64(identity_keypair.pubKey); data['identity_keypair'] = {
'privKey': u.arrayBufferToBase64(identity_keypair.privKey),
'pubKey': identity_key
};
data['identity_key'] = identity_key;
return libsignal.KeyHelper.generateSignedPreKey(identity_keypair, 1); return libsignal.KeyHelper.generateSignedPreKey(identity_keypair, 1);
}).then(signed_prekey => { }).then(signed_prekey => {
_converse.omemo_store.storeSignedPreKey(signed_prekey.keyId, signed_prekey.keyPair); _converse.omemo_store.storeSignedPreKey(signed_prekey.keyId, signed_prekey.keyPair);
data['signed_prekey'] = signed_prekey; data['signed_prekey'] = {
'keyId': signed_prekey.keyId,
'keyPair': {
'privKey': u.arrayBufferToBase64(signed_prekey.keyPair.privKey),
'pubKey': u.arrayBufferToBase64(signed_prekey.keyPair.pubKey)
},
'signature': u.arrayBufferToBase64(signed_prekey.signature)
};
return Promise.all(_.map(_.range(0, _converse.NUM_PREKEYS), id => libsignal.KeyHelper.generatePreKey(id))); return Promise.all(_.map(_.range(0, _converse.NUM_PREKEYS), id => libsignal.KeyHelper.generatePreKey(id)));
}).then(keys => { }).then(keys => {
_.forEach(keys, k => _converse.omemo_store.storePreKey(k.keyId, k.keyPair)); _.forEach(keys, k => _converse.omemo_store.storePreKey(k.keyId, k.keyPair));
data['prekeys'] = keys; const marshalled_keys = _.map(keys, k => {
return {
'keyId': k.keyId,
'keyPair': {
'pubKey': u.arrayBufferToBase64(k.keyPair.pubKey),
'privKey': u.arrayBufferToBase64(k.keyPair.privKey)
}
};
});
data['prekeys'] = marshalled_keys;
this.save(data); // Save the bundle to the device this.save(data); // Save the bundle to the device
const devicelist = _converse.devicelists.get(_converse.bare_jid), const devicelist = _converse.devicelists.get(_converse.bare_jid),
...@@ -74746,7 +74804,6 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_ ...@@ -74746,7 +74804,6 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
}); });
_converse.Device = Backbone.Model.extend({ _converse.Device = Backbone.Model.extend({
defaults: { defaults: {
'active': true,
'trusted': UNDECIDED 'trusted': UNDECIDED
}, },
...@@ -74832,10 +74889,7 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_ ...@@ -74832,10 +74889,7 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
'id': device_id 'id': device_id
}); });
if (!_.includes(device_ids, device_id) || !own_device.get('active')) { if (!_.includes(device_ids, device_id)) {
own_device.save('active', true, {
'silent': true
});
return this.publishDevices(); return this.publishDevices();
} }
}); });
...@@ -74874,15 +74928,9 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_ ...@@ -74874,15 +74928,9 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
}).c('item').c('list', { }).c('item').c('list', {
'xmlns': Strophe.NS.OMEMO 'xmlns': Strophe.NS.OMEMO
}); });
this.devices.each(device => stanza.c('device', {
_.each(this.devices.where({ 'id': device.get('id')
'active': true }).up());
}), device => {
stanza.c('device', {
'id': device.get('id')
}).up();
});
return _converse.api.sendIQ(stanza); return _converse.api.sendIQ(stanza);
}, },
...@@ -74915,13 +74963,11 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_ ...@@ -74915,13 +74963,11 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
'xmlns': Strophe.NS.OMEMO 'xmlns': Strophe.NS.OMEMO
}).c('signedPreKeyPublic', { }).c('signedPreKeyPublic', {
'signedPreKeyId': signed_prekey.keyId 'signedPreKeyId': signed_prekey.keyId
}).t(u.arrayBufferToBase64(signed_prekey.keyPair.pubKey)).up().c('signedPreKeySignature').t(u.arrayBufferToBase64(signed_prekey.signature)).up().c('identityKey').t(u.arrayBufferToBase64(store.get('identity_keypair').pubKey)).up().c('prekeys'); }).t(signed_prekey.keyPair.pubKey).up().c('signedPreKeySignature').t(signed_prekey.signature).up().c('identityKey').t(store.get('identity_keypair').pubKey).up().c('prekeys');
_.forEach(store.get('prekeys').slice(0, _converse.NUM_PREKEYS), prekey => { _.forEach(store.get('prekeys').slice(0, _converse.NUM_PREKEYS), prekey => stanza.c('preKeyPublic', {
stanza.c('preKeyPublic', { 'preKeyId': prekey.keyId
'preKeyId': prekey.keyId }).t(prekey.keyPair.pubKey).up());
}).t(u.arrayBufferToBase64(prekey.keyPair.pubKey)).up();
});
return _converse.api.sendIQ(stanza); return _converse.api.sendIQ(stanza);
} }
...@@ -74987,16 +75033,17 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_ ...@@ -74987,16 +75033,17 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
devices = devicelist.devices, devices = devicelist.devices,
removed_ids = _.difference(devices.pluck('id'), device_ids); removed_ids = _.difference(devices.pluck('id'), device_ids);
_.forEach(removed_ids, removed_id => devices.get(removed_id).save('active', false)); _.forEach(removed_ids, id => {
if (jid === _converse.bare_jid && id === _converse.omemo_store.get('device_id')) {
// We don't remove the current device
return;
}
devices.get(id).destroy();
});
_.forEach(device_ids, device_id => { _.forEach(device_ids, device_id => {
const dev = devices.get(device_id); if (!devices.get(device_id)) {
if (dev) {
dev.save({
'active': true
});
} else {
devices.create({ devices.create({
'id': device_id, 'id': device_id,
'jid': jid 'jid': jid
...@@ -428,11 +428,7 @@ ...@@ -428,11 +428,7 @@
this.toggleview = new _converse.MinimizedChatsToggleView({ this.toggleview = new _converse.MinimizedChatsToggleView({
'model': new _converse.MinimizedChatsToggle({'id': id}) 'model': new _converse.MinimizedChatsToggle({'id': id})
}); });
try { this.toggleview.model.browserStorage = new Backbone.BrowserStorage[storage](id);
this.toggleview.model.browserStorage = new Backbone.BrowserStorage[storage](id);
} catch (e) {
debugger;
}
this.toggleview.model.fetch(); this.toggleview.model.fetch();
}, },
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment