Electron: Load app from custom protocol

This puts the app into its own origin so it doesn't have access
to the filesystem via file:// URIs.

Next step: migrate over localstorage & indexeddb data from the old
origin...
This commit is contained in:
David Baker 2018-12-19 12:04:40 +00:00
parent b35903bb19
commit fc4e1485ad
2 changed files with 56 additions and 2 deletions

View File

@ -24,7 +24,7 @@ const checkSquirrelHooks = require('./squirrelhooks');
if (checkSquirrelHooks()) return;
const argv = require('minimist')(process.argv);
const {app, ipcMain, powerSaveBlocker, BrowserWindow, Menu, autoUpdater} = require('electron');
const {app, ipcMain, powerSaveBlocker, BrowserWindow, Menu, autoUpdater, protocol} = require('electron');
const AutoLaunch = require('auto-launch');
const path = require('path');
@ -171,6 +171,13 @@ const launcher = new AutoLaunch({
},
});
// Register the scheme the app is served from as 'standard'
// which allows things like relative URLs and IndexedDB to
// work.
// Also mark it as secure (ie. accessing resources from this
// protocol and HTTPS won't trigger mixed content warnings).
protocol.registerStandardSchemes(['vector'], {secure: true});
app.on('ready', () => {
if (argv['devtools']) {
try {
@ -186,6 +193,45 @@ app.on('ready', () => {
}
}
protocol.registerFileProtocol('vector', (request, callback) => {
if (request.method !== 'GET') {
callback({error: -322}); // METHOD_NOT_SUPPORTED from chromium/src/net/base/net_error_list.h
return null;
}
const parsedUrl = new URL(request.url);
if (parsedUrl.protocol !== 'vector:') {
callback({error: -302}); // UNKNOWN_URL_SCHEME
return;
}
if (parsedUrl.host !== 'vector') {
callback({error: -105}); // NAME_NOT_RESOLVED
return;
}
const target = parsedUrl.pathname.split('/');
if (target[target.length - 1] == '') {
target[target.length - 1] = 'index.html';
}
// Normalise the base dir and the target path separately, then make sure
// the target path isn't trying to back out beyond its root
const appBaseDir = path.normalize(__dirname + "/../../webapp");
const relTarget = path.normalize(path.join(...target));
if (relTarget.startsWith('..')) {
callback({error: -6}); // FILE_NOT_FOUND
return;
}
const absTarget = path.join(appBaseDir, relTarget);
callback({
path: absTarget,
});
}, (error) => {
if (error) console.error('Failed to register protocol')
});
if (vectorConfig['update_base_url']) {
console.log(`Starting auto update with base URL: ${vectorConfig['update_base_url']}`);
@ -225,7 +271,7 @@ app.on('ready', () => {
webgl: false,
},
});
mainWindow.loadURL(`file://${__dirname}/../../webapp/index.html`);
mainWindow.loadURL('vector://vector/');
Menu.setApplicationMenu(vectorMenu);
// explicitly hide because setApplicationMenu on Linux otherwise shows...

View File

@ -19,3 +19,11 @@ const { ipcRenderer } = require('electron');
// expose ipcRenderer to the renderer process
window.ipcRenderer = ipcRenderer;
// Allow the fetch API to load resources from this
// protocol: this is necessary to load olm.wasm.
// (Also mark it a secure although we've already
// done this in the main process).
webFrame.registerURLSchemeAsPrivileged('vector', {
secure: true,
supportFetchAPI: true,
});