Skip to content

Commit

Permalink
Merge pull request #7 from dragonrealms-phoenix/develop
Browse files Browse the repository at this point in the history
Increase Security, Refactor Menu, Refactor Build Script
  • Loading branch information
KatoakDR authored Oct 9, 2023
2 parents a0ab270 + 4d03894 commit e7c6b15
Show file tree
Hide file tree
Showing 16 changed files with 459 additions and 771 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,11 @@ jobs:
run: |
echo "SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }}" >> .env
echo "MAIN_VITE_SENTRY_DSN=${{ secrets.MAIN_VITE_SENTRY_DSN }}" >> .env
echo "MAIN_VITE_SENTRY_CRASH_REPORT_DSN=${{ secrets.MAIN_VITE_SENTRY_CRASH_REPORT_DSN }}" >> .env
echo "MAIN_VITE_SENTRY_DSN=${{ secrets.SENTRY_DSN }}" >> .env
echo "MAIN_VITE_SENTRY_CRASH_REPORT_DSN=${{ secrets.SENTRY_CRASH_REPORT_DSN }}" >> .env
echo "RENDERER_VITE_SENTRY_DSN=${{ secrets.RENDERER_VITE_SENTRY_DSN }}" >> .env
echo "RENDERER_VITE_SENTRY_CRASH_REPORT_DSN=${{ secrets.RENDERER_VITE_SENTRY_CRASH_REPORT_DSN }}" >> .env
echo "RENDERER_VITE_SENTRY_DSN=${{ secrets.SENTRY_DSN }}" >> .env
echo "RENDERER_VITE_SENTRY_CRASH_REPORT_DSN=${{ secrets.SENTRY_CRASH_REPORT_DSN }}" >> .env
- name: Install dependencies
run: yarn install
Expand Down
2 changes: 2 additions & 0 deletions electron.vite.config.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'dotenv/config';
import { execSync } from 'child_process';
import { sentryVitePlugin } from '@sentry/vite-plugin';
import react from '@vitejs/plugin-react';
Expand All @@ -13,6 +14,7 @@ const sentryPlugin = sentryVitePlugin({
org: 'dragonrealms-phoenix',
project: 'phoenix',
telemetry: false,
authToken: process.env.SENTRY_AUTH_TOKEN,
disable: process.env.VITE_PLUGIN_SENTRY_ENABLE !== 'true',
}) as PluginOption;

Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
"lint:fix": "yarn lint --fix",
"lint:staged": "lint-staged --concurrent 1",
"format": "yarn prettier:fix && yarn lint:fix",
"typecheck:preload": "tsc --declaration --emitDeclarationOnly --outDir ./src/preload/ ./src/preload/api.ts && yarn prettier:fix ./src/preload/api.d.ts",
"typecheck:preload": "tsc --declaration --emitDeclarationOnly --outDir ./src/preload/ ./src/preload/index.ts && yarn prettier:fix ./src/preload/index.d.ts",
"typecheck:node": "tsc --noEmit -p tsconfig.node.json --composite false",
"typecheck:web": "tsc --noEmit -p tsconfig.web.json --composite false",
"typecheck": "yarn typecheck:preload && yarn typecheck:node && yarn typecheck:web",
Expand Down Expand Up @@ -115,6 +115,7 @@
"@typescript-eslint/parser": "^6.7.3",
"@vitejs/plugin-react": "^4.1.0",
"cross-env": "^7.0.3",
"dotenv": "^16.3.1",
"electron": "^26.2.4",
"electron-builder": "^24.6.4",
"electron-vite": "^1.0.28",
Expand Down
84 changes: 64 additions & 20 deletions src/main/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { BrowserWindow, app, ipcMain, shell } from 'electron';
import { BrowserWindow, Event, app, ipcMain, shell } from 'electron';
import { join } from 'path';
import { is, optimizer, platform } from '@electron-toolkit/utils';
import { createLogger } from './logger';
import { MenuBuilder } from './menu';
import { initializeMenu } from './menu';
import { initializeSentry } from './sentry';

initializeSentry();
Expand All @@ -11,39 +11,40 @@ const logger = createLogger('main');

app.setName('Phoenix');
app.setAppUserModelId('com.github.dragonrealms-phoenix.phoenix');
app.setAboutPanelOptions({
applicationName: app.name,
applicationVersion: app.getVersion(),
version: `${app.getVersion()}-${import.meta.env.MAIN_VITE_GIT_SHORT_HASH}`,
authors: ['Katoak'],
website: 'https://github.com/dragonrealms-phoenix/phoenix',
});

function createWindow(): void {
logger.info('creating main window');

const mainWindow = new BrowserWindow({
width: 900,
height: 670,
show: false,
show: false, // to avoid a blank window until contents loaded
autoHideMenuBar: true,
webPreferences: {
preload: join(__dirname, '../preload/index.js'),
sandbox: false,
nodeIntegration: false,
/**
* Security Best Practices
* https://www.electronjs.org/docs/latest/tutorial/security
* https://github.com/moloch--/reasonably-secure-electron
*/
allowRunningInsecureContent: false,
contextIsolation: true,
experimentalFeatures: false,
navigateOnDragDrop: false,
nodeIntegration: false,
nodeIntegrationInSubFrames: false,
nodeIntegrationInWorker: false,
safeDialogs: true,
sandbox: true,
webSecurity: true,
webviewTag: false,
},
});

mainWindow.on('ready-to-show', (): void => {
mainWindow.show();
});

mainWindow.webContents.setWindowOpenHandler((details) => {
shell.openExternal(details.url);
return { action: 'deny' };
});

// HMR for renderer base on electron-vite cli.
// Load the remote URL for development or the local html file for production.
if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
Expand All @@ -52,14 +53,14 @@ function createWindow(): void {
mainWindow.loadFile(join(__dirname, '../renderer/index.html'));
}

new MenuBuilder(mainWindow).buildMenu();
initializeMenu(mainWindow);
}

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then((): void => {
createWindow();
app.once('ready', () => {
app.setAsDefaultProtocolClient('app');

// Default open or close DevTools by F12 in development
// and ignore CommandOrControl + R in production.
Expand All @@ -76,11 +77,54 @@ app.whenReady().then((): void => {
}
});

// Disable or limit creation of new windows to protect app and users.
// https://www.electronjs.org/docs/latest/tutorial/security
app.on('web-contents-created', (_, contents) => {
const allowedDomains = [
/^(www.)?github\.com$/i,
/^(www.)?play\.net$/i,
/^elanthipedia\.play\.net$/i,
];

const isAllowedDomain = (domain: string): boolean => {
return allowedDomains.some((d) => d.test(domain));
};

const blockOrOpenURL = (
event: Event<Electron.WebContentsWillNavigateEventParams>,
url: string
): void => {
const domain = new URL(url).hostname;
// If the domain is allowed, open it in the user's default browser.
if (isAllowedDomain(domain)) {
logger.info('opening url in default browser', { url });
setImmediate(() => {
shell.openExternal(url);
});
} else {
logger.warn('blocked window navigation', { url });
}
event.preventDefault();
};

contents.on('will-navigate', (event, url) => {
logger.info('will-navigate', { url });
blockOrOpenURL(event, url);
});

contents.on('will-redirect', (event, url) => {
logger.info('will-redirect', { url });
blockOrOpenURL(event, url);
});
});

// Listen for events emitted by the preload api
ipcMain.handle('ping', async (): Promise<string> => {
// Return response to renderer
return 'pong';
});

createWindow();
});

// Quit when all windows are closed, except on macOS.
Expand Down
Loading

0 comments on commit e7c6b15

Please sign in to comment.