You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
vizality/injector/index.js

132 lines
4.0 KiB

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');
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');
}
require('./ipc');
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 = electronExports;
/**
* 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, '..', 'src', 'core', '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);