From 08e2c650cacb372b913e60c91874af9fcbb786a0 Mon Sep 17 00:00:00 2001 From: NateN1222 Date: Fri, 28 Jul 2017 12:16:55 -0500 Subject: Initial commit --- .gitignore | 4 + html/display_panel/content/README | 21 +++ html/display_panel/content/background-panel.png | Bin 0 -> 14814 bytes html/display_panel/content/display-panel.html | 73 +++++++++ html/display_panel/content/librejs-title-old.png | Bin 0 -> 2673 bytes html/display_panel/content/librejs-title.png | Bin 0 -> 14123 bytes html/display_panel/content/main_panel.js | 96 ++++++++++++ html/display_panel/content/panel-styles.css | 190 +++++++++++++++++++++++ html/preferences_panel/pref.js | 56 +++++++ html/preferences_panel/preferences_panel.html | 63 ++++++++ html/report_page/report.html | 0 html/report_page/report.js | 0 icons/librejs.png | Bin 0 -> 1604 bytes main_background.js | 161 +++++++++++++++++++ manifest.json | 44 ++++++ 15 files changed, 708 insertions(+) create mode 100644 .gitignore create mode 100644 html/display_panel/content/README create mode 100644 html/display_panel/content/background-panel.png create mode 100644 html/display_panel/content/display-panel.html create mode 100644 html/display_panel/content/librejs-title-old.png create mode 100644 html/display_panel/content/librejs-title.png create mode 100644 html/display_panel/content/main_panel.js create mode 100644 html/display_panel/content/panel-styles.css create mode 100644 html/preferences_panel/pref.js create mode 100644 html/preferences_panel/preferences_panel.html create mode 100644 html/report_page/report.html create mode 100644 html/report_page/report.js create mode 100644 icons/librejs.png create mode 100644 main_background.js create mode 100644 manifest.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b7da9fb --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +*~ +old/ +*.zip +SDK LibreJS source/ \ No newline at end of file diff --git a/html/display_panel/content/README b/html/display_panel/content/README new file mode 100644 index 0000000..a56ea46 --- /dev/null +++ b/html/display_panel/content/README @@ -0,0 +1,21 @@ +/** + * GNU LibreJS - A browser add-on to block nonfree nontrivial JavaScript. + * * + * Copyright (C) 2011, 2012, 2014 Loic J. Duros + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +All images in this directory are free, released under the GPLv3 or later. \ No newline at end of file diff --git a/html/display_panel/content/background-panel.png b/html/display_panel/content/background-panel.png new file mode 100644 index 0000000..022ffb3 Binary files /dev/null and b/html/display_panel/content/background-panel.png differ diff --git a/html/display_panel/content/display-panel.html b/html/display_panel/content/display-panel.html new file mode 100644 index 0000000..9ef3eef --- /dev/null +++ b/html/display_panel/content/display-panel.html @@ -0,0 +1,73 @@ + + + + +Display JS Monitoring Panel + + + + + + + +
+
+ +

LibreJS

+
+
+
+ gnu.org/software/librejs +
+
+ LibreJS 6.0.13 +
+
+ +
+
+

+
    +
    + +
    +

    +
      +
      + +
      +

      +
        +
      + +
      +

      +
        +
        +
        + + diff --git a/html/display_panel/content/librejs-title-old.png b/html/display_panel/content/librejs-title-old.png new file mode 100644 index 0000000..8a11527 Binary files /dev/null and b/html/display_panel/content/librejs-title-old.png differ diff --git a/html/display_panel/content/librejs-title.png b/html/display_panel/content/librejs-title.png new file mode 100644 index 0000000..c1a911c Binary files /dev/null and b/html/display_panel/content/librejs-title.png differ diff --git a/html/display_panel/content/main_panel.js b/html/display_panel/content/main_panel.js new file mode 100644 index 0000000..3bcb164 --- /dev/null +++ b/html/display_panel/content/main_panel.js @@ -0,0 +1,96 @@ +/** +* +* Sets global variable "webex" to either "chrome" or "browser" for +* use on Chrome or a Firefox variant. +* +* Change this to support a new browser that isn't Chrome or Firefox, +* given that it supports webExtensions. +* +* (Use the variable "webex" for all API calls after calling this) +*/ +var webex; +function set_webex(){ + if(typeof(browser) == "undefined"){ + webex = chrome; + } else{ + webex = browser; + } +} +set_webex(); + +/** +* update the HTML of the pop-up window. +* If return_HTML is true, it returns the HTML of the popup window without updating it. +* example input: +* +* var example_input = { +* "accepted": [["REASON 1","SOURCE 1"],["REASON 2","SOURCE 2"]], +* "blocked": [["REASON 1","SOURCE 1"],["REASON 2","SOURCE 2"]], +* "url": "example.com" +* } +* +*/ +function generate_HTML(blocked_data){ + var a = blocked_data; + var button_complain = 'Complain to site owner'; + var button_allow_all = 'Allow all scripts in this page'; + var button_block_nonfree = 'Block all nonfree/nontrivial scripts from this page'; + var button_new_tab = 'Open this report in a new tab'; + var htmlDoc = document;// Not neccessary + var accept = htmlDoc.getElementById("accepted"); + var blocked = htmlDoc.getElementById("blocked"); + // HTML taken directly from the current LibreJS, display-panel.html + if(a["accepted"].length == 0){ + accept.innerHTML = '
      • LibreJS did not allow the execution of any scripts on this page: \n\n
        • There may be no scripts on this page (check source, C-u)
        • The inline and on-page JavaScript code may not be free and/or may not have proper license information and external scripts (if present) may have been removed by default.
        • External scripts may not be free and/or may not have proper licensing and are not part of the whitelist of free JavaScript libraries.
      • '; + } else{ + accept.innerHTML = ""; + accept.innerHTML = '

        List of
        ACCEPTED
        javascript in '+a["url"]+':

        '; + accept.innerHTML += '"; + } + // HTML taken directly from the current LibreJS, display-panel.html + if(a["blocked"].length == 0){ + blocked.innerHTML += '
      • LibreJS did not block any scripts on this page: \n\n
        • There may be no scripts on this page (check source, C-u).
        • All the scripts on this page may be trivial and/or free.
        • You may have whitelisted this domain name or url from the preferences (Type about:addons in your location bar to check)
        • You may have clicked the "allow all scripts" button, which causes LibreJS to load all JavaScript on a page regardless of whether it is free, trivial, nontrivial or nonfree. This policy is effective for the entire duration of a Firefox session.
        • If for any reason you think LibreJS should have blocked JavaScript code on this page, please report this issue to: bug-librejs@gnu.org
      • '; + } else{ + blocked.innerHTML = ""; + blocked.innerHTML = "

        List of
        BLOCKED
        javascript in" + a["url"]+":

        "; + blocked.innerHTML += '"; + } + // At this point, it has the HTML that the popup needs and the only problem is + // getting it into the popup. (browserAction() needs a (local) URL to work). + +} + + +// content-script.js + +var myPort = webex.runtime.connect({name:"port-from-cs"}); + +myPort.onMessage.addListener(function(m) { + if(m["show_info"] !== undefined){ + generate_HTML(m["show_info"]); + } +}); +function onGot(tabInfo) { + myPort.postMessage({"tab_info": tabInfo}); +} +var gettingCurrent = webex.tabs.getCurrent(onGot); + + diff --git a/html/display_panel/content/panel-styles.css b/html/display_panel/content/panel-styles.css new file mode 100644 index 0000000..2e5223b --- /dev/null +++ b/html/display_panel/content/panel-styles.css @@ -0,0 +1,190 @@ +/** + * GNU LibreJS - A browser add-on to block nonfree nontrivial JavaScript. + * * + * Copyright (C) 2011, 2012, 2014 Loic J. Duros + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +html { + padding:10px; + color:#000 !important; + background:url('background-panel.png') !important; +} +document { + padding:10px; +} +body { + padding:10px; + font-size:67.5%; + overflow-x:hidden; + overflow-y:visible; + color:#000; +} + +.libre { + width:230px; + height:104px; + display:block; + margin-bottom: 4px; +} +h1.libre { + font-size:1.5em; + font-weight:normal; + font-family:Arial; + margin:-20px 0 0 0; + padding:0; + font-weight:bold; + background:url('librejs-title.png') no-repeat top left; + text-indent:-1000px; + overflow:hidden; +} +h2 { + font-size:1.5em; + font-weight:bold; + font-family:arial; + border-bottom:4px solid #444; + padding-bottom:0; + margin:30px 0 0 0; + width:710px; + line-height:140%; +} +code { + font-size:1.2em; + margin:0; + padding:0; +} +ul { + margin:0; + padding:0; + list-style:none; +} +ul.blocked-js li, ul.accepted-js li, ul.dryrun-js li { + padding:5px; + border-bottom:2px solid #CCC; + margin:0; + width:700px; +} + +ul ul { + margin:10px; + list-style:disc; +} +ul.blocked-js ul li, ul.accepted-js ul li, ul.dryrun-js ul li { + padding:5px; + border-bottom:0; + width:auto; +} +#info { + clear:both; +} +.button { + float:right; + padding:10px; + display:none; + clear:both; + margin:10px; +} + +/* + Pure JS button styles below taken from: + http://webdesignerwall.com/tutorials/css3-gradient-buttons + */ +.button { + display: inline-block; + outline: none; + cursor: pointer; + text-align: center; + text-decoration: none; + font: 14px/100% Arial, Helvetica, sans-serif; + padding: .5em 2em .55em; + text-shadow: 0 1px 1px rgba(0,0,0,.3); + -webkit-border-radius: .5em; + -moz-border-radius: .5em; + border-radius: .5em; + -webkit-box-shadow: 0 1px 2px rgba(0,0,0,.2); + -moz-box-shadow: 0 1px 2px rgba(0,0,0,.2); + box-shadow: 0 1px 2px rgba(0,0,0,.2); +} +.small.button { + font-size:11px; + padding:.5em .5em; + margin-top:10px; +} +.button:hover { + text-decoration: none; +} +.button:active { + position: relative; + top: 1px; +} +.orange { + color: #fef4e9; + border: solid 1px #da7c0c; + background: #f78d1d; + background: -webkit-gradient(linear, left top, left bottom, from(#faa51a), to(#f47a20)); + background: -moz-linear-gradient(top, #faa51a, #f47a20); +} +.orange:hover { + background: #f47c20; + background: -webkit-gradient(linear, left top, left bottom, from(#f88e11), to(#f06015)); + background: -moz-linear-gradient(top, #f88e11, #f06015); +} +.orange:active { + color: #fcd3a5; + background: -webkit-gradient(linear, left top, left bottom, from(#f47a20), to(#faa51a)); + background: -moz-linear-gradient(top, #f47a20, #faa51a); +} +.white { + background: -moz-linear-gradient(center top , #FFFFFF, #EDEDED) repeat scroll 0 0 transparent; + border: 1px solid #B7B7B7; + /* color: #606060;*/ + color:#9d0d0d; +} +.white:hover { + background: -moz-linear-gradient(center top , #FFFFFF, #DCDCDC) repeat scroll 0 0 transparent; +} +.white:active { + background: -moz-linear-gradient(center top , #EDEDED, #FFFFFF) repeat scroll 0 0 transparent; +/*color: #999999;*/ + +} + +span.accepted, span.blocked { + color:#008e00; + font-size:145%; + font-variant:small-caps; + font-weight:bold; +} +ul.blocked-js li { + overflow:hidden; +} +span.blocked { + color:#8e0000; +} + +.title-area { + width: 230px; + text-align: center; +} + +.title-area #librejs-web-link { + font-size: 18px; +} + +#librejs-web-labels-pages>ul { + margin-top: 8px; + font-size: 14px; + list-style-type: disc; +} \ No newline at end of file diff --git a/html/preferences_panel/pref.js b/html/preferences_panel/pref.js new file mode 100644 index 0000000..aa88f5d --- /dev/null +++ b/html/preferences_panel/pref.js @@ -0,0 +1,56 @@ +/** +* +* Sets global variable "webex" to either "chrome" or "browser" for +* use on Chrome or a Firefox variant. +* +* Change this to support a new browser that isn't Chrome or Firefox, +* given that it supports webExtensions. +* +* (Use the variable "webex" for all API calls after calling this) +*/ +var store; +function set_webex(){ + if(typeof(browser) == "undefined"){ + webex = chrome; + } else{ + webex = browser; + } +} +set_webex(); + +function storage_got(items){ + var inputs = document.getElementsByTagName("input"); + for(var i = 0; i < inputs.length; i++){ + if(inputs[i].id.indexOf("pref_") != -1){ + if(inputs[i].type == "checkbox" && items[inputs[i].id]){ + inputs[i].checked = true; + } + if(inputs[i].type == "text"){ + inputs[i].value = items[inputs[i].id]; + } + } + } +} +webex.storage.local.get(storage_got); + +document.getElementById("save_changes").addEventListener("click", function(){ + var inputs = document.getElementsByTagName("input"); + // TODO: validate/sanitize the user inputs + var data = {}; + for(var i = 0; i < inputs.length; i++){ + if(inputs[i].id.indexOf("pref_") != -1){ + var input_val = ""; + if(inputs[i].type == "checkbox"){ + input_val = inputs[i].checked; + } else{ + input_val = inputs[i].value; + } + var input_id = inputs[i].id; + data[input_id] = input_val; + } + } + console.log(data); + webex.storage.local.set(data); +}); + + diff --git a/html/preferences_panel/preferences_panel.html b/html/preferences_panel/preferences_panel.html new file mode 100644 index 0000000..5c5a217 --- /dev/null +++ b/html/preferences_panel/preferences_panel.html @@ -0,0 +1,63 @@ + + + + + LibreJS preferences + + + + +

        + LibreJS Preferences +

        + + + + + + + + + + + + + + + + + + + + + + + + + + +

        Whitelist domains, seperated by comma (wildcard is *)

        Display complaint tab on sites where nonfree nontrivial Javascript detected

        Display notifications of the JavaScript code being analyzed by LibreJS

        Default complaint email subject

        Default complaint email body

        + + + diff --git a/html/report_page/report.html b/html/report_page/report.html new file mode 100644 index 0000000..e69de29 diff --git a/html/report_page/report.js b/html/report_page/report.js new file mode 100644 index 0000000..e69de29 diff --git a/icons/librejs.png b/icons/librejs.png new file mode 100644 index 0000000..82ac632 Binary files /dev/null and b/icons/librejs.png differ diff --git a/main_background.js b/main_background.js new file mode 100644 index 0000000..300cfb7 --- /dev/null +++ b/main_background.js @@ -0,0 +1,161 @@ +console.debug("main_background.js"); + +/** +* +* Sets global variable "webex" to either "chrome" or "browser" for +* use on Chrome or a Firefox variant. +* +* Change this to support a new browser that isn't Chrome or Firefox, +* given that it supports webExtensions. +* +* (Use the variable "webex" for all API calls after calling this) +*/ +var webex; +function set_webex(){ + if(typeof(browser) == "undefined"){ + webex = chrome; + } else{ + webex = browser; + } +} + +/* +* +* Called when something changes the persistent data of the add-on. +* +* The only things that should need to change this data are: +* a) The "Whitelist this page" button +* b) The options screen +* +* When the actual blocking is implemented, this will need to comminicate +* with its code to update accordingly +* +*/ +function options_listener(changes, area){ + console.log("Items updated in area" + area +": "); + + var changedItems = Object.keys(changes); + var changed_items = ""; + for (var item of changedItems) { + changed_items += item + ","; + } + console.log(changed_items); + +} +/** +* Executes the "Display this report in new tab" function +* by opening a new tab with whatever HTML is in the popup +* at the moment. +*/ +function open_popup_tab(){ + function gotPopup(popupURL){ + var creating = webex.tabs.create({"url":popupURL}); + } + + var gettingPopup = webex.browserAction.getPopup({},gotPopup); +} + +/** +* +* This is what you call when a page gets changed to update the info box. +* +* Sends a message to the content script that updates the popup for a page. +* +* +* var example_blocked_info = { +* "accepted": [["REASON 1","SOURCE 1"],["REASON 2","SOURCE 2"]], +* "blocked": [["REASON 1","SOURCE 1"],["REASON 2","SOURCE 2"]], +* "url": "example.com" +* } +* +*/ + +var active_connections = {}; +var unused_data = {}; +function update_popup(tab_id,blocked_info){ + // this will happen almost every time (browser action not opened before javascript has been filtered) + // store the blocked info until it is opened and needed + if(active_connections[tab_id] === undefined){ + console.log("[TABID:"+tab_id+"]"+"Storing blocked_info for when the browser action is opened."); + unused_data[tab_id] = blocked_info; + } else{ + console.log("[TABID:"+tab_id+"]"+"Sending blocked_info directly to browser action"); + active_connections[tab_id].postMessage({"show_info":blocked_info}); + delete active_connections[tab_id]; + } +} +/** +* +* This is the callback where the content scripts of the browser action will contact the background script. +* +*/ +var portFromCS; +function connected(p) { + console.log(p); + p.onMessage.addListener(function(m) { + function logTabs(tabs) { + for(let tab of tabs) { + var tab_id = tab["id"] + console.log(tab_id) + if(unused_data[tab_id] !== undefined){ + // If we have some data stored here for this tabID, send it and then delete our copy + console.log("[TABID:"+tab_id+"]"+"Sending stored data associated with browser action"); + p.postMessage({"show_info":unused_data[tab_id]}); + } else{ + // create a new entry + unused_data[tab_id] = {"url":tab["url"],"blocked":"","accepted":""}; + p.postMessage({"show_info":unused_data[tab_id]}); + console.log("[TABID:"+tab_id+"]"+"No data found, creating a new entry for this window."); + } + } + } + var querying = webex.tabs.query({active: true,currentWindow: true},logTabs); + + }); +} + +/** +* The callback for tab closings. +* +* Delete the info we are storing about this tab if there is any. +* +*/ +function delete_removed_tab_info(tab_id, remove_info){ + console.log("[TABID:"+tab_id+"]"+"Deleting stored info about closed tab"); + if(unused_data[tab_id] !== undefined){ + delete unused_data[tab_id]; + } + if(active_connections[tab_id] !== undefined){ + delete active_connections[tab_id]; + } +} + + +/** +* Initializes various add-on functions +* only meant to be called once when the script starts +*/ +function init_addon(){ + set_webex(); + webex.runtime.onConnect.addListener(connected); + webex.storage.onChanged.addListener(options_listener); + webex.tabs.onRemoved.addListener(delete_removed_tab_info); +} + + +init_addon(); + +// some misc. debugging: +var example_input = { + "accepted": [["FILENAME 1","REASON 1"],["FILENAME 2","REASON 2"]], + "blocked": [["FILENAME 1","REASON 1"],["FILENAME 2","REASON 2"]], + "url":"example.com" +} +example_input["accepted"] = []; +example_input["blocked"] = []; + +//open_popup_tab(); + + + + diff --git a/manifest.json b/manifest.json new file mode 100644 index 0000000..4d6825a --- /dev/null +++ b/manifest.json @@ -0,0 +1,44 @@ +{ + "manifest_version": 2, + "name": "GNU LibreJS [webExtensions]", + "short_name": "LibreJS [experimental]", + "version": "1.0", + "author": "See file 'authors'", + "description": "Only allows free and/or trivial Javascript to run.", + "applications": { + "gecko": { + "id": "bug-librejs@gnu.org", + "strict_min_version": "42.0" + } + }, + "icons":{ + "64": "icons/librejs.png" + }, + "permissions": [ + "contextMenus", + "webRequest", + "webRequestBlocking", + "activeTab", + "notifications", + "storage", + "tabs" + ], + "browser_action": { + "browser_style": true, + "default_icon": { + "64": "icons/librejs.png" + }, + "default_title": "LibreJS", + "default_popup": "html/display_panel/content/display-panel.html" + }, + "options_ui": { + "page": "html/preferences_panel/preferences_panel.html" + }, + "web_accessible_resources": [ + "html/report_page/report.html" + ], + "background": { + "scripts": ["main_background.js"] + } + +} -- cgit v1.2.3