diff --git a/CHANGELOG.md b/CHANGELOG.md index bc251d7..d9926f6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ - Multiple listen addresses for HTTP-01 and TLS-ALPN-01 solvers (`listen = ["[::]:80", "[::]:8080"]`). Certforge tries all addresses and succeeds if at least one binds. Useful for initial provisioning when a proxy isn't running yet. - `dane-check` now queries published TLSA records from DNS and verifies them against expected values. Exits with code 1 if any records are missing or mismatched. - Configurable DNS propagation delay per solver (`propagation_delay`, default 5s). +- Implement `account deactivate` command. ### Fixes diff --git a/src/acme.rs b/src/acme.rs index 3ff4328..e173e56 100644 --- a/src/acme.rs +++ b/src/acme.rs @@ -254,4 +254,9 @@ impl AcmeClient { pub fn account(&self) -> &Account { &self.account } + + pub async fn deactivate(self) -> Result<()> { + self.account.deactivate().await?; + Ok(()) + } } diff --git a/src/main.rs b/src/main.rs index 303c3bb..6b5e147 100644 --- a/src/main.rs +++ b/src/main.rs @@ -90,7 +90,25 @@ async fn main() -> anyhow::Result<()> { println!("Account ID: {}", client.account().id()); } AccountAction::Deactivate => { - tracing::warn!("account deactivation not yet implemented"); + let client = acme::AcmeClient::load(&config.acme).await?; + let id = client.account().id().to_string(); + client.deactivate().await?; + + // Remove local credentials so show/renew don't use the stale account + if let Some(path) = &config.acme.account_key_credential + && path.exists() + { + std::fs::remove_file(path)?; + tracing::info!(path = %path.display(), "removed account credential"); + } + if let Some(path) = &config.acme.account_key_path + && path.exists() + { + std::fs::remove_file(path)?; + tracing::info!(path = %path.display(), "removed account key file"); + } + + println!("Account {id} deactivated"); } } }