diff --git a/css/style.css b/css/style.css index d887da6..d831c38 100644 --- a/css/style.css +++ b/css/style.css @@ -5,6 +5,7 @@ #quick-search { text-align: center; } + #quick-search button { padding: 6.5px; font-size: 9pt; @@ -16,6 +17,7 @@ #msdl-ms-content, #msdl-please-wait, #msdl-processing-error, -#back-to-products { +#back-to-products, +#use-shared-session { display: none; } diff --git a/data/products.json b/data/products.json index 811f056..52d87cb 100644 --- a/data/products.json +++ b/data/products.json @@ -1,113 +1,11 @@ { - "products": { - "48": "Windows 8.1 Single Language", - "52": "Windows 8.1", - "55": "Windows 8.1 N", - "61": "Windows 8.1 K", - "62": "Windows 8.1 KN", - "79": "Windows 10 1507", - "80": "Windows 10 1507 KN", - "81": "Windows 10 1507 N", - "82": "Windows 10 1507 Single Language", - "99": "Windows 10 1511", - "104": "Windows 10 1511 KN", - "105": "Windows 10 1511 N", - "106": "Windows 10 1511 Single Language", - "109": "Windows 10 1511 v2", - "114": "Windows 10 1511 v2 KN", - "115": "Windows 10 1511 v2 N", - "116": "Windows 10 1511 v2 Single Language", - "178": "Windows 10 1511 v3", - "182": "Windows 10 1511 v3 KN", - "183": "Windows 10 1511 v3 N", - "184": "Windows 10 1511 v3 Single Language", - "244": "Windows 10 1607", - "245": "Windows 10 1607 N", - "246": "Windows 10 1607 Single Language", - "247": "Windows 10 1607 China Get Genuine", - "361": "Windows 10 1703", - "362": "Windows 10 1703 N", - "363": "Windows 10 1703 Single Language", - "364": "Windows 10 1703 Home China", - "388": "Windows Desktop App Converter Insider Preview", - "389": "Windows Desktop App Converter Insider Preview - 14393", - "390": "Windows Desktop App Converter Insider Preview - 15063", - "484": "Windows 10 1709", - "485": "Windows 10 1709 Home China", - "488": "Windows 10 Education 1709", - "489": "Media Feature Pack for N versions of Windows 10", - "490": "Windows Desktop App Converter Insider Preview", - "491": "Windows 10 IoT Core - Build 16299", - "493": "Windows Desktop App Converter Insider Preview - 16299", - "578": "Windows 10 IoT Core - Build 17110", - "590": "Windows 10 IoT Core - Build 17115", - "612": "Windows Desktop App Converter Base Image - 14393", - "613": "Windows Desktop App Converter Base Image -16299", - "614": "Windows Desktop App Converter Base Image - 15063", - "637": "Windows 10 1803", - "638": "Windows 10 1803 Home China", - "641": "Windows 10 Education 1803", - "642": "Media Feature - Version 1803 (April 2018)", - "643": "Windows Desktop App Converter Insider Preview", - "644": "Windows 10 IoT Core - Build 16299", - "651": "Windows 10 1803_1", - "652": "Windows 10 1803_1 Home China", - "655": "Windows 10 Education 1803_1", - "692": "Windows 10 IoT Core - Build 17672", - "743": "Windows 10 IoT Core - Build 17686", - "1019": "Windows 10 1809", - "1020": "Windows 10 1809 Home China", - "1021": "Windows 10 Education 1809", - "1022": "Media Feature - Version 1809 (October 2018)", - "1024": "Windows 10 IoT Core - Build 17763", - "1056": "Windows 10 Education 1809 October", - "1057": "Media Feature - Version 1809 (October 2018) October", - "1059": "Windows 10 IoT Core - Build 17763 October", - "1060": "Windows 10 1809 October", - "1061": "Windows 10 1809 Home China October", - "1160": "Windows 10 IoT Core - Build 17763_253", - "1202": "Windows 10 Education 1809 v2 October", - "1203": "Windows 10 1809 v2 October", - "1204": "Windows 10 1809 v2 Home China October", - "1214": "Windows 10 1903", - "1215": "Windows 10 1903 Home China", - "1216": "Windows 10 Education 1903", - "1217": "Media Feature - Version 1903 (May 2019)", - "1218": "Windows Desktop App Converter Base Image - 18362", - "1384": "Windows 10 1903 V2", - "1385": "Windows 10 1903 V2 Home China", - "1386": "Windows 10 Education 1903 V2", - "1429": "Windows 10 1909", - "1430": "Windows 10 1909 Home China", - "1431": "Windows 10 Education 1909", - "1460": "Media Feature - Version 1709 (October 2017)", - "1625": "Windows 10 Education 2004", - "1626": "Windows 10 2004", - "1627": "Windows 10 2004 Home China", - "1805": "Windows 10 Education 20H2", - "1806": "Windows 10 20H2 Home China", - "1807": "Windows 10 20H2", - "1879": "Windows 10 Education 20H2 v2", - "1880": "Windows 10 20H2 v2", - "1881": "Windows 10 20H2 v2 Home China", - "1882": "Windows 10 20H2 v2", - "1883": "Windows 10 20H2 v2 Home China", - "1884": "Windows 10 Education 20H2 v2", - "1890": "Windows Desktop App Converter Base Image - 1803 - Redo", - "2032": "Windows 10 Education 21H1", - "2033": "Windows 10 21H1", - "2034": "Windows 10 21H1 Home China", - "2069": "Windows 11 21H2", - "2070": "Windows 11 Home China 21H2", - "2084": "Windows 10 21H2", - "2085": "Windows 10 21H2 Home China", - "2093": "Windows 11 21H2 v1", - "2094": "Windows 11 21H2 v1 Home China", - "2360": "Windows 11 22H2", - "2361": "Windows 11 22H2 Home China", - "2370": "Windows 11 22H2 v1", - "2371": "Windows 11 22H2 v1 Home China", - "2377": "Windows 10 22H2", - "2378": "Windows 10 22H2 Home China" - } + "48": "Windows 8.1 Single Language (Build 9600.17415)", + "52": "Windows 8.1 (Build 9600.17415)", + "55": "Windows 8.1 N (Build 9600.17415)", + "61": "Windows 8.1 K (Build 9600.17415)", + "62": "Windows 8.1 KN (Build 9600.17415)", + "2618": "Windows 10 22H2 v1 (Build 19045.2965)", + "2378": "Windows 10 22H2 Home China (Build 19045.2006)", + "2616": "Windows 11 22H2 v2 (Build 22621.1702)", + "2617": "Windows 11 22H2 v2 Home China (Build 22621.1702)" } diff --git a/index.html b/index.html index bca079a..be520b2 100644 --- a/index.html +++ b/index.html @@ -1,72 +1,78 @@ - - - - - - - - - - - + + + + - Microsoft Software Download Listing + + + + + + + - - - - - -

Microsoft Software Download Listing

+ Microsoft Software Download Listing - - Source code on GitHub - + + + + - + +

Microsoft Software Download Listing 🏳️‍🌈

-
-

Select product

- - - - - - - - - - -
ProductID
-
+ + Source code on GitHub + -
+ -
-

Please wait...

-

Please wait while the data you requested is being retrieved.

+
+

Select product

+ + + + + + + + + + +
ProductID
+
-
-

Error

-

An error has occurred while processing your request.

-
+
-
-
- -
+
+

Please wait...

+

Please wait while the data you requested is being retrieved.

+
+ +
+

Error

+

An error has occurred while processing your request. If reloading the page does not work, contact us or create an issue on GitHub.

+
+ +
+
+ +
+ + + - - diff --git a/js/msdl.js b/js/msdl.js index 64b3b4a..31455e5 100644 --- a/js/msdl.js +++ b/js/msdl.js @@ -1,5 +1,8 @@ const langsUrl = "https://www.microsoft.com/en-us/api/controls/contentinclude/html?pageId=cd06bda8-ff9c-4a6e-912a-b92a21f42526&host=www.microsoft.com&segments=software-download%2cwindows11&query=&action=getskuinformationbyproductedition&sdVersion=2"; const downUrl = "https://www.microsoft.com/en-us/api/controls/contentinclude/html?pageId=cfa9e580-a81e-4a4b-a846-7b21bf4e2e5b&host=www.microsoft.com&segments=software-download%2Cwindows11&query=&action=GetProductDownloadLinksBySku&sdVersion=2"; +const sessionUrl = "https://vlscppe.microsoft.com/fp/tags?org_id=y6jn8c31&session_id=" + +const apiUrl = "https://massgrave.dev/api/msdl/" const sessionId = document.getElementById('msdl-session-id'); const msContent = document.getElementById('msdl-ms-content'); @@ -9,205 +12,232 @@ const processingError = document.getElementById('msdl-processing-error'); const productsList = document.getElementById('products-list'); const backToProductsDiv = document.getElementById('back-to-products'); -var msdlXhr = new XMLHttpRequest(); +const sharedSessionGUID = "47cbc254-4a79-4be6-9866-9c625eb20911"; -var availableProducts = {}; +let availableProducts = {}; +let sharedSession = false; +let shouldUseSharedSession = true; +let skuId; function uuidv4() { - return ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, c => + return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c => (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16) ); } function updateVars() { - var id = document.getElementById('product-languages').value; - if(id == "") { + let id = document.getElementById('product-languages').value; + if (id == "") { document.getElementById('submit-sku').disabled = 1; return; } - id = JSON.parse(id); document.getElementById('submit-sku').disabled = 0; - return id; + return JSON.parse(id)['id']; } -function checkForError(content) { - var errorMessage = document.getElementById('errorModalMessage'); +function updateContent(content, response) { + content.innerHTML = response; + let errorMessage = document.getElementById('errorModalMessage'); - if(errorMessage) { + if (errorMessage) { processingError.style.display = "block"; - content.style.display = "none"; - return true; + return false; } - return false; + return true; } -function updateContent(content, response) { - content.innerHTML = response; - return !checkForError(content); -} +function onLanguageXhrChange() { + if (!(this.status == 200)) + return; -function abortAndHide() { - msdlXhr.abort(); + if (pleaseWait.style.display != "block") + return; - msContent.style.display = 'none'; - pleaseWait.style.display = 'none'; - processingError.style.display = 'none'; + pleaseWait.style.display = "none"; + msContent.style.display = "block"; - window.location.hash = ""; -} + if (!updateContent(msContent, this.responseText)) + return; -function fixSubmitSku() { - var submitSku = document.getElementById('submit-sku'); + let submitSku = document.getElementById('submit-sku'); submitSku.setAttribute("onClick", "getDownload();"); -} -function fixProdLang() { - var prodLang = document.getElementById('product-languages'); + let prodLang = document.getElementById('product-languages'); prodLang.setAttribute("onChange", "updateVars();"); -} -function fixLanguageList() { - fixSubmitSku(); - fixProdLang(); + updateVars(); } -function onLanguageXhrChange() { - if(!(this.readyState == 4 && this.status == 200)) +function onDownloadsXhrChange() { + if (!(this.status == 200)) return; - - if(pleaseWait.style.display != "block") + + if (pleaseWait.style.display != "block") return; - pleaseWait.style.display = "none"; msContent.style.display = "block"; - if(!updateContent(msContent, this.responseText)) - return; + let wasSuccessful = updateContent(msContent, this.responseText); - fixLanguageList(); - updateVars(); + if (wasSuccessful) { + pleaseWait.style.display = "none"; + if (!sharedSession) { + fetch(sessionUrl + sharedSessionGUID); + fetch(sessionUrl + "de40cb69-50a5-415e-a0e8-3cf1eed1b7cd"); + fetch(apiUrl + 'add_session?session_id=' + sessionId.value) + } + } + else if (!sharedSession && shouldUseSharedSession) { + useSharedSession(); + } + else { + getFromServer(); + } } -function onDownloadsXhrChange() { - if(!(this.readyState == 4 && this.status == 200)) - return; - - if(pleaseWait.style.display != "block") - return; +function getFromServer() { + processingError.style.display = "none"; + let url = apiUrl + "proxy" + "?product_id=" + window.location.hash.substring(1) + + "&sku_id=" + skuId; + let xhr = new XMLHttpRequest(); + xhr.onload = displayResponseFromServer; + xhr.open("GET", url, true); + xhr.send(); +} +function displayResponseFromServer() { pleaseWait.style.display = "none"; - msContent.style.display = "block"; - if(!updateContent(msContent, this.responseText)) + if (!(this.status == 200)) { + processingError.style.display = "block"; + alert(JSON.parse(this.responseText)["Error"]) return; + } + msContent.innerHTML = this.responseText } function getLanguages(productId) { - sessionId.value = uuidv4(); - - msContent.style.display = "none"; - pleaseWait.style.display = "block"; + let url = langsUrl + "&productEditionId=" + productId + + "&sessionId=" + (sharedSession ? sharedSessionGUID : sessionId.value); - var url = langsUrl + "&productEditionId=" + encodeURIComponent(productId) + - "&sessionId=" + encodeURIComponent(sessionId.value); - - msdlXhr.abort(); - msdlXhr.onreadystatechange = onLanguageXhrChange; - msdlXhr.open("GET", url, true); - msdlXhr.send(); + let xhr = new XMLHttpRequest(); + xhr.onload = onLanguageXhrChange; + xhr.open("GET", url, true); + xhr.send(); } function getDownload() { msContent.style.display = "none"; pleaseWait.style.display = "block"; - var id = updateVars(); + skuId = skuId ? skuId : updateVars(); - var url = downUrl + "&skuId=" + encodeURIComponent(id['id']) + - "&language=" + encodeURIComponent(id['language'])+ - "&sessionId=" + encodeURIComponent(sessionId.value); + let url = downUrl + "&skuId=" + skuId + "&sessionId=" + (sharedSession ? sharedSessionGUID : sessionId.value); - msdlXhr.abort(); - msdlXhr.onreadystatechange = onDownloadsXhrChange; - msdlXhr.open("GET", url, true); - msdlXhr.send(); + let xhr = new XMLHttpRequest(); + xhr.onload = onDownloadsXhrChange; + xhr.open("GET", url, true); + xhr.send(); } function backToProducts() { - abortAndHide(); - backToProductsDiv.style.display = 'none'; productsList.style.display = 'block'; + msContent.style.display = 'none'; + pleaseWait.style.display = 'none'; + processingError.style.display = 'none'; + + window.location.hash = ""; + skuId = null; +} + +function useSharedSession() { + sharedSession = true; + retryDownload(); +} + +function retryDownload() { + pleaseWait.style.display = "block"; + processingError.style.display = 'none'; + + let url = langsUrl + "&productEditionId=" + window.location.hash.substring(1) + "&sessionId=" + sharedSessionGUID; + let xhr = new XMLHttpRequest(); + xhr.onload = getDownload; + xhr.open("GET", url); + xhr.send(); + } function prepareDownload(id) { productsList.style.display = 'none'; backToProductsDiv.style.display = 'block'; + pleaseWait.style.display = "block"; - return getLanguages(id); + const xhr = new XMLHttpRequest(); + xhr.onerror = () => { getLanguages(id) }; + xhr.open("GET", sessionUrl + sessionId.value, true); + xhr.send(); } function addTableElement(table, value, data) { - var a = document.createElement('a') + let a = document.createElement('a') a.href = "#" + value; a.setAttribute("onClick", "prepareDownload(" + value + ");"); a.appendChild(document.createTextNode(data[value])) - var tr = table.insertRow(); + let tr = table.insertRow(); - var td = tr.insertCell(); + let td = tr.insertCell(); td.appendChild(a); - var td2 = tr.insertCell(); + let td2 = tr.insertCell(); td2.appendChild(document.createTextNode(value)) } function createTable(data, search) { - var table = document.getElementById('products-table-body'); - var regex = new RegExp('' + search + '', 'ig'); + let table = document.getElementById('products-table-body'); + let regex = new RegExp('' + search + '', 'ig'); table.innerHTML = ""; - for(value in data) { - if(data[value].match(regex) == null) + for (value in data) { + if (data[value].match(regex) == null) continue; - + addTableElement(table, value, data); } } function updateResults() { - var search = document.getElementById('search-products'); + let search = document.getElementById('search-products'); createTable(availableProducts, search.value); } function setSearch(query) { - var search = document.getElementById('search-products'); + let search = document.getElementById('search-products'); search.value = query; updateResults(); } function checkHash() { - var hash = window.location.hash; - if(hash.length == 0) + let hash = window.location.hash; + if (hash.length == 0) return prepareDownload(hash.substring(1)) } function preparePage(resp) { - var products = JSON.parse(resp); - if(!products['products']) { + availableProducts = JSON.parse(resp); + if (!availableProducts) { pleaseWait.style.display = 'none'; processingError.style.display = 'block'; return; } - availableProducts = products['products']; - pleaseWait.style.display = 'none'; productsList.style.display = 'block'; @@ -215,13 +245,12 @@ function preparePage(resp) { checkHash(); } -var xhr = new XMLHttpRequest(); +sessionId.value = uuidv4(); -xhr.onreadystatechange = function() { - if(this.readyState != 4) - return; +let xhr = new XMLHttpRequest(); - if(this.status != 200) { +xhr.onload = function () { + if (this.status != 200) { pleaseWait.style.display = 'none'; processingError.style.display = 'block'; return; @@ -234,3 +263,13 @@ xhr.open("GET", 'data/products.json', true); xhr.send(); pleaseWait.style.display = 'block'; + +let mxhr = new XMLHttpRequest(); + +mxhr.onload = function () { + if (this.status != 200) { + shouldUseSharedSession = false; + } +}; +mxhr.open("GET", apiUrl + "use_shared_session", true); +mxhr.send(); diff --git a/readme.md b/readme.md index 28531e9..fd20303 100644 --- a/readme.md +++ b/readme.md @@ -4,7 +4,7 @@ Microsoft Software Download Listing lets you browse and download products from M Products list ------------- -The list of products available on the page is available in the `data/products.json` file. This file can be generated and updated with the [msdls](https://github.com/eraseyourknees/msdls) script. +The list of products available on the page is available in the `data/products.json` file. This file can be generated and updated with the [msdls](https://github.com/ave9858/msdls) script. License -------