fix: implement Claude API key save RPC, VPN status on home page
Some checks failed
Build Archipelago ISO (dev) / build-iso (push) Failing after 2m19s
Some checks failed
Build Archipelago ISO (dev) / build-iso (push) Failing after 2m19s
- Add system.settings.get/set RPC methods for Claude API key management - Save key to secrets/claude-api-key, restart claude-api-proxy service - Home Network card now fetches VPN status via vpn.status RPC - Shows provider name (nostr-vpn, tailscale) instead of just "Connected" Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -292,6 +292,8 @@ impl RpcHandler {
|
||||
"system.disk-cleanup" => self.handle_system_disk_cleanup().await,
|
||||
"system.reboot" => self.handle_system_reboot(params).await,
|
||||
"system.factory-reset" => self.handle_system_factory_reset(params).await,
|
||||
"system.settings.get" => self.handle_system_settings_get(params).await,
|
||||
"system.settings.set" => self.handle_system_settings_set(params).await,
|
||||
|
||||
// Opt-in anonymous analytics
|
||||
"analytics.get-status" => self.handle_analytics_get_status().await,
|
||||
|
||||
@@ -327,4 +327,78 @@ impl RpcHandler {
|
||||
|
||||
Ok(serde_json::json!({ "status": "resetting" }))
|
||||
}
|
||||
|
||||
/// system.settings.get — Read a settings value
|
||||
pub(in crate::api::rpc) async fn handle_system_settings_get(
|
||||
&self,
|
||||
params: Option<serde_json::Value>,
|
||||
) -> Result<serde_json::Value> {
|
||||
let params = params.ok_or_else(|| anyhow::anyhow!("Missing params"))?;
|
||||
let key = params.get("key").and_then(|v| v.as_str())
|
||||
.ok_or_else(|| anyhow::anyhow!("Missing key"))?;
|
||||
|
||||
match key {
|
||||
"claude_api_key_set" => {
|
||||
let key_file = self.config.data_dir.join("secrets/claude-api-key");
|
||||
let has_key = tokio::fs::metadata(&key_file).await.is_ok();
|
||||
Ok(serde_json::json!({ "value": has_key }))
|
||||
}
|
||||
_ => Ok(serde_json::json!({ "value": null })),
|
||||
}
|
||||
}
|
||||
|
||||
/// system.settings.set — Write a settings value
|
||||
pub(in crate::api::rpc) async fn handle_system_settings_set(
|
||||
&self,
|
||||
params: Option<serde_json::Value>,
|
||||
) -> Result<serde_json::Value> {
|
||||
let params = params.ok_or_else(|| anyhow::anyhow!("Missing params"))?;
|
||||
let key = params.get("key").and_then(|v| v.as_str())
|
||||
.ok_or_else(|| anyhow::anyhow!("Missing key"))?;
|
||||
let value = params.get("value").and_then(|v| v.as_str()).unwrap_or("");
|
||||
|
||||
match key {
|
||||
"claude_api_key" => {
|
||||
let secrets_dir = self.config.data_dir.join("secrets");
|
||||
tokio::fs::create_dir_all(&secrets_dir).await
|
||||
.context("Failed to create secrets dir")?;
|
||||
let key_file = secrets_dir.join("claude-api-key");
|
||||
|
||||
if value.is_empty() {
|
||||
// Remove key
|
||||
tokio::fs::remove_file(&key_file).await.ok();
|
||||
info!("Claude API key removed");
|
||||
} else {
|
||||
// Save key
|
||||
tokio::fs::write(&key_file, value).await
|
||||
.context("Failed to write API key")?;
|
||||
#[cfg(unix)]
|
||||
{
|
||||
use std::os::unix::fs::PermissionsExt;
|
||||
std::fs::set_permissions(&key_file, std::fs::Permissions::from_mode(0o600)).ok();
|
||||
}
|
||||
info!("Claude API key saved");
|
||||
}
|
||||
|
||||
// Update the claude-api-proxy environment and restart
|
||||
let env_line = format!("ANTHROPIC_API_KEY={}", value);
|
||||
let env_file = self.config.data_dir.join("secrets/claude-api-proxy.env");
|
||||
tokio::fs::write(&env_file, &env_line).await.ok();
|
||||
#[cfg(unix)]
|
||||
{
|
||||
use std::os::unix::fs::PermissionsExt;
|
||||
std::fs::set_permissions(&env_file, std::fs::Permissions::from_mode(0o600)).ok();
|
||||
}
|
||||
|
||||
// Restart the proxy to pick up the new key
|
||||
let _ = tokio::process::Command::new("sudo")
|
||||
.args(["systemctl", "restart", "claude-api-proxy"])
|
||||
.output()
|
||||
.await;
|
||||
|
||||
Ok(serde_json::json!({ "saved": true }))
|
||||
}
|
||||
_ => anyhow::bail!("Unknown setting: {}", key),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user