addDevice.js 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. /* This Source Code Form is subject to the terms of the Mozilla Public
  2. * License, v. 2.0. If a copy of the MPL was not distributed with this
  3. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  4. var Ci = Components.interfaces;
  5. var Cc = Components.classes;
  6. var Cu = Components.utils;
  7. Cu.import("resource://services-sync/main.js");
  8. Cu.import("resource://gre/modules/XPCOMUtils.jsm");
  9. const PIN_PART_LENGTH = 4;
  10. const ADD_DEVICE_PAGE = 0;
  11. const SYNC_KEY_PAGE = 1;
  12. const DEVICE_CONNECTED_PAGE = 2;
  13. var gSyncAddDevice = {
  14. init: function() {
  15. this.pin1.setAttribute("maxlength", PIN_PART_LENGTH);
  16. this.pin2.setAttribute("maxlength", PIN_PART_LENGTH);
  17. this.pin3.setAttribute("maxlength", PIN_PART_LENGTH);
  18. this.nextFocusEl = {pin1: this.pin2,
  19. pin2: this.pin3,
  20. pin3: this.wizard.getButton("next")};
  21. this.throbber = document.getElementById("pairDeviceThrobber");
  22. this.errorRow = document.getElementById("errorRow");
  23. // Kick off a sync. That way the server will have the most recent data from
  24. // this computer and it will show up immediately on the new device.
  25. Weave.Service.scheduler.scheduleNextSync(0);
  26. },
  27. onPageShow: function() {
  28. this.wizard.getButton("back").hidden = true;
  29. switch (this.wizard.pageIndex) {
  30. case ADD_DEVICE_PAGE:
  31. this.onTextBoxInput();
  32. this.wizard.canRewind = false;
  33. this.wizard.getButton("next").hidden = false;
  34. this.pin1.focus();
  35. break;
  36. case SYNC_KEY_PAGE:
  37. this.wizard.canAdvance = false;
  38. this.wizard.canRewind = true;
  39. this.wizard.getButton("back").hidden = false;
  40. this.wizard.getButton("next").hidden = true;
  41. document.getElementById("weavePassphrase").value =
  42. Weave.Utils.hyphenatePassphrase(Weave.Service.identity.syncKey);
  43. break;
  44. case DEVICE_CONNECTED_PAGE:
  45. this.wizard.canAdvance = true;
  46. this.wizard.canRewind = false;
  47. this.wizard.getButton("cancel").hidden = true;
  48. break;
  49. }
  50. },
  51. onWizardAdvance: function() {
  52. switch (this.wizard.pageIndex) {
  53. case ADD_DEVICE_PAGE:
  54. this.startTransfer();
  55. return false;
  56. case DEVICE_CONNECTED_PAGE:
  57. window.close();
  58. return false;
  59. }
  60. return true;
  61. },
  62. startTransfer: function() {
  63. this.errorRow.hidden = true;
  64. // When onAbort is called, Weave may already be gone.
  65. const JPAKE_ERROR_USERABORT = Weave.JPAKE_ERROR_USERABORT;
  66. let self = this;
  67. let jpakeclient = this._jpakeclient = new Weave.JPAKEClient({
  68. onPaired: function() {
  69. let credentials = {account: Weave.Service.identity.account,
  70. password: Weave.Service.identity.basicPassword,
  71. synckey: Weave.Service.identity.syncKey,
  72. serverURL: Weave.Service.serverURL};
  73. jpakeclient.sendAndComplete(credentials);
  74. },
  75. onComplete: function() {
  76. delete self._jpakeclient;
  77. self.wizard.pageIndex = DEVICE_CONNECTED_PAGE;
  78. // Schedule a Sync for soonish to fetch the data uploaded by the
  79. // device with which we just paired.
  80. Weave.Service.scheduler.scheduleNextSync(Weave.Service.scheduler.activeInterval);
  81. },
  82. onAbort: function(error) {
  83. delete self._jpakeclient;
  84. // Aborted by user, ignore.
  85. if (error == JPAKE_ERROR_USERABORT) {
  86. return;
  87. }
  88. self.errorRow.hidden = false;
  89. self.throbber.hidden = true;
  90. self.pin1.value = self.pin2.value = self.pin3.value = "";
  91. self.pin1.disabled = self.pin2.disabled = self.pin3.disabled = false;
  92. self.pin1.focus();
  93. }
  94. });
  95. this.throbber.hidden = false;
  96. this.pin1.disabled = this.pin2.disabled = this.pin3.disabled = true;
  97. this.wizard.canAdvance = false;
  98. let pin = this.pin1.value + this.pin2.value + this.pin3.value;
  99. let expectDelay = false;
  100. jpakeclient.pairWithPIN(pin, expectDelay);
  101. },
  102. onWizardBack: function() {
  103. if (this.wizard.pageIndex != SYNC_KEY_PAGE)
  104. return true;
  105. this.wizard.pageIndex = ADD_DEVICE_PAGE;
  106. return false;
  107. },
  108. onWizardCancel: function() {
  109. if (this._jpakeclient) {
  110. this._jpakeclient.abort();
  111. delete this._jpakeclient;
  112. }
  113. return true;
  114. },
  115. onTextBoxInput: function(textbox) {
  116. if (textbox && textbox.value.length == PIN_PART_LENGTH)
  117. this.nextFocusEl[textbox.id].focus();
  118. this.wizard.canAdvance = (this.pin1.value.length == PIN_PART_LENGTH
  119. && this.pin2.value.length == PIN_PART_LENGTH
  120. && this.pin3.value.length == PIN_PART_LENGTH);
  121. },
  122. goToSyncKeyPage: function() {
  123. this.wizard.pageIndex = SYNC_KEY_PAGE;
  124. }
  125. };
  126. // onWizardAdvance() and onPageShow() are run before init() so we'll set
  127. // these up as lazy getters.
  128. ["wizard", "pin1", "pin2", "pin3"].forEach(function(id) {
  129. XPCOMUtils.defineLazyGetter(gSyncAddDevice, id, function() {
  130. return document.getElementById(id);
  131. });
  132. });