diff options
author | Alex Xu <alex_y_xu@yahoo.ca> | 2014-12-06 23:52:16 -0500 |
---|---|---|
committer | Alex Xu <alex_y_xu@yahoo.ca> | 2014-12-07 00:06:53 -0500 |
commit | 2c30652840889cd2e1c5e15574e93aefdb720fcf (patch) | |
tree | 82def2bd41173dbb629e573cd8b53309120b36a1 /src | |
download | eib-2c30652840889cd2e1c5e15574e93aefdb720fcf.tar.xz eib-2c30652840889cd2e1c5e15574e93aefdb720fcf.zip |
Initial commit
Diffstat (limited to 'src')
-rw-r--r-- | src/bootstrap.js | 171 | ||||
-rw-r--r-- | src/chrome.manifest | 2 | ||||
-rw-r--r-- | src/chrome/content/options.xul | 7 | ||||
-rw-r--r-- | src/chrome/locale/en/options.dtd | 1 | ||||
-rw-r--r-- | src/defaults/preferences/preferences.js | 1 | ||||
-rw-r--r-- | src/install.rdf | 26 |
6 files changed, 208 insertions, 0 deletions
diff --git a/src/bootstrap.js b/src/bootstrap.js new file mode 100644 index 0000000..2625c92 --- /dev/null +++ b/src/bootstrap.js @@ -0,0 +1,171 @@ +const PORT = 26001; + +if (typeof EIB === "undefined") + var EIB = { + headers: {}, + pending: [] + }; + +const Cc = Components.classes, Ci = Components.interfaces, Cu = Components.utils, CC = Components.Constructor, Cr = Components.results; +const ScriptableInputStream = CC("@mozilla.org/scriptableinputstream;1", "nsIScriptableInputStream", "init"); + +Cu.import("resource://gre/modules/Services.jsm"); + +function install() {} +function uninstall() {} + +EIB.listen = function () { + this.serverSocket = Cc["@mozilla.org/network/server-socket;1"] + .createInstance(Ci.nsIServerSocket); + this.serverSocket.init(PORT, true, -1); + const tm = Cc["@mozilla.org/thread-manager;1"].getService(); + this.serverSocket.asyncListen({ + onSocketAccepted: function (socket, transport) { + var is = transport.openInputStream(0, 0, 0); + var os = transport.openOutputStream(Ci.nsITransport.OPEN_BLOCKING, 0, 0); + var sis = new ScriptableInputStream(is); + var buf = ""; + // TODO: run on separate thread + is.asyncWait({ + onInputStreamReady: function () { + while (sis.available()) { + buf += sis.read(2048); + } + if (buf.indexOf("\n\n") !== 2) { + var headers = {}; + var rx = /\n(EVE_[^:]*): (.*)$/gm, arr; + while ((arr = rx.exec(buf)) !== null) { + headers[arr[1]] = arr[2]; + } + EIB.headers = headers; + + var resp = "HTTP/1.0 200 OK\r\n"; + resp += "Content-Type: text/html\r\n\r\n"; + resp += "<!DOCTYPE html><html><head><title>EVE-IGB Bridge</title>"; + if (headers["EVE_TRUSTED"]) { + resp += "<script>"; + if (headers["EVE_TRUSTED"] == "Yes") { + resp += EIB.pending.join("\r\n"); + EIB.pending = []; + resp += 'setTimeout(function () {'; + resp += ' window.location.reload();'; + resp += '}, 100);'; + } else { + resp += 'CCPEVE.requestTrust("http://127.0.0.1:' + EIB.serverSocket.port + '");'; + } + resp += "</script></head><body>"; + resp += headers["EVE_TRUSTED"] == "Yes" ? + "Connected to the EVE-IGB Bridge. Please do not close this window. You may minimize it, however. Note that this window will refresh repeatedly; this does not indicate a malfunction and will not count towards your internet data usage if you have one." : + "Please grant trust to this site, then refresh the page."; + resp += "</body></html>"; + } else { + resp += "</head><body>Please open this page in the EVE in-game browser.</body></html>"; + } + os.write(resp, resp.length); + + is.close(); + os.close(); + } + } + }, 0, 0, tm.mainThread); + } + }); +} + +var HttpObserver = { + observe: function (subject, topic, data) { + var channel = subject.QueryInterface(Ci.nsIHttpChannel); + // TODO: is this secure? + if (checkTrusted(channel.URI.specIgnoringRef)) { + for (var header in EIB.headers) { + channel.setRequestHeader(header, EIB.headers[header], false); + } + } + } +}; + +function forEachOpenWindow(todo) { + var windows = Services.wm.getEnumerator("navigator:browser"); + while (windows.hasMoreElements()) + todo(windows.getNext().QueryInterface(Ci.nsIDOMWindow)); +} + +var WindowListener = { + onOpenWindow: function(xulWindow) + { + var window = xulWindow.QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIDOMWindow); + function onWindowLoad() + { + window.removeEventListener("load", onWindowLoad); + if (window.document.documentElement.getAttribute("windowtype") == "navigator:browser") + loadIntoWindow(window); + } + window.addEventListener("load", onWindowLoad); + }, + onCloseWindow: function(xulWindow) {}, + onWindowTitleChange: function(xulWindow, newTitle) {} +}; + +var TrustedReparser = { + observe: function () { + EIB.trusted = JSON.parse(EIB.prefs.getCharPref("trusted")); + } +}; + +function startup(data, reason) { + EIB.listen(); + + EIB.prefs = Services.prefs.getBranch("extensions.eib."); + EIB.prefs.addObserver("trusted", TrustedReparser, false); + reparseTrusted(); + + forEachOpenWindow(loadIntoWindow); + Services.wm.addListener(WindowListener); + + Services.obs.addObserver(HttpObserver, "http-on-modify-request", false); +} + +function shutdown(data, reason) { + if (reason === APP_SHUTDOWN) + return; + + if (EIB.serverSocket) + EIB.serverSocket.close(); + delete EIB.serverSocket; + + EIB.prefs.removeObserver("trusted", TrustedReparser); + + forEachOpenWindow(unloadFromWindow); + Services.wm.removeListener(WindowListener); + + Services.obs.removeObserver(HttpObserver, "http-on-modify-request"); +} + +function checkTrusted(href) { + for (var i = 0; i < EIB.trusted.length; i++) + if (href.indexOf(EIB.trusted[i]) === 0) + return true; + return false; +} + +function injectCCPEVE(e) { + var window = e.originalTarget.defaultView; + if (checkTrusted(window.location.href)) { + var CCPEVE = Cu.createObjectIn(window, {defineAs: "CCPEVE"}); + ["openEveMail", "showInfo", "showPreview", "showRouteTo", "showMap", "showFitting", "showContract", "showMarketDetails", "setDestination", "addWaypoint", "joinChannel", "joinMailingList", "createContract", "buyType", "findInContracts", "addToMarketQuickBar", "addContact", "removeContact", "addCorpContact", "removeCorpContact", "block", "addBounty", "inviteToFleet", "startConversation", "showContracts", "showOnMap", "editMember", "awardDecoration", "sendMail", "showContents", "bookmark"].forEach(function (n) { + Cu.exportFunction(function () { + EIB.pending.push('CCPEVE.' + n + '(' + Array.prototype.join.call(arguments, ',') + ');'); + return null; + }, CCPEVE, {defineAs: n}); + }); + } +} + +function loadIntoWindow(window) { + window.document.getElementById("appcontent").addEventListener("DOMContentLoaded", injectCCPEVE, false); +} + +function unloadFromWindow(window) { + window.document.getElementById("appcontent").removeEventListener("DOMContentLoaded", injectCCPEVE, false); +} diff --git a/src/chrome.manifest b/src/chrome.manifest new file mode 100644 index 0000000..87c823b --- /dev/null +++ b/src/chrome.manifest @@ -0,0 +1,2 @@ +content eib chrome/content/ +locale eib en chrome/locale/en/ diff --git a/src/chrome/content/options.xul b/src/chrome/content/options.xul new file mode 100644 index 0000000..29543ba --- /dev/null +++ b/src/chrome/content/options.xul @@ -0,0 +1,7 @@ +<?xml version="1.0"?> + +<!DOCTYPE options SYSTEM "chrome://eib/locale/options.dtd"> + +<vbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <setting type="string" pref="extensions.eib.trusted" title="&eib.options.trusted" desc="&eib.options.trusted" /> +</vbox> diff --git a/src/chrome/locale/en/options.dtd b/src/chrome/locale/en/options.dtd new file mode 100644 index 0000000..d5e8503 --- /dev/null +++ b/src/chrome/locale/en/options.dtd @@ -0,0 +1 @@ +<!ENTITY eib.options.trusted "Trusted sites"> diff --git a/src/defaults/preferences/preferences.js b/src/defaults/preferences/preferences.js new file mode 100644 index 0000000..baa73a8 --- /dev/null +++ b/src/defaults/preferences/preferences.js @@ -0,0 +1 @@ +pref("extensions.eib.trusted", "[]"); diff --git a/src/install.rdf b/src/install.rdf new file mode 100644 index 0000000..9295bbd --- /dev/null +++ b/src/install.rdf @@ -0,0 +1,26 @@ +<?xml version="1.0"?> + +<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:em="http://www.mozilla.org/2004/em-rdf#"> + + <Description about="urn:mozilla:install-manifest"> + <em:id>{b0bdf19d-9121-4bad-a13c-e47654633be9}</em:id> + <em:name>EVE-IGB Bridge</em:name> + <em:description>Bridges EVE-IGB headers and JS functions securely</em:description> + <em:version>0.1</em:version> + <em:creator>Alex Xu (Hello71)</em:creator> + <em:type>2</em:type> + <em:bootstrap>true</em:bootstrap> + <em:optionsURL>chrome://eib/content/options.xul</em:optionsURL> + <em:optionsType>2</em:optionsType> + + <!-- Mozilla Firefox --> + <em:targetApplication> + <Description> + <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id> + <em:minVersion>4.*</em:minVersion> + <em:maxVersion>10.*</em:maxVersion> + </Description> + </em:targetApplication> + </Description> +</RDF> |