Fix window not showing for some users (#2967)

Co-authored-by: Max Novich <mnovich@squareup.com>
This commit is contained in:
Zane
2025-06-17 12:46:10 -07:00
committed by GitHub
parent 3bec469043
commit d9ca16d9e6
8 changed files with 140 additions and 1471 deletions

View File

@@ -3,34 +3,33 @@ module temporal-service
go 1.23.0
require (
go.temporal.io/api v1.44.1
go.temporal.io/sdk v1.24.0
go.temporal.io/api v1.46.0
go.temporal.io/sdk v1.34.0
gopkg.in/yaml.v2 v2.4.0
)
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/facebookgo/clock v0.0.0-20150410010913-600d898af40a // indirect
github.com/gogo/googleapis v1.4.1 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/gogo/status v1.1.1 // indirect
github.com/golang/mock v1.6.0 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect
github.com/pborman/uuid v1.2.1 // indirect
github.com/nexus-rpc/sdk-go v0.3.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/robfig/cron v1.2.0 // indirect
github.com/stretchr/objx v0.5.2 // indirect
github.com/stretchr/testify v1.9.0 // indirect
go.uber.org/atomic v1.9.0 // indirect
github.com/stretchr/testify v1.10.0 // indirect
golang.org/x/net v0.38.0 // indirect
golang.org/x/sync v0.12.0 // indirect
golang.org/x/sys v0.31.0 // indirect
golang.org/x/text v0.23.0 // indirect
golang.org/x/time v0.3.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240827150818-7e3bb234dfed // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240827150818-7e3bb234dfed // indirect
google.golang.org/grpc v1.66.0 // indirect
google.golang.org/protobuf v1.34.2 // indirect
google.golang.org/protobuf v1.36.5 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@@ -54,8 +54,7 @@
"tailwind-merge": "^2.5.4",
"tailwindcss-animate": "^1.0.7",
"unist-util-visit": "^5.0.0",
"uuid": "^11.1.0",
"yauzl": "^3.0.0"
"uuid": "^11.1.0"
},
"devDependencies": {
"@electron-forge/cli": "^7.5.0",
@@ -5550,6 +5549,7 @@
"version": "0.2.13",
"resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
"integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": "*"
@@ -13011,6 +13011,7 @@
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
"integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==",
"dev": true,
"license": "MIT"
},
"node_modules/perfect-debounce": {
@@ -17265,19 +17266,6 @@
"node": ">=8"
}
},
"node_modules/yauzl": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/yauzl/-/yauzl-3.2.0.tgz",
"integrity": "sha512-Ow9nuGZE+qp1u4JIPvg+uCiUr7xGQWdff7JQSk5VGYTAZMDe2q8lxJ10ygv10qmSj031Ty/6FNJpLO4o1Sgc+w==",
"license": "MIT",
"dependencies": {
"buffer-crc32": "~0.2.3",
"pend": "~1.2.0"
},
"engines": {
"node": ">=12"
}
},
"node_modules/yocto-queue": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",

View File

@@ -128,7 +128,6 @@
"tailwind-merge": "^2.5.4",
"tailwindcss-animate": "^1.0.7",
"unist-util-visit": "^5.0.0",
"uuid": "^11.1.0",
"yauzl": "^3.0.0"
"uuid": "^11.1.0"
}
}

View File

@@ -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}`);

View File

@@ -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();

View File

@@ -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);