@ -38314,79 +38314,6 @@ axolotlInternal.RecipientRecord = function() {
loadProtoBufs ( 'DeviceMessages.proto' ) ;
loadProtoBufs ( 'DeviceMessages.proto' ) ;
} ) ( ) ;
} ) ( ) ;
/ *
* vim : ts = 4 : sw = 4 : expandtab
*
* var socket = TextSecureWebSocket ( url ) ;
*
* Returns an adamantium - reinforced super socket , capable of
* automatically reconnecting .
*
* /
TextSecureWebSocket = function ( url , opts ) {
'use strict' ;
opts = opts || { } ;
var reconnectTimeout = 1000 ;
if ( opts && opts . reconnectTimeout !== undefined ) {
reconnectTimeout = opts . reconnectTimeout ;
}
var reconnectSemaphore = 0 ;
var socket ;
var calledClose = false ;
var socketWrapper = {
onmessage : function ( ) { } ,
onclose : function ( ) { } ,
onerror : function ( ) { } ,
getStatus : function ( ) { return socket . readyState ; } ,
close : function ( code , reason ) {
calledClose = true ;
socket . close ( code , reason ) ;
}
} ;
var error ;
function onclose ( e ) {
if ( ! error && ! calledClose && reconnectTimeout ) {
reconnectSemaphore -- ;
setTimeout ( connect , reconnectTimeout ) ;
}
if ( e !== 1000 ) { // CLOSE_NORMAL
console . log ( 'websocket closed' , e . code ) ;
}
socketWrapper . onclose ( e ) ;
} ;
function onerror ( e ) {
error = e ;
console . log ( 'websocket error' ) ;
socketWrapper . onerror ( e ) ;
} ;
function onmessage ( response ) {
socketWrapper . onmessage ( response ) ;
} ;
function send ( msg ) {
socket . send ( msg ) ;
} ;
function connect ( ) {
if ( ++ reconnectSemaphore <= 0 ) { return ; }
if ( socket ) { socket . close ( ) ; }
socket = new WebSocket ( url ) ;
socket . onerror = onerror
socket . onclose = onclose ;
socket . onmessage = onmessage ;
socketWrapper . send = send ;
} ;
connect ( ) ;
return socketWrapper ;
} ;
/ *
/ *
* vim : ts = 4 : sw = 4 : expandtab
* vim : ts = 4 : sw = 4 : expandtab
* /
* /
@ -38899,42 +38826,10 @@ function processDecrypted(decrypted, source) {
* vim : ts = 4 : sw = 4 : expandtab
* vim : ts = 4 : sw = 4 : expandtab
* /
* /
TextSecureServer = function ( ) {
var TextSecureServer = ( function ( ) {
'use strict' ;
'use strict' ;
var self = { } ;
// Promise-based async xhr routine
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* * * Utilities to communicate with the server * * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
// Staging server
var URL _BASE = "https://textsecure-service-staging.whispersystems.org" ;
// This is the real server
//var URL_BASE = "https://textsecure-service.whispersystems.org";
var URL _CALLS = { } ;
URL _CALLS . accounts = "/v1/accounts" ;
URL _CALLS . devices = "/v1/devices" ;
URL _CALLS . keys = "/v2/keys" ;
URL _CALLS . push = "/v1/websocket" ;
URL _CALLS . temp _push = "/v1/websocket/provisioning" ;
URL _CALLS . messages = "/v1/messages" ;
URL _CALLS . attachment = "/v1/attachments" ;
/ * *
* REQUIRED PARAMS :
* call : URL _CALLS entry
* httpType : POST / GET / PUT / etc
* OPTIONAL PARAMS :
* success _callback : function ( response object ) called on success
* error _callback : function ( http status code = - 1 or != 200 ) called on failure
* urlParameters : crap appended to the url ( probably including a leading / )
* user : user name to be sent in a basic auth header
* password : password to be sent in a basic auth header
* do _auth : alternative to user / password where user / password are figured out automagically
* jsonData : JSON data sent in the request body
* /
function ajax ( url , options ) {
function ajax ( url , options ) {
return new Promise ( function ( resolve , reject ) {
return new Promise ( function ( resolve , reject ) {
console . log ( options . type , url ) ;
console . log ( options . type , url ) ;
@ -38991,23 +38886,35 @@ TextSecureServer = function () {
return e ;
return e ;
}
}
var doAjax = function ( param ) {
var URL _CALLS = {
if ( param . urlParameters === undefined ) {
accounts : "/v1/accounts" ,
param . urlParameters = "" ;
devices : "/v1/devices" ,
}
keys : "/v2/keys" ,
messages : "/v1/messages" ,
attachment : "/v1/attachments"
} ;
var attachment _id _regex = RegExp ( "^https:\/\/.*\/(\\d+)\?" ) ;
if ( param . do _auth ) {
function TextSecureServer ( url , username , password ) {
param . user = textsecure . storage . user . getNumber ( ) + "." + textsecure . storage . user . getDeviceId ( ) ;
this . url = url ;
param . password = textsecure . storage . get ( "password" ) ;
this . username = username ;
this . password = password ;
}
}
return ajax ( URL _BASE + URL _CALLS [ param . call ] + param . urlParameters , {
TextSecureServer . prototype = {
constructor : TextSecureServer ,
ajax : function ( param ) {
if ( ! param . urlParameters ) {
param . urlParameters = '' ;
}
return ajax ( this . url + URL _CALLS [ param . call ] + param . urlParameters , {
type : param . httpType ,
type : param . httpType ,
data : param . jsonData && textsecure . utils . jsonThing ( param . jsonData ) ,
data : param . jsonData && textsecure . utils . jsonThing ( param . jsonData ) ,
contentType : 'application/json; charset=utf-8' ,
contentType : 'application/json; charset=utf-8' ,
dataType : 'json' ,
dataType : 'json' ,
user : param . user ,
user : this . username ,
password : param . password
password : this . password
} ) . catch ( function ( e ) {
} ) . catch ( function ( e ) {
var code = e . code ;
var code = e . code ;
if ( code === 200 ) {
if ( code === 200 ) {
@ -39043,32 +38950,22 @@ TextSecureServer = function () {
e . message = message
e . message = message
throw e ;
throw e ;
} ) ;
} ) ;
} ;
} ,
requestVerificationSMS : function ( number ) {
function requestVerificationCode ( number , transport ) {
return this . ajax ( {
return doAjax ( {
call : 'accounts' ,
call : 'accounts' ,
httpType : 'GET' ,
httpType : 'GET' ,
urlParameters : '/' + transport + ' /code/' + number ,
urlParameters : '/sms /code/' + number ,
} ) ;
} ) ;
} ;
} ,
self . requestVerificationSMS = function ( number ) {
requestVerificationVoice : function ( number ) {
return requestVerificationCode ( number , 'sms' ) ;
return this . ajax ( {
} ;
call : 'accounts' ,
self . requestVerificationVoice = function ( number ) {
return requestVerificationCode ( number , 'voice' ) ;
} ;
self . getDevices = function ( number ) {
return doAjax ( {
call : 'devices' ,
httpType : 'GET' ,
httpType : 'GET' ,
do _auth : true
urlParameters : '/voice/code/' + number ,
} ) ;
} ) ;
} ;
} ,
confirmCode : function ( number , code , password , signaling _key , registrationId , deviceName ) {
self . confirmCode = function ( number , code , password ,
signaling _key , registrationId , deviceName ) {
var call = deviceName ? 'devices' : 'accounts' ;
var call = deviceName ? 'devices' : 'accounts' ;
var urlPrefix = deviceName ? '/' : '/code/' ;
var urlPrefix = deviceName ? '/' : '/code/' ;
@ -39081,17 +38978,22 @@ TextSecureServer = function () {
if ( deviceName ) {
if ( deviceName ) {
jsonData . name = deviceName ;
jsonData . name = deviceName ;
}
}
return doAjax ( {
this . username = number ;
this . password = password ;
return this . ajax ( {
call : call ,
call : call ,
httpType : 'PUT' ,
httpType : 'PUT' ,
urlParameters : urlPrefix + code ,
urlParameters : urlPrefix + code ,
user : number ,
password : password ,
jsonData : jsonData
jsonData : jsonData
} ) ;
} ) ;
} ;
} ,
getDevices : function ( number ) {
self . registerKeys = function ( genKeys ) {
return this . ajax ( {
call : 'devices' ,
httpType : 'GET' ,
} ) ;
} ,
registerKeys : function ( genKeys ) {
var keys = { } ;
var keys = { } ;
keys . identityKey = btoa ( getString ( genKeys . identityKey ) ) ;
keys . identityKey = btoa ( getString ( genKeys . identityKey ) ) ;
keys . signedPreKey = { keyId : genKeys . signedPreKey . keyId , publicKey : btoa ( getString ( genKeys . signedPreKey . publicKey ) ) ,
keys . signedPreKey = { keyId : genKeys . signedPreKey . keyId , publicKey : btoa ( getString ( genKeys . signedPreKey . publicKey ) ) ,
@ -39106,32 +39008,27 @@ TextSecureServer = function () {
// it needs removed before release
// it needs removed before release
keys . lastResortKey = { keyId : 0x7fffFFFF , publicKey : btoa ( "42" ) } ;
keys . lastResortKey = { keyId : 0x7fffFFFF , publicKey : btoa ( "42" ) } ;
return doA jax( {
return this . a jax( {
call : 'keys' ,
call : 'keys' ,
httpType : 'PUT' ,
httpType : 'PUT' ,
do _auth : true ,
jsonData : keys ,
jsonData : keys ,
} ) ;
} ) ;
} ;
} ,
getMyKeys : function ( number , deviceId ) {
self . getMyKeys = function ( number , deviceId ) {
return this . ajax ( {
return doAjax ( {
call : 'keys' ,
call : 'keys' ,
httpType : 'GET' ,
httpType : 'GET' ,
do _auth : true ,
} ) . then ( function ( res ) {
} ) . then ( function ( res ) {
return parseInt ( res . count ) ;
return parseInt ( res . count ) ;
} ) ;
} ) ;
} ;
} ,
getKeysForNumber : function ( number , deviceId ) {
self . getKeysForNumber = function ( number , deviceId ) {
if ( deviceId === undefined )
if ( deviceId === undefined )
deviceId = "*" ;
deviceId = "*" ;
return doA jax( {
return this . a jax( {
call : 'keys' ,
call : 'keys' ,
httpType : 'GET' ,
httpType : 'GET' ,
do _auth : true ,
urlParameters : "/" + number + "/" + deviceId ,
urlParameters : "/" + number + "/" + deviceId ,
} ) . then ( function ( res ) {
} ) . then ( function ( res ) {
var promises = [ ] ;
var promises = [ ] ;
@ -39146,9 +39043,8 @@ TextSecureServer = function () {
}
}
return res ;
return res ;
} ) ;
} ) ;
} ;
} ,
sendMessages : function ( destination , messageArray , legacy ) {
self . sendMessages = function ( destination , messageArray , legacy ) {
//TODO: Do this conversion somewhere else?
//TODO: Do this conversion somewhere else?
for ( var i = 0 ; i < messageArray . length ; i ++ ) {
for ( var i = 0 ; i < messageArray . length ; i ++ ) {
messageArray [ i ] . content = btoa ( messageArray [ i ] . content ) ;
messageArray [ i ] . content = btoa ( messageArray [ i ] . content ) ;
@ -39160,21 +39056,18 @@ TextSecureServer = function () {
var jsonData = { messages : messageArray } ;
var jsonData = { messages : messageArray } ;
jsonData . timestamp = messageArray [ 0 ] . timestamp ;
jsonData . timestamp = messageArray [ 0 ] . timestamp ;
return doA jax( {
return this . a jax( {
call : 'messages' ,
call : 'messages' ,
httpType : 'PUT' ,
httpType : 'PUT' ,
urlParameters : '/' + destination ,
urlParameters : '/' + destination ,
do _auth : true ,
jsonData : jsonData ,
jsonData : jsonData ,
} ) ;
} ) ;
} ;
} ,
getAttachment : function ( id ) {
self . getAttachment = function ( id ) {
return this . ajax ( {
return doAjax ( {
call : 'attachment' ,
call : 'attachment' ,
httpType : 'GET' ,
httpType : 'GET' ,
urlParameters : '/' + id ,
urlParameters : '/' + id ,
do _auth : true ,
} ) . then ( function ( response ) {
} ) . then ( function ( response ) {
return ajax ( response . location , {
return ajax ( response . location , {
type : "GET" ,
type : "GET" ,
@ -39182,14 +39075,11 @@ TextSecureServer = function () {
contentType : "application/octet-stream"
contentType : "application/octet-stream"
} ) ;
} ) ;
} ) ;
} ) ;
} ;
} ,
putAttachment : function ( encryptedBin ) {
var id _regex = RegExp ( "^https:\/\/.*\/(\\d+)\?" ) ;
return this . ajax ( {
self . putAttachment = function ( encryptedBin ) {
return doAjax ( {
call : 'attachment' ,
call : 'attachment' ,
httpType : 'GET' ,
httpType : 'GET' ,
do _auth : true ,
} ) . then ( function ( response ) {
} ) . then ( function ( response ) {
return ajax ( response . location , {
return ajax ( response . location , {
type : "PUT" ,
type : "PUT" ,
@ -39199,26 +39089,29 @@ TextSecureServer = function () {
} ) . then ( function ( ) {
} ) . then ( function ( ) {
// Parse the id as a string from the location url
// Parse the id as a string from the location url
// (workaround for ids too large for Javascript numbers)
// (workaround for ids too large for Javascript numbers)
return response . location . match ( id_regex ) [ 1 ] ;
return response . location . match ( attachment_ id_regex ) [ 1 ] ;
} ) ;
} ) ;
} ) ;
} ) ;
} ;
} ,
getMessageSocket : function ( ) {
self . getMessageWebsocket = function ( url ) {
return new WebSocket (
var user = textsecure . storage . user . getNumber ( ) + "." + textsecure . storage . user . getDeviceId ( ) ;
this . url . replace ( 'https://' , 'wss://' )
var password = textsecure . storage . get ( "password" ) ;
. replace ( 'http://' , 'ws://' )
var params = 'login=%2B' + encodeURIComponent ( user . substring ( 1 ) ) + '&password=' + encodeURIComponent ( password ) ;
+ '/v1/websocket/?login=' + encodeURIComponent ( this . username )
var url = url + URL _CALLS [ 'push' ] + '/?' + params ;
+ '&password=' + encodeURIComponent ( this . password )
return TextSecureWebSocket ( url , { reconnectTimeout : false } ) ;
) ;
}
} ,
getProvisioningSocket : function ( ) {
self . getTempWebsocket = function ( ) {
return new WebSocket (
var url = URL _BASE . replace ( /^http/g , 'ws' ) + URL _CALLS [ 'temp_push' ] + '/?' ;
this . url . replace ( 'https://' , 'wss://' )
return TextSecureWebSocket ( url , { reconnectTimeout : false } ) ;
. replace ( 'http://' , 'ws://' )
+ '/v1/websocket/provisioning/'
) ;
}
}
} ;
return self ;
return TextSecureServer ;
} () ;
} ) () ;
/ *
/ *
* vim : ts = 4 : sw = 4 : expandtab
* vim : ts = 4 : sw = 4 : expandtab
@ -39229,46 +39122,53 @@ TextSecureServer = function () {
'use strict' ;
'use strict' ;
window . textsecure = window . textsecure || { } ;
window . textsecure = window . textsecure || { } ;
function AccountManager ( ) {
function AccountManager ( url , username , password ) {
this . server = new TextSecureServer ( url , username , password ) ;
}
}
AccountManager . prototype = {
AccountManager . prototype = {
constructor : AccountManager ,
constructor : AccountManager ,
requestVoiceVerification : function ( number ) {
requestVoiceVerification : function ( number ) {
return TextSecureS erver. requestVerificationVoice ( number ) ;
return this . s erver. requestVerificationVoice ( number ) ;
} ,
} ,
requestSMSVerification : function ( number ) {
requestSMSVerification : function ( number ) {
return TextSecureS erver. requestVerificationSMS ( number ) ;
return this . s erver. requestVerificationSMS ( number ) ;
} ,
} ,
registerSingleDevice : function ( number , verificationCode ) {
registerSingleDevice : function ( number , verificationCode ) {
var registerKeys = this . server . registerKeys . bind ( this . server ) ;
var createAccount = this . createAccount . bind ( this ) ;
var generateKeys = this . generateKeys . bind ( this , 100 ) ;
return axolotl . util . generateIdentityKeyPair ( ) . then ( function ( identityKeyPair ) {
return axolotl . util . generateIdentityKeyPair ( ) . then ( function ( identityKeyPair ) {
return createAccount ( number , verificationCode , identityKeyPair ) .
return createAccount ( number , verificationCode , identityKeyPair ) .
then ( function ( ) { return generateKeys ( 100 ) ; } ) .
then ( generateKeys ) .
then ( TextSecureServer. registerKeys) .
then ( registerKeys) .
then ( textsecure . registration . done ) ;
then ( textsecure . registration . done ) ;
} );
} .bind ( this ) );
} ,
} ,
registerSecondDevice : function ( setProvisioningUrl , confirmNumber , progressCallback ) {
registerSecondDevice : function ( setProvisioningUrl , confirmNumber , progressCallback ) {
var socket = this . server . getProvisioningSocket ( ) ;
var createAccount = this . createAccount . bind ( this ) ;
var generateKeys = this . generateKeys . bind ( this , 100 , progressCallback ) ;
var registerKeys = this . server . registerKeys . bind ( this . server ) ;
return textsecure . protocol _wrapper . createIdentityKeyRecvSocket ( ) . then ( function ( cryptoInfo ) {
return textsecure . protocol _wrapper . createIdentityKeyRecvSocket ( ) . then ( function ( cryptoInfo ) {
return new Promise ( function ( resolve ) {
return new Promise ( function ( resolve ) {
var socket = TextSecureServer . getTempWebsocket ( ) ;
var wsr = new WebSocketResource ( socket , {
var wsr = new WebSocketResource ( socket , {
keepalive : { path : '/v1/keepalive/provisioning' } ,
keepalive : { path : '/v1/keepalive/provisioning' } ,
handleRequest : function ( request ) {
handleRequest : function ( request ) {
if ( request . path == "/v1/address" && request . verb == "PUT" ) {
if ( request . path == = "/v1/address" && request . verb = == "PUT" ) {
var proto = textsecure . protobuf . ProvisioningUuid . decode ( request . body ) ;
var proto = textsecure . protobuf . ProvisioningUuid . decode ( request . body ) ;
setProvisioningUrl ( [
setProvisioningUrl ( [
'tsdevice:/?uuid=' , proto . uuid , '&pub_key=' ,
'tsdevice:/?uuid=' , proto . uuid , '&pub_key=' ,
encodeURIComponent ( btoa ( getString ( cryptoInfo . pubKey ) ) )
encodeURIComponent ( btoa ( getString ( cryptoInfo . pubKey ) ) )
] . join ( '' ) ) ;
] . join ( '' ) ) ;
request . respond ( 200 , 'OK' ) ;
request . respond ( 200 , 'OK' ) ;
} else if ( request . path == "/v1/message" && request . verb == "PUT" ) {
} else if ( request . path == = "/v1/message" && request . verb = == "PUT" ) {
var envelope = textsecure . protobuf . ProvisionEnvelope . decode ( request . body , 'binary' ) ;
var envelope = textsecure . protobuf . ProvisionEnvelope . decode ( request . body , 'binary' ) ;
request . respond ( 200 , 'OK' ) ;
request . respond ( 200 , 'OK' ) ;
wsr . close ( ) ;
wsr . close ( ) ;
resolve ( cryptoInfo . decryptAndHandleDeviceInit ( envelope ) . then ( function ( provisionMessage ) {
resolve ( cryptoInfo . decryptAndHandleDeviceInit ( envelope ) . then ( function ( provisionMessage ) {
return confirmNumber ( provisionMessage . number ) . then ( function ( deviceName ) {
return confirmNumber ( provisionMessage . number ) . then ( function ( deviceName ) {
if ( typeof deviceName !== 'string' || deviceName . length == 0 ) {
if ( typeof deviceName !== 'string' || deviceName . length == = 0 ) {
throw new Error ( 'Invalid device name' ) ;
throw new Error ( 'Invalid device name' ) ;
}
}
return createAccount (
return createAccount (
@ -39285,26 +39185,26 @@ TextSecureServer = function () {
}
}
} ) ;
} ) ;
} ) ;
} ) ;
} ) . then ( function ( ) {
} ) . then ( generateKeys ) .
return generateKeys ( 100 , progressCallback ) ;
then ( registerKeys ) .
} ) . then ( TextSecureServer . registerKeys ) .
then ( textsecure . registration . done ) ;
then ( textsecure . registration . done ) ;
} ,
} ,
refreshPreKeys : function ( ) {
refreshPreKeys : function ( ) {
return TextSecureServer . getMyKeys ( ) . then ( function ( preKeyCount ) {
var generateKeys = this . generateKeys . bind ( this , 100 ) ;
var registerKeys = this . server . registerKeys . bind ( this . server ) ;
return this . server . getMyKeys ( ) . then ( function ( preKeyCount ) {
if ( preKeyCount < 10 ) {
if ( preKeyCount < 10 ) {
return generateKeys ( 100 ) . then ( TextSecureServer . registerKeys ) ;
return generateKeys ( ) . then ( registerKeys ) ;
}
} ) ;
}
}
} ;
} . bind ( this ) ) ;
function createAccount ( number , verificationCode , identityKeyPair , deviceName ) {
} ,
createAccount : function ( number , verificationCode , identityKeyPair , deviceName ) {
var signalingKey = textsecure . crypto . getRandomBytes ( 32 + 20 ) ;
var signalingKey = textsecure . crypto . getRandomBytes ( 32 + 20 ) ;
var password = btoa ( getString ( textsecure . crypto . getRandomBytes ( 16 ) ) ) ;
var password = btoa ( getString ( textsecure . crypto . getRandomBytes ( 16 ) ) ) ;
password = password . substring ( 0 , password . length - 2 ) ;
password = password . substring ( 0 , password . length - 2 ) ;
var registrationId = axolotl . util . generateRegistrationId ( ) ;
var registrationId = axolotl . util . generateRegistrationId ( ) ;
return TextSecureS erver. confirmCode (
return this . s erver. confirmCode (
number , verificationCode , password , signalingKey , registrationId , deviceName
number , verificationCode , password , signalingKey , registrationId , deviceName
) . then ( function ( response ) {
) . then ( function ( response ) {
textsecure . storage . remove ( 'identityKey' ) ;
textsecure . storage . remove ( 'identityKey' ) ;
@ -39322,13 +39222,8 @@ TextSecureServer = function () {
textsecure . storage . user . setNumberAndDeviceId ( number , response . deviceId || 1 , deviceName ) ;
textsecure . storage . user . setNumberAndDeviceId ( number , response . deviceId || 1 , deviceName ) ;
textsecure . storage . put ( 'regionCode' , libphonenumber . util . getRegionCodeForNumber ( number ) ) ;
textsecure . storage . put ( 'regionCode' , libphonenumber . util . getRegionCodeForNumber ( number ) ) ;
} ) ;
} ) ;
}
} ,
generateKeys : function ( count , progressCallback ) {
textsecure . AccountManager = AccountManager ;
} ( ) ) ;
function generateKeys ( count , progressCallback ) {
if ( typeof progressCallback !== 'function' ) {
if ( typeof progressCallback !== 'function' ) {
progressCallback = undefined ;
progressCallback = undefined ;
}
}
@ -39342,6 +39237,7 @@ function generateKeys(count, progressCallback) {
throw new Error ( 'Invalid signedKeyId' ) ;
throw new Error ( 'Invalid signedKeyId' ) ;
}
}
var store = textsecure . storage . axolotl ;
var store = textsecure . storage . axolotl ;
return store . getMyIdentityKey ( ) . then ( function ( identityKey ) {
return store . getMyIdentityKey ( ) . then ( function ( identityKey ) {
var result = { preKeys : [ ] , identityKey : identityKey . pubKey } ;
var result = { preKeys : [ ] , identityKey : identityKey . pubKey } ;
@ -39379,6 +39275,10 @@ function generateKeys(count, progressCallback) {
} ) ;
} ) ;
} ) ;
} ) ;
}
}
} ;
textsecure . AccountManager = AccountManager ;
} ( ) ) ;
/ *
/ *
* vim : ts = 4 : sw = 4 : expandtab
* vim : ts = 4 : sw = 4 : expandtab
@ -39393,6 +39293,7 @@ function generateKeys(count, progressCallback) {
this . signalingKey = signalingKey ;
this . signalingKey = signalingKey ;
this . username = username ;
this . username = username ;
this . password = password ;
this . password = password ;
this . server = new TextSecureServer ( url , username , password ) ;
var unencoded = textsecure . utils . unencodeNumber ( username ) ;
var unencoded = textsecure . utils . unencodeNumber ( username ) ;
this . number = unencoded [ 0 ] ;
this . number = unencoded [ 0 ] ;
@ -39403,17 +39304,12 @@ function generateKeys(count, progressCallback) {
MessageReceiver . prototype = {
MessageReceiver . prototype = {
constructor : MessageReceiver ,
constructor : MessageReceiver ,
connect : function ( ) {
connect : function ( ) {
// initialize the socket and start listening for messages
if ( this . socket && this . socket . readyState !== WebSocket . CLOSED ) {
if ( this . socket && this . socket . readyState !== WebSocket . CLOSED ) {
this . socket . close ( ) ;
this . socket . close ( ) ;
}
}
console . log ( 'opening websocket' ) ;
console . log ( 'opening websocket' ) ;
this . socket = new WebSocket (
// initialize the socket and start listening for messages
this . url . replace ( 'https://' , 'wss://' ) . replace ( 'http://' , 'ws://' )
this . socket = this . server . getMessageSocket ( ) ;
+ '/v1/websocket/?login=' + encodeURIComponent ( this . username )
+ '&password=' + encodeURIComponent ( this . password )
) ;
this . socket . onclose = this . onclose . bind ( this ) ;
this . socket . onclose = this . onclose . bind ( this ) ;
this . socket . onerror = this . onerror . bind ( this ) ;
this . socket . onerror = this . onerror . bind ( this ) ;
this . socket . onopen = this . onopen . bind ( this ) ;
this . socket . onopen = this . onopen . bind ( this ) ;
@ -39436,7 +39332,7 @@ function generateKeys(count, progressCallback) {
var eventTarget = this ;
var eventTarget = this ;
console . log ( 'websocket closed' , ev . code ) ;
console . log ( 'websocket closed' , ev . code ) ;
// possible 403 or network issue. Make an request to confirm
// possible 403 or network issue. Make an request to confirm
TextSecureS erver. getDevices ( this . number ) .
this . s erver. getDevices ( this . number ) .
then ( this . connect . bind ( this ) ) . // No HTTP error? Reconnect
then ( this . connect . bind ( this ) ) . // No HTTP error? Reconnect
catch ( function ( e ) {
catch ( function ( e ) {
var ev = new Event ( 'error' ) ;
var ev = new Event ( 'error' ) ;