P5: settings, persistence, polkit packaging, README
Backend - regenerate_identity command stops the daemon, deletes priv_key.bin, leaves the user to restart for a fresh identity; falls back to the canonical XDG path when sidecar.key_path() isn't populated yet - tauri.conf.json ships the polkit policy via deb.files mapping; src-tauri/packaging/polkit/tech.threefold.mycellium-ui.policy declares the spawn action with auth_admin_keep so the dialog appears once per session Frontend - config store persists SidecarConfig (peers, tunName, noTun) through tauri-plugin-store; App.vue reads it and forwards to start_daemon, replacing the hard-coded defaults - Settings view: daemon-config form, identity panel with the destructive regenerate button, sidecar log viewer, About - README rewritten end-to-end: HTTP-loopback architecture, polkit install path, build commands, verification matrix, and a honest "known limitations" section
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE policyconfig PUBLIC
|
||||
"-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
|
||||
"https://www.freedesktop.org/standards/PolicyKit/1/policyconfig.dtd">
|
||||
<policyconfig>
|
||||
<vendor>Threefold</vendor>
|
||||
<vendor_url>https://threefold.io</vendor_url>
|
||||
|
||||
<action id="tech.threefold.mycellium-ui.spawn">
|
||||
<description>Run the Mycelium overlay daemon</description>
|
||||
<description xml:lang="fr">Lancer le démon de l'overlay Mycelium</description>
|
||||
<message>Authentication is required to start the Mycelium overlay daemon.</message>
|
||||
<message xml:lang="fr">Une authentification est requise pour démarrer le démon Mycelium.</message>
|
||||
<defaults>
|
||||
<allow_any>auth_admin</allow_any>
|
||||
<allow_inactive>auth_admin</allow_inactive>
|
||||
<!-- Cache the authentication for the user's session so the polkit
|
||||
dialog only appears once per login (5-minute window). To allow
|
||||
passwordless start for trusted desktops, change to "yes" — be
|
||||
aware this lets any process on the machine spawn the daemon. -->
|
||||
<allow_active>auth_admin_keep</allow_active>
|
||||
</defaults>
|
||||
</action>
|
||||
</policyconfig>
|
||||
@@ -247,3 +247,52 @@ pub async fn topic_forward_remove(state: State<'_, AppState>, topic_b64: String)
|
||||
pub async fn lookup_pubkey(state: State<'_, AppState>, ip: String) -> AppResult<PubkeyLookup> {
|
||||
require_client(&state)?.lookup_pubkey(&ip).await
|
||||
}
|
||||
|
||||
// ─── Identity ────────────────────────────────────────────────────────────────
|
||||
|
||||
/// Stops the daemon (if running), removes the saved private key file, and
|
||||
/// returns the daemon to the idle state. The caller restarts the daemon
|
||||
/// to provoke regeneration.
|
||||
#[tauri::command]
|
||||
pub async fn regenerate_identity(state: State<'_, AppState>) -> AppResult<()> {
|
||||
state.poller.stop();
|
||||
let key_path = state.sidecar.key_path();
|
||||
state.sidecar.stop().await;
|
||||
|
||||
if let Some(path) = key_path {
|
||||
if path.exists() {
|
||||
std::fs::remove_file(&path).map_err(AppError::from)?;
|
||||
}
|
||||
} else {
|
||||
// Sidecar never started; resolve the canonical path via app_data_dir.
|
||||
if let Some(p) = default_key_path() {
|
||||
if p.exists() {
|
||||
std::fs::remove_file(&p).map_err(AppError::from)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn default_key_path() -> Option<std::path::PathBuf> {
|
||||
// Best-effort: fall back to the same XDG location the sidecar uses.
|
||||
dirs_like_app_data().ok().map(|d| d.join("priv_key.bin"))
|
||||
}
|
||||
|
||||
fn dirs_like_app_data() -> std::io::Result<std::path::PathBuf> {
|
||||
// We can't reach the AppHandle here, so we mirror Tauri's path:
|
||||
// $XDG_DATA_HOME/<identifier>/ or $HOME/.local/share/<identifier>/.
|
||||
let identifier = "tech.threefold.mycellium-ui";
|
||||
if let Ok(d) = std::env::var("XDG_DATA_HOME") {
|
||||
return Ok(std::path::PathBuf::from(d).join(identifier));
|
||||
}
|
||||
if let Ok(home) = std::env::var("HOME") {
|
||||
return Ok(std::path::PathBuf::from(home)
|
||||
.join(".local/share")
|
||||
.join(identifier));
|
||||
}
|
||||
Err(std::io::Error::new(
|
||||
std::io::ErrorKind::NotFound,
|
||||
"no app data dir",
|
||||
))
|
||||
}
|
||||
|
||||
@@ -57,6 +57,7 @@ pub fn run() {
|
||||
commands::topic_forward_set,
|
||||
commands::topic_forward_remove,
|
||||
commands::lookup_pubkey,
|
||||
commands::regenerate_identity,
|
||||
])
|
||||
.run(tauri::generate_context!())
|
||||
.expect("error while running tauri application");
|
||||
|
||||
@@ -40,7 +40,10 @@
|
||||
"externalBin": ["binaries/mycelium"],
|
||||
"linux": {
|
||||
"deb": {
|
||||
"depends": ["policykit-1"]
|
||||
"depends": ["policykit-1"],
|
||||
"files": {
|
||||
"/usr/share/polkit-1/actions/tech.threefold.mycellium-ui.policy": "packaging/polkit/tech.threefold.mycellium-ui.policy"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user