UNPKG

@codingame/monaco-vscode-extensions-service-override

Version:

VSCode public API plugged on the monaco editor - extensions service-override

124 lines (111 loc) 4.02 kB
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Security-Policy" content=" default-src 'none'; child-src 'self' data: blob:; script-src 'self' 'unsafe-eval' 'sha256-OTnWt0xD0mDGlMgzQref1DqApnE9MipgFz2t0Q/3vcE=' https:; connect-src 'self' https: wss: http://localhost:* http://127.0.0.1:* ws://localhost:* ws://127.0.0.1:*;"/> </head> <body> <script> (function() { const searchParams = new URL(document.location.href).searchParams; const vscodeWebWorkerExtHostId = searchParams.get('vscodeWebWorkerExtHostId') || ''; const name = searchParams.get('debugged') ? 'DebugWorkerExtensionHost' : 'WorkerExtensionHost'; const parentOrigin = searchParams.get('parentOrigin') || window.origin; const salt = searchParams.get('salt'); const vscodeExtHostWorkerSrc = searchParams.get('vscodeExtHostWorkerSrc'); const vscodeExtHostWorkerOptions = JSON.parse(searchParams.get('vscodeExtHostWorkerOptions') ?? '{}'); (async function() { const hostnameValidationMarker = 'v--'; const hostname = location.hostname; if (!hostname.startsWith(hostnameValidationMarker)) { // validation not requested return start(); } if (!crypto.subtle) { // cannot validate, not running in a secure context return sendError(new Error(`Cannot validate in current context!`)); } // Here the `parentOriginHash()` function from `src/vs/workbench/common/webview.ts` is inlined // compute a sha-256 composed of `parentOrigin` and `salt` converted to base 32 let parentOriginHash; try { const strData = JSON.stringify({ parentOrigin, salt }); const encoder = new TextEncoder(); const arrData = encoder.encode(strData); const hash = await crypto.subtle.digest('sha-256', arrData); const hashArray = Array.from(new Uint8Array(hash)); const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join(''); // sha256 has 256 bits, so we need at most ceil(lg(2^256-1)/lg(32)) = 52 chars to represent it in base 32 parentOriginHash = BigInt(`0x${hashHex}`).toString(32).padStart(52, '0'); } catch(err) { return sendError(err instanceof Error ? err : new Error(String(err))); } const requiredSubdomain = `${hostnameValidationMarker}${parentOriginHash}.`; if (hostname.substring(0, requiredSubdomain.length) === requiredSubdomain) { // validation succeeded! return start(); } return sendError(new Error(`Expected '${requiredSubdomain}' as subdomain!`)); })(); function sendError(error) { window.parent.postMessage({ vscodeWebWorkerExtHostId, error: { name: error ? error.name : '', message: error ? error.message : '', stack: error ? error.stack : [] } }, '*'); } function start() { try { let workerUrl = vscodeExtHostWorkerSrc if(globalThis.crossOriginIsolated) { workerUrl += '?vscode-coi=2'; // COEP } const worker = new Worker(workerUrl, Object.assign({ name }, vscodeExtHostWorkerOptions)); const nestedWorkers = new Map(); worker.onmessage = (event) => { const { data } = event; if (data?.type === '_newWorker') { const { id, port, url, options } = data; const newWorker = new Worker(url, options); newWorker.postMessage(port, [port]); worker.onerror = console.error.bind(console); nestedWorkers.set(id, newWorker); } else if (data?.type === '_terminateWorker') { const { id } = data; if(nestedWorkers.has(id)) { nestedWorkers.get(id).terminate(); nestedWorkers.delete(id); } } else { worker.onerror = console.error.bind(console); window.parent.postMessage({ vscodeWebWorkerExtHostId, data }, parentOrigin, [data]); } }; worker.onerror = (event) => { console.error(event.message, event.error); sendError(event.error); }; self.onmessage = (event) => { if (event.origin !== parentOrigin) { return; } worker.postMessage(event.data, event.ports); } } catch(err) { console.error(err); sendError(err); } } })(); </script> </body> </html>