mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1038648: [Loop] ensure exposed objects are immutable to prevent abuse by others. r=dolske
This commit is contained in:
parent
73a68a8ebb
commit
9102cf83c7
@ -33,7 +33,6 @@ function injectLoopAPI(targetWindow) {
|
||||
*/
|
||||
doNotDisturb: {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
get: function() {
|
||||
return MozLoopService.doNotDisturb;
|
||||
},
|
||||
@ -49,7 +48,6 @@ function injectLoopAPI(targetWindow) {
|
||||
*/
|
||||
locale: {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
get: function() {
|
||||
return MozLoopService.locale;
|
||||
}
|
||||
@ -65,7 +63,6 @@ function injectLoopAPI(targetWindow) {
|
||||
*/
|
||||
getStrings: {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true,
|
||||
value: function(key) {
|
||||
return MozLoopService.getStrings(key);
|
||||
@ -85,7 +82,6 @@ function injectLoopAPI(targetWindow) {
|
||||
*/
|
||||
ensureRegistered: {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true,
|
||||
value: function(callback) {
|
||||
// We translate from a promise to a callback, as we can't pass promises from
|
||||
@ -112,7 +108,6 @@ function injectLoopAPI(targetWindow) {
|
||||
*/
|
||||
noteCallUrlExpiry: {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true,
|
||||
value: function(expiryTimeSeconds) {
|
||||
MozLoopService.noteCallUrlExpiry(expiryTimeSeconds);
|
||||
@ -130,7 +125,6 @@ function injectLoopAPI(targetWindow) {
|
||||
*/
|
||||
setLoopCharPref: {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true,
|
||||
value: function(prefName, value) {
|
||||
MozLoopService.setLoopCharPref(prefName, value);
|
||||
@ -152,7 +146,6 @@ function injectLoopAPI(targetWindow) {
|
||||
*/
|
||||
getLoopCharPref: {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true,
|
||||
value: function(prefName) {
|
||||
return MozLoopService.getLoopCharPref(prefName);
|
||||
@ -164,7 +157,6 @@ function injectLoopAPI(targetWindow) {
|
||||
*/
|
||||
startAlerting: {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true,
|
||||
value: function() {
|
||||
let chromeWindow = getChromeWindow(targetWindow);
|
||||
@ -188,7 +180,6 @@ function injectLoopAPI(targetWindow) {
|
||||
*/
|
||||
stopAlerting: {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true,
|
||||
value: function() {
|
||||
if (ringerStopper) {
|
||||
@ -224,7 +215,6 @@ function injectLoopAPI(targetWindow) {
|
||||
*/
|
||||
hawkRequest: {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true,
|
||||
value: function(path, method, payloadObj, callback) {
|
||||
// XXX Should really return a DOM promise here.
|
||||
@ -239,6 +229,7 @@ function injectLoopAPI(targetWindow) {
|
||||
|
||||
let contentObj = Cu.createObjectIn(targetWindow);
|
||||
Object.defineProperties(contentObj, api);
|
||||
Object.seal(contentObj);
|
||||
Cu.makeObjectPropsNormal(contentObj);
|
||||
|
||||
targetWindow.navigator.wrappedJSObject.__defineGetter__("mozLoop", function() {
|
||||
|
@ -47,6 +47,16 @@ XPCOMUtils.defineLazyServiceGetter(this, "uuidgen",
|
||||
"@mozilla.org/uuid-generator;1",
|
||||
"nsIUUIDGenerator");
|
||||
|
||||
// The current deferred for the registration process. This is set if in progress
|
||||
// or the registration was successful. This is null if a registration attempt was
|
||||
// unsuccessful.
|
||||
let gRegisteredDeferred = null;
|
||||
let gPushHandler = null;
|
||||
let gHawkClient = null;
|
||||
let gRegisteredLoopServer = false;
|
||||
let gLocalizedStrings = null;
|
||||
let gInitializeTimer = null;
|
||||
|
||||
/**
|
||||
* Internal helper methods and state
|
||||
*
|
||||
@ -56,12 +66,7 @@ XPCOMUtils.defineLazyServiceGetter(this, "uuidgen",
|
||||
*/
|
||||
let MozLoopServiceInternal = {
|
||||
// The uri of the Loop server.
|
||||
loopServerUri: Services.prefs.getCharPref("loop.server"),
|
||||
|
||||
// The current deferred for the registration process. This is set if in progress
|
||||
// or the registration was successful. This is null if a registration attempt was
|
||||
// unsuccessful.
|
||||
_registeredDeferred: null,
|
||||
get loopServerUri() Services.prefs.getCharPref("loop.server"),
|
||||
|
||||
/**
|
||||
* The initial delay for push registration. This ensures we don't start
|
||||
@ -137,18 +142,18 @@ let MozLoopServiceInternal = {
|
||||
* rejected with an error code or string.
|
||||
*/
|
||||
promiseRegisteredWithServers: function(mockPushHandler) {
|
||||
if (this._registeredDeferred) {
|
||||
return this._registeredDeferred.promise;
|
||||
if (gRegisteredDeferred) {
|
||||
return gRegisteredDeferred.promise;
|
||||
}
|
||||
|
||||
this._registeredDeferred = Promise.defer();
|
||||
gRegisteredDeferred = Promise.defer();
|
||||
// We grab the promise early in case .initialize or its results sets
|
||||
// it back to null on error.
|
||||
let result = this._registeredDeferred.promise;
|
||||
let result = gRegisteredDeferred.promise;
|
||||
|
||||
this._pushHandler = mockPushHandler || MozLoopPushHandler;
|
||||
gPushHandler = mockPushHandler || MozLoopPushHandler;
|
||||
|
||||
this._pushHandler.initialize(this.onPushRegistered.bind(this),
|
||||
gPushHandler.initialize(this.onPushRegistered.bind(this),
|
||||
this.onHandleNotification.bind(this));
|
||||
|
||||
return result;
|
||||
@ -168,8 +173,8 @@ let MozLoopServiceInternal = {
|
||||
* rejected with this JSON-parsed response.
|
||||
*/
|
||||
hawkRequest: function(path, method, payloadObj) {
|
||||
if (!this._hawkClient) {
|
||||
this._hawkClient = new HawkClient(this.loopServerUri);
|
||||
if (!gHawkClient) {
|
||||
gHawkClient = new HawkClient(this.loopServerUri);
|
||||
}
|
||||
|
||||
let sessionToken;
|
||||
@ -186,7 +191,7 @@ let MozLoopServiceInternal = {
|
||||
2 * 32, true);
|
||||
}
|
||||
|
||||
return this._hawkClient.request(path, method, credentials, payloadObj);
|
||||
return gHawkClient.request(path, method, credentials, payloadObj);
|
||||
},
|
||||
|
||||
/**
|
||||
@ -205,8 +210,8 @@ let MozLoopServiceInternal = {
|
||||
} else {
|
||||
// XXX Bubble the precise details up to the UI somehow (bug 1013248).
|
||||
console.warn("Loop server sent an invalid session token");
|
||||
this._registeredDeferred.reject("session-token-wrong-size");
|
||||
this._registeredDeferred = null;
|
||||
gRegisteredDeferred.reject("session-token-wrong-size");
|
||||
gRegisteredDeferred = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -221,8 +226,8 @@ let MozLoopServiceInternal = {
|
||||
*/
|
||||
onPushRegistered: function(err, pushUrl) {
|
||||
if (err) {
|
||||
this._registeredDeferred.reject(err);
|
||||
this._registeredDeferred = null;
|
||||
gRegisteredDeferred.reject(err);
|
||||
gRegisteredDeferred = null;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -239,13 +244,12 @@ let MozLoopServiceInternal = {
|
||||
this.hawkRequest("/registration", "POST", { simple_push_url: pushUrl})
|
||||
.then((response) => {
|
||||
// If this failed we got an invalid token. storeSessionToken rejects
|
||||
// the _registeredDeferred promise for us, so here we just need to
|
||||
// the gRegisteredDeferred promise for us, so here we just need to
|
||||
// early return.
|
||||
if (!this.storeSessionToken(response.headers))
|
||||
return;
|
||||
|
||||
this.registeredLoopServer = true;
|
||||
this._registeredDeferred.resolve();
|
||||
gRegisteredDeferred.resolve();
|
||||
// No need to clear the promise here, everything was good, so we don't need
|
||||
// to re-register.
|
||||
}, (error) => {
|
||||
@ -266,8 +270,8 @@ let MozLoopServiceInternal = {
|
||||
|
||||
// XXX Bubble the precise details up to the UI somehow (bug 1013248).
|
||||
Cu.reportError("Failed to register with the loop server. error: " + error);
|
||||
this._registeredDeferred.reject(error.errno);
|
||||
this._registeredDeferred = null;
|
||||
gRegisteredDeferred.reject(error.errno);
|
||||
gRegisteredDeferred = null;
|
||||
}
|
||||
);
|
||||
},
|
||||
@ -293,8 +297,8 @@ let MozLoopServiceInternal = {
|
||||
* @returns {Object} a map of element ids with attributes to set.
|
||||
*/
|
||||
get localizedStrings() {
|
||||
if (this._localizedStrings)
|
||||
return this._localizedStrings;
|
||||
if (gLocalizedStrings)
|
||||
return gLocalizedStrings;
|
||||
|
||||
var stringBundle =
|
||||
Services.strings.createBundle('chrome://browser/locale/loop/loop.properties');
|
||||
@ -316,7 +320,7 @@ let MozLoopServiceInternal = {
|
||||
map[key][property] = string.value;
|
||||
}
|
||||
|
||||
return this._localizedStrings = map;
|
||||
return gLocalizedStrings = map;
|
||||
},
|
||||
|
||||
/**
|
||||
@ -445,11 +449,28 @@ let MozLoopServiceInternal = {
|
||||
Chat.open(contentWindow, origin, title, url, undefined, undefined, callback);
|
||||
}
|
||||
};
|
||||
Object.freeze(MozLoopServiceInternal);
|
||||
|
||||
let gInitializeTimerFunc = () => {
|
||||
// Kick off the push notification service into registering after a timeout
|
||||
// this ensures we're not doing too much straight after the browser's finished
|
||||
// starting up.
|
||||
gInitializeTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
|
||||
gInitializeTimer.initWithCallback(() => {
|
||||
MozLoopService.register();
|
||||
gInitializeTimer = null;
|
||||
},
|
||||
MozLoopServiceInternal.initialRegistrationDelayMilliseconds, Ci.nsITimer.TYPE_ONE_SHOT);
|
||||
};
|
||||
|
||||
/**
|
||||
* Public API
|
||||
*/
|
||||
this.MozLoopService = {
|
||||
set initializeTimerFunc(value) {
|
||||
gInitializeTimerFunc = value;
|
||||
},
|
||||
|
||||
/**
|
||||
* Initialized the loop service, and starts registration with the
|
||||
* push and loop servers.
|
||||
@ -462,26 +483,10 @@ this.MozLoopService = {
|
||||
|
||||
// If expiresTime is in the future then kick-off registration.
|
||||
if (MozLoopServiceInternal.urlExpiryTimeIsInFuture()) {
|
||||
this._startInitializeTimer();
|
||||
gInitializeTimerFunc();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Internal function, exposed for testing purposes only. Used to start the
|
||||
* initialize timer.
|
||||
*/
|
||||
_startInitializeTimer: function() {
|
||||
// Kick off the push notification service into registering after a timeout
|
||||
// this ensures we're not doing too much straight after the browser's finished
|
||||
// starting up.
|
||||
this._initializeTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
|
||||
this._initializeTimer.initWithCallback(function() {
|
||||
this.register();
|
||||
this._initializeTimer = null;
|
||||
}.bind(this),
|
||||
MozLoopServiceInternal.initialRegistrationDelayMilliseconds, Ci.nsITimer.TYPE_ONE_SHOT);
|
||||
},
|
||||
|
||||
/**
|
||||
* Starts registration of Loop with the push server, and then will register
|
||||
* with the Loop server. It will return early if already registered.
|
||||
@ -623,3 +628,4 @@ this.MozLoopService = {
|
||||
return MozLoopServiceInternal.hawkRequest(path, method, payloadObj);
|
||||
},
|
||||
};
|
||||
Object.freeze(this.MozLoopService);
|
||||
|
@ -52,7 +52,7 @@ function run_test()
|
||||
{
|
||||
// Override MozLoopService's initializeTimer, so that we can verify the timeout is called
|
||||
// correctly.
|
||||
MozLoopService._startInitializeTimer = function() {
|
||||
MozLoopService.initializeTimerFunc = function() {
|
||||
startTimerCalled = true;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user