Add --vanilla flag, strip csp on mainFrame only
This commit is contained in:
		
							parent
							
								
									daf3a1dcac
								
							
						
					
					
						commit
						b9e9d9bd64
					
				
					 1 changed files with 84 additions and 80 deletions
				
			
		
							
								
								
									
										164
									
								
								src/patcher.ts
									
										
									
									
									
								
							
							
						
						
									
										164
									
								
								src/patcher.ts
									
										
									
									
									
								
							|  | @ -42,98 +42,102 @@ require.main!.filename = join(asarPath, discordPkg.main); | |||
| // @ts-ignore Untyped method? Dies from cringe
 | ||||
| app.setAppPath(asarPath); | ||||
| 
 | ||||
| // Repatch after host updates on Windows
 | ||||
| if (process.platform === "win32") | ||||
|     require("./patchWin32Updater"); | ||||
| if (!process.argv.includes("--vanilla")) { | ||||
|     // Repatch after host updates on Windows
 | ||||
|     if (process.platform === "win32") | ||||
|         require("./patchWin32Updater"); | ||||
| 
 | ||||
| class BrowserWindow extends electron.BrowserWindow { | ||||
|     constructor(options: BrowserWindowConstructorOptions) { | ||||
|         if (options?.webPreferences?.preload && options.title) { | ||||
|             const original = options.webPreferences.preload; | ||||
|             options.webPreferences.preload = join(__dirname, "preload.js"); | ||||
|             options.webPreferences.sandbox = false; | ||||
|     class BrowserWindow extends electron.BrowserWindow { | ||||
|         constructor(options: BrowserWindowConstructorOptions) { | ||||
|             if (options?.webPreferences?.preload && options.title) { | ||||
|                 const original = options.webPreferences.preload; | ||||
|                 options.webPreferences.preload = join(__dirname, "preload.js"); | ||||
|                 options.webPreferences.sandbox = false; | ||||
| 
 | ||||
|             process.env.DISCORD_PRELOAD = original; | ||||
|                 process.env.DISCORD_PRELOAD = original; | ||||
| 
 | ||||
|             super(options); | ||||
|             initIpc(this); | ||||
|         } else super(options); | ||||
|     } | ||||
| } | ||||
| Object.assign(BrowserWindow, electron.BrowserWindow); | ||||
| // esbuild may rename our BrowserWindow, which leads to it being excluded
 | ||||
| // from getFocusedWindow(), so this is necessary
 | ||||
| // https://github.com/discord/electron/blob/13-x-y/lib/browser/api/browser-window.ts#L60-L62
 | ||||
| Object.defineProperty(BrowserWindow, "name", { value: "BrowserWindow", configurable: true }); | ||||
| 
 | ||||
| // Replace electrons exports with our custom BrowserWindow
 | ||||
| const electronPath = require.resolve("electron"); | ||||
| delete require.cache[electronPath]!.exports; | ||||
| require.cache[electronPath]!.exports = { | ||||
|     ...electron, | ||||
|     BrowserWindow | ||||
| }; | ||||
| 
 | ||||
| // Patch appSettings to force enable devtools
 | ||||
| onceDefined(global, "appSettings", s => | ||||
|     s.set("DANGEROUS_ENABLE_DEVTOOLS_ONLY_ENABLE_IF_YOU_KNOW_WHAT_YOURE_DOING", true) | ||||
| ); | ||||
| 
 | ||||
| process.env.DATA_DIR = join(app.getPath("userData"), "..", "Vencord"); | ||||
| 
 | ||||
| electron.app.whenReady().then(() => { | ||||
|     // Source Maps! Maybe there's a better way but since the renderer is executed
 | ||||
|     // from a string I don't think any other form of sourcemaps would work
 | ||||
|     electron.protocol.registerFileProtocol("vencord", ({ url: unsafeUrl }, cb) => { | ||||
|         let url = unsafeUrl.slice("vencord://".length); | ||||
|         if (url.endsWith("/")) url = url.slice(0, -1); | ||||
|         switch (url) { | ||||
|             case "renderer.js.map": | ||||
|             case "preload.js.map": | ||||
|             case "patcher.js.map": // doubt
 | ||||
|                 cb(join(__dirname, url)); | ||||
|                 break; | ||||
|             default: | ||||
|                 cb({ statusCode: 403 }); | ||||
|                 super(options); | ||||
|                 initIpc(this); | ||||
|             } else super(options); | ||||
|         } | ||||
|     }); | ||||
|     } | ||||
|     Object.assign(BrowserWindow, electron.BrowserWindow); | ||||
|     // esbuild may rename our BrowserWindow, which leads to it being excluded
 | ||||
|     // from getFocusedWindow(), so this is necessary
 | ||||
|     // https://github.com/discord/electron/blob/13-x-y/lib/browser/api/browser-window.ts#L60-L62
 | ||||
|     Object.defineProperty(BrowserWindow, "name", { value: "BrowserWindow", configurable: true }); | ||||
| 
 | ||||
|     try { | ||||
|         const settings = JSON.parse(readSettings()); | ||||
|         if (settings.enableReactDevtools) | ||||
|             installExt("fmkadmapgofadopljbjfkapdkoienihi") | ||||
|                 .then(() => console.info("[Vencord] Installed React Developer Tools")) | ||||
|                 .catch(err => console.error("[Vencord] Failed to install React Developer Tools", err)); | ||||
|     } catch { } | ||||
|     // Replace electrons exports with our custom BrowserWindow
 | ||||
|     const electronPath = require.resolve("electron"); | ||||
|     delete require.cache[electronPath]!.exports; | ||||
|     require.cache[electronPath]!.exports = { | ||||
|         ...electron, | ||||
|         BrowserWindow | ||||
|     }; | ||||
| 
 | ||||
|     // Patch appSettings to force enable devtools
 | ||||
|     onceDefined(global, "appSettings", s => | ||||
|         s.set("DANGEROUS_ENABLE_DEVTOOLS_ONLY_ENABLE_IF_YOU_KNOW_WHAT_YOURE_DOING", true) | ||||
|     ); | ||||
| 
 | ||||
|     // Remove CSP
 | ||||
|     function patchCsp(headers: Record<string, string[]>, header: string) { | ||||
|         if (header in headers) { | ||||
|             let patchedHeader = headers[header][0]; | ||||
|             for (const directive of ["style-src", "connect-src", "img-src", "font-src", "media-src"]) { | ||||
|                 patchedHeader = patchedHeader.replace(new RegExp(`${directive}.+?;`), `${directive} * blob: data: 'unsafe-inline';`); | ||||
|     process.env.DATA_DIR = join(app.getPath("userData"), "..", "Vencord"); | ||||
| 
 | ||||
|     electron.app.whenReady().then(() => { | ||||
|         // Source Maps! Maybe there's a better way but since the renderer is executed
 | ||||
|         // from a string I don't think any other form of sourcemaps would work
 | ||||
|         electron.protocol.registerFileProtocol("vencord", ({ url: unsafeUrl }, cb) => { | ||||
|             let url = unsafeUrl.slice("vencord://".length); | ||||
|             if (url.endsWith("/")) url = url.slice(0, -1); | ||||
|             switch (url) { | ||||
|                 case "renderer.js.map": | ||||
|                 case "preload.js.map": | ||||
|                 case "patcher.js.map": // doubt
 | ||||
|                     cb(join(__dirname, url)); | ||||
|                     break; | ||||
|                 default: | ||||
|                     cb({ statusCode: 403 }); | ||||
|             } | ||||
|             // TODO: Restrict this to only imported packages with fixed version.
 | ||||
|             // Perhaps auto generate with esbuild
 | ||||
|             patchedHeader = patchedHeader.replace(/script-src.+?(?=;)/, "$& 'unsafe-eval' https://unpkg.com https://cdnjs.cloudflare.com"); | ||||
|             headers[header] = [patchedHeader]; | ||||
|         } | ||||
|     } | ||||
|         }); | ||||
| 
 | ||||
|     electron.session.defaultSession.webRequest.onHeadersReceived(({ responseHeaders, url }, cb) => { | ||||
|         if (responseHeaders) { | ||||
|             patchCsp(responseHeaders, "content-security-policy"); | ||||
|             patchCsp(responseHeaders, "content-security-policy-report-only"); | ||||
|         try { | ||||
|             const settings = JSON.parse(readSettings()); | ||||
|             if (settings.enableReactDevtools) | ||||
|                 installExt("fmkadmapgofadopljbjfkapdkoienihi") | ||||
|                     .then(() => console.info("[Vencord] Installed React Developer Tools")) | ||||
|                     .catch(err => console.error("[Vencord] Failed to install React Developer Tools", err)); | ||||
|         } catch { } | ||||
| 
 | ||||
|             // Fix hosts that don't properly set the content type, such as
 | ||||
|             // raw.githubusercontent.com
 | ||||
|             if (url.endsWith(".css")) | ||||
|                 responseHeaders["content-type"] = ["text/css"]; | ||||
| 
 | ||||
|         // Remove CSP
 | ||||
|         function patchCsp(headers: Record<string, string[]>, header: string) { | ||||
|             if (header in headers) { | ||||
|                 let patchedHeader = headers[header][0]; | ||||
|                 for (const directive of ["style-src", "connect-src", "img-src", "font-src", "media-src"]) { | ||||
|                     patchedHeader = patchedHeader.replace(new RegExp(`${directive}.+?;`), `${directive} * blob: data: 'unsafe-inline';`); | ||||
|                 } | ||||
|                 // TODO: Restrict this to only imported packages with fixed version.
 | ||||
|                 // Perhaps auto generate with esbuild
 | ||||
|                 patchedHeader = patchedHeader.replace(/script-src.+?(?=;)/, "$& 'unsafe-eval' https://unpkg.com https://cdnjs.cloudflare.com"); | ||||
|                 headers[header] = [patchedHeader]; | ||||
|             } | ||||
|         } | ||||
|         cb({ cancel: false, responseHeaders }); | ||||
| 
 | ||||
|         electron.session.defaultSession.webRequest.onHeadersReceived(({ responseHeaders, resourceType }, cb) => { | ||||
|             if (responseHeaders) { | ||||
|                 if (resourceType === "mainFrame") | ||||
|                     patchCsp(responseHeaders, "content-security-policy"); | ||||
| 
 | ||||
|                 // Fix hosts that don't properly set the css content type, such as
 | ||||
|                 // raw.githubusercontent.com
 | ||||
|                 if (resourceType === "stylesheet") | ||||
|                     responseHeaders["content-type"] = ["text/css"]; | ||||
|             } | ||||
|             cb({ cancel: false, responseHeaders }); | ||||
|         }); | ||||
|     }); | ||||
| }); | ||||
| } else { | ||||
|     console.log("[Vencord] Running in vanilla mode. Not loading Vencord"); | ||||
| } | ||||
| 
 | ||||
| console.log("[Vencord] Loading original Discord app.asar"); | ||||
| // Legacy Vencord Injector requires "../app.asar". However, because we
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue