88// - Simplification of certain functions like updateVars
99// - Fixes/adaptations for use in Atlas documentation
1010
11- const msApiUrl = "https://www.microsoft.com/software-download-connector/api/"
12- const parms = "?profile=606624d44113&Locale=en-US&sessionID="
13- const sessionUrl = "https://vlscppe.microsoft.com/fp/tags?org_id=y6jn8c31&session_id="
14- const apiUrl = "https://api.gravesoft.dev/msdl/"
15-
16- const sharedSessionGUID = "47cbc254-4a79-4be6-9866-9c625eb20911" ;
17- const langAttempt = 3 ;
11+ const apiUrl = "https://api.gravesoft.dev/msdl/" ;
1812
1913let sessionId ;
2014let msContent ;
2115let pleaseWait ;
2216let processingError ;
2317let download ;
2418let downloadLink ;
25- let getLangFailCount ;
26- let shouldUseSharedSession = true ;
2719let winProductID ;
2820let skuId ;
2921
3022function uuidv4 ( ) {
31- return ( [ 1e7 ] + - 1e3 + - 4e3 + - 8e3 + - 1e11 ) . replace ( / [ 0 1 8 ] / g, ( c ) => ( c ^ ( crypto . getRandomValues ( new Uint8Array ( 1 ) ) [ 0 ] & ( 15 >> ( c / 4 ) ) ) ) . toString ( 16 ) ) ;
23+ return ( [ 1e7 ] + - 1e3 + - 4e3 + - 8e3 + - 1e11 ) . replace ( / [ 0 1 8 ] / g, ( c ) =>
24+ ( c ^ crypto . getRandomValues ( new Uint8Array ( 1 ) ) [ 0 ] & ( 15 >> ( c / 4 ) ) ) . toString ( 16 )
25+ ) ;
3226}
3327
3428function updateVars ( ) {
29+ // With auto-selection, an option is always selected.
3530 let id = document . getElementById ( 'product-languages' ) . value ;
36- if ( id == "" ) {
37- document . getElementById ( 'submit-sku' ) . disabled = 1 ;
38- return ;
39- }
40-
41- document . getElementById ( 'submit-sku' ) . disabled = 0 ;
31+ document . getElementById ( 'submit-sku' ) . disabled = false ;
4232 skuId = JSON . parse ( id ) [ 'id' ] ;
4333 console . log ( `Updated skuId: ${ skuId } ` ) ;
4434 return skuId ;
@@ -58,17 +48,12 @@ function getFileNameFromLink(link) {
5848}
5949
6050function getLanguages ( productId ) {
61- let url = `${ msApiUrl } getskuinformationbyproductedition ${ parms } ${ sessionId . value } &ProductEditionId =${ productId } ` ;
51+ let url = `${ apiUrl } skuinfo?product_id =${ productId } ` ;
6252 let xhr = new XMLHttpRequest ( ) ;
6353 xhr . onload = onLanguageXhrChange ;
6454 xhr . onerror = function ( ) {
65- getLangFailCount ++ ;
66- if ( getLangFailCount > langAttempt ) {
67- showError ( "Failed to retrieve languages." ) ;
68- } else {
69- getLanguages ( productId ) ;
70- }
71- } ;
55+ showError ( "Failed to retrieve languages." ) ;
56+ } ;
7257 xhr . open ( "GET" , url , true ) ;
7358 xhr . send ( ) ;
7459}
@@ -84,11 +69,8 @@ function onLanguageXhrChange() {
8469 let langHtml = langJsonStrToHTML ( this . responseText ) ;
8570 msContent . innerHTML = langHtml ;
8671
87- let submitSku = document . getElementById ( 'submit-sku' ) ;
88- submitSku . setAttribute ( "onClick" , "getDownload();" ) ;
89-
9072 let prodLang = document . getElementById ( 'product-languages' ) ;
91- prodLang . setAttribute ( "onChange ", " updateVars();" ) ;
73+ prodLang . addEventListener ( "change ", updateVars ) ;
9274
9375 updateVars ( ) ;
9476}
@@ -110,7 +92,7 @@ function langJsonStrToHTML(jsonStr) {
11092
11193 let defaultOption = document . createElement ( 'option' ) ;
11294 defaultOption . value = "" ;
113- defaultOption . selected = "selected" ;
95+ defaultOption . selected = true ;
11496 defaultOption . textContent = "Choose one" ;
11597 select . appendChild ( defaultOption ) ;
11698
@@ -125,130 +107,63 @@ function langJsonStrToHTML(jsonStr) {
125107
126108 let button = document . createElement ( 'button' ) ;
127109 button . id = "submit-sku" ;
128- button . textContent = "Submit " ;
110+ button . textContent = "Download " ;
129111 button . disabled = true ;
130112 button . setAttribute ( "onClick" , "getDownload();" ) ;
131-
132113 container . appendChild ( button ) ;
133114
134115 return container . innerHTML ;
135116}
136117
137- function getDownload ( sharedSession = false ) {
118+ function getDownload ( ) {
138119 msContent . style . display = "none" ;
139120 pleaseWait . style . display = "block" ;
140121 skuId = skuId ? skuId : updateVars ( ) ;
141- let sessionGUID = sharedSession ? sharedSessionGUID : sessionId . value ;
142- let url = `${ msApiUrl } GetProductDownloadLinksBySku${ parms } ${ sessionGUID } &SKU=${ skuId } ` ;
122+ let url = `${ apiUrl } proxy?product_id=${ winProductID } &sku_id=${ skuId } ` ;
143123 console . log ( `Requesting download links from URL: ${ url } ` ) ;
144124 let xhr = new XMLHttpRequest ( ) ;
145- xhr . onload = function ( ) {
146- onDownloadsXhrChange ( sharedSession ) ;
147- } ;
125+ xhr . onload = onDownloadsXhrChange ;
148126 xhr . open ( "GET" , url , true ) ;
149127 xhr . send ( ) ;
150128}
151129
152- function onDownloadsXhrChange ( sharedSession ) {
130+ function onDownloadsXhrChange ( ) {
153131 if ( this . status != 200 ) {
154- if ( ! sharedSession ) {
155- console . log ( "Request failed, retrying with shared session..." ) ;
156- getDownload ( true ) ;
157- } else {
158- console . log ( "Request failed, using server proxy..." ) ;
159- getFromServer ( ) ;
160- }
132+ showError ( "Failed to retrieve download links." ) ;
161133 return ;
162134 }
163-
164135 let response = JSON . parse ( this . responseText ) ;
165136 console . log ( 'Download response:' , response ) ;
166137
167- if ( response . Errors || response . ValidationContainer . Errors ) {
168- if ( ! sharedSession ) {
169- console . log ( "Request failed, retrying with shared session..." ) ;
170- getDownload ( true ) ;
171- } else {
172- console . log ( "Request failed, using server proxy..." ) ;
173- getFromServer ( ) ;
174- }
175- return ;
176- }
177-
178138 pleaseWait . style . display = "none" ;
179139 msContent . innerHTML = "" ;
180140 msContent . style . display = "block" ;
181141
182- response . ProductDownloadOptions . forEach ( option => {
183- let optionContainer = document . createElement ( 'div' ) ;
184- let header = document . createElement ( 'h1' ) ;
185- header . textContent = `Windows 11 ${ option . LocalizedLanguage } ` ;
186- let downloadButton = document . createElement ( 'a' ) ;
187- downloadButton . href = option . Uri ;
188- downloadButton . textContent = getFileNameFromLink ( option . Uri ) ;
189- downloadButton . target = "_blank" ;
190- optionContainer . appendChild ( downloadButton ) ;
191- msContent . appendChild ( optionContainer ) ;
192-
193- // Trigger automatic download
194- const link = document . createElement ( 'a' ) ;
195- link . href = option . Uri ;
196- link . download = getFileNameFromLink ( option . Uri ) ;
197- document . body . appendChild ( link ) ;
198- link . click ( ) ;
199- document . body . removeChild ( link ) ;
200- } ) ;
201- }
202-
203- function getFromServer ( ) {
204- console . log ( "Using server proxy to get the download link." ) ;
205- let url = `${ apiUrl } proxy?product_id=${ winProductID } &sku_id=${ skuId } ` ;
206- let xhr = new XMLHttpRequest ( ) ;
207- xhr . onload = displayResponseFromServer ;
208- xhr . open ( "GET" , url , true ) ;
209- xhr . send ( ) ;
210- }
211-
212- function displayResponseFromServer ( ) {
213- if ( this . status != 200 ) {
214- showError ( "Failed to retrieve download links from server." ) ;
215- return ;
216- }
217-
218- const response = JSON . parse ( this . responseText ) ;
219- console . log ( 'Server proxy response:' , response ) ;
220-
221- // Check if ProductDownloadOptions array is present and has elements
222- if ( ! response . ProductDownloadOptions || response . ProductDownloadOptions . length === 0 ) {
223- showError ( "No download options available from server." ) ;
224- return ;
225- }
226-
227- pleaseWait . style . display = "none" ;
228- msContent . innerHTML = "" ;
229- msContent . style . display = "block" ;
230-
231- response . ProductDownloadOptions . forEach ( option => {
232- if ( option . Uri && option . Uri . includes ( '_x64' ) ) {
233- let optionContainer = document . createElement ( 'div' ) ;
234- let header = document . createElement ( 'h1' ) ;
235- header . textContent = `Windows 11 ${ option . LocalizedLanguage } ` ;
236- let downloadButton = document . createElement ( 'a' ) ;
237- downloadButton . href = option . Uri ;
238- downloadButton . textContent = getFileNameFromLink ( option . Uri ) ;
239- downloadButton . target = "_blank" ;
240- optionContainer . appendChild ( downloadButton ) ;
241- msContent . appendChild ( optionContainer ) ;
242-
243- // Trigger automatic download
244- const link = document . createElement ( 'a' ) ;
245- link . href = option . Uri ;
246- link . download = getFileNameFromLink ( option . Uri ) ;
247- document . body . appendChild ( link ) ;
248- link . click ( ) ;
249- document . body . removeChild ( link ) ;
250- }
251- } ) ;
142+ if ( response . ProductDownloadOptions && response . ProductDownloadOptions . length > 0 ) {
143+ let header = document . createElement ( 'h2' ) ;
144+ header . textContent = `${ response . ProductDownloadOptions [ 0 ] . ProductDisplayName } ${ response . ProductDownloadOptions [ 0 ] . LocalizedLanguage } ` ;
145+ msContent . appendChild ( header ) ;
146+
147+ response . ProductDownloadOptions . forEach ( option => {
148+ let optionContainer = document . createElement ( 'div' ) ;
149+ let downloadButton = document . createElement ( 'a' ) ;
150+ downloadButton . href = option . Uri ;
151+ downloadButton . textContent = getFileNameFromLink ( option . Uri ) ;
152+ downloadButton . target = "_blank" ;
153+ optionContainer . appendChild ( downloadButton ) ;
154+ msContent . appendChild ( optionContainer ) ;
155+
156+ // Trigger automatic download
157+ const link = document . createElement ( 'a' ) ;
158+ link . href = option . Uri ;
159+ link . download = getFileNameFromLink ( option . Uri ) ;
160+ document . body . appendChild ( link ) ;
161+ link . click ( ) ;
162+ document . body . removeChild ( link ) ;
163+ } ) ;
164+ } else {
165+ msContent . innerHTML = "<p>No download options available.</p>" ;
166+ }
252167}
253168
254169function getWindows ( id ) {
@@ -260,23 +175,8 @@ function getWindows(id) {
260175 download = document . getElementById ( "msdl-download" ) ;
261176 downloadLink = document . getElementById ( "msdl-download-link" ) ;
262177
263- // Misc variables
264- getLangFailCount = 0 ;
265-
266- // Start new session
178+ skuId = null ;
267179 sessionId . value = uuidv4 ( ) ;
268- const xhr = new XMLHttpRequest ( ) ;
269- xhr . open ( "GET" , sessionUrl + sessionId . value , true ) ;
270- xhr . send ( ) ;
271-
272- let mxhr = new XMLHttpRequest ( ) ;
273- mxhr . onload = function ( ) {
274- if ( this . status != 200 ) shouldUseSharedSession = false ;
275- } ;
276- mxhr . open ( "GET" , apiUrl + "use_shared_session" , true ) ;
277- mxhr . send ( ) ;
278-
279- // Display the 'Please wait' text
280180 msContent . style . display = "none" ;
281181 processingError . style . display = "none" ;
282182 download . style . display = "none" ;
0 commit comments