Run key generation in a worker
Ground work for a smoother registration flow. Overall UX still needs some polish but at least now we can have a progress gif or animation or whatever. Also adds the phonenumber-confirmation step as a simple alert box, which will be replaced with a nice dialogue in a later commit.
This commit is contained in:
parent
0a9598ae21
commit
bfe23d86aa
5 changed files with 137 additions and 68 deletions
76
js/generate_keys.js
Normal file
76
js/generate_keys.js
Normal file
|
@ -0,0 +1,76 @@
|
|||
/* vim: ts=4:sw=4
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/*
|
||||
* Load this script in a Web Worker to generate new prekeys without
|
||||
* tying up the main thread.
|
||||
* https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API
|
||||
*
|
||||
* Because workers don't have access to the window or localStorage, we
|
||||
* create our own version that proxies back to the caller for actual
|
||||
* storage.
|
||||
*
|
||||
* Example usage:
|
||||
*
|
||||
var myWorker = new Worker('/js/generate_keys.js');
|
||||
myWorker.onmessage = function(e) {
|
||||
switch(e.data.method) {
|
||||
case 'set':
|
||||
localStorage.setItem(e.data.key, e.data.value);
|
||||
break;
|
||||
case 'remove':
|
||||
localStorage.removeItem(e.data.key);
|
||||
break;
|
||||
case 'done':
|
||||
console.log(e.data.keys);
|
||||
}
|
||||
};
|
||||
*/
|
||||
var store = {};
|
||||
var window = this;
|
||||
importScripts('libtextsecure.js');
|
||||
window.textsecure.storage.impl = {
|
||||
/*****************************
|
||||
*** Override Storage Routines ***
|
||||
*****************************/
|
||||
put: function(key, value) {
|
||||
if (value === undefined)
|
||||
throw new Error("Tried to store undefined");
|
||||
store[key] = value;
|
||||
postMessage({method: 'set', key: key, value: value});
|
||||
},
|
||||
|
||||
get: function(key, defaultValue) {
|
||||
if (key in store) {
|
||||
return store[key];
|
||||
} else {
|
||||
return defaultValue;
|
||||
}
|
||||
},
|
||||
|
||||
remove: function(key) {
|
||||
delete store[key];
|
||||
postMessage({method: 'remove', key: key});
|
||||
},
|
||||
};
|
||||
onmessage = function(e) {
|
||||
store = e.data;
|
||||
textsecure.protocol_wrapper.generateKeys().then(function(keys) {
|
||||
postMessage({method: 'done', keys: keys});
|
||||
});
|
||||
}
|
|
@ -38388,7 +38388,7 @@ window.axolotl.sessions = {
|
|||
;(function() {
|
||||
|
||||
function loadProtoBufs(filename) {
|
||||
return dcodeIO.ProtoBuf.loadProtoFile({root: 'protos', file: filename}).build('textsecure');
|
||||
return dcodeIO.ProtoBuf.loadProtoFile({root: '/protos', file: filename}).build('textsecure');
|
||||
};
|
||||
|
||||
var pushMessages = loadProtoBufs('IncomingPushMessageSignal.proto');
|
||||
|
@ -38926,34 +38926,21 @@ window.textsecure.registerSingleDevice = function(number, verificationCode, step
|
|||
});
|
||||
}
|
||||
|
||||
window.textsecure.registerSecondDevice = function(encodedProvisionEnvelope, cryptoInfo, stepDone) {
|
||||
var envelope = textsecure.protobuf.ProvisionEnvelope.decode(encodedProvisionEnvelope, 'binary');
|
||||
return cryptoInfo.decryptAndHandleDeviceInit(envelope).then(function(identityKey) {
|
||||
stepDone(1);
|
||||
window.textsecure.registerSecondDevice = function(provisionMessage) {
|
||||
var signalingKey = textsecure.crypto.getRandomBytes(32 + 20);
|
||||
textsecure.storage.put('signaling_key', signalingKey);
|
||||
|
||||
var signalingKey = textsecure.crypto.getRandomBytes(32 + 20);
|
||||
textsecure.storage.put('signaling_key', signalingKey);
|
||||
var password = btoa(getString(textsecure.crypto.getRandomBytes(16)));
|
||||
password = password.substring(0, password.length - 2);
|
||||
textsecure.storage.put("password", password);
|
||||
|
||||
var password = btoa(getString(textsecure.crypto.getRandomBytes(16)));
|
||||
password = password.substring(0, password.length - 2);
|
||||
textsecure.storage.put("password", password);
|
||||
var registrationId = new Uint16Array(textsecure.crypto.getRandomBytes(2))[0];
|
||||
registrationId = registrationId & 0x3fff;
|
||||
textsecure.storage.put("registrationId", registrationId);
|
||||
|
||||
var registrationId = new Uint16Array(textsecure.crypto.getRandomBytes(2))[0];
|
||||
registrationId = registrationId & 0x3fff;
|
||||
textsecure.storage.put("registrationId", registrationId);
|
||||
|
||||
return textsecure.api.confirmCode(identityKey.number, identityKey.provisioningCode, password, signalingKey, registrationId, false).then(function(result) {
|
||||
textsecure.storage.user.setNumberAndDeviceId(identityKey.number, result.deviceId);
|
||||
textsecure.storage.put("regionCode", libphonenumber.util.getRegionCodeForNumber(identityKey.number));
|
||||
stepDone(2);
|
||||
|
||||
return textsecure.protocol_wrapper.generateKeys().then(function(keys) {
|
||||
stepDone(3);
|
||||
return textsecure.api.registerKeys(keys).then(function() {
|
||||
stepDone(4);
|
||||
});
|
||||
});
|
||||
});
|
||||
return textsecure.api.confirmCode(provisionMessage.number, provisionMessage.provisioningCode, password, signalingKey, registrationId, false).then(function(result) {
|
||||
textsecure.storage.user.setNumberAndDeviceId(provisionMessage.number, result.deviceId);
|
||||
textsecure.storage.put("regionCode", libphonenumber.util.getRegionCodeForNumber(provisionMessage.number));
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
@ -56,23 +56,42 @@
|
|||
request.respond(200, 'OK');
|
||||
} else if (request.path == "/v1/message" && request.verb == "PUT") {
|
||||
$('#qr').hide();
|
||||
textsecure.registerSecondDevice(request.body, cryptoInfo, function(step) {
|
||||
switch(step) {
|
||||
case 1:
|
||||
|
||||
var envelope = textsecure.protobuf.ProvisionEnvelope.decode(request.body, 'binary');
|
||||
cryptoInfo.decryptAndHandleDeviceInit(envelope).then(function(provisionMessage) {
|
||||
if (confirm(provisionMessage.number)) {
|
||||
$('#status').text('Registering new device...');
|
||||
break;
|
||||
case 2:
|
||||
$('#status').text('Generating keys...');
|
||||
break;
|
||||
case 3:
|
||||
$('#status').text('Uploading keys...');
|
||||
break;
|
||||
case 4:
|
||||
$('#status').text('All done!');
|
||||
textsecure.registration.done();
|
||||
$('#init-setup').hide();
|
||||
$('#setup-complete').show().addClass('in');
|
||||
initOptions();
|
||||
window.textsecure.registerSecondDevice(provisionMessage).then(function() {
|
||||
$('#status').text('Generating keys...');
|
||||
var counter = 0;
|
||||
var myWorker = new Worker('/js/generate_keys.js');
|
||||
myWorker.postMessage({
|
||||
maxPreKeyId: textsecure.storage.get("maxPreKeyId", 0),
|
||||
signedKeyId: textsecure.storage.get("signedKeyId", 0),
|
||||
libaxolotl25519KeyidentityKey: textsecure.storage.get("libaxolotl25519KeyidentityKey"),
|
||||
});
|
||||
myWorker.onmessage = function(e) {
|
||||
switch(e.data.method) {
|
||||
case 'set':
|
||||
textsecure.storage.put(e.data.key, e.data.value);
|
||||
counter = counter + 1;
|
||||
$('#status').text('Generating keys...' + counter);
|
||||
break;
|
||||
case 'remove':
|
||||
textsecure.storage.remove(e.data.key);
|
||||
break;
|
||||
case 'done':
|
||||
$('#status').text('Uploading keys...');
|
||||
textsecure.api.registerKeys(e.data.keys).then(function() {
|
||||
$('#status').text('All done!');
|
||||
textsecure.registration.done();
|
||||
$('#init-setup').hide();
|
||||
$('#setup-complete').show().addClass('in');
|
||||
initOptions();
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
});
|
||||
} else
|
||||
|
|
|
@ -279,33 +279,20 @@ window.textsecure.registerSingleDevice = function(number, verificationCode, step
|
|||
});
|
||||
}
|
||||
|
||||
window.textsecure.registerSecondDevice = function(encodedProvisionEnvelope, cryptoInfo, stepDone) {
|
||||
var envelope = textsecure.protobuf.ProvisionEnvelope.decode(encodedProvisionEnvelope, 'binary');
|
||||
return cryptoInfo.decryptAndHandleDeviceInit(envelope).then(function(identityKey) {
|
||||
stepDone(1);
|
||||
window.textsecure.registerSecondDevice = function(provisionMessage) {
|
||||
var signalingKey = textsecure.crypto.getRandomBytes(32 + 20);
|
||||
textsecure.storage.put('signaling_key', signalingKey);
|
||||
|
||||
var signalingKey = textsecure.crypto.getRandomBytes(32 + 20);
|
||||
textsecure.storage.put('signaling_key', signalingKey);
|
||||
var password = btoa(getString(textsecure.crypto.getRandomBytes(16)));
|
||||
password = password.substring(0, password.length - 2);
|
||||
textsecure.storage.put("password", password);
|
||||
|
||||
var password = btoa(getString(textsecure.crypto.getRandomBytes(16)));
|
||||
password = password.substring(0, password.length - 2);
|
||||
textsecure.storage.put("password", password);
|
||||
var registrationId = new Uint16Array(textsecure.crypto.getRandomBytes(2))[0];
|
||||
registrationId = registrationId & 0x3fff;
|
||||
textsecure.storage.put("registrationId", registrationId);
|
||||
|
||||
var registrationId = new Uint16Array(textsecure.crypto.getRandomBytes(2))[0];
|
||||
registrationId = registrationId & 0x3fff;
|
||||
textsecure.storage.put("registrationId", registrationId);
|
||||
|
||||
return textsecure.api.confirmCode(identityKey.number, identityKey.provisioningCode, password, signalingKey, registrationId, false).then(function(result) {
|
||||
textsecure.storage.user.setNumberAndDeviceId(identityKey.number, result.deviceId);
|
||||
textsecure.storage.put("regionCode", libphonenumber.util.getRegionCodeForNumber(identityKey.number));
|
||||
stepDone(2);
|
||||
|
||||
return textsecure.protocol_wrapper.generateKeys().then(function(keys) {
|
||||
stepDone(3);
|
||||
return textsecure.api.registerKeys(keys).then(function() {
|
||||
stepDone(4);
|
||||
});
|
||||
});
|
||||
});
|
||||
return textsecure.api.confirmCode(provisionMessage.number, provisionMessage.provisioningCode, password, signalingKey, registrationId, false).then(function(result) {
|
||||
textsecure.storage.user.setNumberAndDeviceId(provisionMessage.number, result.deviceId);
|
||||
textsecure.storage.put("regionCode", libphonenumber.util.getRegionCodeForNumber(provisionMessage.number));
|
||||
});
|
||||
};
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
;(function() {
|
||||
|
||||
function loadProtoBufs(filename) {
|
||||
return dcodeIO.ProtoBuf.loadProtoFile({root: 'protos', file: filename}).build('textsecure');
|
||||
return dcodeIO.ProtoBuf.loadProtoFile({root: '/protos', file: filename}).build('textsecure');
|
||||
};
|
||||
|
||||
var pushMessages = loadProtoBufs('IncomingPushMessageSignal.proto');
|
||||
|
|
Loading…
Reference in a new issue