☠☠ backed out by e3d409d10dea ☠ ☠ | |
author | Edouard Oger <eoger@fastmail.com> |
Tue, 24 May 2016 16:19:47 -0700 | |
changeset 338886 | 7520b940afc85c299b6cb500477c8906eecde531 |
parent 338885 | e88afebe9226340f67730f2c867a78a33e7fa4e0 |
child 338887 | e3d409d10dea7c1c94630abf52e6e9245a77f448 |
push id | 6249 |
push user | jlund@mozilla.com |
push date | Mon, 01 Aug 2016 13:59:36 +0000 |
treeherder | mozilla-beta@bad9d4f5bf7e [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | kitcambridge |
bugs | 1267760 |
milestone | 49.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/services/fxaccounts/FxAccounts.jsm +++ b/services/fxaccounts/FxAccounts.jsm @@ -291,16 +291,20 @@ function copyObjectProperties(from, to, if (desc.set) { desc.set = desc.set.bind(thisArg); } Object.defineProperty(to, prop, desc); } } +function urlsafeBase64Encode(key) { + return ChromeUtils.base64URLEncode(new Uint8Array(key), { pad: false }); +} + /** * The public API's constructor. */ this.FxAccounts = function (mockInternal) { let internal = new FxAccountsInternal(); let external = {}; // Copy all public properties to the 'external' object. @@ -350,17 +354,17 @@ function FxAccountsInternal() { */ FxAccountsInternal.prototype = { // The timeout (in ms) we use to poll for a verified mail for the first 2 mins. VERIFICATION_POLL_TIMEOUT_INITIAL: 15000, // 15 seconds // And how often we poll after the first 2 mins. VERIFICATION_POLL_TIMEOUT_SUBSEQUENT: 30000, // 30 seconds. // The current version of the device registration, we use this to re-register // devices after we update what we send on device registration. - DEVICE_REGISTRATION_VERSION: 1, + DEVICE_REGISTRATION_VERSION: 2, _fxAccountsClient: null, // All significant initialization should be done in this initialize() method, // as it's called after this object has been mocked for tests. initialize() { this.currentTimer = null; this.currentAccountState = this.newAccountState(); @@ -1508,16 +1512,22 @@ FxAccountsInternal.prototype = { return this.fxaPushService.registerPushEndpoint().then(subscription => { const deviceName = this._getDeviceName(); let deviceOptions = {}; // if we were able to obtain a subscription if (subscription && subscription.endpoint) { deviceOptions.pushCallback = subscription.endpoint; + let publicKey = subscription.getKey('p256dh'); + let authKey = subscription.getKey('auth'); + if (publicKey && authKey) { + deviceOptions.pushPublicKey = urlsafeBase64Encode(publicKey); + deviceOptions.pushAuthKey = urlsafeBase64Encode(authKey); + } } if (signedInUser.deviceId) { log.debug("updating existing device details"); return this.fxAccountsClient.updateDevice( signedInUser.sessionToken, signedInUser.deviceId, deviceName, deviceOptions); }
--- a/services/fxaccounts/FxAccountsClient.jsm +++ b/services/fxaccounts/FxAccountsClient.jsm @@ -362,16 +362,20 @@ this.FxAccountsClient.prototype = { * @param name * Device name * @param type * Device type (mobile|desktop) * @param [options] * Extra device options * @param [options.pushCallback] * `pushCallback` push endpoint callback + * @param [options.pushPublicKey] + * `pushPublicKey` push public key (URLSafe Base64 string) + * @param [options.pushAuthKey] + * `pushAuthKey` push auth secret (URLSafe Base64 string) * @return Promise * Resolves to an object: * { * id: Device identifier * createdAt: Creation time (milliseconds since epoch) * name: Name of device * type: Type of device (mobile|desktop) * } @@ -380,16 +384,20 @@ this.FxAccountsClient.prototype = { let path = "/account/device"; let creds = deriveHawkCredentials(sessionTokenHex, "sessionToken"); let body = { name, type }; if (options.pushCallback) { body.pushCallback = options.pushCallback; } + if (options.pushPublicKey && options.pushAuthKey) { + body.pushPublicKey = options.pushPublicKey; + body.pushAuthKey = options.pushAuthKey; + } return this._request(path, "POST", creds, body); }, /** * Update the session or name for an existing device * * @method updateDevice @@ -398,31 +406,39 @@ this.FxAccountsClient.prototype = { * @param id * Device identifier * @param name * Device name * @param [options] * Extra device options * @param [options.pushCallback] * `pushCallback` push endpoint callback + * @param [options.pushPublicKey] + * `pushPublicKey` push public key (URLSafe Base64 string) + * @param [options.pushAuthKey] + * `pushAuthKey` push auth secret (URLSafe Base64 string) * @return Promise * Resolves to an object: * { * id: Device identifier * name: Device name * } */ updateDevice(sessionTokenHex, id, name, options = {}) { let path = "/account/device"; let creds = deriveHawkCredentials(sessionTokenHex, "sessionToken"); let body = { id, name }; if (options.pushCallback) { body.pushCallback = options.pushCallback; } + if (options.pushPublicKey && options.pushAuthKey) { + body.pushPublicKey = options.pushPublicKey; + body.pushAuthKey = options.pushAuthKey; + } return this._request(path, "POST", creds, body); }, /** * Delete a device and its associated session token, signing the user * out of the server. *
--- a/services/fxaccounts/tests/xpcshell/test_accounts_device_registration.js +++ b/services/fxaccounts/tests/xpcshell/test_accounts_device_registration.js @@ -11,16 +11,19 @@ Cu.import("resource://gre/modules/FxAcco Cu.import("resource://gre/modules/Promise.jsm"); Cu.import("resource://gre/modules/Log.jsm"); initTestLogging("Trace"); var log = Log.repository.getLogger("Services.FxAccounts.test"); log.level = Log.Level.Debug; +const BOGUS_PUBLICKEY = "BBXOKjUb84pzws1wionFpfCBjDuCh4-s_1b52WA46K5wYL2gCWEOmFKWn_NkS5nmJwTBuO8qxxdjAIDtNeklvQc"; +const BOGUS_AUTHKEY = "GSsIiaD2Mr83iPqwFNK4rw"; + Services.prefs.setCharPref("identity.fxaccounts.loglevel", "Trace"); Log.repository.getLogger("FirefoxAccounts").level = Log.Level.Trace; Services.prefs.setCharPref("identity.fxaccounts.remote.oauth.uri", "https://example.com/v1"); Services.prefs.setCharPref("identity.fxaccounts.oauth.client_id", "abc123"); Services.prefs.setCharPref("identity.fxaccounts.remote.profile.uri", "http://example.com/v1"); Services.prefs.setCharPref("identity.fxaccounts.settings.uri", "http://accounts.example.com/"); @@ -101,17 +104,21 @@ function MockFxAccounts(device = {}) { _getDeviceName() { return device.name || "mock device name"; }, fxAccountsClient: new MockFxAccountsClient(device), fxaPushService: { registerPushEndpoint() { return new Promise((resolve) => { resolve({ - endpoint: "http://mochi.test:8888" + endpoint: "http://mochi.test:8888", + getKey: function(type) { + return ChromeUtils.base64URLDecode( + type === "auth" ? BOGUS_AUTHKEY : BOGUS_PUBLICKEY, + { padding: "ignore" }); }); }); }, }, DEVICE_REGISTRATION_VERSION }); } @@ -157,16 +164,18 @@ add_task(function* test_updateDeviceRegi do_check_eq(spy.updateDevice.count, 0); do_check_eq(spy.getDeviceList.count, 0); do_check_eq(spy.registerDevice.count, 1); do_check_eq(spy.registerDevice.args[0].length, 4); do_check_eq(spy.registerDevice.args[0][0], credentials.sessionToken); do_check_eq(spy.registerDevice.args[0][1], deviceName); do_check_eq(spy.registerDevice.args[0][2], "desktop"); do_check_eq(spy.registerDevice.args[0][3].pushCallback, "http://mochi.test:8888"); + do_check_eq(spy.registerDevice.args[0][3].pushPublicKey, BOGUS_PUBLICKEY); + do_check_eq(spy.registerDevice.args[0][3].pushAuthKey, BOGUS_AUTHKEY); const state = fxa.internal.currentAccountState; const data = yield state.getUserAccountData(); do_check_eq(data.deviceId, "newly-generated device id"); do_check_eq(data.deviceRegistrationVersion, DEVICE_REGISTRATION_VERSION); }); @@ -208,16 +217,18 @@ add_task(function* test_updateDeviceRegi do_check_eq(spy.registerDevice.count, 0); do_check_eq(spy.getDeviceList.count, 0); do_check_eq(spy.updateDevice.count, 1); do_check_eq(spy.updateDevice.args[0].length, 4); do_check_eq(spy.updateDevice.args[0][0], credentials.sessionToken); do_check_eq(spy.updateDevice.args[0][1], credentials.deviceId); do_check_eq(spy.updateDevice.args[0][2], deviceName); do_check_eq(spy.updateDevice.args[0][3].pushCallback, "http://mochi.test:8888"); + do_check_eq(spy.updateDevice.args[0][3].pushPublicKey, BOGUS_PUBLICKEY); + do_check_eq(spy.updateDevice.args[0][3].pushAuthKey, BOGUS_AUTHKEY); const state = fxa.internal.currentAccountState; const data = yield state.getUserAccountData(); do_check_eq(data.deviceId, credentials.deviceId); do_check_eq(data.deviceRegistrationVersion, DEVICE_REGISTRATION_VERSION); }); @@ -265,16 +276,18 @@ add_task(function* test_updateDeviceRegi do_check_eq(spy.getDeviceList.count, 0); do_check_eq(spy.registerDevice.count, 0); do_check_eq(spy.updateDevice.count, 1); do_check_eq(spy.updateDevice.args[0].length, 4); do_check_eq(spy.updateDevice.args[0][0], credentials.sessionToken); do_check_eq(spy.updateDevice.args[0][1], credentials.deviceId); do_check_eq(spy.updateDevice.args[0][2], deviceName); do_check_eq(spy.updateDevice.args[0][3].pushCallback, "http://mochi.test:8888"); + do_check_eq(spy.updateDevice.args[0][3].pushPublicKey, BOGUS_PUBLICKEY); + do_check_eq(spy.updateDevice.args[0][3].pushAuthKey, BOGUS_AUTHKEY); const state = fxa.internal.currentAccountState; const data = yield state.getUserAccountData(); do_check_null(data.deviceId); do_check_eq(data.deviceRegistrationVersion, DEVICE_REGISTRATION_VERSION); }); @@ -328,16 +341,18 @@ add_task(function* test_updateDeviceRegi do_check_eq(result, credentials.deviceId); do_check_eq(spy.registerDevice.count, 0); do_check_eq(spy.updateDevice.count, 1); do_check_eq(spy.updateDevice.args[0].length, 4); do_check_eq(spy.updateDevice.args[0][0], credentials.sessionToken); do_check_eq(spy.updateDevice.args[0][1], credentials.deviceId); do_check_eq(spy.updateDevice.args[0][2], deviceName); do_check_eq(spy.updateDevice.args[0][3].pushCallback, "http://mochi.test:8888"); + do_check_eq(spy.updateDevice.args[0][3].pushPublicKey, BOGUS_PUBLICKEY); + do_check_eq(spy.updateDevice.args[0][3].pushAuthKey, BOGUS_AUTHKEY); do_check_eq(spy.getDeviceList.count, 1); do_check_eq(spy.getDeviceList.args[0].length, 1); do_check_eq(spy.getDeviceList.args[0][0], credentials.sessionToken); do_check_true(spy.getDeviceList.time >= spy.updateDevice.time); const state = fxa.internal.currentAccountState; const data = yield state.getUserAccountData();