fix(frontend): filter empty env vars to prevent OAuth token override (#520)
* fix(frontend): filter empty env vars to prevent OAuth token override When .auto-claude/.env contains CLAUDE_CODE_OAUTH_TOKEN= (empty value), it was overriding valid OAuth tokens from profiles, causing 'Control request timeout: initialize' errors. The fix filters out empty values when loading environment variables from .env files in loadProjectEnv() and loadAutoBuildEnv() functions. Fixes #451 * refactor(frontend): extract parseEnvFile helper per code review Address code review feedback from gemini-code-assist and coderabbitai: - Extract duplicated .env parsing logic into shared parseEnvFile() helper - Clarify comment: filter applies to all env vars, not just tokens - Follows DRY principle for better maintainability --------- Co-authored-by: Andy <119136210+AndyMik90@users.noreply.github.com>
This commit is contained in:
@@ -239,6 +239,51 @@ export class AgentProcessManager {
|
||||
return env;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse environment variables from a .env file content.
|
||||
* Filters out empty values to prevent overriding valid tokens from profiles.
|
||||
*/
|
||||
private parseEnvFile(envPath: string): Record<string, string> {
|
||||
if (!existsSync(envPath)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
try {
|
||||
const envContent = readFileSync(envPath, 'utf-8');
|
||||
const envVars: Record<string, string> = {};
|
||||
|
||||
// Handle both Unix (\n) and Windows (\r\n) line endings
|
||||
for (const line of envContent.split(/\r?\n/)) {
|
||||
const trimmed = line.trim();
|
||||
// Skip comments and empty lines
|
||||
if (!trimmed || trimmed.startsWith('#')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const eqIndex = trimmed.indexOf('=');
|
||||
if (eqIndex > 0) {
|
||||
const key = trimmed.substring(0, eqIndex).trim();
|
||||
let value = trimmed.substring(eqIndex + 1).trim();
|
||||
|
||||
// Remove quotes if present
|
||||
if ((value.startsWith('"') && value.endsWith('"')) ||
|
||||
(value.startsWith("'") && value.endsWith("'"))) {
|
||||
value = value.slice(1, -1);
|
||||
}
|
||||
|
||||
// Skip empty values to prevent overriding valid values from other sources
|
||||
if (value) {
|
||||
envVars[key] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return envVars;
|
||||
} catch {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load environment variables from project's .auto-claude/.env file
|
||||
* This contains frontend-configured settings like memory/Graphiti configuration
|
||||
@@ -253,41 +298,7 @@ export class AgentProcessManager {
|
||||
}
|
||||
|
||||
const envPath = path.join(projectPath, project.autoBuildPath, '.env');
|
||||
if (!existsSync(envPath)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
try {
|
||||
const envContent = readFileSync(envPath, 'utf-8');
|
||||
const envVars: Record<string, string> = {};
|
||||
|
||||
// Handle both Unix (\n) and Windows (\r\n) line endings
|
||||
for (const line of envContent.split(/\r?\n/)) {
|
||||
const trimmed = line.trim();
|
||||
// Skip comments and empty lines
|
||||
if (!trimmed || trimmed.startsWith('#')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const eqIndex = trimmed.indexOf('=');
|
||||
if (eqIndex > 0) {
|
||||
const key = trimmed.substring(0, eqIndex).trim();
|
||||
let value = trimmed.substring(eqIndex + 1).trim();
|
||||
|
||||
// Remove quotes if present
|
||||
if ((value.startsWith('"') && value.endsWith('"')) ||
|
||||
(value.startsWith("'") && value.endsWith("'"))) {
|
||||
value = value.slice(1, -1);
|
||||
}
|
||||
|
||||
envVars[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
return envVars;
|
||||
} catch {
|
||||
return {};
|
||||
}
|
||||
return this.parseEnvFile(envPath);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -300,41 +311,7 @@ export class AgentProcessManager {
|
||||
}
|
||||
|
||||
const envPath = path.join(autoBuildSource, '.env');
|
||||
if (!existsSync(envPath)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
try {
|
||||
const envContent = readFileSync(envPath, 'utf-8');
|
||||
const envVars: Record<string, string> = {};
|
||||
|
||||
// Handle both Unix (\n) and Windows (\r\n) line endings
|
||||
for (const line of envContent.split(/\r?\n/)) {
|
||||
const trimmed = line.trim();
|
||||
// Skip comments and empty lines
|
||||
if (!trimmed || trimmed.startsWith('#')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const eqIndex = trimmed.indexOf('=');
|
||||
if (eqIndex > 0) {
|
||||
const key = trimmed.substring(0, eqIndex).trim();
|
||||
let value = trimmed.substring(eqIndex + 1).trim();
|
||||
|
||||
// Remove quotes if present
|
||||
if ((value.startsWith('"') && value.endsWith('"')) ||
|
||||
(value.startsWith("'") && value.endsWith("'"))) {
|
||||
value = value.slice(1, -1);
|
||||
}
|
||||
|
||||
envVars[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
return envVars;
|
||||
} catch {
|
||||
return {};
|
||||
}
|
||||
return this.parseEnvFile(envPath);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user