const { default: installExtension, REACT_DEVELOPER_TOOLS } = require('electron-devtools-installer'); const { join, dirname, normalize, sep } = require('path'); const electron = require('electron'); const Module = require('module'); require('./ipc'); let reactDeveloperTools = false; let smoothScrolling = true; let settings = {}; try { settings = require(join(__dirname, '..', 'settings', 'settings.json')); ({ reactDeveloperTools, smoothScrolling } = settings); } catch (err) { // @todo Consider handling this. } if (smoothScrolling === false) { electron.app.commandLine.appendSwitch('disable-smooth-scrolling'); } let fakeAppSettings; Object.defineProperty(global, 'appSettings', { get () { return fakeAppSettings; }, set (value) { if (!value.hasOwnProperty('settings')) { value.settings = {}; } value.settings.DANGEROUS_ENABLE_DEVTOOLS_ONLY_ENABLE_IF_YOU_KNOW_WHAT_YOURE_DOING = true; fakeAppSettings = value; } }); const discordPath = join(dirname(require.main.filename), '..', 'app.asar'); const PatchedBrowserWindow = require('./browserwindow'); const electronPath = require.resolve('electron'); const electronExports = new Proxy(electron, { get (target, prop) { switch (prop) { case 'BrowserWindow': return PatchedBrowserWindow; default: return target[prop]; } } }); delete require.cache[electronPath].exports; require.cache[electronPath].exports = { ...electron, BrowserWindow: PatchedBrowserWindow }; /** * Register our protocol sceheme with elevated privileges. */ electron.protocol.registerSchemesAsPrivileged([ { scheme: 'vizality', privileges: { supportFetchAPI: true, corsEnabled: true, standard: true, secure: true } } ]); electron.app.once('ready', () => { if (reactDeveloperTools) { installExtension(REACT_DEVELOPER_TOOLS) .then(name => console.log(`Added Extension: ${name}`)) .catch(err => console.error(`An error occurred: ${err}`)); } /** * @todo Possibly add whitelists instead of just disabling CSP. */ electron.session.defaultSession.webRequest.onHeadersReceived(({ responseHeaders }, done) => { Object.keys(responseHeaders) .filter(k => (/^content-security-policy/i).test(k) || (/^x-frame-options/i).test(k)) .map(k => (delete responseHeaders[k])); done({ responseHeaders }); }); const urlRegex = /^(https:\/\/(?:canary|ptb)?.?discord(app)?\.com)\/vizality/; electron.session.defaultSession.webRequest.onBeforeRequest((details, done) => { if (urlRegex.test(details.url)) { /** * It should get restored to the Vizality URL later. */ done({ redirectURL: `${details.url.match(urlRegex)[1]}/app` }); } else { done({}); } }); /** * Now we can register the vizality:// file protocol to be able to conveniently * link to local files from within Discord. */ electron.protocol.registerFileProtocol('vizality', (request, callback) => { /** * Seems to be a security thing to limit users from accessing things they shouldn't be. * We're splitting by ? because protocol file URLs can't seem to deal with queries. * https://security.stackexchange.com/a/123723 */ const [ url ] = normalize(request.url.replace('vizality://', '')).replace(/^(\.\.(\/|\\|$))+/, '').split('?'); /** * Try to get the type of the asset. */ const type = url.split(sep)[0]; /** * Remove the type to determine the file path. */ const path = url.replace(`${type}${sep}`, ''); if (type === 'assets') { return callback({ path: join(__dirname, '..', 'assets', path) }); } else if (type === 'plugins' || type === 'themes') { return callback({ path: join(__dirname, '..', 'addons', type, path) }); } else if (type === 'builtins') { return callback({ path: join(__dirname, '..', 'renderer', 'src', 'builtins', path) }); } }); }); const discordPackage = require(join(discordPath, 'package.json')); electron.app.setAppPath(discordPath); electron.app.name = discordPackage.name; Module._load(join(discordPath, discordPackage.main), null, true);