const path = require("path"); const { app, BrowserWindow, session, dialog, shell } = require("electron"); function isUrlSafeToOpen(urlString) { const url = new URL(urlString); if (url.protocol !== "https:" && url.protocol !== "http:") { return false; } return true; } async function main() { await app.whenReady(); app.on('web-contents-created', async (event, contents) => { contents.on('will-attach-webview', (event, webPreferences, params) => { delete webPreferences.preload; webPreferences.nodeIntegration = false; webPreferences.nodeIntegrationInSubFrames = false; webPreferences.nodeIntegrationInWorker = false; webPreferences.contextIsolation = true; webPreferences.sandbox = true; console.error("[security]", `Prevented creation of WebView element with src: '${params.src}'`); event.preventDefault(); }); contents.on('will-navigate', (event, navigationUrl) => { const parsedUrl = new URL(navigationUrl); if (parsedUrl.origin !== 'https://discord.com') { console.error("[security]", `Prevented navigation to untrusted link: '${navigationUrl}'`); event.preventDefault(); } }); contents.setWindowOpenHandler(({ url }) => { new Promise((resolve, reject) => { if (isUrlSafeToOpen(url)) { const buttons = ["Cancel", "Open Link"]; const openButton = 1; dialog.showMessageBox( BrowserWindow.fromWebContents(contents), { type: "question", title: "Open Link", message: "Do you want to open this link?", detail: url, buttons: buttons, cancelId: 0, defaultId: openButton, } ).then(({ response }) => { if (response === openButton) { console.warn("[security]", `User has allowed opening of link: '${url}'`); setImmediate(() => { shell.openExternal(url); }); } else { console.error("[security]", `User has declined opening link: '${url}'`); } }); } else { console.error("[security]", `URL is not safe to open, thus dialog was not shown to user: '${url}'`); } }); return { action: "deny" }; }); }); const window = new BrowserWindow({ webPreferences: { preload: path.join(__dirname, "preload.js"), nodeIntegration: false, nodeIntegrationInWorker: false, nodeIntegrationInSubFrames: false, contextIsolation: true, enableWebSQL: false, webgl: false, backgroundThrottling: true, spellcheck: true, sandbox: true, }, width: 800, height: 600, autoHideMenuBar: true, }); session.defaultSession.webRequest.onBeforeRequest( { urls: [ "*://*/cdn-cgi/*/api.js*", // fingerprinting "*://*/api/*/science*", // analytics/tracking "*://*/api/*/track*", // analytics/tracking "*://*/api/*/experiments*", // experiments "*://*/api/*/applications/detectable", // applications "*://*/api/*/users/@me/billing/*", // don't need billing stuff "*://*/api/*/users/@me/library*", // don't need the library "*://status.discord.com/*", // don't care about status "*://*.sentry.io/*", // error tracking "*://*.braintreegateway.com/*", // braintree "*://*.braintree-api.com/*", // braintree // youtube/google "*://*.doubleclick.net/*", "*://*.jnn-pa.googleapis.com/*", "*://play.google.com/*", "*://*.youtube.com/*log_event*", "*://*.youtube.com/ptracking*", "*://*.youtube.com/generate_204*", "*://*.youtube.com/api/stats/qoe*", "*://*.youtube.com/api/stats/atr*", ] }, (details, callback) => { console.log("[request filter]", "Blocked request:", details.url); callback({ cancel: true }); } ); // for linux, xorg, with pipewire (amd gpu) // THANKS: // https://github.com/SpacingBat3/WebCord/blob/7af952b0f2ab2aa24e8d8587f12a427131348ec1/sources/code/main/modules/optimize.ts // https://github.com/GooseMod/OpenAsar/blob/main/src/cmdSwitches.js // https://www.reddit.com/r/archlinux/comments/rkutzo/comment/hpcg1h5/?context=3 app.commandLine.appendSwitch("use-gl", "desktop"); app.commandLine.appendSwitch("enable-features", "VaapiVideoDecoder,WebRTCPipeWireCapturer,MiddleClickAutoscroll"); app.commandLine.appendSwitch("disable-features", "WebUSB,WebXR"); app.commandLine.appendSwitch("ignore-gpu-blocklist"); app.commandLine.appendArgument("enable-gpu-rasterization"); app.commandLine.appendArgument("enable-zero-copy"); window.loadURL("https://discord.com/app"); } main();