discord-sandboxed/main.js
2022-02-24 18:24:19 -06:00

247 lines
6.6 KiB
JavaScript

const { app, BrowserWindow, ipcMain } = require('electron')
const {clipboard} = require('electron')
const path = require('path')
const URL = require('url').URL
'use strict';
let mainWindow
let logWindow
let devMode = false
let webViewSession = null
// Set Dev mode
if (process.argv.length === 3) {
if (process.argv[2] === 'dev'){
devMode = true
}
}
function createMainWindow () {
// Create the browser window.
mainWindow = new BrowserWindow({
width: 1230,
height: 800,
webPreferences: {
preload: path.join(__dirname, 'src/mainLoad.js'),
partition: 'persist:discord',
nodeIntegration: false, // https://electronjs.org/docs/tutorial/security#2-do-not-enable-nodejs-integration-for-remote-content
enableRemoteModule: false, // https://electronjs.org/docs/tutorial/security#15-disable-the-remote-module
webviewTag: true,
sandbox: true,
nodeIntegrationInSubFrames: false,
webSecurity: true,
allowRunningInsecureContent: false,
plugins: false,
experimentalFeatures: false
},
frame: false
})
mainWindow.loadFile('./views/index.html')
mainWindow.setTitle("Discord Sandboxed")
mainWindow.on('closed', function () {
mainWindow = null
})
}
function createLogWindow() {
logWindow = new BrowserWindow({
width: 700,
height: 400,
resizable: false,
webPreferences: {
preload: path.join(__dirname, 'src/logLoad.js'),
nodeIntegration: false, // https://electronjs.org/docs/tutorial/security#2-do-not-enable-nodejs-integration-for-remote-content
enableRemoteModule: false, // https://electronjs.org/docs/tutorial/security#15-disable-the-remote-module
webviewTag: true,
sandbox: true,
nodeIntegrationInSubFrames: false,
webSecurity: true,
allowRunningInsecureContent: false,
plugins: false,
experimentalFeatures: false
},
frame: false
})
logWindow.loadFile('./views/log.html')
logWindow.setTitle("Logs")
logWindow.on('closed', function () {
logWindow = null
})
}
function maximizeMinimizeState(windowName){
if (windowName.isMaximized()) {
windowName.unmaximize()
} else {
windowName.maximize()
}
}
function listenForKeySignal() {
console.log('listening for key signals...');
// Listen for process signal
// SIGUSR2 - Toggle muted
process.on('SIGUSR2', () => {
mainWindow.webContents.send('micToggle', 'mic-toggled');
});
}
app.on('ready', createMainWindow)
// Quit when all windows are closed.
app.on('window-all-closed', function () {
if (process.platform !== 'darwin') app.quit()
})
app.on('activate', function () {
if (mainWindow === null) createMainWindow()
})
// Force single instance
let isSingleInstance = app.requestSingleInstanceLock()
if (!isSingleInstance) {
app.quit()
}
// Force focus on single instance
app.on('second-instance', (event, argv, cwd) => {
if (mainWindow) {
if (mainWindow.isMinimized()) mainWindow.restore()
mainWindow.focus()
}
if (logWindow) {
if (logWindow.isMinimized()) mainWindow.restore()
logWindow.focus()
}
})
/* Security Stuff */
app.on('web-contents-created', (event, contents) => { // https://electronjs.org/docs/tutorial/security#11-verify-webview-options-before-creation
contents.on('will-attach-webview', (event, webPreferences, params) => {
// Strip away preload scripts if unused or verify their location is legitimate
delete webPreferences.preload
delete webPreferences.preloadURL
// Disable Node.js integration
webPreferences.nodeIntegration = false
console.log(`web-contents-created: ${params.src}`)
// Verify discord.com is being loaded
if (!params.src.startsWith('https://discord.com/')) {
event.preventDefault()
}
})
})
app.on('web-contents-created', (event, contents) => { // https://electronjs.org/docs/tutorial/security#12-disable-or-limit-navigation
contents.on('will-navigate', (event, navigationUrl) => { // https://electronjs.org/docs/tutorial/security#13-disable-or-limit-creation-of-new-windows
const parsedUrl = new URL(navigationUrl)
console.log(`will-navigate ${navigationUrl}`)
if (parsedUrl.origin !== 'https://discord.com/') { // Limit navigation to discordapp.com; not really relevant
event.preventDefault()
}
})
contents.on('new-window', async (event, navigationUrl) => {
clipboard.writeText(navigationUrl, 'selection') // I really hope this is safe to do. Could also do a little URL cleaning here to remove trackers
console.log(`URL ${navigationUrl.toString().slice(0, 20)} Copied to Clipboard`)
mainWindow.webContents.send('URLCopied', null)
//event.preventDefault() // Prevents external links from opening
})
})
/* ---- */
app.on ('browser-window-blur', function (event, browserWindow) {
browserWindow.webContents.send('unfocused', null)
})
app.on ('browser-window-focus', function (event, browserWindow) {
browserWindow.webContents.send('focused', null)
})
app.on('ready', () => {
// Handle permission requests
webViewSession = mainWindow.webContents.session
webViewSession.setPermissionRequestHandler((webContents, permission, callback) => { // deny all permissions
const url = webContents.getURL()
if (url.startsWith('https://discord.com/')) {
if (permission === 'media') { // if user is connected to Discord voice then enable microphone
console.log("Granted permission for 'media'");
return callback(true)
}
}
console.log("Denied permission: ", permission)
return callback(false)
})
})
ipcMain.on('asynchronous-message', (event, _data) => {
let msg = _data.msg
if (msg === 'DOMready') {
console.log("Discord webview loaded")
mainWindow.webContents.send('devMode', devMode)
}
if (msg === 'blockUpdate') {
if (logWindow){
logWindow.webContents.send('blockUpdate', _data.data)
}
}
if (msg === 'minimizeApplication') {
if (_data.data.wName === 0) {
mainWindow.minimize()
}
if (_data.data.wName === 1) {
logWindow.minimize()
}
}
if (msg === 'maximizeApplication') {
if (_data.data.wName === 0) {
maximizeMinimizeState(mainWindow)
}
if (_data.data.wName === 1) {
maximizeMinimizeState(logWindow)
}
}
if (msg === 'closeApplication') {
if (_data.data.wName === 0) {
app.quit()
}
if (_data.data.wName === 1) {
logWindow.close()
}
}
if (msg === 'openLog') {
if (logWindow) {
if (logWindow.isMinimized()) logWindow.restore()
logWindow.focus()
}else {
createLogWindow()
logWindow.center()
}
}
})
app.on('ready', event => {
console.log(`Dev Mode: ${devMode}`)
listenForKeySignal();
})