@ -934,11 +934,17 @@ MessageReceiver.prototype.extend({
return this . innerHandleContentMessage ( envelope , plaintext ) ;
return this . innerHandleContentMessage ( envelope , plaintext ) ;
} ) ;
} ) ;
} ,
} ,
promptUserToAcceptFriendRequest ( pubK ey , message , preKeyBundl e) {
promptUserToAcceptFriendRequest ( envelo pe, message , preKeyBundl eMessag e) {
window . Whisper . events . trigger ( 'showFriendRequest' , {
window . Whisper . events . trigger ( 'showFriendRequest' , {
pubKey ,
pubKey : envelope . source ,
message ,
message ,
preKeyBundle ,
preKeyBundle : this . decodePreKeyBundleMessage ( preKeyBundleMessage ) ,
options : {
source : envelope . source ,
sourceDevice : envelope . sourceDevice ,
timestamp : envelope . timestamp . toNumber ( ) ,
receivedAt : envelope . receivedAt ,
} ,
} ) ;
} ) ;
} ,
} ,
// A handler function for when a friend request is accepted or declined
// A handler function for when a friend request is accepted or declined
@ -973,52 +979,49 @@ MessageReceiver.prototype.extend({
const content = textsecure . protobuf . Content . decode ( plaintext ) ;
const content = textsecure . protobuf . Content . decode ( plaintext ) ;
if ( envelope . type === textsecure . protobuf . Envelope . Type . FRIEND _REQUEST ) {
if ( envelope . type === textsecure . protobuf . Envelope . Type . FRIEND _REQUEST ) {
// only prompt friend request if there is no conversation yet
let conversation ;
let conversation ;
try {
try {
conversation = ConversationController . get ( envelope . source ) ;
conversation = ConversationController . get ( envelope . source ) ;
} catch ( e ) { }
} catch ( e ) { }
// only prompt friend request if there is no conversation yet
if ( ! conversation ) {
if ( ! conversation ) {
this . promptUserToAcceptFriendRequest (
this . promptUserToAcceptFriendRequest (
envelope .source ,
envelope ,
content . dataMessage . body ,
content . dataMessage . body ,
content . preKeyBundle ,
content . preKeyBundle Message ,
) ;
) ;
return ;
} else {
}
const keyExchangeComplete = conversation . isKeyExchangeCompleted ( ) ;
}
// Check here if we received preKeys from the other user
// Check if our friend request got accepted
// We are certain that other user accepted the friend request IF:
if ( content . preKeyBundle ) {
// - The message has a preKeyBundleMessage
// By default we don't want to save the preKey
// - We have an outgoing friend request that is pending
let savePreKey = false ;
// The second check is crucial because it makes sure we don't save the preKeys of the incoming friend request (which is saved only when we press accept)
if ( ! keyExchangeComplete && content . preKeyBundleMessage ) {
// The conversation
// Check for any outgoing friend requests
let conversation = null ;
const pending = await conversation . getPendingFriendRequests ( 'outgoing' ) ;
const successful = pending . filter ( p => ! p . hasErrors ( ) ) ;
try {
conversation = ConversationController . get ( envelope . source ) ;
// Save the key only if we have an outgoing friend request
const savePreKey = ( successful . length > 0 ) ;
// We only want to save the preKey if we have a outgoing friend request which is pending
const pending = await conversation . getPendingFriendRequests ( 'outgoing' ) ;
// Save the pre key
const successful = pending . filter ( p => ! p . hasErrors ( ) ) ;
if ( savePreKey ) {
await this . handlePreKeyBundleMessage (
// Save the key only if we have an outgoing friend request
envelope . source ,
savePreKey = ( successful . length > 0 ) ;
this . decodePreKeyBundleMessage ( content . preKeyBundleMessage ) ,
} catch ( e ) { }
) ;
// Save the pre key if we have a conversation
if ( savePreKey && conversation ) {
await this . handlePreKeyBundleMessage (
envelope . source ,
content . preKeyBundle
) ;
// Update the conversation
await conversation . onFriendRequestAccepted ( ) ;
return ;
// Update the conversation
await conversation . onFriendRequestAccepted ( ) ;
}
}
}
}
// Exit early since the friend request reply will be a regular empty message
return ;
}
}
if ( content . syncMessage ) {
if ( content . syncMessage ) {
@ -1235,8 +1238,7 @@ MessageReceiver.prototype.extend({
return this . removeFromCache ( envelope ) ;
return this . removeFromCache ( envelope ) ;
} ,
} ,
async handlePreKeyBundleMessage ( pubKey , preKeyBundleMessage ) {
decodePreKeyBundleMessage ( preKeyBundleMessage ) {
const { preKeyId , signedKeyId } = preKeyBundleMessage ;
const [ identityKey , preKey , signedKey , signature ] = [
const [ identityKey , preKey , signedKey , signature ] = [
preKeyBundleMessage . identityKey ,
preKeyBundleMessage . identityKey ,
preKeyBundleMessage . preKey ,
preKeyBundleMessage . preKey ,
@ -1244,6 +1246,24 @@ MessageReceiver.prototype.extend({
preKeyBundleMessage . signature ,
preKeyBundleMessage . signature ,
] . map ( k => dcodeIO . ByteBuffer . wrap ( k ) . toArrayBuffer ( ) ) ;
] . map ( k => dcodeIO . ByteBuffer . wrap ( k ) . toArrayBuffer ( ) ) ;
return {
... preKeyBundleMessage ,
identityKey ,
preKey ,
signedKey ,
signature ,
} ;
} ,
async handlePreKeyBundleMessage ( pubKey , preKeyBundleMessage ) {
const {
preKeyId ,
signedKeyId ,
identityKey ,
preKey ,
signedKey ,
signature ,
} = preKeyBundleMessage ;
if ( pubKey != StringView . arrayBufferToHex ( identityKey ) ) {
if ( pubKey != StringView . arrayBufferToHex ( identityKey ) ) {
throw new Error (
throw new Error (
'Error in handlePreKeyBundleMessage: envelope pubkey does not match pubkey in prekey bundle'
'Error in handlePreKeyBundleMessage: envelope pubkey does not match pubkey in prekey bundle'