refactor: move M_UNKNOWN_TOKEN recovery into client::build_and_restore
This commit is contained in:
parent
7010d06c34
commit
92ed989f8c
2 changed files with 34 additions and 41 deletions
|
|
@ -60,7 +60,35 @@ pub async fn build_and_restore(
|
||||||
return Err(anyhow!("matrix token at {} is empty", token_file.display()));
|
return Err(anyhow!("matrix token at {} is empty", token_file.display()));
|
||||||
}
|
}
|
||||||
|
|
||||||
let (user_id, device_id) = whoami(homeserver, &token).await?;
|
let (user_id, device_id) = match whoami(homeserver, &token).await {
|
||||||
|
Ok(ids) => ids,
|
||||||
|
Err(e) => {
|
||||||
|
let msg = format!("{e:#}");
|
||||||
|
if msg.contains("M_UNKNOWN_TOKEN") {
|
||||||
|
// Homeserver rejected our token — stale session after a homeserver
|
||||||
|
// state wipe or token expiry. Delete the token file (and the
|
||||||
|
// matrix-sdk sqlite state keyed to the now-invalid session) so
|
||||||
|
// hive-c0re's periodic `ensure_all` sweep re-provisions the account.
|
||||||
|
// Exit 0: systemd's Restart=on-failure must not loop us here; the
|
||||||
|
// systemd.paths watcher restarts us once the new token file appears.
|
||||||
|
tracing::warn!(
|
||||||
|
path = %token_file.display(),
|
||||||
|
"matrix token rejected (M_UNKNOWN_TOKEN); deleting stale token + \
|
||||||
|
sdk state for re-provisioning"
|
||||||
|
);
|
||||||
|
let _ = fs::remove_file(token_file).await;
|
||||||
|
if let Err(re) = fs::remove_dir_all(state_dir).await {
|
||||||
|
tracing::warn!(
|
||||||
|
path = %state_dir.display(),
|
||||||
|
err = %re,
|
||||||
|
"failed to remove sdk state dir; next startup may fail with stale state"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
std::process::exit(0);
|
||||||
|
}
|
||||||
|
return Err(e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
fs::create_dir_all(state_dir)
|
fs::create_dir_all(state_dir)
|
||||||
.await
|
.await
|
||||||
|
|
|
||||||
|
|
@ -14,14 +14,8 @@
|
||||||
//! systemd's `ConditionPathExists=` doesn't have to be perfectly
|
//! systemd's `ConditionPathExists=` doesn't have to be perfectly
|
||||||
//! synced with hive-c0re's token-provisioning timing.
|
//! synced with hive-c0re's token-provisioning timing.
|
||||||
//!
|
//!
|
||||||
//! Stale-token recovery: when the homeserver rejects the token with
|
//! Stale-token recovery: handled in `client::build_and_restore` — see
|
||||||
//! `M_UNKNOWN_TOKEN` (e.g. after a homeserver state wipe or session
|
//! that module for the M_UNKNOWN_TOKEN detection + cleanup flow.
|
||||||
//! expiry), the daemon deletes both the token file and the matrix-sdk
|
|
||||||
//! sqlite state dir, then exits 0. hive-c0re's periodic
|
|
||||||
//! `matrix::ensure_all` sweep detects the missing token file and
|
|
||||||
//! re-provisions the account (login with the stored password → new
|
|
||||||
//! token). The systemd.paths watcher on the token file path then
|
|
||||||
//! restarts this daemon with a valid token.
|
|
||||||
|
|
||||||
use anyhow::{Context, Result};
|
use anyhow::{Context, Result};
|
||||||
use matrix_sdk::config::SyncSettings;
|
use matrix_sdk::config::SyncSettings;
|
||||||
|
|
@ -66,38 +60,9 @@ async fn main() -> Result<()> {
|
||||||
"hive-matrix-daemon starting"
|
"hive-matrix-daemon starting"
|
||||||
);
|
);
|
||||||
|
|
||||||
let matrix_client =
|
let matrix_client = client::build_and_restore(&homeserver, &token_file, &state_dir)
|
||||||
match client::build_and_restore(&homeserver, &token_file, &state_dir).await {
|
.await
|
||||||
Ok(c) => c,
|
.context("build matrix client")?;
|
||||||
Err(e) => {
|
|
||||||
let msg = format!("{e:#}");
|
|
||||||
if msg.contains("M_UNKNOWN_TOKEN") {
|
|
||||||
// Homeserver rejected our token — stale session after a
|
|
||||||
// homeserver state wipe or token expiry. Delete the token
|
|
||||||
// file (and the matrix-sdk sqlite state which is keyed to
|
|
||||||
// the now-invalid session) so hive-c0re's next
|
|
||||||
// `ensure_all` sweep re-provisions the account. Exit 0 so
|
|
||||||
// systemd's Restart=on-failure doesn't loop us here —
|
|
||||||
// the systemd.paths watcher will restart us once the new
|
|
||||||
// token file appears.
|
|
||||||
tracing::warn!(
|
|
||||||
path = %token_file.display(),
|
|
||||||
"matrix token rejected (M_UNKNOWN_TOKEN); deleting stale \
|
|
||||||
token + sdk state for re-provisioning"
|
|
||||||
);
|
|
||||||
let _ = tokio::fs::remove_file(&token_file).await;
|
|
||||||
if let Err(e) = tokio::fs::remove_dir_all(&state_dir).await {
|
|
||||||
tracing::warn!(
|
|
||||||
path = %state_dir.display(),
|
|
||||||
err = %e,
|
|
||||||
"failed to remove sdk state dir; next startup may fail with stale state"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
return Err(e.context("build matrix client"));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
timeline::install_message_handler(&matrix_client, hyperhive_socket.clone());
|
timeline::install_message_handler(&matrix_client, hyperhive_socket.clone());
|
||||||
timeline::install_invite_handler(&matrix_client, hyperhive_socket);
|
timeline::install_invite_handler(&matrix_client, hyperhive_socket);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue