diff options
Diffstat (limited to 'components/sync/addDevice.js')
-rw-r--r-- | components/sync/addDevice.js | 157 |
1 files changed, 157 insertions, 0 deletions
diff --git a/components/sync/addDevice.js b/components/sync/addDevice.js new file mode 100644 index 0000000..0390d43 --- /dev/null +++ b/components/sync/addDevice.js @@ -0,0 +1,157 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +var Ci = Components.interfaces; +var Cc = Components.classes; +var Cu = Components.utils; + +Cu.import("resource://services-sync/main.js"); +Cu.import("resource://gre/modules/XPCOMUtils.jsm"); + +const PIN_PART_LENGTH = 4; + +const ADD_DEVICE_PAGE = 0; +const SYNC_KEY_PAGE = 1; +const DEVICE_CONNECTED_PAGE = 2; + +var gSyncAddDevice = { + + init: function init() { + this.pin1.setAttribute("maxlength", PIN_PART_LENGTH); + this.pin2.setAttribute("maxlength", PIN_PART_LENGTH); + this.pin3.setAttribute("maxlength", PIN_PART_LENGTH); + + this.nextFocusEl = {pin1: this.pin2, + pin2: this.pin3, + pin3: this.wizard.getButton("next")}; + + this.throbber = document.getElementById("pairDeviceThrobber"); + this.errorRow = document.getElementById("errorRow"); + + // Kick off a sync. That way the server will have the most recent data from + // this computer and it will show up immediately on the new device. + Weave.Service.scheduler.scheduleNextSync(0); + }, + + onPageShow: function onPageShow() { + this.wizard.getButton("back").hidden = true; + + switch (this.wizard.pageIndex) { + case ADD_DEVICE_PAGE: + this.onTextBoxInput(); + this.wizard.canRewind = false; + this.wizard.getButton("next").hidden = false; + this.pin1.focus(); + break; + case SYNC_KEY_PAGE: + this.wizard.canAdvance = false; + this.wizard.canRewind = true; + this.wizard.getButton("back").hidden = false; + this.wizard.getButton("next").hidden = true; + document.getElementById("weavePassphrase").value = + Weave.Utils.hyphenatePassphrase(Weave.Service.identity.syncKey); + break; + case DEVICE_CONNECTED_PAGE: + this.wizard.canAdvance = true; + this.wizard.canRewind = false; + this.wizard.getButton("cancel").hidden = true; + break; + } + }, + + onWizardAdvance: function onWizardAdvance() { + switch (this.wizard.pageIndex) { + case ADD_DEVICE_PAGE: + this.startTransfer(); + return false; + case DEVICE_CONNECTED_PAGE: + window.close(); + return false; + } + return true; + }, + + startTransfer: function startTransfer() { + this.errorRow.hidden = true; + // When onAbort is called, Weave may already be gone. + const JPAKE_ERROR_USERABORT = Weave.JPAKE_ERROR_USERABORT; + + let self = this; + let jpakeclient = this._jpakeclient = new Weave.JPAKEClient({ + onPaired: function onPaired() { + let credentials = {account: Weave.Service.identity.account, + password: Weave.Service.identity.basicPassword, + synckey: Weave.Service.identity.syncKey, + serverURL: Weave.Service.serverURL}; + jpakeclient.sendAndComplete(credentials); + }, + onComplete: function onComplete() { + delete self._jpakeclient; + self.wizard.pageIndex = DEVICE_CONNECTED_PAGE; + + // Schedule a Sync for soonish to fetch the data uploaded by the + // device with which we just paired. + Weave.Service.scheduler.scheduleNextSync(Weave.Service.scheduler.activeInterval); + }, + onAbort: function onAbort(error) { + delete self._jpakeclient; + + // Aborted by user, ignore. + if (error == JPAKE_ERROR_USERABORT) { + return; + } + + self.errorRow.hidden = false; + self.throbber.hidden = true; + self.pin1.value = self.pin2.value = self.pin3.value = ""; + self.pin1.disabled = self.pin2.disabled = self.pin3.disabled = false; + self.pin1.focus(); + } + }); + this.throbber.hidden = false; + this.pin1.disabled = this.pin2.disabled = this.pin3.disabled = true; + this.wizard.canAdvance = false; + + let pin = this.pin1.value + this.pin2.value + this.pin3.value; + let expectDelay = false; + jpakeclient.pairWithPIN(pin, expectDelay); + }, + + onWizardBack: function onWizardBack() { + if (this.wizard.pageIndex != SYNC_KEY_PAGE) + return true; + + this.wizard.pageIndex = ADD_DEVICE_PAGE; + return false; + }, + + onWizardCancel: function onWizardCancel() { + if (this._jpakeclient) { + this._jpakeclient.abort(); + delete this._jpakeclient; + } + return true; + }, + + onTextBoxInput: function onTextBoxInput(textbox) { + if (textbox && textbox.value.length == PIN_PART_LENGTH) + this.nextFocusEl[textbox.id].focus(); + + this.wizard.canAdvance = (this.pin1.value.length == PIN_PART_LENGTH + && this.pin2.value.length == PIN_PART_LENGTH + && this.pin3.value.length == PIN_PART_LENGTH); + }, + + goToSyncKeyPage: function goToSyncKeyPage() { + this.wizard.pageIndex = SYNC_KEY_PAGE; + } + +}; +// onWizardAdvance() and onPageShow() are run before init() so we'll set +// these up as lazy getters. +["wizard", "pin1", "pin2", "pin3"].forEach(function (id) { + XPCOMUtils.defineLazyGetter(gSyncAddDevice, id, function() { + return document.getElementById(id); + }); +}); |