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…
	
	Add table
		Add a link
		
	
		Reference in a new issue