Wrap Discord’s preload script instead of enabling Node integration

This commit is contained in:
Samuel Elliott 2018-05-28 01:42:59 +01:00
parent a5c7aaab3b
commit bba1165c77
No known key found for this signature in database
GPG Key ID: 8420C7CDE43DC4D6
14 changed files with 62 additions and 27 deletions

View File

@ -39,7 +39,13 @@ class BetterDiscord {
plugins: PluginManager.localContent,
themes: ThemeManager.localContent,
extmodules: ExtModuleManager.localContent
extmodules: ExtModuleManager.localContent,
__filename, __dirname,
module: Globals.require.cache[__filename],
require: Globals.require,
webpack_require: __webpack_require__,
get discord_require() { return WebpackModules.require }
};
const developermode = Settings.getSetting('core', 'advanced', 'developer-mode');

View File

@ -269,7 +269,7 @@ export default class {
const index = this.getContentIndex(content);
delete window.require.cache[window.require.resolve(content.paths.mainPath)];
delete Globals.require.cache[Globals.require.resolve(content.paths.mainPath)];
if (reload) {
const newcontent = await this.preloadContent(content.dirName, true, index);

View File

@ -8,13 +8,14 @@
* LICENSE file in the root directory of this source tree.
*/
import Globals from './globals';
import Content from './content';
export default class ExtModule extends Content {
constructor(internals) {
super(internals);
this.__require = window.require(this.paths.mainPath);
this.__require = Globals.require(this.paths.mainPath);
}
get type() { return 'module' }

View File

@ -17,6 +17,8 @@ export default new class extends Module {
constructor(args) {
super(args);
this.require = __non_webpack_require__;
}
initg() {

View File

@ -12,6 +12,7 @@ import { Events, Permissions } from 'modules';
import { Modals } from 'ui';
import { ErrorEvent } from 'structs';
import { ClientLogger as Logger } from 'common';
import Globals from './globals';
import ContentManager from './contentmanager';
import ExtModuleManager from './extmodulemanager';
import Plugin from './plugin';
@ -96,7 +97,7 @@ export default class extends ContentManager {
}
}
const plugin = window.require(paths.mainPath)(Plugin, new PluginApi(info, paths.contentPath), Vendor, deps);
const plugin = Globals.require(paths.mainPath)(Plugin, new PluginApi(info, paths.contentPath), Vendor, deps);
if (!(plugin.prototype instanceof Plugin))
throw {message: `Plugin ${info.name} did not return a class that extends Plugin.`};

View File

@ -8,10 +8,11 @@
* LICENSE file in the root directory of this source tree.
*/
import { Globals } from 'modules';
import path from 'path';
import Setting from './basesetting';
import SettingsCategory from '../settingscategory';
import SettingsScheme from '../settingsscheme';
import path from 'path';
export default class CustomSetting extends Setting {
@ -68,7 +69,7 @@ export default class CustomSetting extends Setting {
* @param {String} classExport The name of a property of the file's exports that will be used (optional)
*/
setClass(class_file, class_export) {
const component = window.require(path.join(this.path, class_file));
const component = Globals.require(path.join(this.path, class_file));
const setting_class = class_export ? component[class_export](CustomSetting) : component.default ? component.default(CustomSetting) : component(CustomSetting);
if (!(setting_class.prototype instanceof CustomSetting))

View File

@ -23,6 +23,7 @@
// Imports
import { Events, Settings } from 'modules';
import { Modals } from 'ui';
import process from 'process';
import BdSettings from './BdSettings.vue';
export default {
@ -33,7 +34,7 @@
active: false,
animating: false,
timeout: null,
platform: global.process.platform
platform: process.platform
};
},
components: {

View File

@ -28,11 +28,10 @@
<script>
// Imports
import process from 'process';
import { Modal } from '../../common';
import { MiError } from '../../common/MaterialIcon';
const process = window.require('process');
export default {
props: ['modal'],
components: {

View File

@ -27,7 +27,7 @@
</template>
<script>
import { PluginManager } from 'modules';
import { Globals, PluginManager } from 'modules';
import SettingsPanel from '../SettingsPanel.vue';
import Drawer from '../../common/Drawer.vue';
import Button from '../../common/Button.vue';
@ -42,7 +42,7 @@
computed: {
component() {
if (typeof this.setting.file === 'string') {
const component = window.require(path.join(this.setting.path, this.setting.file));
const component = Globals.require(path.join(this.setting.path, this.setting.file));
return this.setting.component ? component[this.setting.component] : component.default ? component.default : component;
}

View File

@ -31,10 +31,11 @@ module.exports = {
loaders: [jsLoader, vueLoader, scssLoader]
},
externals: {
electron: 'window.require("electron")',
fs: 'window.require("fs")',
path: 'window.require("path")',
util: 'window.require("util")',
electron: 'require("electron")',
fs: 'require("fs")',
path: 'require("path")',
util: 'require("util")',
process: 'require("process")',
sparkplug: 'require("../../core/dist/sparkplug")'
},
resolve: {

View File

@ -32,10 +32,11 @@ module.exports = {
loaders: [jsLoader, vueLoader, scssLoader]
},
externals: {
electron: 'window.require("electron")',
fs: 'window.require("fs")',
path: 'window.require("path")',
util: 'window.require("util")',
electron: 'require("electron")',
fs: 'require("fs")',
path: 'require("path")',
util: 'require("util")',
process: 'require("process")',
sparkplug: 'require("./sparkplug")'
},
resolve: {

View File

@ -58,9 +58,12 @@ class PatchedBrowserWindow extends BrowserWindow {
options.webPreferences = Object.assign({}, options.webPreferences);
// Make sure Node integration is enabled
options.webPreferences.nodeIntegration = true;
const originalPreloadScript = options.webPreferences.preload;
options.webPreferences.preload = sparkplug;
return new BrowserWindow(options);
super(options);
this.__bd_preload = [originalPreloadScript];
}
}
@ -147,7 +150,6 @@ class BetterDiscord {
this.csseditor = new CSSEditor(this, this.config.getPath('csseditor'));
this.windowUtils.on('did-get-response-details', () => this.ignite());
this.windowUtils.on('did-finish-load', () => this.injectScripts(true));
this.windowUtils.on('did-navigate-in-page', (event, url, isMainFrame) => {
@ -165,10 +167,6 @@ class BetterDiscord {
const defer = setInterval(() => {
const windows = BrowserWindow.getAllWindows();
for (let window of windows) {
if (window) BetterDiscord.ignite(window);
}
if (windows.length === 1 && windows[0].webContents.getURL().includes('discordapp.com')) {
resolve(windows[0]);
clearInterval(defer);

View File

@ -185,7 +185,7 @@ class WindowUtils extends Module {
return WindowUtils.injectScript(this.window, fpath, variable);
}
static injectScript(window, fpath, variable) {
static async injectScript(window, fpath, variable) {
window = window.webContents || window;
if (!window) return;
// console.log(`Injecting: ${fpath} to`, window);
@ -193,6 +193,10 @@ class WindowUtils extends Module {
const escaped_path = fpath.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
const escaped_variable = variable ? variable.replace(/\\/g, '\\\\').replace(/"/g, '\\"') : null;
const nodeIntegration = await window.executeJavaScript(`typeof require !== 'undefined'`);
if (!nodeIntegration) return window.send('--bd-inject-script', {script: fpath, variable});
if (variable) return window.executeJavaScript(`window["${escaped_variable}"] = require("${escaped_path}");`);
else return window.executeJavaScript(`require("${escaped_path}");`);
}

View File

@ -10,11 +10,31 @@
* This file is evaluated in the renderer process!
*/
import electron, { ipcRenderer } from 'electron';
(() => {
if (module.exports.bd) return;
console.log('[BetterDiscord|Sparkplug]');
const currentWindow = electron.remote.getCurrentWindow();
if (currentWindow.__bd_preload) {
for (let preloadScript of currentWindow.__bd_preload) {
try {
require(preloadScript);
} catch (err) {
console.error('[BetterDiscord|Sparkplug] Error thrown in preload script', preloadScript, err);
}
}
}
ipcRenderer.on('--bd-inject-script', (event, {script, variable}) => {
console.log('[BetterDiscord|Sparkplug] Injecting script', script, variable);
if (variable) window[variable] = require(script);
else require(script);
});
const ls = window.localStorage;
if (!ls) console.warn('[BetterDiscord|Sparkplug] Failed to hook localStorage :(');
const wsOrig = window.WebSocket;