Skip to content

fix: msdl fixed #256

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 28, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
186 changes: 43 additions & 143 deletions docs/javascript/msdl.v1.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,37 +8,27 @@
// - Simplification of certain functions like updateVars
// - Fixes/adaptations for use in Atlas documentation

const msApiUrl = "https://www.microsoft.com/software-download-connector/api/"
const parms = "?profile=606624d44113&Locale=en-US&sessionID="
const sessionUrl = "https://vlscppe.microsoft.com/fp/tags?org_id=y6jn8c31&session_id="
const apiUrl = "https://api.gravesoft.dev/msdl/"

const sharedSessionGUID = "47cbc254-4a79-4be6-9866-9c625eb20911";
const langAttempt = 3;
const apiUrl = "https://api.gravesoft.dev/msdl/";

let sessionId;
let msContent;
let pleaseWait;
let processingError;
let download;
let downloadLink;
let getLangFailCount;
let shouldUseSharedSession = true;
let winProductID;
let skuId;

function uuidv4() {
return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, (c) => (c ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))).toString(16));
return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, (c) =>
(c ^ crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4))).toString(16)
);
}

function updateVars() {
// With auto-selection, an option is always selected.
let id = document.getElementById('product-languages').value;
if (id == "") {
document.getElementById('submit-sku').disabled = 1;
return;
}

document.getElementById('submit-sku').disabled = 0;
document.getElementById('submit-sku').disabled = false;
skuId = JSON.parse(id)['id'];
console.log(`Updated skuId: ${skuId}`);
return skuId;
Expand All @@ -58,17 +48,12 @@ function getFileNameFromLink(link) {
}

function getLanguages(productId) {
let url = `${msApiUrl}getskuinformationbyproductedition${parms}${sessionId.value}&ProductEditionId=${productId}`;
let url = `${apiUrl}skuinfo?product_id=${productId}`;
let xhr = new XMLHttpRequest();
xhr.onload = onLanguageXhrChange;
xhr.onerror = function() {
getLangFailCount++;
if (getLangFailCount > langAttempt) {
showError("Failed to retrieve languages.");
} else {
getLanguages(productId);
}
};
showError("Failed to retrieve languages.");
};
xhr.open("GET", url, true);
xhr.send();
}
Expand All @@ -84,11 +69,8 @@ function onLanguageXhrChange() {
let langHtml = langJsonStrToHTML(this.responseText);
msContent.innerHTML = langHtml;

let submitSku = document.getElementById('submit-sku');
submitSku.setAttribute("onClick", "getDownload();");

let prodLang = document.getElementById('product-languages');
prodLang.setAttribute("onChange", "updateVars();");
prodLang.addEventListener("change", updateVars);

updateVars();
}
Expand All @@ -110,7 +92,7 @@ function langJsonStrToHTML(jsonStr) {

let defaultOption = document.createElement('option');
defaultOption.value = "";
defaultOption.selected = "selected";
defaultOption.selected = true;
defaultOption.textContent = "Choose one";
select.appendChild(defaultOption);

Expand All @@ -125,130 +107,63 @@ function langJsonStrToHTML(jsonStr) {

let button = document.createElement('button');
button.id = "submit-sku";
button.textContent = "Submit";
button.textContent = "Download";
button.disabled = true;
button.setAttribute("onClick", "getDownload();");

container.appendChild(button);

return container.innerHTML;
}

function getDownload(sharedSession = false) {
function getDownload() {
msContent.style.display = "none";
pleaseWait.style.display = "block";
skuId = skuId ? skuId : updateVars();
let sessionGUID = sharedSession ? sharedSessionGUID : sessionId.value;
let url = `${msApiUrl}GetProductDownloadLinksBySku${parms}${sessionGUID}&SKU=${skuId}`;
let url = `${apiUrl}proxy?product_id=${winProductID}&sku_id=${skuId}`;
console.log(`Requesting download links from URL: ${url}`);
let xhr = new XMLHttpRequest();
xhr.onload = function() {
onDownloadsXhrChange(sharedSession);
};
xhr.onload = onDownloadsXhrChange;
xhr.open("GET", url, true);
xhr.send();
}

function onDownloadsXhrChange(sharedSession) {
function onDownloadsXhrChange() {
if (this.status != 200) {
if (!sharedSession) {
console.log("Request failed, retrying with shared session...");
getDownload(true);
} else {
console.log("Request failed, using server proxy...");
getFromServer();
}
showError("Failed to retrieve download links.");
return;
}

let response = JSON.parse(this.responseText);
console.log('Download response:', response);

if (response.Errors || response.ValidationContainer.Errors) {
if (!sharedSession) {
console.log("Request failed, retrying with shared session...");
getDownload(true);
} else {
console.log("Request failed, using server proxy...");
getFromServer();
}
return;
}

pleaseWait.style.display = "none";
msContent.innerHTML = "";
msContent.style.display = "block";

response.ProductDownloadOptions.forEach(option => {
let optionContainer = document.createElement('div');
let header = document.createElement('h1');
header.textContent = `Windows 11 ${option.LocalizedLanguage}`;
let downloadButton = document.createElement('a');
downloadButton.href = option.Uri;
downloadButton.textContent = getFileNameFromLink(option.Uri);
downloadButton.target = "_blank";
optionContainer.appendChild(downloadButton);
msContent.appendChild(optionContainer);

// Trigger automatic download
const link = document.createElement('a');
link.href = option.Uri;
link.download = getFileNameFromLink(option.Uri);
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
});
}

function getFromServer() {
console.log("Using server proxy to get the download link.");
let url = `${apiUrl}proxy?product_id=${winProductID}&sku_id=${skuId}`;
let xhr = new XMLHttpRequest();
xhr.onload = displayResponseFromServer;
xhr.open("GET", url, true);
xhr.send();
}

function displayResponseFromServer() {
if (this.status != 200) {
showError("Failed to retrieve download links from server.");
return;
}

const response = JSON.parse(this.responseText);
console.log('Server proxy response:', response);

// Check if ProductDownloadOptions array is present and has elements
if (!response.ProductDownloadOptions || response.ProductDownloadOptions.length === 0) {
showError("No download options available from server.");
return;
}

pleaseWait.style.display = "none";
msContent.innerHTML = "";
msContent.style.display = "block";

response.ProductDownloadOptions.forEach(option => {
if (option.Uri && option.Uri.includes('_x64')) {
let optionContainer = document.createElement('div');
let header = document.createElement('h1');
header.textContent = `Windows 11 ${option.LocalizedLanguage}`;
let downloadButton = document.createElement('a');
downloadButton.href = option.Uri;
downloadButton.textContent = getFileNameFromLink(option.Uri);
downloadButton.target = "_blank";
optionContainer.appendChild(downloadButton);
msContent.appendChild(optionContainer);

// Trigger automatic download
const link = document.createElement('a');
link.href = option.Uri;
link.download = getFileNameFromLink(option.Uri);
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
});
if (response.ProductDownloadOptions && response.ProductDownloadOptions.length > 0) {
let header = document.createElement('h2');
header.textContent = `${response.ProductDownloadOptions[0].ProductDisplayName} ${response.ProductDownloadOptions[0].LocalizedLanguage}`;
msContent.appendChild(header);

response.ProductDownloadOptions.forEach(option => {
let optionContainer = document.createElement('div');
let downloadButton = document.createElement('a');
downloadButton.href = option.Uri;
downloadButton.textContent = getFileNameFromLink(option.Uri);
downloadButton.target = "_blank";
optionContainer.appendChild(downloadButton);
msContent.appendChild(optionContainer);

// Trigger automatic download
const link = document.createElement('a');
link.href = option.Uri;
link.download = getFileNameFromLink(option.Uri);
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
});
} else {
msContent.innerHTML = "<p>No download options available.</p>";
}
}

function getWindows(id) {
Expand All @@ -260,23 +175,8 @@ function getWindows(id) {
download = document.getElementById("msdl-download");
downloadLink = document.getElementById("msdl-download-link");

// Misc variables
getLangFailCount = 0;

// Start new session
skuId = null;
sessionId.value = uuidv4();
const xhr = new XMLHttpRequest();
xhr.open("GET", sessionUrl + sessionId.value, true);
xhr.send();

let mxhr = new XMLHttpRequest();
mxhr.onload = function () {
if (this.status != 200) shouldUseSharedSession = false;
};
mxhr.open("GET", apiUrl + "use_shared_session", true);
mxhr.send();

// Display the 'Please wait' text
msContent.style.display = "none";
processingError.style.display = "none";
download.style.display = "none";
Expand Down