Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 28 additions & 8 deletions src/main/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
createLogger,
createStores,
registerBaseHandlers,
validateWgConfig,
} = require('@gatecontrol/client-core');

const { i18n } = require('@gatecontrol/client-core');
Expand Down Expand Up @@ -77,7 +78,7 @@
if (!bytes || bytes <= 0) return '0 B';
const units = ['B', 'KB', 'MB', 'GB', 'TB'];
const i = Math.floor(Math.log(bytes) / Math.log(1024));
return (bytes / Math.pow(1024, i)).toFixed(i > 0 ? 1 : 0) + ' ' + units[i];

Check warning on line 81 in src/main/main.js

View workflow job for this annotation

GitHub Actions / ESLint Security

Generic Object Injection Sink
}

// ── Tray Icon (Sun/Star design — circle + 8 rays) ───────────
Expand All @@ -96,7 +97,7 @@
const y = Math.round(py);
if (x < 0 || x >= size || y < 0 || y >= size) return;
const i = (y * size + x) * 4;
buf[i] = color[0]; buf[i + 1] = color[1]; buf[i + 2] = color[2]; buf[i + 3] = 255;

Check warning on line 100 in src/main/main.js

View workflow job for this annotation

GitHub Actions / ESLint Security

Generic Object Injection Sink
}

// Ring
Expand Down Expand Up @@ -306,15 +307,30 @@
const apiKey = store.get('server.apiKey');

if (serverUrl && apiKey) {
let fetchedConfig = null;
try {
const config = await apiClient.fetchConfig();
if (config) {
await wgService.writeConfig(WG_CONFIG_FILE, config);
log.info('Konfiguration vom Server aktualisiert');
}
fetchedConfig = await apiClient.fetchConfig();
} catch (err) {
log.warn('Config-Abruf fehlgeschlagen, nutze lokale Config:', err.message);
}
if (fetchedConfig) {
// Fail-closed: validate before overwriting the existing config.
// A bad fetch must NOT clobber a good local config; abort the connect.
const validation = validateWgConfig(fetchedConfig);
if (!validation.ok) {
const msg = 'Invalid WireGuard config: ' + validation.errors.join(', ');
log.error('Config-Update abgelehnt, behalte lokale Config: ' + msg);
updateTray('disconnected');
broadcastState('error', msg);
showNotification(t('notify.connectionError'), msg);
return;
}
if (validation.warnings && validation.warnings.length > 0) {
log.warn('Config-Warnungen: ' + validation.warnings.join(', '));
}
await wgService.writeConfig(WG_CONFIG_FILE, fetchedConfig);
log.info('Konfiguration vom Server aktualisiert');
}
}

if (store.get('tunnel.killSwitch', false)) {
Expand Down Expand Up @@ -575,8 +591,8 @@
// ── App Lifecycle ────────────────────────────────────────────
async function initServices() {
const fs = require('fs');
if (!fs.existsSync(WG_CONFIG_DIR)) {

Check warning on line 594 in src/main/main.js

View workflow job for this annotation

GitHub Actions / ESLint Security

Found existsSync from package "fs" with non literal argument at index 0
fs.mkdirSync(WG_CONFIG_DIR, { recursive: true });

Check warning on line 595 in src/main/main.js

View workflow job for this annotation

GitHub Actions / ESLint Security

Found mkdirSync from package "fs" with non literal argument at index 0
}

wgService = new WireGuardService(log, { resourcesPath: RESOURCES_PATH });
Expand Down Expand Up @@ -701,7 +717,7 @@

// Auto-Connect
if (store.get('tunnel.autoConnect', true)) {
const configExists = require('fs').existsSync(WG_CONFIG_FILE);

Check warning on line 720 in src/main/main.js

View workflow job for this annotation

GitHub Actions / ESLint Security

Found existsSync from package "fs" with non literal argument at index 0
const hasServer = store.get('server.url', '') !== '';

if (configExists || hasServer) {
Expand All @@ -720,10 +736,14 @@
try {
const newConfig = await apiClient.checkConfigUpdate();
if (newConfig) {
// Validate before applying — reject empty or malformed configs
if (!newConfig.includes('[Interface]') || !newConfig.includes('PrivateKey')) {
log.warn('Config update rejected: missing [Interface] or PrivateKey');
// Validate before applying — fail-closed via shared validator.
const validation = validateWgConfig(newConfig);
if (!validation.ok) {
log.warn('Config update rejected: ' + validation.errors.join(', '));
} else {
if (validation.warnings && validation.warnings.length > 0) {
log.warn('Config update warnings: ' + validation.warnings.join(', '));
}
log.info('Neue Konfiguration vom Server erhalten');
await wgService.writeConfig(WG_CONFIG_FILE, newConfig);
if (tunnelState.connected) {
Expand Down
Loading