diff --git a/README.md b/README.md index fe400b4e..90c80fe8 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,8 @@ A web browser extension that emulates Content Delivery Networks to improve your LocalCDN based on Decentraleyes. It includes more frameworks and more CDNs: -* **New: Font Awesome v4.7.0 and v5.7.2** :tada: :tada: :tada: +* **NEW: Removed integrity checks of embedded script and style elements** :tada: :tada: :tada: +* Font Awesome * jQuery up to 3.4.1 * Bootstrap CSS (Delivered by StackPath, NetDNA and MaxCDN) * Bootstrap JavaScript (Delivered by StackPath, NetDNA and MaxCDN) @@ -16,6 +17,20 @@ LocalCDN based on Decentraleyes. It includes more frameworks and more CDNs: > **Note:** LocalCDN is no silver bullet, but it does prevent a lot of websites from making you send these kinds of requests. Ultimately, you can make LocalCDN block requests for any missing CDN resources, too. +## What is the different of LocalCDN in comparison to other CDN emulators? + +The Replacement of Libraries + +**Advantages of LocalCDN:** + +:thumbsup: more frameworks/libraries + +:thumbsup: smaller size than other extensions + +:thumbsup: remove crossorigin and integrity attributes of script and stylesheet tags to increase replacements + +:thumbsup: doesn't matter which version a website requested + ## We need you! ![We Need You!](/pages/welcome/we-need-you.png?raw=true "We Need You!") @@ -64,6 +79,11 @@ Please read this [developer guide](https://developer.mozilla.org/en-US/Add-ons/W > **Important:** All tagged commits are signed with GPG. It's likely best to ignore unsigned commits, unless you really know what you're doing. Please send an email if you have any questions or security concerns. +## Contact + +Just open an issue with your question or write an [email](https://localcdn.de/contact/) (PGP possible!). + + ## Donations LocalCDN is free, open-source and based on Decentraleyes. If you like LocalCDN and/or Decentraleyes you can support continued development by making a donation. Any help would be greatly appreciated! diff --git a/_locales/en_GB/messages.json b/_locales/en_GB/messages.json index 660eb2ad..99a13eb3 100644 --- a/_locales/en_GB/messages.json +++ b/_locales/en_GB/messages.json @@ -100,11 +100,11 @@ "description": "If enabled, you wont receive any information about new features in LocalCDN. This includes information about new uBlock/uMatrix rules." }, "featureBreaksWebsitesDescription": { - "message": "", + "message": "This feature breaks websites. Do not leave it enabled, unless you are prepared to manually whitelist any affected domains.", "description": "This feature breaks websites. Do not leave it enabled, unless you are prepared to manually whitelist any affected domains." }, "featureBreaksWebsitesButton": { - "message": "", + "message": "Disable", "description": "Disable" } } diff --git a/_locales/it/messages.json b/_locales/it/messages.json index 3811d719..3c2fa265 100644 --- a/_locales/it/messages.json +++ b/_locales/it/messages.json @@ -1,6 +1,6 @@ { "extensionDescription": { - "message": "Protegge dal tracciamento tramite CDN centralizzato \"gratis\".", + "message": "Protegge dal tracciamento tramite CDN centralizzati \"liberi\".", "description": "Extension description." }, "disableProtectionTitle": { @@ -16,7 +16,7 @@ "description": "Amount injected title." }, "amountInjectedDescription": { - "message": "Quantità di iniezioni di risorse dalla Rete di Distribuzione di Contenuti locale sin dall'installazione.", + "message": "Quantità di iniezioni di risorse dalla CDN locale sin dall'installazione.", "description": "Amount injected description." }, "optionsTitle": { @@ -32,7 +32,7 @@ "description": "Show icon badge description." }, "blockMissingTitle": { - "message": "Bloccare richieste di risorse mancanti", + "message": "Blocca le richieste di risorse mancanti", "description": "Block requests for missing resources title." }, "blockMissingDescription": { @@ -40,27 +40,27 @@ "description": "Block requests for missing resources description." }, "disablePrefetchTitle": { - "message": "Disabilita il prefetching dei link", + "message": "Disabilita il precaricamento dei collegamenti", "description": "Disable prefetch title." }, "disablePrefetchDescription": { - "message": "Impedisci alle richieste vietate di informare le reti di consegna.", + "message": "Impedisci alle richieste non consentite di uscire dalle reti di distribuzione.", "description": "Disable prefetch description." }, "stripMetadataTitle": { - "message": "Elimina i metadata dalle richieste consentite", + "message": "Togli i metadati dalle richieste consentite", "description": "Strip metadata title." }, "stripMetadataDescription": { - "message": "Cancella i dati sensibili dalle richieste CDN consentite per una migliore privacy.", + "message": "Cancella i dati sensibili dalle richieste consentite alle CDN per migliorare la privacy.", "description": "Strip metadata description." }, "whitelistedDomainsTitle": { - "message": "Escludere domini dalle ispezioni", + "message": "Escludi i domini dalle ispezioni", "description": "Whitelisted domains title." }, "whitelistedDomainsDescription": { - "message": "Inserire domini nella whitelist per escluderli. Separare voci multiple con punti e virgola (;).", + "message": "Inserisci i domini nella whitelist per escluderli. Separa le voci multiple con punti e virgola (;).", "description": "Whitelisted domains description." }, "advancedLabel": { @@ -68,43 +68,43 @@ "description": "Advanced label." }, "generateRuleSetTitle": { - "message": "Genera set di regole per uBlock o uMatrix", + "message": "Genera gruppo di regole per uBlock o uMatrix", "description": "Generate rule set title." }, "generateRuleSetDescription": { - "message": "", + "message": "Nel caso stessi utilizzando uBlock o uMatrix è possibile generare le regole qui. È necessario aggiungere queste regole manualmente in uBlock o uMatrix.", "description": "In case you're using uBlock or uMatrix you can generate the rules here. You have to add these rules manually in uBlock or uMatrix." }, "lastUpdate": { - "message": "", + "message": "Ultimo aggiornamento:", "description": "Last update." }, "copyRuleSet": { - "message": "", + "message": "Copia", "description": "Text of button to copy ruleset." }, "loggingTitle": { - "message": "", + "message": "Abilita l'accesso alla console del browser", "description": "Enable logging in browser console." }, "loggingDescription": { - "message": "", + "message": "Apri la Console del Browser ( CTRL + SHIFT + J ) per mostrare le risorse mancanti", "description": "Open \"Browser Console\" ( CTRL + SHIFT + J ) to show missing resources." }, "hideReleaseNotesTitle": { - "message": "", + "message": "Disabilita le note di rilascio", "description": "Disable release notes" }, "hideReleaseNotesDescription": { - "message": "", + "message": "Se abilitato, non riceverai alcuna informazione sulle nuove funzionalità di LocalCDN. Questo include informazioni sulle nuove regole per uBlock/uMatrix.", "description": "If enabled, you wont receive any information about new features in LocalCDN. This includes information about new uBlock/uMatrix rules." }, "featureBreaksWebsitesDescription": { - "message": "", + "message": "Questa funzione rompe i siti web. Non lasciarla abilitata, a meno che tu non sia pronto a mettere manualmente nella whitelist i domini interessati.", "description": "This feature breaks websites. Do not leave it enabled, unless you are prepared to manually whitelist any affected domains." }, "featureBreaksWebsitesButton": { - "message": "", + "message": "Disabilita", "description": "Disable" } } diff --git a/_locales/pl/messages.json b/_locales/pl/messages.json index a0cb0c46..bce40bbe 100644 --- a/_locales/pl/messages.json +++ b/_locales/pl/messages.json @@ -72,39 +72,39 @@ "description": "Generate rule set title." }, "generateRuleSetDescription": { - "message": "", + "message": "Jeśli używasz uBlock lub uMatrix, to możesz wygenerować tutaj odpowiednie reguły. Musisz je potem dodać ręcznie w uBlock albo uMatrix.", "description": "In case you're using uBlock or uMatrix you can generate the rules here. You have to add these rules manually in uBlock or uMatrix." }, "lastUpdate": { - "message": "", + "message": "Ostatnia aktualizacja: ", "description": "Last update." }, "copyRuleSet": { - "message": "", + "message": "Kopiuj", "description": "Text of button to copy ruleset." }, "loggingTitle": { - "message": "", + "message": "Włącz logowanie w konsoli przeglądarki.", "description": "Enable logging in browser console." }, "loggingDescription": { - "message": "", + "message": "Otwórz \"Konsolę Przeglądarki\" ( CTRL + SHIFT + J) żeby wyświetlić brakujące zasoby.", "description": "Open \"Browser Console\" ( CTRL + SHIFT + J ) to show missing resources." }, "hideReleaseNotesTitle": { - "message": "", + "message": "Wyłącz informacje o zmianach", "description": "Disable release notes" }, "hideReleaseNotesDescription": { - "message": "", + "message": "Po włączeniu nie będziesz otrzymywać żadnych informacji o nowych funkcjach w LocalCDN. W tym informacji o nowych regułach uBlock/uMatrix.", "description": "If enabled, you wont receive any information about new features in LocalCDN. This includes information about new uBlock/uMatrix rules." }, "featureBreaksWebsitesDescription": { - "message": "", + "message": "Ta opcja psuje strony. Nie włączaj jej, chyba że jesteś gotów samemu dodawać niedziałające domeny do białej listy.", "description": "This feature breaks websites. Do not leave it enabled, unless you are prepared to manually whitelist any affected domains." }, "featureBreaksWebsitesButton": { - "message": "", + "message": "Wyłącz", "description": "Disable" } } diff --git a/core/constants.js b/core/constants.js index 756a5950..17c3a8c3 100644 --- a/core/constants.js +++ b/core/constants.js @@ -92,4 +92,17 @@ const Whitelist = { const BrowserType = { 'CHROMIUM': chrome.runtime.getURL("/").startsWith("chrome-extension"), 'FIREFOX': chrome.runtime.getURL("/").startsWith("moz-extension") -} +}; + +const CharsetDomains = { + 'dejure.org': 'iso-8859-1', + 'privacy-handbuch.de': 'iso-8859-1', + 'winfuture.de': 'iso-8859-1', + 'drwindows.de': 'iso-8859-1', + 'sphinx-soft.com': 'iso-8859-1', + 'ekaterinaguseva.ru': 'windows-1251', + 'hobbybrauerversand.de': 'iso-8859-1', + 'pro-linux.de': 'iso-8859-15', + 'wwwuser.gwdg.de': 'windows-1252', + 'tyurem.net': 'windows-1251' +}; diff --git a/core/files.js b/core/files.js index 215ed4d1..53d03592 100644 --- a/core/files.js +++ b/core/files.js @@ -250,6 +250,10 @@ var files = { // lozad.js 'resources/lozad.js/1.14.0/lozad.min.jsm': true, + // Material Design for Bootstrap + 'resources/mdbootstrap/4.18.0/js/mdb.min.jsm': true, + 'resources/mdbootstrap/4.18.0/css/mdb.min.css': true, + // Modernizr 'resources/modernizr/2.8.3/modernizr.min.jsm': true, @@ -313,6 +317,9 @@ var files = { // SWFObject 'resources/swfobject/2.2/swfobject.jsm': true, + // Tether JS + 'resources/tether/1.4.7/js/tether.min.jsm': true, + // toastr.js 'resources/toastr.js/2.1.4/toastr.min.css': true, 'resources/toastr.js/2.1.4/toastr.min.jsm': true, @@ -320,6 +327,8 @@ var files = { // Twitter Bootstrap 'resources/twitter-bootstrap/3.4.1/js/bootstrap.min.jsm': true, 'resources/twitter-bootstrap/3.4.1/css/bootstrap.min.css': true, + 'resources/twitter-bootstrap/4.5.0/js/bootstrap.min.jsm': true, + 'resources/twitter-bootstrap/4.5.0/css/bootstrap.min.css': true, // Underscore.js 'resources/underscore.js/1.8.3/underscore-min.jsm': true, diff --git a/core/manipulate-dom.js b/core/manipulate-dom.js index 2593a2af..05d21885 100644 --- a/core/manipulate-dom.js +++ b/core/manipulate-dom.js @@ -26,6 +26,18 @@ var manipulateDOM = {}; * Private Methods */ +manipulateDOM._getEncoding = function (domain) { + + let encodingByDomain = CharsetDomains[domain]; + + if(typeof encodingByDomain === 'undefined') { + return 'UTF-8'; + } + + return encodingByDomain; + +}; + manipulateDOM._removeCrossOriginAndIntegrityAttr = function (details) { // by Jaap (https://gitlab.com/Jaaap) @@ -44,7 +56,7 @@ manipulateDOM._removeCrossOriginAndIntegrityAttr = function (details) { if (!isWhitelisted && mimeType === 'text/html') { header.value = 'text/html; charset=UTF-8'; - let decoder = new TextDecoder(charset); + let decoder = new TextDecoder(manipulateDOM._getEncoding(initiatorDomain)); let encoder = new TextEncoder(); let filter = browser.webRequest.filterResponseData(details.requestId); diff --git a/core/mappings.js b/core/mappings.js index c942110b..129bc408 100644 --- a/core/mappings.js +++ b/core/mappings.js @@ -135,6 +135,8 @@ var mappings = { 'js-cookie/{version}/js.cookie.min.js': resources.jscookie, 'lazysizes/{version}/lazysizes.min.js': resources.lazysizes, 'lodash.js/{version}/lodash.': resources.lodashJS, + 'mdbootstrap/{version}/js/mdb.': resources.mdbootstrapJS, + 'mdbootstrap/{version}/css/mdb.': resources.mdbootstrapCSS, 'modernizr/{version}/modernizr.': resources.modernizr, 'moment.js/{version}/moment.': resources.moment, 'moment.js/{version}/moment.min.': resources.moment, @@ -155,9 +157,12 @@ var mappings = { 'spin.js/{version}/spin.min.js': resources.spinJS, 'socket.io/{version}/socket.io.': resources.socketIO, 'swfobject/{version}/swfobject.': resources.swfobject, + 'tether/{version}/js/tether.': resources.tetherJS, 'toastr.js/{version}/toastr.min.css': resources.toastrCSS, 'toastr.js/{version}/toastr.min.js': resources.toastrJS, 'twitter-bootstrap/{version}/js/bootstrap.min.js': resources.twitterBootstrapJS, + 'twitter-bootstrap/{version}-alpha.3/js/bootstrap.min.js': resources.twitterBootstrapJS, + 'twitter-bootstrap/{version}-alpha.3/css/bootstrap.min.css': resources.twitterBootstrapCSS, 'twitter-bootstrap/{version}/css/bootstrap.': resources.twitterBootstrapCSS, 'underscore.js/{version}/underscore.': resources.underscore, 'underscore.js/{version}/underscore-min.': resources.underscore, diff --git a/core/resources.js b/core/resources.js index 69a523cc..b4ed39d3 100644 --- a/core/resources.js +++ b/core/resources.js @@ -309,6 +309,15 @@ var resources = { 'path': 'resources/lozad.js/{version}/lozad.min.jsm', 'type': 'application/javascript' }, + // Material Design for Bootstrap + 'mdbootstrapJS': { + 'path': 'resources/mdbootstrap/{version}/js/mdb.min.jsm', + 'type': 'application/javascript' + }, + 'mdbootstrapCSS': { + 'path': 'resources/mdbootstrap/{version}/css/mdb.min.css', + 'type': 'text/css' + }, // Modernizr 'modernizr': { 'path': 'resources/modernizr/{version}/modernizr.min.jsm', @@ -421,6 +430,11 @@ var resources = { 'path': 'resources/swfobject/{version}/swfobject.jsm', 'type': 'application/javascript' }, + // Tether JS + 'tetherJS': { + 'path': 'resources/tether/{version}/js/tether.min.jsm', + 'type': 'application/javascript' + }, // Twitter Bootstrap JS 'twitterBootstrapJS': { 'path': 'resources/twitter-bootstrap/{version}/js/bootstrap.min.jsm', diff --git a/icons/credits b/icons/credits index 90b98910..19899a39 100644 --- a/icons/credits +++ b/icons/credits @@ -3,3 +3,7 @@ enabled.svg (edited) settings-dark.svg, settings-light.svg (edited) https://www.svgrepo.com/vectors/web-security-fill/ Creative Commons BY 4.0 + +donate.svg (edited) +https://www.svgrepo.com/svg/39500/heart +CC0 diff --git a/icons/donate.svg b/icons/donate.svg new file mode 100644 index 00000000..d513fae5 --- /dev/null +++ b/icons/donate.svg @@ -0,0 +1,124 @@ + + + +image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/manifest.json b/manifest.json index 3938c8d3..388a45c1 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "manifest_version": 2, "name": "LocalCDN (fork from Decentraleyes)", - "version": "2.2.0", + "version": "2.2.1", "browser_specific_settings": { "gecko": { "id": "{b86e4813-687a-43e6-ab65-0bde4ab75758}", diff --git a/modules/internal/helpers.js b/modules/internal/helpers.js index ebe66768..a0470448 100644 --- a/modules/internal/helpers.js +++ b/modules/internal/helpers.js @@ -324,6 +324,10 @@ helpers.determineResourceName = function (filename) { return 'Lodash'; case 'lozad.min.jsm': return 'lozad.js'; + case 'mdb.min.css': + return 'MDBootstrap (CSS)'; + case 'mdb.min.jsm': + return 'MDBootstrap (JS)'; case 'modernizr.min.jsm': return 'Modernizr'; case 'moment.min.jsm': @@ -370,6 +374,8 @@ helpers.determineResourceName = function (filename) { return 'Store.js'; case 'swfobject.jsm': return 'SWFObject'; + case 'tether.min.jsm': + return 'Tether JS'; case 'toastr.min.css': return 'toastr.js'; case 'toastr.min.jsm': @@ -563,6 +569,8 @@ helpers.setLastVersion = function (type, version) { version = '4.17.10'; } else if (type.includes('lozad')) { version = '1.14.0'; + } else if (type.includes('/mdbootstrap/4.')) { + version = '4.18.0'; } else if (type.includes('/modernizr/2.')) { version = '2.8.3'; } else if (type.includes('/moment.js/2.')) { @@ -601,6 +609,10 @@ helpers.setLastVersion = function (type, version) { version = '2.0.4'; } else if (type.includes('/swfobject/2.')) { version = '2.2'; + } else if (type.includes('/tether/1.')) { + version = '1.4.7'; + } else if (type.includes('/twitter-bootstrap/4.')) { + version = '4.5.0'; } else if (type.includes('/twitter-bootstrap/3.')) { version = '3.4.1'; } else if (type.includes('/toastr.js/2.')) { diff --git a/pages/popup/popup.css b/pages/popup/popup.css index c1cc0246..2cca6b15 100644 --- a/pages/popup/popup.css +++ b/pages/popup/popup.css @@ -20,6 +20,7 @@ header { border-bottom: solid #d3d3d3 1px; display: flex; position: relative; + padding: 8px; } .panel { @@ -76,6 +77,7 @@ footer { font-size: 14px; font-weight: 600; padding-left: 0; + width: 100%; } .subheading { @@ -177,7 +179,8 @@ footer { color: #339a6f; } -#options-button-svg { +#options-button-svg, +#donate-button-svg { background-size: cover; width: 15px; height: 15px; @@ -187,6 +190,10 @@ footer { background-image: url("../../icons/settings-dark.svg"); } +#donate-button-svg { + background-image: url("../../icons/donate.svg"); +} + #protection-toggle { -moz-user-select: none; cursor: pointer; diff --git a/pages/popup/popup.html b/pages/popup/popup.html index ca8e1f1d..ce8ce09f 100644 --- a/pages/popup/popup.html +++ b/pages/popup/popup.html @@ -27,6 +27,10 @@
LocalCDN
+ +
diff --git a/pages/popup/popup.js b/pages/popup/popup.js index 071887b2..955693c3 100644 --- a/pages/popup/popup.js +++ b/pages/popup/popup.js @@ -39,18 +39,20 @@ popup._renderContents = function () { popup._renderNonContextualContents = function () { - let versionLabelElement, counterElement, testingUtilityLinkElement, optionsButtonElement; + let versionLabelElement, counterElement, testingUtilityLinkElement, optionsButtonElement, donationButtonElement; versionLabelElement = document.getElementById('version-label'); counterElement = document.getElementById('injection-counter'); testingUtilityLinkElement = document.getElementById('testing-utility-link'); optionsButtonElement = document.getElementById('options-button'); + donationButtonElement = document.getElementById('donate-button'); versionLabelElement.innerText = popup._version; counterElement.innerText = helpers.formatNumber(popup._amountInjected); testingUtilityLinkElement.addEventListener('mouseup', popup._onTestingUtilityLinkClicked); optionsButtonElement.addEventListener('mouseup', popup._onOptionsButtonClicked); + donationButtonElement.addEventListener('mouseup', popup._onDonationButtonClicked); }; popup._renderContextualContents = function () { @@ -356,6 +358,20 @@ popup._onOptionsButtonClicked = function () { return window.close(); }; +popup._onDonationButtonClicked = function () { + if (event.button === 0 || event.button === 1) { + + chrome.tabs.create({ + 'url': 'https://localcdn.de/donate/', + 'active': (event.button === 0) + }); + } + + if (event.button === 0) { + window.close(); + } +}; + popup._onProtectionToggled = function () { let bypassCache = (typeof browser === 'undefined'); diff --git a/pages/updates/updates.html b/pages/updates/updates.html index 0b7937b0..529a2ae3 100644 --- a/pages/updates/updates.html +++ b/pages/updates/updates.html @@ -21,6 +21,14 @@
New in LocalCDN: +
    +
  • Fixed: Encoding problem with some websites (maybe only temporary, because at the moment only 9 websites are affected) (#75)
  • +
  • Added: Twitter Bootstrap JS and CSS v4.5.0 (#77)
  • +
  • Added: Donation button
  • +
  • Added: Material Design for Bootstrap (MDB) v4.18.0 (#77)
  • +
  • Added: Tether v1.4.7 (#77)
  • +
  • Addition to the encoding problem (#75)
  • +