Merge pull request #613 from BeaudanBrown/bugfixes

[multi-device] Bugfixes and throttle pairing check
pull/622/head
Beaudan Campbell-Brown 6 years ago committed by GitHub
commit 5a630118ed
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1235,15 +1235,19 @@
if (activeAt !== null) {
activeAt = activeAt || Date.now();
}
const ourAuthorisations = await libloki.storage.getPrimaryDeviceMapping(
window.storage.get('primaryDevicePubKey')
const ourPrimaryKey = window.storage.get('primaryDevicePubKey');
const ourDevices = await libloki.storage.getAllDevicePubKeysForPrimaryPubKey(
ourPrimaryKey
);
const isSecondaryDevice =
ourAuthorisations &&
ourAuthorisations.some(auth => auth.secondaryDevicePubKey === id);
if (isSecondaryDevice) {
await conversation.setSecondaryStatus(true);
// TODO: We should probably just *not* send any secondary devices and
// just load them all and send FRs when we get the mapping
const isOurSecondaryDevice =
id !== ourPrimaryKey &&
ourDevices &&
ourDevices.some(devicePubKey => devicePubKey === id);
if (isOurSecondaryDevice) {
await conversation.setSecondaryStatus(true, ourPrimaryKey);
}
if (conversation.isFriendRequestStatusNone()) {

@ -766,9 +766,15 @@
isSecondaryDevice() {
return !!this.get('secondaryStatus');
},
async setSecondaryStatus(newStatus) {
getPrimaryDevicePubKey() {
return this.get('primaryDevicePubKey') || this.id;
},
async setSecondaryStatus(newStatus, primaryDevicePubKey) {
if (this.get('secondaryStatus') !== newStatus) {
this.set({ secondaryStatus: newStatus });
this.set({
secondaryStatus: newStatus,
primaryDevicePubKey,
});
await window.Signal.Data.updateConversation(this.id, this.attributes, {
Conversation: Whisper.Conversation,
});
@ -804,7 +810,17 @@
if (!response) {
return;
}
const pending = await this.getFriendRequests(direction, status);
const primaryConversation = ConversationController.get(
this.getPrimaryDevicePubKey()
);
// Should never happen
if (!primaryConversation) {
return;
}
const pending = await primaryConversation.getFriendRequests(
direction,
status
);
await Promise.all(
pending.map(async request => {
if (request.hasErrors()) {
@ -815,7 +831,7 @@
await window.Signal.Data.saveMessage(request.attributes, {
Message: Whisper.Message,
});
this.trigger('updateMessage', request);
primaryConversation.trigger('updateMessage', request);
})
);
},

@ -367,8 +367,6 @@
await window.Signal.Data.saveMessage(this.attributes, {
Message: Whisper.Message,
});
const pubKey = this.get('conversationId');
await libloki.storage.saveAllPairingAuthorisationsFor(pubKey);
conversation.onAcceptFriendRequest();
},
async declineFriendRequest() {

@ -213,7 +213,7 @@
Whisper.events.off('devicePairingRequestReceived');
});
dialog.once('devicePairingRequestAccepted', (pubKey, cb) =>
dialog.on('devicePairingRequestAccepted', (pubKey, cb) =>
Whisper.events.trigger('devicePairingRequestAccepted', pubKey, cb)
);
dialog.on('devicePairingRequestRejected', pubKey =>

@ -92,7 +92,7 @@
if (!errors) {
this.$('.transmissionStatus').text(i18n('provideDeviceAlias'));
this.$('#deviceAliasView').show();
this.$('#deviceAlias').on('keydown', e => {
this.$('#deviceAlias').on('input', e => {
if (e.target.value.trim()) {
this.$('.requestAcceptedView .ok').removeAttr('disabled');
} else {

@ -114,7 +114,7 @@
buffers.forEach(buffer => {
// bytebuffer container expands and increments
// offset automatically
result.writeVarint32(buffer.limit);
result.writeInt32(buffer.limit);
result.append(buffer);
});
result.limit = result.offset;

@ -5,6 +5,9 @@
(function() {
window.libloki = window.libloki || {};
const timers = {};
const REFRESH_DELAY = 60 * 1000;
async function getPreKeyBundleForContact(pubKey) {
const myKeyPair = await textsecure.storage.protocol.getIdentityKeyPair();
const identityKey = myKeyPair.pubKey;
@ -149,6 +152,12 @@
// if the device is a secondary device,
// fetch the device mappings for its primary device
async function saveAllPairingAuthorisationsFor(pubKey) {
// Will be false if there is no timer
const cacheValid = timers[pubKey] > Date.now();
if (cacheValid) {
return;
}
timers[pubKey] = Date.now() + REFRESH_DELAY;
const authorisations = await getPrimaryDeviceMapping(pubKey);
await Promise.all(
authorisations.map(authorisation =>
@ -163,7 +172,10 @@
authorisation.secondaryDevicePubKey,
'private'
);
await conversation.setSecondaryStatus(true);
await conversation.setSecondaryStatus(
true,
authorisation.primaryDevicePubKey
);
await window.Signal.Data.createOrUpdatePairingAuthorisation(authorisation);
}
@ -199,6 +211,7 @@
// Transforms signatures from base64 to ArrayBuffer!
async function getAuthorisationForSecondaryPubKey(secondaryPubKey) {
await saveAllPairingAuthorisationsFor(secondaryPubKey);
const authorisation = await window.Signal.Data.getAuthorisationForSecondaryPubKey(
secondaryPubKey
);

@ -596,7 +596,7 @@
// throws if invalid
this.validatePubKeyHex(secondaryDevicePubKey);
// we need a conversation for sending a message
await ConversationController.getOrCreateAndWait(
const secondaryConversation = await ConversationController.getOrCreateAndWait(
secondaryDevicePubKey,
'private'
);
@ -626,6 +626,13 @@
authorisation,
secondaryDevicePubKey
);
// Always be friends with secondary devices
await secondaryConversation.setFriendRequestStatus(
window.friends.friendRequestStatusEnum.friends,
{
blockSync: true,
}
);
},
validatePubKeyHex(pubKey) {
const c = new Whisper.Conversation({

@ -14,7 +14,7 @@ ProtoParser.prototype = {
if (this.buffer.limit === this.buffer.offset) {
return undefined; // eof
}
const len = this.buffer.readVarint32();
const len = this.buffer.readInt32();
const nextBuffer = this.buffer
.slice(this.buffer.offset, this.buffer.offset + len)
.toArrayBuffer();

@ -1104,13 +1104,13 @@ MessageReceiver.prototype.extend({
window.log.info(
`Received pairing authorisation from ${primaryDevicePubKey}`
);
await libloki.storage.savePairingAuthorisation(pairingAuthorisation);
// Set current device as secondary.
// This will ensure the authorisation is sent
// along with each friend request.
window.storage.remove('secondaryDeviceStatus');
window.storage.put('isSecondaryDevice', true);
window.storage.put('primaryDevicePubKey', primaryDevicePubKey);
await libloki.storage.savePairingAuthorisation(pairingAuthorisation);
const primaryConversation = await ConversationController.getOrCreateAndWait(
primaryDevicePubKey,
'private'
@ -1464,16 +1464,11 @@ MessageReceiver.prototype.extend({
async handleSyncMessage(envelope, syncMessage) {
const ourNumber = textsecure.storage.user.getNumber();
// NOTE: Maybe we should be caching this list?
const ourAuthorisations = await libloki.storage.getPrimaryDeviceMapping(
ourNumber
const ourDevices = await libloki.storage.getAllDevicePubKeysForPrimaryPubKey(
window.storage.get('primaryDevicePubKey')
);
const validSyncSender =
ourAuthorisations &&
ourAuthorisations.some(
auth =>
auth.secondaryDevicePubKey === ourNumber ||
auth.primaryDevicePubKey === ourNumber
);
ourDevices && ourDevices.some(devicePubKey => devicePubKey === ourNumber);
if (!validSyncSender) {
throw new Error(
"Received sync message from a device we aren't paired with"

@ -18,7 +18,7 @@ describe('ContactBuffer', () => {
const contactInfoBuffer = contactInfo.encode().toArrayBuffer();
for (let i = 0; i < 3; i += 1) {
buffer.writeVarint32(contactInfoBuffer.byteLength);
buffer.writeInt32(contactInfoBuffer.byteLength);
buffer.append(contactInfoBuffer);
buffer.append(avatarBuffer.clone());
}
@ -69,7 +69,7 @@ describe('GroupBuffer', () => {
const groupInfoBuffer = groupInfo.encode().toArrayBuffer();
for (let i = 0; i < 3; i += 1) {
buffer.writeVarint32(groupInfoBuffer.byteLength);
buffer.writeInt32(groupInfoBuffer.byteLength);
buffer.append(groupInfoBuffer);
buffer.append(avatarBuffer.clone());
}

Loading…
Cancel
Save