Merge pull request #54 from Mikunj/fix/prekey-saving

Updated pre key saving logic.
pull/55/head
sachaaaaa 6 years ago committed by GitHub
commit 7aa80b6ca6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -49,7 +49,7 @@ module.exports = {
getContactPreKeys, getContactPreKeys,
getAllContactPreKeys, getAllContactPreKeys,
bulkAddContactPreKeys, bulkAddContactPreKeys,
removeContactPreKeyById, removeContactPreKeyByIdentityKey,
removeAllContactPreKeys, removeAllContactPreKeys,
createOrUpdateContactSignedPreKey, createOrUpdateContactSignedPreKey,
@ -57,7 +57,7 @@ module.exports = {
getContactSignedPreKeyByIdentityKey, getContactSignedPreKeyByIdentityKey,
getContactSignedPreKeys, getContactSignedPreKeys,
bulkAddContactSignedPreKeys, bulkAddContactSignedPreKeys,
removeContactSignedPreKeyById, removeContactSignedPreKeyByIdentityKey,
removeAllContactSignedPreKeys, removeAllContactSignedPreKeys,
createOrUpdateItem, createOrUpdateItem,
@ -712,8 +712,10 @@ async function getContactPreKeys(keyId, identityKeyString) {
async function bulkAddContactPreKeys(array) { async function bulkAddContactPreKeys(array) {
return bulkAdd(CONTACT_PRE_KEYS_TABLE, array); return bulkAdd(CONTACT_PRE_KEYS_TABLE, array);
} }
async function removeContactPreKeyById(id) { async function removeContactPreKeyByIdentityKey(key) {
return removeById(CONTACT_PRE_KEYS_TABLE, id); await db.run(`DELETE FROM ${CONTACT_PRE_KEYS_TABLE} WHERE identityKeyString = $identityKeyString;`, {
$identityKeyString: key,
});
} }
async function removeAllContactPreKeys() { async function removeAllContactPreKeys() {
return removeAllFromTable(CONTACT_PRE_KEYS_TABLE); return removeAllFromTable(CONTACT_PRE_KEYS_TABLE);
@ -765,8 +767,10 @@ async function getContactSignedPreKeys(keyId, identityKeyString) {
async function bulkAddContactSignedPreKeys(array) { async function bulkAddContactSignedPreKeys(array) {
return bulkAdd(CONTACT_SIGNED_PRE_KEYS_TABLE, array); return bulkAdd(CONTACT_SIGNED_PRE_KEYS_TABLE, array);
} }
async function removeContactSignedPreKeyById(id) { async function removeContactSignedPreKeyByIdentityKey(key) {
return removeById(CONTACT_SIGNED_PRE_KEYS_TABLE, id); await db.run(`DELETE FROM ${CONTACT_SIGNED_PRE_KEYS_TABLE} WHERE identityKeyString = $identityKeyString;`, {
$identityKeyString: key,
});
} }
async function removeAllContactSignedPreKeys() { async function removeAllContactSignedPreKeys() {
return removeAllFromTable(CONTACT_SIGNED_PRE_KEYS_TABLE); return removeAllFromTable(CONTACT_SIGNED_PRE_KEYS_TABLE);

@ -1268,7 +1268,6 @@
unidentifiedDeliveryReceived: data.unidentifiedDeliveryReceived, unidentifiedDeliveryReceived: data.unidentifiedDeliveryReceived,
type: 'incoming', type: 'incoming',
unread: 1, unread: 1,
preKeyBundle: data.preKeyBundle || null,
}; };
if (data.type === 'friend-request') { if (data.type === 'friend-request') {

@ -80,7 +80,7 @@ module.exports = {
getContactPreKeys, getContactPreKeys,
getAllContactPreKeys, getAllContactPreKeys,
bulkAddContactPreKeys, bulkAddContactPreKeys,
removeContactPreKeyById, removeContactPreKeyByIdentityKey,
removeAllContactPreKeys, removeAllContactPreKeys,
createOrUpdateContactSignedPreKey, createOrUpdateContactSignedPreKey,
@ -88,7 +88,7 @@ module.exports = {
getContactSignedPreKeyByIdentityKey, getContactSignedPreKeyByIdentityKey,
getContactSignedPreKeys, getContactSignedPreKeys,
bulkAddContactSignedPreKeys, bulkAddContactSignedPreKeys,
removeContactSignedPreKeyById, removeContactSignedPreKeyByIdentityKey,
removeAllContactSignedPreKeys, removeAllContactSignedPreKeys,
createOrUpdateItem, createOrUpdateItem,
@ -528,8 +528,8 @@ async function bulkAddContactPreKeys(array) {
const updated = map(array, data => keysFromArrayBuffer(PRE_KEY_KEYS, data)); const updated = map(array, data => keysFromArrayBuffer(PRE_KEY_KEYS, data));
await channels.bulkAddContactPreKeys(updated); await channels.bulkAddContactPreKeys(updated);
} }
async function removeContactPreKeyById(id) { async function removeContactPreKeyByIdentityKey(id) {
await channels.removePreContactKeyById(id); await channels.removeContactPreKeyByIdentityKey(id);
} }
async function removeAllContactPreKeys() { async function removeAllContactPreKeys() {
await channels.removeAllContactPreKeys(); await channels.removeAllContactPreKeys();
@ -556,8 +556,8 @@ async function bulkAddContactSignedPreKeys(array) {
const updated = map(array, data => keysFromArrayBuffer(PRE_KEY_KEYS, data)); const updated = map(array, data => keysFromArrayBuffer(PRE_KEY_KEYS, data));
await channels.bulkAddContactSignedPreKeys(updated); await channels.bulkAddContactSignedPreKeys(updated);
} }
async function removeContactSignedPreKeyById(id) { async function removeContactSignedPreKeyByIdentityKey(id) {
await channels.removePreContactSignedKeyById(id); await channels.removeContactSignedPreKeyByIdentityKey(id);
} }
async function removeAllContactSignedPreKeys() { async function removeAllContactSignedPreKeys() {
await channels.removeAllContactSignedPreKeys(); await channels.removeAllContactSignedPreKeys();
@ -727,7 +727,6 @@ async function searchConversations(query, { ConversationCollection }) {
} }
// Message // Message
const MESSAGE_PRE_KEYS = ['identityKey', 'preKey', 'signature', 'signedKey'].map(k => `preKeyBundle.${k}`);
async function getMessageCount() { async function getMessageCount() {
return channels.getMessageCount(); return channels.getMessageCount();
} }
@ -745,8 +744,7 @@ async function saveSeenMessageHash(data) {
} }
async function saveMessage(data, { forceSave, Message } = {}) { async function saveMessage(data, { forceSave, Message } = {}) {
const updated = keysFromArrayBuffer(MESSAGE_PRE_KEYS, data); const id = await channels.saveMessage(_cleanData(data), { forceSave });
const id = await channels.saveMessage(_cleanData(updated), { forceSave });
Message.refreshExpirationTimer(); Message.refreshExpirationTimer();
return id; return id;
} }
@ -789,8 +787,7 @@ async function saveLegacyMessage(data) {
} }
async function saveMessages(arrayOfMessages, { forceSave } = {}) { async function saveMessages(arrayOfMessages, { forceSave } = {}) {
const updated = arrayOfMessages.map(m => keysFromArrayBuffer(MESSAGE_PRE_KEYS, m)); await channels.saveMessages(_cleanData(arrayOfMessages), { forceSave });
await channels.saveMessages(_cleanData(updated), { forceSave });
} }
async function removeMessage(id, { Message }) { async function removeMessage(id, { Message }) {
@ -815,22 +812,18 @@ async function getMessageById(id, { Message }) {
return null; return null;
} }
const encoded = keysToArrayBuffer(MESSAGE_PRE_KEYS, message); return new Message(message);
return new Message(encoded);
} }
// For testing only // For testing only
async function getAllMessages({ MessageCollection }) { async function getAllMessages({ MessageCollection }) {
const messages = await channels.getAllMessages(); const messages = await channels.getAllMessages();
const encoded = messages.map(m => keysToArrayBuffer(MESSAGE_PRE_KEYS, m)); return new MessageCollection(messages);
return new MessageCollection(encoded);
} }
async function getAllUnsentMessages({ MessageCollection }) { async function getAllUnsentMessages({ MessageCollection }) {
const messages = await channels.getAllUnsentMessages(); const messages = await channels.getAllUnsentMessages();
const encoded = messages.map(m => keysToArrayBuffer(MESSAGE_PRE_KEYS, m)); return new MessageCollection(messages);
return new MessageCollection(encoded);
} }
async function getAllMessageIds() { async function getAllMessageIds() {
@ -852,9 +845,7 @@ async function getMessageBySender(
return null; return null;
} }
const encoded = keysToArrayBuffer(MESSAGE_PRE_KEYS, messages[0]); return new Message(messages[0]);
return new Message(encoded);
} }
async function getUnreadByConversation(conversationId, { MessageCollection }) { async function getUnreadByConversation(conversationId, { MessageCollection }) {
@ -872,9 +863,7 @@ async function getMessagesByConversation(
type, type,
}); });
const encoded = messages.map(m => keysToArrayBuffer(MESSAGE_PRE_KEYS, m)); return new MessageCollection(messages);
return new MessageCollection(encoded);
} }
async function getSeenMessagesByHashList( async function getSeenMessagesByHashList(
@ -916,26 +905,22 @@ async function removeAllMessagesInConversation(
async function getMessagesBySentAt(sentAt, { MessageCollection }) { async function getMessagesBySentAt(sentAt, { MessageCollection }) {
const messages = await channels.getMessagesBySentAt(sentAt); const messages = await channels.getMessagesBySentAt(sentAt);
const encoded = messages.map(m => keysToArrayBuffer(MESSAGE_PRE_KEYS, m)); return new MessageCollection(messages);
return new MessageCollection(encoded);
} }
async function getExpiredMessages({ MessageCollection }) { async function getExpiredMessages({ MessageCollection }) {
const messages = await channels.getExpiredMessages(); const messages = await channels.getExpiredMessages();
const encoded = messages.map(m => keysToArrayBuffer(MESSAGE_PRE_KEYS, m)); return new MessageCollection(messages);
return new MessageCollection(encoded);
} }
async function getOutgoingWithoutExpiresAt({ MessageCollection }) { async function getOutgoingWithoutExpiresAt({ MessageCollection }) {
const messages = await channels.getOutgoingWithoutExpiresAt(); const messages = await channels.getOutgoingWithoutExpiresAt();
const encoded = messages.map(m => keysToArrayBuffer(MESSAGE_PRE_KEYS, m)); return new MessageCollection(messages);
return new MessageCollection(encoded);
} }
async function getNextExpiringMessage({ MessageCollection }) { async function getNextExpiringMessage({ MessageCollection }) {
const messages = await channels.getNextExpiringMessage(); const messages = await channels.getNextExpiringMessage();
const encoded = messages.map(m => keysToArrayBuffer(MESSAGE_PRE_KEYS, m)); return new MessageCollection(messages);
return new MessageCollection(encoded);
} }
// Unprocessed // Unprocessed

@ -162,7 +162,7 @@
}, },
async getLocalRegistrationId() { async getLocalRegistrationId() {
return 1; return 1;
// const item = await window.Signal.Data.getItemById('registrationId'); // const item = await window.Signal.Data.getItemById('registrationId');
// if (item) { // if (item) {
// return item.value; // return item.value;
@ -197,6 +197,8 @@
recipient: key.recipient, recipient: key.recipient,
}; };
} }
return undefined;
}, },
async loadContactPreKey(pubKey) { async loadContactPreKey(pubKey) {
const preKey = await window.Signal.Data.getContactPreKeyByIdentityKey(pubKey); const preKey = await window.Signal.Data.getContactPreKeyByIdentityKey(pubKey);
@ -266,6 +268,13 @@
await window.Signal.Data.removeAllPreKeys(); await window.Signal.Data.removeAllPreKeys();
}, },
async removeContactPreKey(pubKey) {
await window.Signal.Data.removeContactPreKeyByIdentityKey(pubKey);
},
async clearContactPreKeysStore() {
await window.Signal.Data.removeAllContactPreKeys();
},
/* Returns a signed keypair object or undefined */ /* Returns a signed keypair object or undefined */
async loadSignedPreKey(keyId) { async loadSignedPreKey(keyId) {
const key = await window.Signal.Data.getSignedPreKeyById(keyId); const key = await window.Signal.Data.getSignedPreKeyById(keyId);
@ -366,6 +375,13 @@
await window.Signal.Data.removeAllSignedPreKeys(); await window.Signal.Data.removeAllSignedPreKeys();
}, },
async removeContactSignedPreKey(pubKey) {
await window.Signal.Data.removeContactSignedPreKeyByIdentityKey(pubKey);
},
async clearContactSignedPreKeysStore() {
await window.Signal.Data.removeAllContactSignedPreKeys();
},
async loadSession(encodedNumber) { async loadSession(encodedNumber) {
if (encodedNumber === null || encodedNumber === undefined) { if (encodedNumber === null || encodedNumber === undefined) {
throw new Error('Tried to get session for undefined/null number'); throw new Error('Tried to get session for undefined/null number');

@ -98,51 +98,37 @@
signedKey, signedKey,
signature, signature,
}) { }) {
const signedKeyPromise = new Promise(async resolve => { const signedPreKey = {
const existingSignedKeys = await textsecure.storage.protocol.loadContactSignedPreKeys( keyId: signedKeyId,
{ identityKeyString: pubKey, keyId: signedKeyId } publicKey: signedKey,
); signature,
if ( };
!existingSignedKeys ||
(existingSignedKeys instanceof Array && existingSignedKeys.length === 0)
) {
const signedPreKey = {
keyId: signedKeyId,
publicKey: signedKey,
signature,
};
await textsecure.storage.protocol.storeContactSignedPreKey(
pubKey,
signedPreKey
);
}
resolve();
});
const preKeyPromise = new Promise(async resolve => { const signedKeyPromise = textsecure.storage.protocol.storeContactSignedPreKey(
const existingPreKeys = await textsecure.storage.protocol.loadContactPreKeys({ pubKey,
identityKeyString: pubKey, signedPreKey
keyId: preKeyId, );
});
if ( const preKeyObject = {
!existingPreKeys || publicKey: preKey,
(existingPreKeys instanceof Array && existingPreKeys.length === 0) keyId: preKeyId,
) { };
const preKeyObject = {
publicKey: preKey, const preKeyPromise = textsecure.storage.protocol.storeContactPreKey(
keyId: preKeyId, pubKey,
}; preKeyObject
await textsecure.storage.protocol.storeContactPreKey( );
pubKey,
preKeyObject
);
}
resolve();
});
await Promise.all([signedKeyPromise, preKeyPromise]); await Promise.all([signedKeyPromise, preKeyPromise]);
} }
async function removePreKeyBundleForNumber(pubKey) {
await Promise.all([
textsecure.storage.protocol.removeContactPreKey(pubKey),
textsecure.storage.protocol.removeContactSignedPreKey(pubKey),
]);
}
async function sendFriendRequestAccepted(pubKey) { async function sendFriendRequestAccepted(pubKey) {
// empty content message // empty content message
const content = new textsecure.protobuf.Content(); const content = new textsecure.protobuf.Content();
@ -175,5 +161,6 @@
window.libloki.getPreKeyBundleForNumber = getPreKeyBundleForNumber; window.libloki.getPreKeyBundleForNumber = getPreKeyBundleForNumber;
window.libloki.FallBackDecryptionError = FallBackDecryptionError; window.libloki.FallBackDecryptionError = FallBackDecryptionError;
window.libloki.savePreKeyBundleForNumber = savePreKeyBundleForNumber; window.libloki.savePreKeyBundleForNumber = savePreKeyBundleForNumber;
window.libloki.removePreKeyBundleForNumber = removePreKeyBundleForNumber;
window.libloki.sendFriendRequestAccepted = sendFriendRequestAccepted; window.libloki.sendFriendRequestAccepted = sendFriendRequestAccepted;
})(); })();

@ -328,7 +328,7 @@
textsecure.storage.remove('userAgent'), textsecure.storage.remove('userAgent'),
textsecure.storage.remove('read-receipts-setting'), textsecure.storage.remove('read-receipts-setting'),
]); ]);
// update our own identity key, which may have changed // update our own identity key, which may have changed
// if we're relinking after a reinstall on the master device // if we're relinking after a reinstall on the master device
await textsecure.storage.protocol.saveIdentityWithAttributes(pubKeyString, { await textsecure.storage.protocol.saveIdentityWithAttributes(pubKeyString, {
@ -362,7 +362,9 @@
window.log.info('clearing all sessions, prekeys, and signed prekeys'); window.log.info('clearing all sessions, prekeys, and signed prekeys');
return Promise.all([ return Promise.all([
store.clearPreKeyStore(), store.clearPreKeyStore(),
store.clearContactPreKeysStore(),
store.clearSignedPreKeysStore(), store.clearSignedPreKeysStore(),
store.clearContactSignedPreKeysStore(),
store.clearSessionStore(), store.clearSessionStore(),
]); ]);
}, },

@ -721,15 +721,11 @@ MessageReceiver.prototype.extend({
// eslint-disable-next-line no-param-reassign // eslint-disable-next-line no-param-reassign
envelope.preKeyBundleMessage = decodedBundle; envelope.preKeyBundleMessage = decodedBundle;
// Save the preKey bundle if this is not a friend request. // Save the preKeyBundle
// We don't automatically save on a friend request because await this.handlePreKeyBundleMessage(
// we only want to save the preKeys when we click the accept button. envelope.source,
if (envelope.type !== textsecure.protobuf.Envelope.Type.FRIEND_REQUEST) { envelope.preKeyBundleMessage
await this.handlePreKeyBundleMessage( );
envelope.source,
envelope.preKeyBundleMessage
);
}
} }
const me = { const me = {
@ -970,7 +966,6 @@ MessageReceiver.prototype.extend({
receivedAt: envelope.receivedAt, receivedAt: envelope.receivedAt,
unidentifiedDeliveryReceived: envelope.unidentifiedDeliveryReceived, unidentifiedDeliveryReceived: envelope.unidentifiedDeliveryReceived,
message, message,
preKeyBundle: envelope.preKeyBundleMessage || null,
}; };
return this.dispatchAndWait(ev); return this.dispatchAndWait(ev);
}) })
@ -1010,24 +1005,23 @@ MessageReceiver.prototype.extend({
await conversation.updateTextInputState(); await conversation.updateTextInputState();
} }
// If we accepted an incoming friend request then save the preKeyBundle // Check if we changed the state of the incoming friend request
if (message.direction === 'incoming' && message.friendStatus === 'accepted') { if (message.direction === 'incoming') {
// Register the preKeys used for communication // If we accepted an incoming friend request then update our state
if (message.preKeyBundle) { if (message.friendStatus === 'accepted') {
await this.handlePreKeyBundleMessage( // Accept the friend request
pubKey, if (conversation) {
message.preKeyBundle await conversation.onFriendRequestAccepted();
); }
}
// Accept the friend request // Send a reply back
if (conversation) { libloki.sendFriendRequestAccepted(pubKey);
await conversation.onFriendRequestAccepted(); } else if (message.friendStatus === 'declined') {
// Delete the preKeys
await libloki.removePreKeyBundleForNumber(pubKey);
} }
// Send a reply back
libloki.sendFriendRequestAccepted(pubKey);
} }
window.log.info(`Friend request for ${pubKey} was ${message.friendStatus}`, message); window.log.info(`Friend request for ${pubKey} was ${message.friendStatus}`, message);
}, },
async innerHandleContentMessage(envelope, plaintext) { async innerHandleContentMessage(envelope, plaintext) {

Loading…
Cancel
Save