修复多端登录互相顶号

单设备退出只撤销当前 refresh session,不再提升账号级 token_version

认证中间件和 refresh 接口在本进程未命中会话时按需刷新 SpacetimeDB 认证工作集

补充多端登录与跨进程会话补水回归测试

同步项目文档和 Hermes 共享决策记录
This commit is contained in:
2026-06-07 20:54:35 +08:00
parent a5143fa0cb
commit cc84656a1f
9 changed files with 463 additions and 55 deletions

View File

@@ -12,7 +12,8 @@ use axum::extract::FromRef;
use module_ai::{AiTaskService, InMemoryAiTaskStore};
use module_auth::{
AuthUserService, InMemoryAuthStore, PasswordEntryService, PhoneAuthService,
RefreshSessionService, WechatAuthService, WechatAuthStateService,
RefreshAuthStoreSnapshotResult, RefreshSessionService, WechatAuthService,
WechatAuthStateService,
};
use module_runtime::RuntimeSnapshotRecord;
#[cfg(test)]
@@ -660,6 +661,46 @@ impl AppState {
Ok(())
}
pub fn refresh_auth_store_from_snapshot_json(
&self,
snapshot_json: &str,
) -> Result<RefreshAuthStoreSnapshotResult, SpacetimeClientError> {
self.auth_store
.refresh_from_snapshot_json(snapshot_json)
.map_err(SpacetimeClientError::Runtime)
}
pub async fn refresh_auth_store_from_spacetime(&self) -> Result<bool, SpacetimeClientError> {
#[cfg(test)]
{
return Ok(false);
}
#[cfg(not(test))]
{
let snapshot = self
.spacetime_client
.export_auth_store_snapshot_from_tables()
.await?;
let Some(snapshot_json) = snapshot
.snapshot_json
.as_deref()
.map(str::trim)
.filter(|value| !value.is_empty())
else {
return Ok(false);
};
let result = self.refresh_auth_store_from_snapshot_json(snapshot_json)?;
info!(
user_count = result.user_count,
session_count = result.session_count,
updated_at_micros = snapshot.updated_at_micros,
"已按需刷新本进程认证工作集"
);
Ok(true)
}
}
pub async fn try_restore_auth_store_from_spacetime(
config: AppConfig,
) -> Result<Self, AppStateInitError> {