2020-10-05 08:52:15 +00:00
|
|
|
const electron = require('electron')
|
|
|
|
const express = require('express')
|
|
|
|
const log = require('electron-log')
|
|
|
|
const fs = require('fs')
|
|
|
|
const Menu = electron.Menu
|
|
|
|
const https = require('https')
|
|
|
|
const detect = require('detect-port')
|
|
|
|
const autoUpdater = require('./auto-updater')
|
|
|
|
|
2020-10-15 15:01:12 +00:00
|
|
|
const { app, session, BrowserWindow, shell } = electron
|
2020-10-05 08:52:15 +00:00
|
|
|
|
|
|
|
const path = require('path')
|
|
|
|
const isDev = require('electron-is-dev')
|
2020-04-24 14:10:37 +00:00
|
|
|
|
|
|
|
const options = {
|
2020-10-05 08:52:15 +00:00
|
|
|
key: fs.readFileSync(path.join(__dirname, './ssl/server.key')),
|
2020-04-24 14:10:37 +00:00
|
|
|
cert: fs.readFileSync(path.join(__dirname, './ssl/server.crt')),
|
2020-10-05 08:52:15 +00:00
|
|
|
ca: fs.readFileSync(path.join(__dirname, './ssl/rootCA.crt')),
|
2020-04-24 14:10:37 +00:00
|
|
|
}
|
|
|
|
|
2020-10-05 08:52:15 +00:00
|
|
|
const DEFAULT_PORT = 5000
|
|
|
|
|
|
|
|
const createServer = async () => {
|
|
|
|
const app = express()
|
|
|
|
const staticRoute = path.join(__dirname, '../build')
|
|
|
|
app.use(express.static(staticRoute))
|
|
|
|
let selectedPort = DEFAULT_PORT
|
|
|
|
try {
|
|
|
|
const _port = await detect(DEFAULT_PORT)
|
|
|
|
if (_port !== DEFAULT_PORT) selectedPort = _port
|
|
|
|
https.createServer(options, app).listen(selectedPort)
|
|
|
|
} catch (e) {
|
|
|
|
log.error(e)
|
|
|
|
} finally {
|
|
|
|
return selectedPort
|
|
|
|
}
|
|
|
|
}
|
2020-04-24 14:10:37 +00:00
|
|
|
|
2020-10-05 08:52:15 +00:00
|
|
|
let mainWindow
|
2020-04-24 14:10:37 +00:00
|
|
|
|
2020-10-05 08:52:15 +00:00
|
|
|
function getOpenedWindow(url, options) {
|
|
|
|
let display = electron.screen.getPrimaryDisplay()
|
|
|
|
let width = display.bounds.width
|
|
|
|
let height = display.bounds.height
|
2020-04-24 14:10:37 +00:00
|
|
|
|
|
|
|
// filter all requests to trezor-bridge and change origin to make it work
|
2020-10-05 08:52:15 +00:00
|
|
|
const filter = {
|
|
|
|
urls: ['http://127.0.0.1:21325/*'],
|
|
|
|
}
|
2020-04-24 14:10:37 +00:00
|
|
|
|
2020-10-05 08:52:15 +00:00
|
|
|
options.webPreferences.affinity = 'main-window'
|
2020-04-24 14:10:37 +00:00
|
|
|
|
2020-10-05 08:52:15 +00:00
|
|
|
if (url.includes('trezor')) {
|
2020-04-24 14:10:37 +00:00
|
|
|
session.defaultSession.webRequest.onBeforeSendHeaders(filter, (details, callback) => {
|
2020-10-05 08:52:15 +00:00
|
|
|
details.requestHeaders['Origin'] = 'https://connect.trezor.io'
|
|
|
|
callback({ cancel: false, requestHeaders: details.requestHeaders })
|
|
|
|
})
|
2020-04-24 14:10:37 +00:00
|
|
|
}
|
|
|
|
|
2020-10-05 08:52:15 +00:00
|
|
|
if (url.includes('wallet.portis') || url.includes('trezor') || url.includes('app.tor.us')) {
|
2020-04-24 14:10:37 +00:00
|
|
|
const win = new BrowserWindow({
|
2020-10-05 08:52:15 +00:00
|
|
|
width: 350,
|
|
|
|
height: 700,
|
2020-04-24 14:10:37 +00:00
|
|
|
x: width - 1300,
|
2020-10-05 08:52:15 +00:00
|
|
|
parent: mainWindow,
|
2020-06-03 23:33:44 +00:00
|
|
|
y: height - (process.platform === 'win32' ? 750 : 200),
|
2020-04-24 14:10:37 +00:00
|
|
|
webContents: options.webContents, // use existing webContents if provided
|
|
|
|
fullscreen: false,
|
|
|
|
show: false,
|
2020-10-05 08:52:15 +00:00
|
|
|
})
|
|
|
|
win.webContents.on('new-window', function (event, url) {
|
2020-10-15 15:01:12 +00:00
|
|
|
if (url.includes('trezor') && url.includes('bridge')) shell.openExternal(url)
|
2020-10-05 08:52:15 +00:00
|
|
|
})
|
|
|
|
win.once('ready-to-show', () => win.show())
|
|
|
|
|
|
|
|
if (!options.webPreferences) {
|
|
|
|
win.loadURL(url)
|
2020-04-24 14:10:37 +00:00
|
|
|
}
|
|
|
|
return win
|
|
|
|
}
|
|
|
|
|
2020-10-05 08:52:15 +00:00
|
|
|
return null
|
2020-04-24 14:10:37 +00:00
|
|
|
}
|
|
|
|
|
2020-10-05 08:52:15 +00:00
|
|
|
function createWindow(port = DEFAULT_PORT) {
|
2020-04-24 14:10:37 +00:00
|
|
|
mainWindow = new BrowserWindow({
|
|
|
|
show: false,
|
|
|
|
width: 1024,
|
|
|
|
height: 768,
|
|
|
|
webPreferences: {
|
|
|
|
preload: path.join(__dirname, '../scripts/preload.js'),
|
|
|
|
allowRunningInsecureContent: true,
|
|
|
|
nativeWindowOpen: true, // need to be set in order to display modal
|
|
|
|
},
|
2020-10-05 08:52:15 +00:00
|
|
|
icon: electron.nativeImage.createFromPath(path.join(__dirname, './build/safe.png')),
|
|
|
|
})
|
2020-04-24 14:10:37 +00:00
|
|
|
|
|
|
|
mainWindow.once('ready-to-show', () => {
|
2020-10-05 08:52:15 +00:00
|
|
|
mainWindow.show()
|
|
|
|
})
|
2020-04-24 14:10:37 +00:00
|
|
|
|
2020-10-05 08:52:15 +00:00
|
|
|
mainWindow.loadURL(isDev ? 'http://localhost:3000' : `https://localhost:${port}`)
|
2020-04-24 14:10:37 +00:00
|
|
|
|
|
|
|
if (isDev) {
|
|
|
|
// Open the DevTools.
|
2020-10-05 08:52:15 +00:00
|
|
|
mainWindow.webContents.openDevTools()
|
2020-04-24 14:10:37 +00:00
|
|
|
//BrowserWindow.addDevToolsExtension('<location to your react chrome extension>');
|
|
|
|
}
|
|
|
|
|
2020-10-05 08:52:15 +00:00
|
|
|
mainWindow.setMenu(null)
|
|
|
|
mainWindow.setMenuBarVisibility(false)
|
2020-04-24 14:10:37 +00:00
|
|
|
|
2020-10-05 08:52:15 +00:00
|
|
|
mainWindow.webContents.on('new-window', function (event, url, frameName, disposition, options) {
|
|
|
|
event.preventDefault()
|
|
|
|
const win = getOpenedWindow(url, options)
|
|
|
|
if (win) {
|
|
|
|
win.once('ready-to-show', () => win.show())
|
2020-04-24 14:10:37 +00:00
|
|
|
|
2020-10-05 08:52:15 +00:00
|
|
|
if (!options.webPreferences) {
|
|
|
|
win.loadURL(url)
|
2020-04-24 14:10:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
event.newGuest = win
|
2020-10-15 15:01:12 +00:00
|
|
|
} else shell.openExternal(url)
|
2020-10-05 08:52:15 +00:00
|
|
|
})
|
2020-04-24 14:10:37 +00:00
|
|
|
|
|
|
|
mainWindow.webContents.on('did-finish-load', () => {
|
2020-10-05 08:52:15 +00:00
|
|
|
autoUpdater.init(mainWindow)
|
|
|
|
})
|
2020-04-24 14:10:37 +00:00
|
|
|
|
2020-05-04 13:33:12 +00:00
|
|
|
mainWindow.webContents.on('crashed', (event) => {
|
2020-10-05 08:52:15 +00:00
|
|
|
log.info(`App Crashed: ${event}`)
|
|
|
|
mainWindow.reload()
|
|
|
|
})
|
2020-04-24 14:10:37 +00:00
|
|
|
|
2020-10-05 08:52:15 +00:00
|
|
|
mainWindow.on('closed', () => (mainWindow = null))
|
2020-04-24 14:10:37 +00:00
|
|
|
}
|
|
|
|
|
2020-10-05 08:52:15 +00:00
|
|
|
process.on('uncaughtException', function (error) {
|
|
|
|
log.error(error)
|
|
|
|
})
|
2020-05-04 13:33:12 +00:00
|
|
|
|
2020-10-05 08:52:15 +00:00
|
|
|
app.userAgentFallback =
|
|
|
|
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) old-airport-include/1.0.0 Chrome Electron/7.1.7 Safari/537.36'
|
2020-04-24 14:10:37 +00:00
|
|
|
|
2020-09-14 19:06:10 +00:00
|
|
|
// We have one non-context-aware module in node_modules/usb. This is used by @ledgerhq/hw-transport-node-hid
|
|
|
|
// This type of modules will be impossible to use after electron 10
|
2020-10-05 08:52:15 +00:00
|
|
|
app.allowRendererProcessReuse = false
|
2020-09-14 19:06:10 +00:00
|
|
|
|
2020-10-05 08:52:15 +00:00
|
|
|
app.commandLine.appendSwitch('ignore-certificate-errors')
|
|
|
|
app.on('ready', async () => {
|
2020-04-24 14:10:37 +00:00
|
|
|
// Hide the menu
|
2020-10-05 08:52:15 +00:00
|
|
|
Menu.setApplicationMenu(null)
|
|
|
|
let usedPort = DEFAULT_PORT
|
|
|
|
if (!isDev) usedPort = await createServer()
|
|
|
|
createWindow(usedPort)
|
|
|
|
})
|
|
|
|
|
|
|
|
app.on('window-all-closed', () => {
|
|
|
|
if (process.platform !== 'darwin') {
|
|
|
|
app.quit()
|
2020-04-24 14:10:37 +00:00
|
|
|
}
|
2020-10-05 08:52:15 +00:00
|
|
|
})
|
2020-04-24 14:10:37 +00:00
|
|
|
|
2020-10-05 08:52:15 +00:00
|
|
|
app.on('activate', () => {
|
2020-04-24 14:10:37 +00:00
|
|
|
if (mainWindow === null) {
|
2020-10-05 08:52:15 +00:00
|
|
|
createWindow()
|
2020-04-24 14:10:37 +00:00
|
|
|
}
|
2020-10-05 08:52:15 +00:00
|
|
|
})
|