1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/browser/base/content/sync/addDevice.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,157 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +const Ci = Components.interfaces; 1.9 +const Cc = Components.classes; 1.10 +const Cu = Components.utils; 1.11 + 1.12 +Cu.import("resource://services-sync/main.js"); 1.13 +Cu.import("resource://gre/modules/XPCOMUtils.jsm"); 1.14 + 1.15 +const PIN_PART_LENGTH = 4; 1.16 + 1.17 +const ADD_DEVICE_PAGE = 0; 1.18 +const SYNC_KEY_PAGE = 1; 1.19 +const DEVICE_CONNECTED_PAGE = 2; 1.20 + 1.21 +let gSyncAddDevice = { 1.22 + 1.23 + init: function init() { 1.24 + this.pin1.setAttribute("maxlength", PIN_PART_LENGTH); 1.25 + this.pin2.setAttribute("maxlength", PIN_PART_LENGTH); 1.26 + this.pin3.setAttribute("maxlength", PIN_PART_LENGTH); 1.27 + 1.28 + this.nextFocusEl = {pin1: this.pin2, 1.29 + pin2: this.pin3, 1.30 + pin3: this.wizard.getButton("next")}; 1.31 + 1.32 + this.throbber = document.getElementById("pairDeviceThrobber"); 1.33 + this.errorRow = document.getElementById("errorRow"); 1.34 + 1.35 + // Kick off a sync. That way the server will have the most recent data from 1.36 + // this computer and it will show up immediately on the new device. 1.37 + Weave.Service.scheduler.scheduleNextSync(0); 1.38 + }, 1.39 + 1.40 + onPageShow: function onPageShow() { 1.41 + this.wizard.getButton("back").hidden = true; 1.42 + 1.43 + switch (this.wizard.pageIndex) { 1.44 + case ADD_DEVICE_PAGE: 1.45 + this.onTextBoxInput(); 1.46 + this.wizard.canRewind = false; 1.47 + this.wizard.getButton("next").hidden = false; 1.48 + this.pin1.focus(); 1.49 + break; 1.50 + case SYNC_KEY_PAGE: 1.51 + this.wizard.canAdvance = false; 1.52 + this.wizard.canRewind = true; 1.53 + this.wizard.getButton("back").hidden = false; 1.54 + this.wizard.getButton("next").hidden = true; 1.55 + document.getElementById("weavePassphrase").value = 1.56 + Weave.Utils.hyphenatePassphrase(Weave.Service.identity.syncKey); 1.57 + break; 1.58 + case DEVICE_CONNECTED_PAGE: 1.59 + this.wizard.canAdvance = true; 1.60 + this.wizard.canRewind = false; 1.61 + this.wizard.getButton("cancel").hidden = true; 1.62 + break; 1.63 + } 1.64 + }, 1.65 + 1.66 + onWizardAdvance: function onWizardAdvance() { 1.67 + switch (this.wizard.pageIndex) { 1.68 + case ADD_DEVICE_PAGE: 1.69 + this.startTransfer(); 1.70 + return false; 1.71 + case DEVICE_CONNECTED_PAGE: 1.72 + window.close(); 1.73 + return false; 1.74 + } 1.75 + return true; 1.76 + }, 1.77 + 1.78 + startTransfer: function startTransfer() { 1.79 + this.errorRow.hidden = true; 1.80 + // When onAbort is called, Weave may already be gone. 1.81 + const JPAKE_ERROR_USERABORT = Weave.JPAKE_ERROR_USERABORT; 1.82 + 1.83 + let self = this; 1.84 + let jpakeclient = this._jpakeclient = new Weave.JPAKEClient({ 1.85 + onPaired: function onPaired() { 1.86 + let credentials = {account: Weave.Service.identity.account, 1.87 + password: Weave.Service.identity.basicPassword, 1.88 + synckey: Weave.Service.identity.syncKey, 1.89 + serverURL: Weave.Service.serverURL}; 1.90 + jpakeclient.sendAndComplete(credentials); 1.91 + }, 1.92 + onComplete: function onComplete() { 1.93 + delete self._jpakeclient; 1.94 + self.wizard.pageIndex = DEVICE_CONNECTED_PAGE; 1.95 + 1.96 + // Schedule a Sync for soonish to fetch the data uploaded by the 1.97 + // device with which we just paired. 1.98 + Weave.Service.scheduler.scheduleNextSync(Weave.Service.scheduler.activeInterval); 1.99 + }, 1.100 + onAbort: function onAbort(error) { 1.101 + delete self._jpakeclient; 1.102 + 1.103 + // Aborted by user, ignore. 1.104 + if (error == JPAKE_ERROR_USERABORT) { 1.105 + return; 1.106 + } 1.107 + 1.108 + self.errorRow.hidden = false; 1.109 + self.throbber.hidden = true; 1.110 + self.pin1.value = self.pin2.value = self.pin3.value = ""; 1.111 + self.pin1.disabled = self.pin2.disabled = self.pin3.disabled = false; 1.112 + self.pin1.focus(); 1.113 + } 1.114 + }); 1.115 + this.throbber.hidden = false; 1.116 + this.pin1.disabled = this.pin2.disabled = this.pin3.disabled = true; 1.117 + this.wizard.canAdvance = false; 1.118 + 1.119 + let pin = this.pin1.value + this.pin2.value + this.pin3.value; 1.120 + let expectDelay = false; 1.121 + jpakeclient.pairWithPIN(pin, expectDelay); 1.122 + }, 1.123 + 1.124 + onWizardBack: function onWizardBack() { 1.125 + if (this.wizard.pageIndex != SYNC_KEY_PAGE) 1.126 + return true; 1.127 + 1.128 + this.wizard.pageIndex = ADD_DEVICE_PAGE; 1.129 + return false; 1.130 + }, 1.131 + 1.132 + onWizardCancel: function onWizardCancel() { 1.133 + if (this._jpakeclient) { 1.134 + this._jpakeclient.abort(); 1.135 + delete this._jpakeclient; 1.136 + } 1.137 + return true; 1.138 + }, 1.139 + 1.140 + onTextBoxInput: function onTextBoxInput(textbox) { 1.141 + if (textbox && textbox.value.length == PIN_PART_LENGTH) 1.142 + this.nextFocusEl[textbox.id].focus(); 1.143 + 1.144 + this.wizard.canAdvance = (this.pin1.value.length == PIN_PART_LENGTH 1.145 + && this.pin2.value.length == PIN_PART_LENGTH 1.146 + && this.pin3.value.length == PIN_PART_LENGTH); 1.147 + }, 1.148 + 1.149 + goToSyncKeyPage: function goToSyncKeyPage() { 1.150 + this.wizard.pageIndex = SYNC_KEY_PAGE; 1.151 + } 1.152 + 1.153 +}; 1.154 +// onWizardAdvance() and onPageShow() are run before init() so we'll set 1.155 +// these up as lazy getters. 1.156 +["wizard", "pin1", "pin2", "pin3"].forEach(function (id) { 1.157 + XPCOMUtils.defineLazyGetter(gSyncAddDevice, id, function() { 1.158 + return document.getElementById(id); 1.159 + }); 1.160 +});