fix: harden production electron app behavior
- No developer tools or zoom - No refresh window - Open links externally
This commit is contained in:
+67
-6
@@ -5,12 +5,14 @@ import { updateElectronApp, UpdateSourceType } from 'update-electron-app';
|
||||
|
||||
import type { LinkMetadata } from './lib/link-metadata';
|
||||
|
||||
updateElectronApp({
|
||||
updateSource: {
|
||||
type: UpdateSourceType.StaticStorage,
|
||||
baseUrl: `https://storage.googleapis.com/flowy-releases/llink/${process.platform}/${process.arch}`
|
||||
}
|
||||
});
|
||||
if (app.isPackaged) {
|
||||
updateElectronApp({
|
||||
updateSource: {
|
||||
type: UpdateSourceType.StaticStorage,
|
||||
baseUrl: `https://storage.googleapis.com/flowy-releases/llink/${process.platform}/${process.arch}`
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Handle creating/removing shortcuts on Windows when installing/uninstalling.
|
||||
if (started) {
|
||||
@@ -27,6 +29,61 @@ let autoplayWindow: BrowserWindow | null = null;
|
||||
let huddleWindow: BrowserWindow | null = null;
|
||||
let screenRecordWindow: BrowserWindow | null = null;
|
||||
|
||||
function hardenWindow(win: BrowserWindow) {
|
||||
const wc = win.webContents;
|
||||
|
||||
// Disable pinch / Cmd+scroll zoom; our layouts assume DPR=1.
|
||||
wc.setVisualZoomLevelLimits(1, 1);
|
||||
|
||||
// Block devtools, reload, and zoom keyboard shortcuts in packaged builds.
|
||||
wc.on('before-input-event', (event, input) => {
|
||||
if (input.type !== 'keyDown') return;
|
||||
const key = input.key.toLowerCase();
|
||||
const cmdOrCtrl = input.meta || input.control;
|
||||
|
||||
const isDevtools =
|
||||
key === 'f12' ||
|
||||
(cmdOrCtrl && input.alt && key === 'i') ||
|
||||
(cmdOrCtrl && input.shift && key === 'i') ||
|
||||
(cmdOrCtrl && input.shift && key === 'c') ||
|
||||
(cmdOrCtrl && input.shift && key === 'j');
|
||||
const isReload = cmdOrCtrl && (key === 'r' || key === 'f5');
|
||||
const isZoom = cmdOrCtrl && (key === '=' || key === '+' || key === '-' || key === '0');
|
||||
|
||||
if (app.isPackaged && (isDevtools || isReload)) {
|
||||
event.preventDefault();
|
||||
}
|
||||
if (isZoom) {
|
||||
event.preventDefault();
|
||||
}
|
||||
});
|
||||
|
||||
// Route window.open / target=_blank through the OS browser instead of a new BrowserWindow.
|
||||
wc.setWindowOpenHandler(({ url }) => {
|
||||
if (url.startsWith('http://') || url.startsWith('https://')) {
|
||||
shell.openExternal(url);
|
||||
}
|
||||
return { action: 'deny' };
|
||||
});
|
||||
|
||||
// Freeze the window to its initial origin — block any full-page navigation.
|
||||
// In-app routing uses pushState / hash which don't trigger will-navigate.
|
||||
wc.on('will-navigate', (event, url) => {
|
||||
const currentUrl = wc.getURL();
|
||||
if (!currentUrl) return;
|
||||
try {
|
||||
if (new URL(url).origin !== new URL(currentUrl).origin) {
|
||||
event.preventDefault();
|
||||
if (url.startsWith('http://') || url.startsWith('https://')) {
|
||||
shell.openExternal(url);
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
event.preventDefault();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const createWindow = () => {
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
@@ -39,6 +96,7 @@ const createWindow = () => {
|
||||
backgroundThrottling: false,
|
||||
},
|
||||
});
|
||||
hardenWindow(mainWindow);
|
||||
|
||||
if (MAIN_WINDOW_VITE_DEV_SERVER_URL) {
|
||||
mainWindow.loadURL(MAIN_WINDOW_VITE_DEV_SERVER_URL);
|
||||
@@ -72,6 +130,7 @@ const createAutoplayWindow = () => {
|
||||
},
|
||||
});
|
||||
autoplayWindow.setVisibleOnAllWorkspaces(true);
|
||||
hardenWindow(autoplayWindow);
|
||||
|
||||
if (AUTOPLAY_WINDOW_VITE_DEV_SERVER_URL) {
|
||||
autoplayWindow.loadURL(AUTOPLAY_WINDOW_VITE_DEV_SERVER_URL);
|
||||
@@ -103,6 +162,7 @@ const createHuddleWindow = () => {
|
||||
preload: path.join(__dirname, 'preload.js'),
|
||||
},
|
||||
});
|
||||
hardenWindow(huddleWindow);
|
||||
|
||||
if (HUDDLE_WINDOW_VITE_DEV_SERVER_URL) {
|
||||
huddleWindow.loadURL(HUDDLE_WINDOW_VITE_DEV_SERVER_URL);
|
||||
@@ -147,6 +207,7 @@ const createScreenRecordWindow = () => {
|
||||
},
|
||||
});
|
||||
screenRecordWindow.setVisibleOnAllWorkspaces(true);
|
||||
hardenWindow(screenRecordWindow);
|
||||
|
||||
if (SCREEN_RECORD_WINDOW_VITE_DEV_SERVER_URL) {
|
||||
screenRecordWindow.loadURL(SCREEN_RECORD_WINDOW_VITE_DEV_SERVER_URL);
|
||||
|
||||
Reference in New Issue
Block a user