From 8b9260a195578dbc187ab2352f54ec2883ddb6ec Mon Sep 17 00:00:00 2001 From: M_Viper Date: Sat, 8 Mar 2025 13:45:53 +0000 Subject: [PATCH] Dateien nach "/" hochladen --- 128.png | Bin 0 -> 6515 bytes 16.png | Bin 0 -> 380 bytes 48.png | Bin 0 -> 2525 bytes README.md | 7 +- background.js | 191 ++++++++++++++++++++++++++++++++++++++++++++++++++ manifest.json | 31 ++++++++ popup.html | 157 +++++++++++++++++++++++++++++++++++++++++ popup.js | 96 +++++++++++++++++++++++++ 8 files changed, 481 insertions(+), 1 deletion(-) create mode 100644 128.png create mode 100644 16.png create mode 100644 48.png create mode 100644 background.js create mode 100644 manifest.json create mode 100644 popup.html create mode 100644 popup.js diff --git a/128.png b/128.png new file mode 100644 index 0000000000000000000000000000000000000000..9d04da250daaedf4fe5b4b774d3e1035609ca91d GIT binary patch literal 6515 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 ab-n^4L8koPu|={~mhg&6 z%JNzoB0ft*L?mxy%aZLI^?vX7efRe}_nh;;&v~BzbN=_9-;FiyO_&-cHYp z6oBybCS4#P=mBI78UXa^dYoYZf#wON2V4rI>d_5gKM{JI@m?4SgZ_lj{0(4k_9vlc zBnknliO@i(!VCqVP^dn|+egm{WAXQL&ddPjOQVtXkjRjb5JZSNf<(E9MCt14B30Fp zYHBJRgbFn@kmgBO38cb*k^F}TL!f$5h-4a(6bRkp^}Ij|q8Y$odqV$Qzw)FJeg3Ny zNd4Ou#~^a=2@-`+MgGIhS*pJm)pMW_2^{4;enXW0Pvrl_{?^e)?uq|TGQXVujB>0R z3g{#M*)~G~yCwx30Pr2Q#+bPH?wiZNS*4wkY#Ws6oPM2XQ8mQ&g$m|1$;ZNMgkj2D zb<%;N^`A3It25Ci!v6$mqV{>L2(S@1fL(p>Y85(`nk1Oh))TJR!Kl32g zw^oP3gm*Q+)(<*fmB>p?O*INP96LYnRT!2!x}FKoDQ#PxYwVpRyP(h3B_t&5fEipP z6<%#d+na01t(7l~KdP%yIjZ9z?vFg>`T25RhN_BQgf16e*j$}E6OM^!hy+aqa(&yH zx28D2_KOFGfE*&We|*o0U|(-XU&xvnf6a4X+XIXi@7~(lP#2M7J^z^fRC4Q7XdVh^xRF39e>@r@s z2#h%PUu&7$63MAQ0t>D8PxN}7akk{UmBGRxk^-;W!sfOFA5VUL{kfMB+mA_iRF4RO zSxr+N_mC-9n!{5B7nXC?Gfq5bT54-~iR&jX9)}>+#~rz%{qN8oIpi4jJ~@s2zTO-s zswXNoX!pobR-@%bkN6i^Dvfn^m&V{2a~|z9n<=W}nrF|HMRj@x zk8<0+3|qryyZzytVwbJw>g4QPV0jzz7!2nyr)6rB*wy}nl0vQV2iXIqXB6O;w_Naf zUdHsQ4rAYg=0er^S_Ffbb{@>c(O18pueu=9NdNYs-gPbCn&CZAf}^Z2cm_QtjlFcj;gqP;o#Ij8 zVsyy-4gbYvY;yJI?i}0T;Ah@GKJ27J+WBQ=*oOUbdYGNL_cdw(!x~92$oX2b2?GB@ z5qbWlkfnriG_UC0W43pTP40Z;q0Th&SGwTwWnNKD`jkWzlfi&v!smvoE5p_T_t_BV zN9#^M3wST@KTwjAjSlg91jyo^78DgdIRWCN`U-p?3{>=#xiYa>XrHO!%6at|)X!bS zz8hkW)x3C{nVyH12bI`Ba^Lm{i|RVf*v4YaG4=%6GpG#92NG0`gpbyat}0n~Lx zw;+MGH@KS#gyar(-ff5wg<^cM`+gedqwv)tvuSQnUAxLr@N}yYc|4K~3mARwy0o;E zUs7@++=zKLd5qF%H)@}*W?orYxl+n~r<{AE#jMZayw3n2Ia$7fgr;=bki0o0Lb9>(Qr($8KnKZ?1jQr1Z_q_CM(d zWvFXOrznKofrjvR;eyG6_uto$1gBb9w*ptWGMN(KcbsE*1qPq^D%~OG8g+s)KDk=x zr*n&YzV*1gK%b%w>r3w_KKD0Aoy!xL?^(wq8l(1Q934QhTTHKVOY%;4=ad_#TPk1= zG;;UE^wc_*MZ$b%3S0Rn?i++@2(}->5uKzoQnGA#L^7`tI_^p}`(hhtoCAcqFL;6x!4D{@xbGYAP0Gh!;Radx9mI1*sR;f?DQSb1 zmt0+(9S5R-SaI$|l<_G$R4)8lrV0J%Wc5b7_7WbSC$eoP0%4d#cCaE1-rfRp0m~I1 zcGE;dk>w$>wlyIiI>xHI-aOI7P6qN$NUlE}niq;O6EC{96R(7QR(EOO@bcL1pMU0d z3`bOOsiJ$0P}OSdEvt2x5HYMY`?L1wx#FZu?H;9=3Y8dE#w(}!JnhSU^Q}K_OT>T0 z@Ohz`jS%wKpUR{6rZoo7`LN=FdJA6%ITyW#Pmr9O;SJT_O$LKc*Y3J0i9~Om+Z~-g YU*^iK;%3YIu=mepZH~p1nR-P18_Cm#6951J literal 0 HcmV?d00001 diff --git a/README.md b/README.md index 4ee8769..75b1727 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,7 @@ -# CRX-Extractor-Downloader +# crx-download +Download CRX files as zip or directly. +### Store Links + +1. [Chrome Store](https://chrome.google.com/webstore/detail/crx-extractordownloader/ajkhmmldknmfjnmeedkbkkojgobmljda) +2. [Microsoft Edge Store](https://microsoftedge.microsoft.com/addons/detail/crx-extractordownloader/gfgehnhkaggeillajnpegcanbdjcbeja) diff --git a/background.js b/background.js new file mode 100644 index 0000000..94276d1 --- /dev/null +++ b/background.js @@ -0,0 +1,191 @@ +let chromeURLPattern = /^https?:\/\/chrome.google.com\/webstore\/.+?\/([a-z]{32})(?=[\/#?]|$)/; +let microsoftURLPattern = /^https?:\/\/microsoftedge.microsoft.com\/addons\/detail\/.+?\/([a-z]{32})(?=[\/#?]|$)/; +let chromeNewURLPattern = /^https?:\/\/chromewebstore.google.com\/detail\/.+?\/([a-z]{32})(?=[\/#?]|$)/; + + +function getChromeVersion() { + var pieces = navigator.userAgent.match(/Chrom(?:e|ium)\/([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)/); + if (pieces == null || pieces.length != 5) { + return undefined; + } + pieces = pieces.map(piece => parseInt(piece, 10)); + return { + major: pieces[1], + minor: pieces[2], + build: pieces[3], + patch: pieces[4] + }; +} + +function getNaclArch() { + var nacl_arch = 'arm'; + if (navigator.userAgent.indexOf('x86') > 0) { + nacl_arch = 'x86-32'; + } else if (navigator.userAgent.indexOf('x64') > 0) { + nacl_arch = 'x86-64'; + } + return nacl_arch; +} +let currentVersion = getChromeVersion(); +let version = currentVersion.major + "." + currentVersion.minor + "." + currentVersion.build + "." + currentVersion.patch; +const nacl_arch = getNaclArch(); + +function getTabTitle(title, currentEXTId, url) { + if (!chromeNewURLPattern.exec(url)) { + title = title.match(/^(.*[-])/); + if (title) { + title = title[0].split(' - ').join(""); + } else { + title = currentEXTId; + } + } + // Ѐ-ӿ matches cyrillic characters + return (title).replace(/[&\/\\#,+()$~%.'":*?<>|{}\sЀ-ӿ]/g, '-').replace(/-*$/g, '').replace(/-+/g, '-'); +} + +function download(downloadAs, tab) { + + var query = { + active: true, + currentWindow: true + }; + result = chromeURLPattern.exec(tab.url); + if (!result) { + result = chromeNewURLPattern.exec(tab.url); + } + if (result && result[1]) { + var name = getTabTitle(tab.title, result[1], tab.url); + if (downloadAs === "zip") { + url = `https://clients2.google.com/service/update2/crx?response=redirect&prodversion=${version}&x=id%3D${result[1]}%26installsource%3Dondemand%26uc&nacl_arch=${nacl_arch}&acceptformat=crx2,crx3`; + convertURLToZip(url, function (urlVal) { + downloadFile(urlVal, name + ".zip"); + + }); + } else if (downloadAs === "crx") { + url = `https://clients2.google.com/service/update2/crx?response=redirect&prodversion=${version}&acceptformat=crx2,crx3&x=id%3D${result[1]}%26uc&nacl_arch=${nacl_arch}`; + downloadFile(url, name + ".crx", result[1] + ".crx"); + } + } + var edgeId = microsoftURLPattern.exec(tab.url); + if (edgeId && edgeId[1] && downloadAs === "crx") { + var name = getTabTitle(tab.title, edgeId[1], tab.url); + url = `https://edge.microsoft.com/extensionwebstorebase/v1/crx?response=redirect&prod=chromiumcrx&prodchannel=&x=id%3D${edgeId[1]}%26installsource%3Dondemand%26uc`; + downloadFile(url, name + ".crx", edgeId[1] + ".crx"); + } + // }); +} + +function ArrayBufferToBlob(arraybuffer, callback) { + + var data = arraybuffer; + var buf = new Uint8Array(data); + var publicKeyLength, signatureLength, header, zipStartOffset; + if (buf[4] === 2) { + header = 16; + publicKeyLength = 0 + buf[8] + (buf[9] << 8) + (buf[10] << 16) + (buf[11] << 24); + signatureLength = 0 + buf[12] + (buf[13] << 8) + (buf[14] << 16) + (buf[15] << 24); + zipStartOffset = header + publicKeyLength + signatureLength; + } else { + publicKeyLength = 0 + buf[8] + (buf[9] << 8) + (buf[10] << 16) + (buf[11] << 24 >>> 0); + zipStartOffset = 12 + publicKeyLength; + } + // 16 = Magic number (4), CRX format version (4), lengths (2x4) + + return new Blob([ + new Uint8Array(arraybuffer, zipStartOffset) + ], { + type: 'application/zip' + }); +} + +function convertURLToZip(url, callback, xhrProgressListener) { + var requestUrl = url; + fetch(requestUrl).then(function (response) { + return (response.arrayBuffer()) + }).then((res) => { + var zipFragment = ArrayBufferToBlob(res); + var reader = new FileReader(); + reader.readAsDataURL(zipFragment); + reader.onloadend = function () { + var base64data = reader.result; + callback(base64data); + } + + }); + +} + + +function downloadFile(url, fileName, currentEXTId = "unknown", _fails = 0) { + chrome.downloads.download({ + url: url, + filename: fileName, + saveAs: true + }, function () { + if (chrome.runtime.lastError) { + if (chrome.runtime.lastError.message === "Invalid filename" && _fails < 1) { + downloadFile(url, currentEXTId, currentEXTId, _fails + 1); + } else { + alert('An error occurred while trying to save ' + fileName + ':\n\n' + + chrome.runtime.lastError.message); + } + } + }); +} + + + + +function onClickEvent(info, tab) { + + if (info.menuItemId === "crx" || info.menuItemId === "crxmicrosoft") { + download("crx", tab) + } else if (info.menuItemId === "zip") { + download("zip", tab) + } + console.log(info) + +} +chrome.contextMenus.onClicked.addListener(onClickEvent); + + +chrome.runtime.setUninstallURL("https://thebyteseffect.com/posts/reason-for-uninstall-crx-extractor/", null); +chrome.runtime.onInstalled.addListener(function (details) { + if (details.reason == "install") { + chrome.tabs.create({ + url: "https://thebyteseffect.com/posts/crx-extractor-features/" + }); + + } + const parent = chrome.contextMenus.create({ + 'title': 'Download CRX for this extension', + 'contexts': ['all'], + 'id': "parent", + 'documentUrlPatterns': ['https://chrome.google.com/webstore/detail/*', 'https://chromewebstore.google.com/detail/*'] + }); + chrome.contextMenus.create({ + 'title': 'Download CRX for this extension', + 'contexts': ['all'], + id: "crx", + parentId: parent, + 'documentUrlPatterns': ['https://chrome.google.com/webstore/detail/*', 'https://chromewebstore.google.com/detail/*'] + }); + + chrome.contextMenus.create({ + 'title': 'Download CRX for this extension', + 'contexts': ['all'], + parentId: parent, + id: "crxmicrosoft", + 'documentUrlPatterns': ['https://microsoftedge.microsoft.com/addons/detail/*'] + }); + chrome.contextMenus.create({ + 'title': 'Download ZIP for this extension', + 'contexts': ['all'], + id: "zip", + parentId: parent, + 'documentUrlPatterns': ['https://chrome.google.com/webstore/detail/*', 'https://chromewebstore.google.com/detail/*'] + }); +}); +chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) { + download(request.download, request.tab); +}); diff --git a/manifest.json b/manifest.json new file mode 100644 index 0000000..3c8d932 --- /dev/null +++ b/manifest.json @@ -0,0 +1,31 @@ +{ + "update_url": "https://clients2.google.com/service/update2/crx", + "name": "CRX Extractor/Downloader", + "version": "1.5.8", + "manifest_version": 3, + "description": "Download CRX Files directly as crx or zip file depending upon your choice", + "permissions": [ + "downloads", + "contextMenus", + "activeTab", + "downloads" + ], + "background": { + "service_worker": "background.js" + }, + "host_permissions": [ + "*://clients2.google.com/service/update2/crx*", + "*://clients2.googleusercontent.com/crx/download/*" +], + "icons": { + "16": "16.png", + "48": "48.png", + "128": "128.png" + }, + + "action": { + "default_icon": "128.png", + "default_popup": "popup.html" + } +} + diff --git a/popup.html b/popup.html new file mode 100644 index 0000000..a3ad9f6 --- /dev/null +++ b/popup.html @@ -0,0 +1,157 @@ + + + + + + Download CRX + + + + + + + + + + +
+ + + +
+
+ + + +
+ + + + + + + + \ No newline at end of file diff --git a/popup.js b/popup.js new file mode 100644 index 0000000..83e5628 --- /dev/null +++ b/popup.js @@ -0,0 +1,96 @@ + + +let chromeURLPattern = /^https?:\/\/chrome.google.com\/webstore\/.+?\/([a-z]{32})(?=[\/#?]|$)/; +let chromeNewURLPattern = /^https?:\/\/chromewebstore.google.com\/detail\/.+?\/([a-z]{32})(?=[\/#?]|$)/; +let microsoftURLPattern = /^https?:\/\/microsoftedge.microsoft.com\/addons\/detail\/.+?\/([a-z]{32})(?=[\/#?]|$)/; + + +function ready() { + document.getElementById('downloadZIP').onclick = async function () { + let queryOptions = { active: true, currentWindow: true }; + let [tab] = await chrome.tabs.query(queryOptions); + chrome.runtime.sendMessage({download:"zip", tab: tab}); + }; + document.getElementById('downloadCRX').onclick = async function () { + let queryOptions = { active: true, currentWindow: true }; + let [tab] = await chrome.tabs.query(queryOptions); + chrome.runtime.sendMessage({download:"crx",tab:tab}); + }; + + document.getElementById("convertCRXToZip").onchange = function (files) { + setTimeout(() => { + document.getElementById("loader").style.display = "none"; + document.getElementById("downloadCRXToZip").style.display = "block"; + }, 2000); + document.getElementById("loader").style.display = "block"; + document.getElementById("downloadCRXToZip").style.display = "none"; + + return false; + } + document.getElementById("downloadCRXToZip").onclick = function () { + var file = document.getElementById("convertCRXToZip").files[0]; + + var reader = new FileReader(); + reader.onload = function (e) { + var data = reader.result; + var buf = new Uint8Array(data); + var publicKeyLength, signatureLength, header, zipStartOffset; + if (buf[4] === 2) { + header = 16; + publicKeyLength = 0 + buf[8] + (buf[9] << 8) + (buf[10] << 16) + (buf[11] << 24); + signatureLength = 0 + buf[12] + (buf[13] << 8) + (buf[14] << 16) + (buf[15] << 24); + zipStartOffset = header + publicKeyLength + signatureLength; + } else { + publicKeyLength = 0 + buf[8] + (buf[9] << 8) + (buf[10] << 16) + (buf[11] << 24 >>> 0); + zipStartOffset = 12 + publicKeyLength; + } + // 16 = Magic number (4), CRX format version (4), lengths (2x4) + var zip = buf.slice(zipStartOffset, buf.length); + var fileName = file.name.replace(".crx", ".zip") + var blob = new Blob([zip], { type: "application/octet-stream" }); + var url = window.URL.createObjectURL(blob); + chrome.downloads.download({ + url: url, + filename: fileName, + saveAs: true + }); + + } + reader.readAsArrayBuffer(file); + + + } + document.getElementById('rating').onclick = function () { + window.open("https://chrome.google.com/webstore/detail/crx-extractordownloader/ajkhmmldknmfjnmeedkbkkojgobmljda/reviews"); + }; + chrome.tabs.query({ active: true, currentWindow: true }, function (tab) { + tab = tab[0]; + var id = chromeURLPattern.exec(tab.url); + + if (!id) { + id = chromeNewURLPattern.exec(tab.url); + } + var edgeId = microsoftURLPattern.exec(tab.url); + + + document.getElementById("info").style.display = "block"; + var elements = document.getElementsByClassName('defaultBtn'); + var length = elements.length; + for (var i = 0; i < length; i++) { + elements[i].style.display = 'none'; + } + + if (edgeId !== null && edgeId[1] !== null) { + document.getElementById("info").style.display = "none"; + document.getElementById('downloadCRX').style.display = 'block'; + } else if (id !== null && id[1] !== null) { + document.getElementById("info").style.display = "none"; + var elements = document.getElementsByClassName('defaultBtn'); + var length = elements.length; + for (var i = 0; i < length; i++) { + elements[i].style.display = 'block'; + } + } + }); +} +ready(); \ No newline at end of file