fix: keep API key setup and export in sync

This commit is contained in:
Eddy committed 2026-07-06 01:00:56 +02:00
1 parent a5667374bf
commit ba1179d469
3 files changed
+57 -21

No files matched your search

+41 -5
View File
@@ -5,14 +5,26 @@ import { join } from 'path';
const configSource = readFileSync(join(process.cwd(), 'src/config/index.ts'), 'utf8');
const setupScript = readFileSync(join(process.cwd(), 'scripts/setup-api.sh'), 'utf8');
function configLoadEnvBlock(): string {
const start = configSource.indexOf('private loadEnvVariables(): void');
expect(start).toBeGreaterThanOrEqual(0);
const end = configSource.indexOf('\n /**\n * Get all settings', start);
expect(end).toBeGreaterThan(start);
function sourceBlock(startMarker: string, endMarker: string): string {
const start = configSource.indexOf(startMarker);
expect(start, `missing start marker ${startMarker}`).toBeGreaterThanOrEqual(0);
const end = configSource.indexOf(endMarker, start);
expect(end, `missing end marker ${endMarker}`).toBeGreaterThan(start);
return configSource.slice(start, end);
}
function configLoadEnvBlock(): string {
return sourceBlock('private loadEnvVariables(): void', '\n /**\n * Get all settings');
}
function exportConfigBlock(): string {
return sourceBlock('exportConfig(filePath: string): void', '\n /**\n * Create a .env template file');
}
function envTemplateBlock(): string {
return sourceBlock('createEnvTemplate(filePath:', '\n writeFileSync(filePath, template);');
}
describe('API key environment handling hardening', () => {
it('ConfigManager does not implicitly read .env from the caller working directory', () => {
const block = configLoadEnvBlock();
@@ -21,6 +33,30 @@ describe('API key environment handling hardening', () => {
expect(block).toContain("join(homedir(), '.t3mp3st', '.env')");
});
it('setup-api.sh writes the same T3MP3ST-owned env file that ConfigManager reads', () => {
const block = configLoadEnvBlock();
expect(setupScript).not.toMatch(/dirname "\$0"\).*\.\.\/\.env/);
expect(setupScript).toMatch(/\.t3mp3st/);
expect(setupScript).toMatch(/mkdir\s+-p\s+"\$\(dirname "\$ENV_FILE"\)"/);
expect(block).toContain("join(homedir(), '.t3mp3st', '.env')");
});
it('env template points users at the T3MP3ST-owned env file, not a caller-cwd .env', () => {
const block = envTemplateBlock();
expect(block).toContain('~/.t3mp3st/.env');
expect(block).not.toContain('Copy this file to .env');
});
it('exportConfig redacts every supported provider key slot', () => {
const block = exportConfigBlock();
for (const provider of ['openrouter', 'venice', 'anthropic', 'openai', 'xai']) {
expect(block).toContain(`${provider}: settings.apiKeys.${provider} ? '***REDACTED***' : undefined`);
}
});
it('ConfigManager uses env keys in-memory and does not persist imported env keys', () => {
const block = configLoadEnvBlock();
+12 -1
View File
@@ -793,8 +793,10 @@ class ConfigManager {
...settings,
apiKeys: {
openrouter: settings.apiKeys.openrouter ? '***REDACTED***' : undefined,
venice: settings.apiKeys.venice ? '***REDACTED***' : undefined,
anthropic: settings.apiKeys.anthropic ? '***REDACTED***' : undefined,
openai: settings.apiKeys.openai ? '***REDACTED***' : undefined,
xai: settings.apiKeys.xai ? '***REDACTED***' : undefined,
},
};
writeFileSync(filePath, JSON.stringify(safeSettings, null, 2));
@@ -805,12 +807,17 @@ class ConfigManager {
*/
createEnvTemplate(filePath: string = join(process.cwd(), '.env.template')): void {
const template = `# T3MP3ST Environment Configuration
# Copy this file to .env and fill in your API keys
# Save this file as ~/.t3mp3st/.env and fill in your API keys
# The setup script writes the same T3MP3ST-owned file.
# OpenRouter API Key (recommended - access to multiple models)
# Get your key at: https://openrouter.ai/keys
OPENROUTER_API_KEY=
# Venice API Key
# Get your key at: https://venice.ai
VENICE_API_KEY=
# Anthropic API Key (direct Claude access)
# Get your key at: https://console.anthropic.com/
ANTHROPIC_API_KEY=
@@ -818,6 +825,10 @@ ANTHROPIC_API_KEY=
# OpenAI API Key
# Get your key at: https://platform.openai.com/api-keys
OPENAI_API_KEY=
# xAI API Key
# Get your key at: https://console.x.ai/
XAI_API_KEY=
`;
writeFileSync(filePath, template);
}