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 5var EXPORTED_SYMBOLS = ["UITourChild"]; 6 7const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm"); 8 9const PREF_TEST_WHITELIST = "browser.uitour.testingOrigins"; 10const UITOUR_PERMISSION = "uitour"; 11 12class UITourChild extends JSWindowActorChild { 13 handleEvent(event) { 14 if (!Services.prefs.getBoolPref("browser.uitour.enabled")) { 15 return; 16 } 17 if (!this.ensureTrustedOrigin()) { 18 return; 19 } 20 21 this.sendAsyncMessage("UITour:onPageEvent", { 22 detail: event.detail, 23 type: event.type, 24 pageVisibilityState: this.document.visibilityState, 25 }); 26 } 27 28 isTestingOrigin(aURI) { 29 if ( 30 Services.prefs.getPrefType(PREF_TEST_WHITELIST) != 31 Services.prefs.PREF_STRING 32 ) { 33 return false; 34 } 35 36 // Add any testing origins (comma-seperated) to the whitelist for the session. 37 for (let origin of Services.prefs 38 .getCharPref(PREF_TEST_WHITELIST) 39 .split(",")) { 40 try { 41 let testingURI = Services.io.newURI(origin); 42 if (aURI.prePath == testingURI.prePath) { 43 return true; 44 } 45 } catch (ex) { 46 Cu.reportError(ex); 47 } 48 } 49 return false; 50 } 51 52 // This function is copied from UITour.jsm. 53 isSafeScheme(aURI) { 54 let allowedSchemes = new Set(["https", "about"]); 55 if (!Services.prefs.getBoolPref("browser.uitour.requireSecure")) { 56 allowedSchemes.add("http"); 57 } 58 59 if (!allowedSchemes.has(aURI.scheme)) { 60 return false; 61 } 62 63 return true; 64 } 65 66 ensureTrustedOrigin() { 67 if (this.browsingContext.top != this.browsingContext) { 68 return false; 69 } 70 71 let uri = this.document.documentURIObject; 72 73 if (uri.schemeIs("chrome")) { 74 return true; 75 } 76 77 if (!this.isSafeScheme(uri)) { 78 return false; 79 } 80 81 let principal = Services.scriptSecurityManager.principalWithOA( 82 this.document.nodePrincipal, 83 {} 84 ); 85 let permission = Services.perms.testPermissionFromPrincipal( 86 principal, 87 UITOUR_PERMISSION 88 ); 89 if (permission == Services.perms.ALLOW_ACTION) { 90 return true; 91 } 92 93 // Bug 1557153: To allow Skyline messaging, workaround for UNKNOWN_ACTION 94 // overriding browser/app/permissions default 95 return uri.host == "www.mozilla.org" || this.isTestingOrigin(uri); 96 } 97 98 receiveMessage(aMessage) { 99 switch (aMessage.name) { 100 case "UITour:SendPageCallback": 101 this.sendPageEvent("Response", aMessage.data); 102 break; 103 case "UITour:SendPageNotification": 104 this.sendPageEvent("Notification", aMessage.data); 105 break; 106 } 107 } 108 109 sendPageEvent(type, detail) { 110 if (!this.ensureTrustedOrigin()) { 111 return; 112 } 113 114 let win = this.contentWindow; 115 let eventName = "mozUITour" + type; 116 let event = new win.CustomEvent(eventName, { 117 bubbles: true, 118 detail: Cu.cloneInto(detail, win), 119 }); 120 win.document.dispatchEvent(event); 121 } 122} 123