Fix window not showing for some users (#2967)
Co-authored-by: Max Novich <mnovich@squareup.com>
This commit is contained in:
@@ -2,6 +2,7 @@ import { spawn, ChildProcess } from 'child_process';
|
||||
import { createServer } from 'net';
|
||||
import os from 'node:os';
|
||||
import path from 'node:path';
|
||||
import fs from 'node:fs';
|
||||
import { getBinaryPath } from './utils/binaryPath';
|
||||
import log from './utils/logger';
|
||||
import { App } from 'electron';
|
||||
@@ -78,6 +79,23 @@ export const startGoosed = async (
|
||||
// Sanitize and validate the directory path
|
||||
dir = path.resolve(path.normalize(dir));
|
||||
|
||||
// Validate that the directory actually exists and is a directory
|
||||
try {
|
||||
const stats = fs.lstatSync(dir);
|
||||
|
||||
// Reject symlinks for security - they could point outside intended directories
|
||||
if (stats.isSymbolicLink()) {
|
||||
log.warn(`Provided path is a symlink, falling back to home directory for security`);
|
||||
dir = homeDir;
|
||||
} else if (!stats.isDirectory()) {
|
||||
log.warn(`Provided path is not a directory, falling back to home directory`);
|
||||
dir = homeDir;
|
||||
}
|
||||
} catch (error) {
|
||||
log.warn(`Directory does not exist, falling back to home directory`);
|
||||
dir = homeDir;
|
||||
}
|
||||
|
||||
// Security check: Ensure the directory path doesn't contain suspicious characters
|
||||
if (dir.includes('..') || dir.includes(';') || dir.includes('|') || dir.includes('&')) {
|
||||
throw new Error(`Invalid directory path: ${dir}`);
|
||||
|
||||
+35
-6
@@ -15,6 +15,7 @@ import {
|
||||
import type { OpenDialogReturnValue } from 'electron';
|
||||
import { Buffer } from 'node:buffer';
|
||||
import fs from 'node:fs/promises';
|
||||
import fsSync from 'node:fs';
|
||||
import started from 'electron-squirrel-startup';
|
||||
import path from 'node:path';
|
||||
import { spawn } from 'child_process';
|
||||
@@ -681,9 +682,28 @@ const openDirectoryDialog = async (
|
||||
})) as unknown as OpenDialogReturnValue;
|
||||
|
||||
if (!result.canceled && result.filePaths.length > 0) {
|
||||
addRecentDir(result.filePaths[0]);
|
||||
const selectedPath = result.filePaths[0];
|
||||
|
||||
// If a file was selected, use its parent directory
|
||||
let dirToAdd = selectedPath;
|
||||
try {
|
||||
const stats = fsSync.lstatSync(selectedPath);
|
||||
|
||||
// Reject symlinks for security
|
||||
if (stats.isSymbolicLink()) {
|
||||
console.warn(`Selected path is a symlink, using parent directory for security`);
|
||||
dirToAdd = path.dirname(selectedPath);
|
||||
} else if (stats.isFile()) {
|
||||
dirToAdd = path.dirname(selectedPath);
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn(`Could not stat selected path, using parent directory`);
|
||||
dirToAdd = path.dirname(selectedPath); // Fallback to parent directory
|
||||
}
|
||||
|
||||
addRecentDir(dirToAdd);
|
||||
const currentWindow = BrowserWindow.getFocusedWindow();
|
||||
await createChat(app, undefined, result.filePaths[0]);
|
||||
await createChat(app, undefined, dirToAdd);
|
||||
if (replaceWindow && currentWindow) {
|
||||
currentWindow.close();
|
||||
}
|
||||
@@ -1220,12 +1240,9 @@ const registerGlobalHotkey = (accelerator: string) => {
|
||||
};
|
||||
|
||||
app.whenReady().then(async () => {
|
||||
// Register update IPC handlers once
|
||||
// Register update IPC handlers once (but don't setup auto-updater yet)
|
||||
registerUpdateIpcHandlers();
|
||||
|
||||
// Setup auto-updater if enabled
|
||||
shouldSetupUpdater() && setupAutoUpdater();
|
||||
|
||||
// Add CSP headers to all sessions
|
||||
session.defaultSession.webRequest.onHeadersReceived((details, callback) => {
|
||||
callback({
|
||||
@@ -1296,6 +1313,18 @@ app.whenReady().then(async () => {
|
||||
|
||||
await createNewWindow(app, dirPath);
|
||||
|
||||
// Setup auto-updater AFTER window is created and displayed (with delay to avoid blocking)
|
||||
setTimeout(() => {
|
||||
if (shouldSetupUpdater()) {
|
||||
log.info('Setting up auto-updater after window creation...');
|
||||
try {
|
||||
setupAutoUpdater();
|
||||
} catch (error) {
|
||||
log.error('Error setting up auto-updater:', error);
|
||||
}
|
||||
}
|
||||
}, 2000); // 2 second delay after window is shown
|
||||
|
||||
// Get the existing menu
|
||||
const menu = Menu.getApplicationMenu();
|
||||
|
||||
|
||||
@@ -14,7 +14,35 @@ export function loadRecentDirs(): string[] {
|
||||
if (fs.existsSync(RECENT_DIRS_FILE)) {
|
||||
const data = fs.readFileSync(RECENT_DIRS_FILE, 'utf8');
|
||||
const recentDirs: RecentDirs = JSON.parse(data);
|
||||
return recentDirs.dirs;
|
||||
|
||||
// Filter out invalid directories (non-existent or not directories)
|
||||
const validDirs = recentDirs.dirs.filter((dir) => {
|
||||
try {
|
||||
// Use lstat to detect symlinks and validate path structure
|
||||
const stats = fs.lstatSync(dir);
|
||||
|
||||
// Reject symlinks for security
|
||||
if (stats.isSymbolicLink()) {
|
||||
console.warn(
|
||||
`Removing symlink from recent directories for security: ${path.basename(dir)}`
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
return stats.isDirectory();
|
||||
} catch (error) {
|
||||
// Directory doesn't exist or can't be accessed - don't log full path for security
|
||||
console.warn(`Removing inaccessible recent directory`);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
// Save the cleaned list back if it changed
|
||||
if (validDirs.length !== recentDirs.dirs.length) {
|
||||
fs.writeFileSync(RECENT_DIRS_FILE, JSON.stringify({ dirs: validDirs }, null, 2));
|
||||
}
|
||||
|
||||
return validDirs;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error loading recent directories:', error);
|
||||
@@ -24,6 +52,25 @@ export function loadRecentDirs(): string[] {
|
||||
|
||||
export function addRecentDir(dir: string): void {
|
||||
try {
|
||||
// Validate that the path is actually a directory before adding it
|
||||
try {
|
||||
const stats = fs.lstatSync(dir);
|
||||
|
||||
// Reject symlinks for security
|
||||
if (stats.isSymbolicLink()) {
|
||||
console.warn(`Cannot add recent directory: symlinks not allowed for security`);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!stats.isDirectory()) {
|
||||
console.warn(`Cannot add recent directory: not a directory`);
|
||||
return;
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn(`Cannot add recent directory: path does not exist or cannot be accessed`);
|
||||
return;
|
||||
}
|
||||
|
||||
let dirs = loadRecentDirs();
|
||||
// Remove the directory if it already exists
|
||||
dirs = dirs.filter((d) => d !== dir);
|
||||
|
||||
Reference in New Issue
Block a user