refactor(common-config): consolidate hooks and migrate Gemini to ENV format

- Delete redundant wrapper hooks (useCommonConfigSnippet, useGeminiCommonConfig)
- Change Gemini common config from JSON to ENV format (.env style)
- Add backend validation with forbidden keys filtering (GEMINI_API_KEY, GOOGLE_GEMINI_BASE_URL)
- Fix localStorage migration to skip empty parsed snippets
- Add error handling for silent JSON parse failures
- Clean up debug logs and unused types
This commit is contained in:
YoVinchen
2026-01-30 10:16:57 +08:00
parent b8a53f9e36
commit aa1231903f
17 changed files with 198 additions and 323 deletions
+16 -7
View File
@@ -654,15 +654,19 @@ impl ProviderService {
Ok(cleaned.trim().to_string())
}
/// Extract common config for Gemini (JSON format)
/// Extract common config for Gemini (ENV format)
///
/// Extracts `.env` values while excluding provider-specific credentials:
/// - GOOGLE_GEMINI_BASE_URL
/// - GEMINI_API_KEY
///
/// Returns ENV format (KEY=VALUE per line) instead of JSON.
/// Values containing newlines/carriage returns are skipped to prevent
/// ENV format injection/truncation.
fn extract_gemini_common_config(settings: &Value) -> Result<String, AppError> {
let env = settings.get("env").and_then(|v| v.as_object());
let mut snippet = serde_json::Map::new();
let mut lines: Vec<String> = Vec::new();
if let Some(env) = env {
for (key, value) in env {
if key == "GOOGLE_GEMINI_BASE_URL" || key == "GEMINI_API_KEY" {
@@ -673,17 +677,22 @@ impl ProviderService {
};
let trimmed = v.trim();
if !trimmed.is_empty() {
snippet.insert(key.to_string(), Value::String(trimmed.to_string()));
// Skip values containing newlines to prevent ENV format injection
if trimmed.contains('\n') || trimmed.contains('\r') {
continue;
}
lines.push(format!("{key}={trimmed}"));
}
}
}
if snippet.is_empty() {
return Ok("{}".to_string());
if lines.is_empty() {
return Ok(String::new());
}
serde_json::to_string_pretty(&Value::Object(snippet))
.map_err(|e| AppError::Message(format!("Serialization failed: {e}")))
// Sort for consistent output
lines.sort();
Ok(lines.join("\n"))
}
/// Extract common config for OpenCode (JSON format)