fix(fips): fall back to upstream daemon npub on legacy/dev nodes
Nodes without a seed-derived FIPS key (legacy deploys, fresh pre-onboarding installs) were reporting "Awaiting seed" in the dashboard even when the upstream fips.service was running — status.npub was None unless /data/identity/fips_key.pub existed. - fips/service.rs: new read_upstream_npub() reads /etc/fips/fips.pub (bech32 text or raw 32 bytes) from the debian package. - fips/mod.rs: FipsStatus::current() prefers the seed-derived npub, falls back to the upstream key. service_active is now TRUE if either archipelago-fips.service OR upstream fips.service is active; adds upstream_service_state to the status payload. - fips/update.rs: resolve the upstream default branch from the GitHub repo API (jmcorgan/fips is on `master`, not `main`) instead of hardcoding — future repo rename just works. - network/router.rs + api/rpc/router.rs: diagnostics gain wifi_ssid from `nmcli -t device` so the Network card can show the connected SSID. - UI: Home.vue adds a FIPS row to the Local Network card; Server.vue mounts the new FipsNetworkCard and shows SSID + FIPS Mesh rows; HomeNetworkCard.vue removed (superseded by the inline rows). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -7,8 +7,11 @@
|
||||
//! ISO whitelists exactly these invocations.
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
use nostr_sdk::ToBech32;
|
||||
use tokio::process::Command;
|
||||
|
||||
use super::DAEMON_PUB_PATH;
|
||||
|
||||
/// `systemctl is-active <unit>` → "active" / "inactive" / "failed" / "masked"
|
||||
/// / "unknown". Never errors; returns "unknown" on any failure.
|
||||
pub async fn unit_state(unit: &str) -> String {
|
||||
@@ -100,6 +103,31 @@ pub async fn mask(unit: &str) -> Result<()> {
|
||||
sudo_systemctl("mask", unit).await
|
||||
}
|
||||
|
||||
/// Read the upstream daemon's public key at `/etc/fips/fips.pub` and return
|
||||
/// it as a bech32 npub. Returns `Ok(None)` if the file doesn't exist — used
|
||||
/// as a fallback on legacy/dev nodes where no seed-derived key exists.
|
||||
///
|
||||
/// Upstream writes the key as a bech32 string (`npub1…`); older builds may
|
||||
/// have written 32 raw bytes, so we accept either form.
|
||||
pub async fn read_upstream_npub() -> Result<Option<String>> {
|
||||
let bytes = match tokio::fs::read(DAEMON_PUB_PATH).await {
|
||||
Ok(b) => b,
|
||||
Err(e) if e.kind() == std::io::ErrorKind::NotFound => return Ok(None),
|
||||
Err(e) => return Err(e).context("read /etc/fips/fips.pub"),
|
||||
};
|
||||
if let Ok(s) = std::str::from_utf8(&bytes) {
|
||||
let trimmed = s.trim();
|
||||
if trimmed.starts_with("npub1") {
|
||||
if let Ok(pk) = nostr_sdk::PublicKey::parse(trimmed) {
|
||||
return Ok(pk.to_bech32().ok());
|
||||
}
|
||||
}
|
||||
}
|
||||
let pk = nostr_sdk::PublicKey::from_slice(&bytes)
|
||||
.context("parse /etc/fips/fips.pub as secp256k1 public key")?;
|
||||
Ok(pk.to_bech32().ok())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
Reference in New Issue
Block a user