More namespacing
This commit is contained in:
parent
05101b69b0
commit
6bc19ef558
8 changed files with 296 additions and 264 deletions
49
js/api.js
49
js/api.js
|
@ -14,24 +14,27 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/************************************************
|
window.textsecure = window.textsecure || {};
|
||||||
*** Utilities to communicate with the server ***
|
|
||||||
************************************************/
|
|
||||||
// WARNING: THIS SERVER LOGS KEY MATERIAL FOR TESTING
|
|
||||||
var URL_BASE = "http://sushiforeveryone.bluematt.me";
|
|
||||||
|
|
||||||
// This is the real server
|
window.textsecure.api = function() {
|
||||||
//var URL_BASE = "https://textsecure-service.whispersystems.org";
|
var self = {};
|
||||||
|
|
||||||
var URL_CALLS = {};
|
/************************************************
|
||||||
URL_CALLS['accounts'] = "/v1/accounts";
|
*** Utilities to communicate with the server ***
|
||||||
URL_CALLS['devices'] = "/v1/devices";
|
************************************************/
|
||||||
URL_CALLS['keys'] = "/v1/keys";
|
// WARNING: THIS SERVER LOGS KEY MATERIAL FOR TESTING
|
||||||
URL_CALLS['push'] = "/v1/websocket";
|
var URL_BASE = "http://sushiforeveryone.bluematt.me";
|
||||||
URL_CALLS['messages'] = "/v1/messages";
|
|
||||||
URL_CALLS['attachment'] = "/v1/attachments";
|
|
||||||
|
|
||||||
var API = new function() {
|
// 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'] = "/v1/keys";
|
||||||
|
URL_CALLS['push'] = "/v1/websocket";
|
||||||
|
URL_CALLS['messages'] = "/v1/messages";
|
||||||
|
URL_CALLS['attachment'] = "/v1/attachments";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* REQUIRED PARAMS:
|
* REQUIRED PARAMS:
|
||||||
|
@ -90,7 +93,7 @@ var API = new function() {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
this.requestVerificationCode = function(number, success_callback, error_callback) {
|
self.requestVerificationCode = function(number, success_callback, error_callback) {
|
||||||
doAjax({
|
doAjax({
|
||||||
call : 'accounts',
|
call : 'accounts',
|
||||||
httpType : 'GET',
|
httpType : 'GET',
|
||||||
|
@ -104,7 +107,7 @@ var API = new function() {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
this.confirmCode = function(code, number, password,
|
self.confirmCode = function(code, number, password,
|
||||||
signaling_key, registrationId, single_device,
|
signaling_key, registrationId, single_device,
|
||||||
success_callback, error_callback) {
|
success_callback, error_callback) {
|
||||||
var call = single_device ? 'accounts' : 'devices';
|
var call = single_device ? 'accounts' : 'devices';
|
||||||
|
@ -129,7 +132,7 @@ var API = new function() {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
this.registerKeys = function(keys, success_callback, error_callback) {
|
self.registerKeys = function(keys, success_callback, error_callback) {
|
||||||
//TODO: Do this conversion somewhere else?
|
//TODO: Do this conversion somewhere else?
|
||||||
var identityKey = btoa(getString(keys.keys[0].identityKey));
|
var identityKey = btoa(getString(keys.keys[0].identityKey));
|
||||||
for (var i = 0; i < keys.keys.length; i++)
|
for (var i = 0; i < keys.keys.length; i++)
|
||||||
|
@ -149,7 +152,7 @@ var API = new function() {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
this.getKeysForNumber = function(number) {
|
self.getKeysForNumber = function(number) {
|
||||||
return doAjax({
|
return doAjax({
|
||||||
call : 'keys',
|
call : 'keys',
|
||||||
httpType : 'GET',
|
httpType : 'GET',
|
||||||
|
@ -168,7 +171,7 @@ var API = new function() {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
this.sendMessages = function(destination, messageArray) {
|
self.sendMessages = function(destination, messageArray) {
|
||||||
//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].body = btoa(messageArray[i].body);
|
messageArray[i].body = btoa(messageArray[i].body);
|
||||||
|
@ -185,7 +188,7 @@ var API = new function() {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
this.getAttachment = function(id) {
|
self.getAttachment = function(id) {
|
||||||
return doAjax({
|
return doAjax({
|
||||||
call : 'attachment',
|
call : 'attachment',
|
||||||
httpType : 'GET',
|
httpType : 'GET',
|
||||||
|
@ -218,4 +221,6 @@ var API = new function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
}(); // API
|
|
||||||
|
return self;
|
||||||
|
}();
|
||||||
|
|
|
@ -14,13 +14,13 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
registerOnLoadFunction(function() {
|
textsecure.registerOnLoadFunction(function() {
|
||||||
if (!localStorage.getItem('first_install_ran')) {
|
if (!localStorage.getItem('first_install_ran')) {
|
||||||
localStorage.setItem('first_install_ran', 1);
|
localStorage.setItem('first_install_ran', 1);
|
||||||
chrome.tabs.create({url: "options.html"});
|
chrome.tabs.create({url: "options.html"});
|
||||||
} else {
|
} else {
|
||||||
if (isRegistrationDone()) {
|
if (isRegistrationDone()) {
|
||||||
subscribeToPush(function(message) {
|
textsecure.subscribeToPush(function(message) {
|
||||||
console.log("Got message from " + message.pushMessage.source + "." + message.pushMessage.sourceDevice +
|
console.log("Got message from " + message.pushMessage.source + "." + message.pushMessage.sourceDevice +
|
||||||
': "' + getString(message.message.body) + '"');
|
': "' + getString(message.message.body) + '"');
|
||||||
var newUnreadCount = storage.getUnencrypted("unreadCount", 0) + 1;
|
var newUnreadCount = storage.getUnencrypted("unreadCount", 0) + 1;
|
||||||
|
|
24
js/crypto.js
24
js/crypto.js
|
@ -14,9 +14,10 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var textsecure = textsecure || {};
|
window.textsecure = window.textsecure || {};
|
||||||
|
|
||||||
textsecure.crypto = new function() {
|
window.textsecure.crypto = new function() {
|
||||||
|
var self = {};
|
||||||
// functions exposed for replacement and direct calling in test code
|
// functions exposed for replacement and direct calling in test code
|
||||||
var testing_only = {};
|
var testing_only = {};
|
||||||
|
|
||||||
|
@ -38,7 +39,7 @@ textsecure.crypto = new function() {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.getRandomBytes = getRandomBytes;
|
self.getRandomBytes = getRandomBytes;
|
||||||
|
|
||||||
function intToArrayBuffer(nInt) {
|
function intToArrayBuffer(nInt) {
|
||||||
var res = new ArrayBuffer(16);
|
var res = new ArrayBuffer(16);
|
||||||
|
@ -67,7 +68,7 @@ textsecure.crypto = new function() {
|
||||||
return pub;
|
return pub;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (USE_NACL) {
|
if (textsecure.nacl.USE_NACL) {
|
||||||
return postNaclMessage({command: "bytesToPriv", priv: privKey}).then(function(message) {
|
return postNaclMessage({command: "bytesToPriv", priv: privKey}).then(function(message) {
|
||||||
var priv = message.res;
|
var priv = message.res;
|
||||||
if (!isIdentity)
|
if (!isIdentity)
|
||||||
|
@ -238,7 +239,7 @@ textsecure.crypto = new function() {
|
||||||
console.error("WARNING: Expected pubkey of length 33, please report the ST and client that generated the pubkey");
|
console.error("WARNING: Expected pubkey of length 33, please report the ST and client that generated the pubkey");
|
||||||
|
|
||||||
return new Promise(function(resolve) {
|
return new Promise(function(resolve) {
|
||||||
if (USE_NACL) {
|
if (textsecure.nacl.USE_NACL) {
|
||||||
postNaclMessage({command: "ECDHE", priv: privKey, pub: pubKey}).then(function(message) {
|
postNaclMessage({command: "ECDHE", priv: privKey, pub: pubKey}).then(function(message) {
|
||||||
resolve(message.res);
|
resolve(message.res);
|
||||||
});
|
});
|
||||||
|
@ -556,7 +557,7 @@ textsecure.crypto = new function() {
|
||||||
*** Public crypto API ***
|
*** Public crypto API ***
|
||||||
*************************/
|
*************************/
|
||||||
// Decrypts message into a raw string
|
// Decrypts message into a raw string
|
||||||
this.decryptWebsocketMessage = function(message) {
|
self.decryptWebsocketMessage = function(message) {
|
||||||
var signaling_key = storage.getEncrypted("signaling_key"); //TODO: in crypto_storage
|
var signaling_key = storage.getEncrypted("signaling_key"); //TODO: in crypto_storage
|
||||||
var aes_key = toArrayBuffer(signaling_key.substring(0, 32));
|
var aes_key = toArrayBuffer(signaling_key.substring(0, 32));
|
||||||
var mac_key = toArrayBuffer(signaling_key.substring(32, 32 + 20));
|
var mac_key = toArrayBuffer(signaling_key.substring(32, 32 + 20));
|
||||||
|
@ -575,7 +576,7 @@ textsecure.crypto = new function() {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
this.decryptAttachment = function(encryptedBin, keys) {
|
self.decryptAttachment = function(encryptedBin, keys) {
|
||||||
var aes_key = keys.slice(0, 32);
|
var aes_key = keys.slice(0, 32);
|
||||||
var mac_key = keys.slice(32, 64);
|
var mac_key = keys.slice(32, 64);
|
||||||
|
|
||||||
|
@ -589,7 +590,7 @@ textsecure.crypto = new function() {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
this.handleIncomingPushMessageProto = function(proto) {
|
self.handleIncomingPushMessageProto = function(proto) {
|
||||||
switch(proto.type) {
|
switch(proto.type) {
|
||||||
case 0: //TYPE_MESSAGE_PLAINTEXT
|
case 0: //TYPE_MESSAGE_PLAINTEXT
|
||||||
return Promise.resolve({message: decodePushMessageContentProtobuf(getString(proto.message)), pushMessage:proto});
|
return Promise.resolve({message: decodePushMessageContentProtobuf(getString(proto.message)), pushMessage:proto});
|
||||||
|
@ -612,7 +613,7 @@ textsecure.crypto = new function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// return Promise(encoded [PreKey]WhisperMessage)
|
// return Promise(encoded [PreKey]WhisperMessage)
|
||||||
this.encryptMessageFor = function(deviceObject, pushMessageContent) {
|
self.encryptMessageFor = function(deviceObject, pushMessageContent) {
|
||||||
var session = crypto_storage.getOpenSession(deviceObject.encodedNumber);
|
var session = crypto_storage.getOpenSession(deviceObject.encodedNumber);
|
||||||
|
|
||||||
var doEncryptPushMessageContent = function() {
|
var doEncryptPushMessageContent = function() {
|
||||||
|
@ -679,7 +680,7 @@ textsecure.crypto = new function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
var GENERATE_KEYS_KEYS_GENERATED = 100;
|
var GENERATE_KEYS_KEYS_GENERATED = 100;
|
||||||
this.generateKeys = function() {
|
self.generateKeys = function() {
|
||||||
var identityKey = crypto_storage.getStoredPubKey("identityKey");
|
var identityKey = crypto_storage.getStoredPubKey("identityKey");
|
||||||
var identityKeyCalculated = function(pubKey) {
|
var identityKeyCalculated = function(pubKey) {
|
||||||
identityKey = pubKey;
|
identityKey = pubKey;
|
||||||
|
@ -721,5 +722,6 @@ textsecure.crypto = new function() {
|
||||||
return identityKeyCalculated(identityKey);
|
return identityKeyCalculated(identityKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.testing_only = testing_only;
|
self.testing_only = testing_only;
|
||||||
|
return self;
|
||||||
}();
|
}();
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
//TODO: Redo this (API has changed to textsecure.api and changed)
|
||||||
var FakeWhisperAPI = function() {
|
var FakeWhisperAPI = function() {
|
||||||
var doAjax = function(param) {
|
var doAjax = function(param) {
|
||||||
if (param.success_callback) {
|
if (param.success_callback) {
|
||||||
|
|
458
js/helpers.js
458
js/helpers.js
|
@ -92,6 +92,8 @@ function base64EncArr (aBytes) {
|
||||||
|
|
||||||
/* END CRAP TO BE DELETED */
|
/* END CRAP TO BE DELETED */
|
||||||
|
|
||||||
|
window.textsecure = window.textsecure || {};
|
||||||
|
|
||||||
/*********************************
|
/*********************************
|
||||||
*** Type conversion utilities ***
|
*** Type conversion utilities ***
|
||||||
*********************************/
|
*********************************/
|
||||||
|
@ -176,7 +178,7 @@ function base64ToArrayBuffer(string) {
|
||||||
return base64DecToArr(string);
|
return base64DecToArr(string);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Protobuf decodingA
|
// Protobuf decoding
|
||||||
//TODO: throw on missing fields everywhere
|
//TODO: throw on missing fields everywhere
|
||||||
var IncomingPushMessageProtobuf = dcodeIO.ProtoBuf.loadProtoFile("protos/IncomingPushMessageSignal.proto").build("textsecure.IncomingPushMessageSignal");
|
var IncomingPushMessageProtobuf = dcodeIO.ProtoBuf.loadProtoFile("protos/IncomingPushMessageSignal.proto").build("textsecure.IncomingPushMessageSignal");
|
||||||
function decodeIncomingPushMessageProtobuf(string) {
|
function decodeIncomingPushMessageProtobuf(string) {
|
||||||
|
@ -224,13 +226,6 @@ function verifyNumber(string) {
|
||||||
return getEncodedNumber(string.trim());
|
return getEncodedNumber(string.trim());
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDeviceId(encodedNumber) {
|
|
||||||
var split = encodedNumber.split(".");
|
|
||||||
if (split.length > 1)
|
|
||||||
return split[1];
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Other
|
// Other
|
||||||
|
|
||||||
function timestampToHumanReadable(timestamp) {
|
function timestampToHumanReadable(timestamp) {
|
||||||
|
@ -251,18 +246,21 @@ function objectContainsKeys(object) {
|
||||||
/************************************************
|
/************************************************
|
||||||
*** Utilities to store data in local storage ***
|
*** Utilities to store data in local storage ***
|
||||||
************************************************/
|
************************************************/
|
||||||
var storage = new function() {
|
//TODO: textsecure.storage
|
||||||
|
window.storage = function() {
|
||||||
|
var self = {};
|
||||||
|
|
||||||
/*****************************
|
/*****************************
|
||||||
*** Base Storage Routines ***
|
*** Base Storage Routines ***
|
||||||
*****************************/
|
*****************************/
|
||||||
this.putEncrypted = function(key, value) {
|
self.putEncrypted = function(key, value) {
|
||||||
//TODO
|
//TODO
|
||||||
if (value === undefined)
|
if (value === undefined)
|
||||||
throw new Error("Tried to store undefined");
|
throw new Error("Tried to store undefined");
|
||||||
localStorage.setItem("e" + key, jsonThing(value));
|
localStorage.setItem("e" + key, jsonThing(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
this.getEncrypted = function(key, defaultValue) {
|
self.getEncrypted = function(key, defaultValue) {
|
||||||
//TODO
|
//TODO
|
||||||
var value = localStorage.getItem("e" + key);
|
var value = localStorage.getItem("e" + key);
|
||||||
if (value === null)
|
if (value === null)
|
||||||
|
@ -270,40 +268,42 @@ var storage = new function() {
|
||||||
return JSON.parse(value);
|
return JSON.parse(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.removeEncrypted = function(key) {
|
self.removeEncrypted = function(key) {
|
||||||
localStorage.removeItem("e" + key);
|
localStorage.removeItem("e" + key);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.putUnencrypted = function(key, value) {
|
self.putUnencrypted = function(key, value) {
|
||||||
if (value === undefined)
|
if (value === undefined)
|
||||||
throw new Error("Tried to store undefined");
|
throw new Error("Tried to store undefined");
|
||||||
localStorage.setItem("u" + key, jsonThing(value));
|
localStorage.setItem("u" + key, jsonThing(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
this.getUnencrypted = function(key, defaultValue) {
|
self.getUnencrypted = function(key, defaultValue) {
|
||||||
var value = localStorage.getItem("u" + key);
|
var value = localStorage.getItem("u" + key);
|
||||||
if (value === null)
|
if (value === null)
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
return JSON.parse(value);
|
return JSON.parse(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.removeUnencrypted = function(key) {
|
self.removeUnencrypted = function(key) {
|
||||||
localStorage.removeItem("u" + key);
|
localStorage.removeItem("u" + key);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
*** Device Storage ***
|
*** Device Storage ***
|
||||||
**********************/
|
**********************/
|
||||||
this.devices = new function() {
|
self.devices = function() {
|
||||||
this.getDeviceObject = function(encodedNumber) {
|
var self = {};
|
||||||
|
|
||||||
|
self.getDeviceObject = function(encodedNumber) {
|
||||||
return storage.getEncrypted("deviceObject" + getEncodedNumber(encodedNumber));
|
return storage.getEncrypted("deviceObject" + getEncodedNumber(encodedNumber));
|
||||||
}
|
}
|
||||||
|
|
||||||
this.getDeviceIdListFromNumber = function(number) {
|
self.getDeviceIdListFromNumber = function(number) {
|
||||||
return storage.getEncrypted("deviceIdList" + getNumberFromString(number), []);
|
return storage.getEncrypted("deviceIdList" + getNumberFromString(number), []);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.addDeviceIdForNumber = function(number, deviceId) {
|
self.addDeviceIdForNumber = function(number, deviceId) {
|
||||||
var deviceIdList = this.getDeviceIdListFromNumber(getNumberFromString(number));
|
var deviceIdList = this.getDeviceIdListFromNumber(getNumberFromString(number));
|
||||||
for (var i = 0; i < deviceIdList.length; i++) {
|
for (var i = 0; i < deviceIdList.length; i++) {
|
||||||
if (deviceIdList[i] == deviceId)
|
if (deviceIdList[i] == deviceId)
|
||||||
|
@ -313,8 +313,15 @@ var storage = new function() {
|
||||||
storage.putEncrypted("deviceIdList" + getNumberFromString(number), deviceIdList);
|
storage.putEncrypted("deviceIdList" + getNumberFromString(number), deviceIdList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var getDeviceId = function(encodedNumber) {
|
||||||
|
var split = encodedNumber.split(".");
|
||||||
|
if (split.length > 1)
|
||||||
|
return split[1];
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
// throws "Identity key mismatch"
|
// throws "Identity key mismatch"
|
||||||
this.saveDeviceObject = function(deviceObject) {
|
self.saveDeviceObject = function(deviceObject) {
|
||||||
var existing = this.getDeviceObject(deviceObject.encodedNumber);
|
var existing = this.getDeviceObject(deviceObject.encodedNumber);
|
||||||
if (existing === undefined)
|
if (existing === undefined)
|
||||||
existing = {encodedNumber: getEncodedNumber(deviceObject.encodedNumber)};
|
existing = {encodedNumber: getEncodedNumber(deviceObject.encodedNumber)};
|
||||||
|
@ -331,15 +338,19 @@ var storage = new function() {
|
||||||
this.addDeviceIdForNumber(deviceObject.encodedNumber, getDeviceId(deviceObject.encodedNumber));
|
this.addDeviceIdForNumber(deviceObject.encodedNumber, getDeviceId(deviceObject.encodedNumber));
|
||||||
}
|
}
|
||||||
|
|
||||||
this.getDeviceObjectListFromNumber = function(number) {
|
self.getDeviceObjectListFromNumber = function(number) {
|
||||||
var deviceObjectList = [];
|
var deviceObjectList = [];
|
||||||
var deviceIdList = this.getDeviceIdListFromNumber(number);
|
var deviceIdList = this.getDeviceIdListFromNumber(number);
|
||||||
for (var i = 0; i < deviceIdList.length; i++)
|
for (var i = 0; i < deviceIdList.length; i++)
|
||||||
deviceObjectList[deviceObjectList.length] = this.getDeviceObject(getNumberFromString(number) + "." + deviceIdList[i]);
|
deviceObjectList[deviceObjectList.length] = this.getDeviceObject(getNumberFromString(number) + "." + deviceIdList[i]);
|
||||||
return deviceObjectList;
|
return deviceObjectList;
|
||||||
}
|
}
|
||||||
};
|
|
||||||
};
|
return self;
|
||||||
|
}();
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}();
|
||||||
|
|
||||||
function registrationDone() {
|
function registrationDone() {
|
||||||
storage.putUnencrypted("registration_done", "");
|
storage.putUnencrypted("registration_done", "");
|
||||||
|
@ -374,221 +385,232 @@ function storeMessage(messageObject) {
|
||||||
/**********************
|
/**********************
|
||||||
*** NaCL Interface ***
|
*** NaCL Interface ***
|
||||||
**********************/
|
**********************/
|
||||||
var USE_NACL = false;
|
window.textsecure.nacl = function() {
|
||||||
|
var self = {};
|
||||||
|
|
||||||
var onLoadCallbacks = [];
|
self.USE_NACL = false;
|
||||||
var naclLoaded = 0;
|
|
||||||
function registerOnLoadFunction(func) {
|
|
||||||
if (naclLoaded || !USE_NACL) {
|
|
||||||
func();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
onLoadCallbacks[onLoadCallbacks.length] = func;
|
|
||||||
}
|
|
||||||
|
|
||||||
var naclMessageNextId = 0;
|
var onLoadCallbacks = [];
|
||||||
var naclMessageIdCallbackMap = {};
|
var naclLoaded = 0;
|
||||||
function moduleDidLoad() {
|
self.registerOnLoadFunction = function(func) {
|
||||||
common.hideModule();
|
if (naclLoaded || !self.USE_NACL) {
|
||||||
naclLoaded = 1;
|
func();
|
||||||
for (var i = 0; i < onLoadCallbacks.length; i++)
|
|
||||||
onLoadCallbacks[i]();
|
|
||||||
onLoadCallbacks = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleMessage(message) {
|
|
||||||
naclMessageIdCallbackMap[message.data.call_id](message.data);
|
|
||||||
}
|
|
||||||
|
|
||||||
function postNaclMessage(message) {
|
|
||||||
if (!USE_NACL)
|
|
||||||
throw new Error("Attempted to make NaCL call with !USE_NACL?");
|
|
||||||
|
|
||||||
return new Promise(function(resolve) {
|
|
||||||
naclMessageIdCallbackMap[naclMessageNextId] = resolve;
|
|
||||||
message.call_id = naclMessageNextId++;
|
|
||||||
|
|
||||||
common.naclModule.postMessage(message);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// message_callback(decoded_protobuf) (use decodeMessage(proto))
|
|
||||||
var subscribeToPushMessageSemaphore = 0;
|
|
||||||
function subscribeToPush(message_callback) {
|
|
||||||
subscribeToPushMessageSemaphore++;
|
|
||||||
if (subscribeToPushMessageSemaphore <= 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var user = storage.getUnencrypted("number_id");
|
|
||||||
var password = storage.getEncrypted("password");
|
|
||||||
var URL = URL_BASE.replace(/^http:/g, "ws:").replace(/^https:/g, "wss:") + URL_CALLS['push'] + "/?user=%2B" + getString(user).substring(1) + "&password=" + getString(password);
|
|
||||||
var socket = new WebSocket(URL);
|
|
||||||
|
|
||||||
var pingInterval;
|
|
||||||
|
|
||||||
//TODO: GUI
|
|
||||||
socket.onerror = function(socketEvent) {
|
|
||||||
console.log('Server is down :(');
|
|
||||||
clearInterval(pingInterval);
|
|
||||||
subscribeToPushMessageSemaphore--;
|
|
||||||
setTimeout(function() { subscribeToPush(message_callback); }, 60000);
|
|
||||||
};
|
|
||||||
socket.onclose = function(socketEvent) {
|
|
||||||
console.log('Server closed :(');
|
|
||||||
clearInterval(pingInterval);
|
|
||||||
subscribeToPushMessageSemaphore--;
|
|
||||||
setTimeout(function() { subscribeToPush(message_callback); }, 60000);
|
|
||||||
};
|
|
||||||
socket.onopen = function(socketEvent) {
|
|
||||||
console.log('Connected to server!');
|
|
||||||
pingInterval = setInterval(function() { console.log("Sending server ping message."); 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;
|
return;
|
||||||
}
|
}
|
||||||
|
onLoadCallbacks[onLoadCallbacks.length] = func;
|
||||||
|
}
|
||||||
|
|
||||||
if (message.type == 3) {
|
var naclMessageNextId = 0;
|
||||||
console.log("Got pong message");
|
var naclMessageIdCallbackMap = {};
|
||||||
} else if (message.type === undefined && message.id !== undefined) {
|
window.moduleDidLoad = function() {
|
||||||
textsecure.crypto.decryptWebsocketMessage(message.message).then(function(plaintext) {
|
common.hideModule();
|
||||||
var proto = decodeIncomingPushMessageProtobuf(getString(plaintext));
|
naclLoaded = 1;
|
||||||
// After this point, a) decoding errors are not the server's fault, and
|
for (var i = 0; i < onLoadCallbacks.length; i++)
|
||||||
// b) we should handle them gracefully and tell the user they received an invalid message
|
onLoadCallbacks[i]();
|
||||||
console.log("Successfully decoded message with id: " + message.id);
|
onLoadCallbacks = [];
|
||||||
socket.send(JSON.stringify({type: 1, id: message.id}));
|
}
|
||||||
return textsecure.crypto.handleIncomingPushMessageProto(proto).then(function(decrypted) {
|
|
||||||
var handleAttachment = function(attachment) {
|
window.handleMessage = function(message) {
|
||||||
return API.getAttachment(attachment.id).then(function(encryptedBin) {
|
naclMessageIdCallbackMap[message.data.call_id](message.data);
|
||||||
return textsecure.crypto.decryptAttachment(encryptedBin, toArrayBuffer(attachment.key)).then(function(decryptedBin) {
|
}
|
||||||
attachment.decrypted = decryptedBin;
|
|
||||||
|
self.postNaclMessage = function(message) {
|
||||||
|
if (!self.USE_NACL)
|
||||||
|
throw new Error("Attempted to make NaCL call with !USE_NACL?");
|
||||||
|
|
||||||
|
return new Promise(function(resolve) {
|
||||||
|
naclMessageIdCallbackMap[naclMessageNextId] = resolve;
|
||||||
|
message.call_id = naclMessageNextId++;
|
||||||
|
|
||||||
|
common.naclModule.postMessage(message);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}();
|
||||||
|
|
||||||
|
//TODO: Some kind of textsecure.init(use_nacl)
|
||||||
|
window.textsecure.registerOnLoadFunction = window.textsecure.nacl.registerOnLoadFunction;
|
||||||
|
|
||||||
|
// message_callback({message: decryptedMessage, pushMessage: server-providedPushMessage})
|
||||||
|
window.textsecure.subscribeToPush = function() {
|
||||||
|
var subscribeToPushMessageSemaphore = 0;
|
||||||
|
return function(message_callback) {
|
||||||
|
subscribeToPushMessageSemaphore++;
|
||||||
|
if (subscribeToPushMessageSemaphore <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var user = storage.getUnencrypted("number_id");
|
||||||
|
var password = storage.getEncrypted("password");
|
||||||
|
var URL = URL_BASE.replace(/^http:/g, "ws:").replace(/^https:/g, "wss:") + URL_CALLS['push'] + "/?user=%2B" + getString(user).substring(1) + "&password=" + getString(password);
|
||||||
|
var socket = new WebSocket(URL);
|
||||||
|
|
||||||
|
var pingInterval;
|
||||||
|
|
||||||
|
//TODO: GUI
|
||||||
|
socket.onerror = function(socketEvent) {
|
||||||
|
console.log('Server is down :(');
|
||||||
|
clearInterval(pingInterval);
|
||||||
|
subscribeToPushMessageSemaphore--;
|
||||||
|
setTimeout(function() { subscribeToPush(message_callback); }, 60000);
|
||||||
|
};
|
||||||
|
socket.onclose = function(socketEvent) {
|
||||||
|
console.log('Server closed :(');
|
||||||
|
clearInterval(pingInterval);
|
||||||
|
subscribeToPushMessageSemaphore--;
|
||||||
|
setTimeout(function() { subscribeToPush(message_callback); }, 60000);
|
||||||
|
};
|
||||||
|
socket.onopen = function(socketEvent) {
|
||||||
|
console.log('Connected to server!');
|
||||||
|
pingInterval = setInterval(function() { console.log("Sending server ping message."); 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message.type == 3) {
|
||||||
|
console.log("Got pong message");
|
||||||
|
} else if (message.type === undefined && message.id !== undefined) {
|
||||||
|
textsecure.crypto.decryptWebsocketMessage(message.message).then(function(plaintext) {
|
||||||
|
var proto = decodeIncomingPushMessageProtobuf(getString(plaintext));
|
||||||
|
// After this point, a) decoding errors are not the server's fault, and
|
||||||
|
// b) we should handle them gracefully and tell the user they received an invalid message
|
||||||
|
console.log("Successfully decoded message with id: " + message.id);
|
||||||
|
socket.send(JSON.stringify({type: 1, id: message.id}));
|
||||||
|
return textsecure.crypto.handleIncomingPushMessageProto(proto).then(function(decrypted) {
|
||||||
|
var handleAttachment = function(attachment) {
|
||||||
|
return textsecure.api.getAttachment(attachment.id).then(function(encryptedBin) {
|
||||||
|
return textsecure.crypto.decryptAttachment(encryptedBin, toArrayBuffer(attachment.key)).then(function(decryptedBin) {
|
||||||
|
attachment.decrypted = decryptedBin;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
var promises = [];
|
||||||
|
for (var i = 0; i < decrypted.message.attachments.length; i++) {
|
||||||
|
promises[i] = handleAttachment(decrypted.message.attachments[i]);
|
||||||
|
}
|
||||||
|
return Promise.all(promises).then(function() {
|
||||||
|
storeMessage(decrypted);
|
||||||
|
message_callback(decrypted);
|
||||||
});
|
});
|
||||||
};
|
})
|
||||||
|
}).catch(function(e) {
|
||||||
var promises = [];
|
console.log("Error handling incoming message: ");
|
||||||
for (var i = 0; i < decrypted.message.attachments.length; i++) {
|
console.log(e);
|
||||||
promises[i] = handleAttachment(decrypted.message.attachments[i]);
|
});
|
||||||
}
|
|
||||||
return Promise.all(promises).then(function() {
|
|
||||||
storeMessage(decrypted);
|
|
||||||
message_callback(decrypted);
|
|
||||||
});
|
|
||||||
})
|
|
||||||
}).catch(function(e) {
|
|
||||||
console.log("Error handling incoming message: ");
|
|
||||||
console.log(e);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// success_callback(identity_key), error_callback(error_msg)
|
|
||||||
function getKeysForNumber(number) {
|
|
||||||
return API.getKeysForNumber(number).then(function(response) {
|
|
||||||
for (var i = 0; i < response.length; i++) {
|
|
||||||
storage.devices.saveDeviceObject({
|
|
||||||
encodedNumber: number + "." + response[i].deviceId,
|
|
||||||
identityKey: response[i].identityKey,
|
|
||||||
publicKey: response[i].publicKey,
|
|
||||||
preKeyId: response[i].keyId,
|
|
||||||
registrationId: response[i].registrationId
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return response[0].identityKey;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// success_callback(server success/failure map), error_callback(error_msg)
|
|
||||||
// message == PushMessageContentProto (NOT STRING)
|
|
||||||
function sendMessageToDevices(number, deviceObjectList, message, success_callback, error_callback) {
|
|
||||||
var jsonData = [];
|
|
||||||
var relay = undefined;
|
|
||||||
var promises = [];
|
|
||||||
|
|
||||||
var addEncryptionFor = function(i) {
|
|
||||||
return textsecure.crypto.encryptMessageFor(deviceObjectList[i], message).then(function(encryptedMsg) {
|
|
||||||
jsonData[i] = {
|
|
||||||
type: encryptedMsg.type,
|
|
||||||
destination: deviceObjectList[i].encodedNumber,
|
|
||||||
destinationRegistrationId: deviceObjectList[i].registrationId,
|
|
||||||
body: encryptedMsg.body,
|
|
||||||
timestamp: new Date().getTime()
|
|
||||||
};
|
|
||||||
|
|
||||||
if (deviceObjectList[i].relay !== undefined) {
|
|
||||||
jsonData[i].relay = deviceObjectList[i].relay;
|
|
||||||
if (relay === undefined)
|
|
||||||
relay = jsonData[i].relay;
|
|
||||||
else if (relay != jsonData[i].relay)
|
|
||||||
throw new Error("Mismatched relays for number " + number);
|
|
||||||
} else {
|
|
||||||
if (relay === undefined)
|
|
||||||
relay = "";
|
|
||||||
else if (relay != "")
|
|
||||||
throw new Error("Mismatched relays for number " + number);
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}();
|
||||||
|
|
||||||
|
// sendMessage(numbers = [], message = PushMessageContentProto, callback(success/failure map))
|
||||||
|
window.textsecure.sendMessage = function() {
|
||||||
|
function getKeysForNumber(number) {
|
||||||
|
return textsecure.api.getKeysForNumber(number).then(function(response) {
|
||||||
|
for (var i = 0; i < response.length; i++) {
|
||||||
|
storage.devices.saveDeviceObject({
|
||||||
|
encodedNumber: number + "." + response[i].deviceId,
|
||||||
|
identityKey: response[i].identityKey,
|
||||||
|
publicKey: response[i].publicKey,
|
||||||
|
preKeyId: response[i].keyId,
|
||||||
|
registrationId: response[i].registrationId
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return response[0].identityKey;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
for (var i = 0; i < deviceObjectList.length; i++)
|
|
||||||
promises[i] = addEncryptionFor(i);
|
|
||||||
return Promise.all(promises).then(function() {
|
|
||||||
return API.sendMessages(number, jsonData);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// callback(success/failure map, see code)
|
// success_callback(server success/failure map), error_callback(error_msg)
|
||||||
// message == PushMessageContentProto (NOT STRING)
|
// message == PushMessageContentProto (NOT STRING)
|
||||||
function sendMessageToNumbers(numbers, message, callback) {
|
function sendMessageToDevices(number, deviceObjectList, message, success_callback, error_callback) {
|
||||||
var numbersCompleted = 0;
|
var jsonData = [];
|
||||||
var errors = [];
|
var relay = undefined;
|
||||||
var successfulNumbers = [];
|
var promises = [];
|
||||||
|
|
||||||
var numberCompleted = function() {
|
var addEncryptionFor = function(i) {
|
||||||
numbersCompleted++;
|
return textsecure.crypto.encryptMessageFor(deviceObjectList[i], message).then(function(encryptedMsg) {
|
||||||
if (numbersCompleted >= numbers.length)
|
jsonData[i] = {
|
||||||
callback({success: successfulNumbers, failure: errors});
|
type: encryptedMsg.type,
|
||||||
|
destination: deviceObjectList[i].encodedNumber,
|
||||||
|
destinationRegistrationId: deviceObjectList[i].registrationId,
|
||||||
|
body: encryptedMsg.body,
|
||||||
|
timestamp: new Date().getTime()
|
||||||
|
};
|
||||||
|
|
||||||
|
if (deviceObjectList[i].relay !== undefined) {
|
||||||
|
jsonData[i].relay = deviceObjectList[i].relay;
|
||||||
|
if (relay === undefined)
|
||||||
|
relay = jsonData[i].relay;
|
||||||
|
else if (relay != jsonData[i].relay)
|
||||||
|
throw new Error("Mismatched relays for number " + number);
|
||||||
|
} else {
|
||||||
|
if (relay === undefined)
|
||||||
|
relay = "";
|
||||||
|
else if (relay != "")
|
||||||
|
throw new Error("Mismatched relays for number " + number);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
for (var i = 0; i < deviceObjectList.length; i++)
|
||||||
|
promises[i] = addEncryptionFor(i);
|
||||||
|
return Promise.all(promises).then(function() {
|
||||||
|
return textsecure.api.sendMessages(number, jsonData);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
var registerError = function(number, message, error) {
|
return function(numbers, message, callback) {
|
||||||
errors[errors.length] = { number: number, reason: message, error: error };
|
var numbersCompleted = 0;
|
||||||
numberCompleted();
|
var errors = [];
|
||||||
}
|
var successfulNumbers = [];
|
||||||
|
|
||||||
var doSendMessage = function(number, devicesForNumber, message) {
|
var numberCompleted = function() {
|
||||||
return sendMessageToDevices(number, devicesForNumber, message).then(function(result) {
|
numbersCompleted++;
|
||||||
successfulNumbers[successfulNumbers.length] = number;
|
if (numbersCompleted >= numbers.length)
|
||||||
|
callback({success: successfulNumbers, failure: errors});
|
||||||
|
}
|
||||||
|
|
||||||
|
var registerError = function(number, message, error) {
|
||||||
|
errors[errors.length] = { number: number, reason: message, error: error };
|
||||||
numberCompleted();
|
numberCompleted();
|
||||||
}).catch(function(error) {
|
}
|
||||||
if (error instanceof Error && error.name == "HTTPError" && (error.message == 410 || error.message == 409)) {
|
|
||||||
//TODO: Re-request keys for number here
|
|
||||||
}
|
|
||||||
registerError(number, "Failed to create or send message", error);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var i = 0; i < numbers.length; i++) {
|
var doSendMessage = function(number, devicesForNumber, message) {
|
||||||
var number = numbers[i];
|
return sendMessageToDevices(number, devicesForNumber, message).then(function(result) {
|
||||||
var devicesForNumber = storage.devices.getDeviceObjectListFromNumber(number);
|
successfulNumbers[successfulNumbers.length] = number;
|
||||||
|
numberCompleted();
|
||||||
if (devicesForNumber.length == 0) {
|
|
||||||
getKeysForNumber(number).then(function(identity_key) {
|
|
||||||
devicesForNumber = storage.devices.getDeviceObjectListFromNumber(number);
|
|
||||||
if (devicesForNumber.length == 0)
|
|
||||||
registerError(number, "Failed to retreive new device keys for number " + number, null);
|
|
||||||
else
|
|
||||||
doSendMessage(number, devicesForNumber, message);
|
|
||||||
}).catch(function(error) {
|
}).catch(function(error) {
|
||||||
registerError(number, "Failed to retreive new device keys for number " + number, error);
|
if (error instanceof Error && error.name == "HTTPError" && (error.message == 410 || error.message == 409)) {
|
||||||
|
//TODO: Re-request keys for number here
|
||||||
|
}
|
||||||
|
registerError(number, "Failed to create or send message", error);
|
||||||
});
|
});
|
||||||
} else
|
}
|
||||||
doSendMessage(number, devicesForNumber, message);
|
|
||||||
|
for (var i = 0; i < numbers.length; i++) {
|
||||||
|
var number = numbers[i];
|
||||||
|
var devicesForNumber = storage.devices.getDeviceObjectListFromNumber(number);
|
||||||
|
|
||||||
|
if (devicesForNumber.length == 0) {
|
||||||
|
getKeysForNumber(number).then(function(identity_key) {
|
||||||
|
devicesForNumber = storage.devices.getDeviceObjectListFromNumber(number);
|
||||||
|
if (devicesForNumber.length == 0)
|
||||||
|
registerError(number, "Failed to retreive new device keys for number " + number, null);
|
||||||
|
else
|
||||||
|
doSendMessage(number, devicesForNumber, message);
|
||||||
|
}).catch(function(error) {
|
||||||
|
registerError(number, "Failed to retreive new device keys for number " + number, error);
|
||||||
|
});
|
||||||
|
} else
|
||||||
|
doSendMessage(number, devicesForNumber, message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}();
|
||||||
|
|
||||||
function requestIdentityPrivKeyFromMasterDevice(number, identityKey) {
|
function requestIdentityPrivKeyFromMasterDevice(number, identityKey) {
|
||||||
sendMessageToDevices([storage.devices.getDeviceObject(getNumberFromString(number)) + ".1"],
|
sendMessageToDevices([storage.devices.getDeviceObject(getNumberFromString(number)) + ".1"],
|
||||||
|
|
|
@ -56,7 +56,7 @@ $('#init-go-single-client').click(function() {
|
||||||
|
|
||||||
single_device = true;
|
single_device = true;
|
||||||
|
|
||||||
API.requestVerificationCode(number,
|
textsecure.api.requestVerificationCode(number,
|
||||||
function(response) { },
|
function(response) { },
|
||||||
function(code) {
|
function(code) {
|
||||||
alert("Failed to send key?" + code); //TODO
|
alert("Failed to send key?" + code); //TODO
|
||||||
|
@ -76,7 +76,7 @@ $('#init-go').click(function() {
|
||||||
$('#verify4done').html('');
|
$('#verify4done').html('');
|
||||||
$('#verify').show();
|
$('#verify').show();
|
||||||
|
|
||||||
API.confirmCode($('#code').val(), number, password, signaling_key, registrationId, single_device,
|
textsecure.api.confirmCode($('#code').val(), number, password, signaling_key, registrationId, single_device,
|
||||||
function(response) {
|
function(response) {
|
||||||
if (single_device)
|
if (single_device)
|
||||||
response = 1;
|
response = 1;
|
||||||
|
@ -91,7 +91,7 @@ $('#init-go').click(function() {
|
||||||
$('#verify2done').html('done');
|
$('#verify2done').html('done');
|
||||||
textsecure.crypto.generateKeys().then(function(keys) {
|
textsecure.crypto.generateKeys().then(function(keys) {
|
||||||
$('#verify3done').html('done');
|
$('#verify3done').html('done');
|
||||||
API.registerKeys(keys,
|
textsecure.api.registerKeys(keys,
|
||||||
function(response) {
|
function(response) {
|
||||||
$('#complete-number').html(number);
|
$('#complete-number').html(number);
|
||||||
$('#verify').hide();
|
$('#verify').hide();
|
||||||
|
@ -105,15 +105,17 @@ $('#init-go').click(function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!single_device) {
|
if (!single_device) {
|
||||||
getKeysForNumber(number).then(function(identityKey) {
|
//TODO: Redo all this
|
||||||
subscribeToPush(function(message) {
|
/*getKeysForNumber(number).then(function(identityKey) {
|
||||||
|
textsecure.subscribeToPush(function(message) {
|
||||||
//TODO receive shared identity key
|
//TODO receive shared identity key
|
||||||
register_keys_func();
|
register_keys_func();
|
||||||
});
|
});
|
||||||
requestIdentityPrivKeyFromMasterDevice(number);
|
requestIdentityPrivKeyFromMasterDevice(number);
|
||||||
}).catch(function(error) {
|
}).catch(function(error) {
|
||||||
alert(error); //TODO
|
alert(error); //TODO
|
||||||
});
|
});*/
|
||||||
|
register_keys_func();
|
||||||
} else {
|
} else {
|
||||||
register_keys_func();
|
register_keys_func();
|
||||||
}
|
}
|
||||||
|
@ -136,7 +138,7 @@ $('#init-go').click(function() {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
registerOnLoadFunction(function() {
|
textsecure.registerOnLoadFunction(function() {
|
||||||
if (!isRegistrationDone()) {
|
if (!isRegistrationDone()) {
|
||||||
$('#init-setup').show();
|
$('#init-setup').show();
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -23,7 +23,7 @@ $('#send_link').click(function() {
|
||||||
$('#send').show();
|
$('#send').show();
|
||||||
});
|
});
|
||||||
|
|
||||||
registerOnLoadFunction(function() {
|
textsecure.registerOnLoadFunction(function() {
|
||||||
if (storage.getUnencrypted("number_id") === undefined) {
|
if (storage.getUnencrypted("number_id") === undefined) {
|
||||||
chrome.tabs.create({url: "options.html"});
|
chrome.tabs.create({url: "options.html"});
|
||||||
} else {
|
} else {
|
||||||
|
@ -73,7 +73,7 @@ registerOnLoadFunction(function() {
|
||||||
var messageProto = new PushMessageContentProtobuf();
|
var messageProto = new PushMessageContentProtobuf();
|
||||||
messageProto.body = input.val();
|
messageProto.body = input.val();
|
||||||
|
|
||||||
sendMessageToNumbers(sendDestinations, messageProto, function(result) {
|
textsecure.sendMessage(sendDestinations, messageProto, function(result) {
|
||||||
console.log(result);
|
console.log(result);
|
||||||
button.removeAttr("disabled");
|
button.removeAttr("disabled");
|
||||||
button.text("Send");
|
button.text("Send");
|
||||||
|
@ -109,7 +109,7 @@ registerOnLoadFunction(function() {
|
||||||
}
|
}
|
||||||
var messageProto = new PushMessageContentProtobuf();
|
var messageProto = new PushMessageContentProtobuf();
|
||||||
messageProto.body = $("#popup_send_text").val();
|
messageProto.body = $("#popup_send_text").val();
|
||||||
sendMessageToNumbers(numbers, messageProto,
|
textsecure.sendMessage(numbers, messageProto,
|
||||||
//TODO: Handle result
|
//TODO: Handle result
|
||||||
function(thing) {console.log(thing);});
|
function(thing) {console.log(thing);});
|
||||||
});
|
});
|
||||||
|
|
|
@ -95,7 +95,7 @@ function hexToArrayBuffer(str) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
registerOnLoadFunction(function() {
|
textsecure.registerOnLoadFunction(function() {
|
||||||
localStorage.clear();
|
localStorage.clear();
|
||||||
|
|
||||||
// Random tests to check my JS knowledge
|
// Random tests to check my JS knowledge
|
||||||
|
|
Loading…
Reference in a new issue