@ -195,9 +195,19 @@ window.textsecure.protos = function() {
return self . PreKeyWhisperMessageProtobuf . decode ( btoa ( string ) ) ;
}
self . KeyExchangeMessageProtobuf = dcodeIO . ProtoBuf . loadProtoFile ( "protos/WhisperTextProtocol.proto" ) . build ( "textsecure.KeyExchangeMessage" ) ;
self . decodeKeyExchangeMessageProtobuf = function ( string ) {
return self . KeyExchangeMessageProtobuf . decode ( btoa ( string ) ) ;
self . DeviceInitProtobuf = dcodeIO . ProtoBuf . loadProtoFile ( "protos/DeviceMessages.proto" ) . build ( "textsecure.DeviceInit" ) ;
self . decodeDeviceInitProtobuf = function ( string ) {
return self . DeviceInitProtobuf . decode ( btoa ( string ) ) ;
}
self . IdentityKeyProtobuf = dcodeIO . ProtoBuf . loadProtoFile ( "protos/DeviceMessages.proto" ) . build ( "textsecure.IdentityKey" ) ;
self . decodeIdentityKeyProtobuf = function ( string ) {
return self . IdentityKeyProtobuf . decode ( btoa ( string ) ) ;
}
self . DeviceControlProtobuf = dcodeIO . ProtoBuf . loadProtoFile ( "protos/DeviceMessages.proto" ) . build ( "textsecure.DeviceControl" ) ;
self . decodeDeviceControlProtobuf = function ( string ) {
return self . DeviceControlProtobuf . decode ( btoa ( string ) ) ;
}
return self ;
@ -635,53 +645,10 @@ window.textsecure.replay = function() {
} ( ) ;
// message_callback({message: decryptedMessage, pushMessage: server-providedPushMessage})
window . textsecure . subscribeToPush = function ( ) {
var subscribeToPushMessageSemaphore = 0 ;
return function ( message _callback ) {
subscribeToPushMessageSemaphore ++ ;
if ( subscribeToPushMessageSemaphore <= 0 )
return ;
var socket = textsecure . api . getWebsocket ( ) ;
var pingInterval ;
//TODO: GUI
socket . onerror = function ( socketEvent ) {
console . log ( 'Server is down :(' ) ;
clearInterval ( pingInterval ) ;
subscribeToPushMessageSemaphore -- ;
setTimeout ( function ( ) { textsecure . subscribeToPush ( message _callback ) ; } , 60000 ) ;
} ;
socket . onclose = function ( socketEvent ) {
console . log ( 'Server closed :(' ) ;
clearInterval ( pingInterval ) ;
subscribeToPushMessageSemaphore -- ;
setTimeout ( function ( ) { textsecure . subscribeToPush ( message _callback ) ; } , 60000 ) ;
} ;
socket . onopen = function ( socketEvent ) {
console . log ( 'Connected to server!' ) ;
pingInterval = setInterval ( function ( ) {
console . log ( "Sending server ping message." ) ;
if ( socket . readyState == socket . CLOSED || socket . readyState == socket . CLOSING ) {
socket . close ( ) ;
socket . onclose ( ) ;
} else
socket . send ( JSON . stringify ( { type : 2 } ) ) ;
} , 30000 ) ;
} ;
socket . onmessage = function ( response ) {
try {
var message = JSON . parse ( response . data ) ;
} catch ( e ) {
console . log ( 'Error parsing server JSON message: ' + response . responseBody . split ( "|" ) [ 1 ] ) ;
return ;
}
window . textsecure . subscribeToPush = function ( message _callback ) {
var socket = textsecure . api . getMessageWebsocket ( ) ;
if ( message . type == 3 ) {
console . log ( "Got pong message" ) ;
} else if ( message . type === undefined && message . id !== undefined ) {
socket . onmessage = function ( message ) {
textsecure . crypto . decryptWebsocketMessage ( message . message ) . then ( function ( plaintext ) {
var proto = textsecure . protos . decodeIncomingPushMessageProtobuf ( getString ( plaintext ) ) ;
// After this point, a) decoding errors are not the server's fault, and
@ -776,13 +743,11 @@ window.textsecure.subscribeToPush = function() {
console . log ( "Error handling incoming message: " ) ;
console . log ( e ) ;
} ) ;
}
} ;
}
} ( ) ;
} ;
window . textsecure . register = function ( ) {
return function ( number , verificationCode , s ingleDevice, s tepDone) {
window . textsecure . register SingleDevice = function ( ) {
return function ( number , verificationCode , s tepDone) {
var signalingKey = textsecure . crypto . getRandomBytes ( 32 + 20 ) ;
textsecure . storage . putEncrypted ( 'signaling_key' , signalingKey ) ;
@ -794,25 +759,55 @@ window.textsecure.register = function() {
registrationId = registrationId & 0x3fff ;
textsecure . storage . putUnencrypted ( "registrationId" , registrationId ) ;
return textsecure . api . confirmCode ( number , verificationCode , password , signalingKey , registrationId , singleDevice ) . then ( function ( response ) {
if ( singleDevice )
response = 1 ;
var numberId = number + "." + response ;
return textsecure . api . confirmCode ( number , verificationCode , password , signalingKey , registrationId , true ) . then ( function ( ) {
var numberId = number + ".1" ;
textsecure . storage . putUnencrypted ( "number_id" , numberId ) ;
textsecure . storage . putUnencrypted ( "regionCode" , textsecure . utils . getRegionCodeForNumber ( number ) ) ;
stepDone ( 1 ) ;
if ( ! singleDevice ) {
//TODO: Do things???
return textsecure . crypto . generateKeys ( ) . then ( function ( keys ) {
stepDone ( 2 ) ;
return textsecure . api . registerKeys ( keys ) . then ( function ( ) {
stepDone ( 3 ) ;
} ) ;
} ) ;
} ) ;
}
} ( ) ;
window . textsecure . registerSecondDevice = function ( encodedDeviceInit , cryptoInfo , stepDone ) {
var deviceInit = textsecure . protos . decodeDeviceInit ( encodedDeviceInit ) ;
return cryptoInfo . decryptAndHandleDeviceInit ( deviceInit ) . then ( function ( identityKey ) {
if ( identityKey . server != textsecure . api . relay )
throw new Error ( "Unknown relay used by master" ) ;
var number = identityKey . phoneNumber ;
stepDone ( 1 ) ;
var signalingKey = textsecure . crypto . getRandomBytes ( 32 + 20 ) ;
textsecure . storage . putEncrypted ( 'signaling_key' , signalingKey ) ;
var password = btoa ( getString ( textsecure . crypto . getRandomBytes ( 16 ) ) ) ;
password = password . substring ( 0 , password . length - 2 ) ;
textsecure . storage . putEncrypted ( "password" , password ) ;
var registrationId = new Uint16Array ( textsecure . crypto . getRandomBytes ( 2 ) ) [ 0 ] ;
registrationId = registrationId & 0x3fff ;
textsecure . storage . putUnencrypted ( "registrationId" , registrationId ) ;
return textsecure . api . confirmCode ( number , identityKey . provisioningCode , password , signalingKey , registrationId , false ) . then ( function ( result ) {
var numberId = number + "." + result ;
textsecure . storage . putUnencrypted ( "number_id" , numberId ) ;
textsecure . storage . putUnencrypted ( "regionCode" , textsecure . utils . getRegionCodeForNumber ( number ) ) ;
stepDone ( 2 ) ;
return textsecure . crypto . generateKeys ( ) . then ( function ( keys ) {
stepDone ( 3 ) ;
return textsecure . api . registerKeys ( keys ) . then ( function ( ) {
stepDone ( 4 ) ;
//TODO: Send DeviceControl.NEW_DEVICE_REGISTERED to all other devices
} ) ;
} ) ;
} ) ;
}
} ( ) ;
} ) ;
} ;