init with react+axum+spacetimedb
Some checks failed
CI / verify (push) Has been cancelled

This commit is contained in:
2026-04-26 18:06:23 +08:00
commit cbc27bad4a
20199 changed files with 883714 additions and 0 deletions

View File

@@ -0,0 +1,90 @@
use axum::{
Json,
extract::{Extension, State},
http::StatusCode,
};
use platform_auth::hash_refresh_session_token;
use shared_contracts::auth::{AuthSessionSummaryPayload, AuthSessionsResponse};
use time::OffsetDateTime;
use crate::{
api_response::json_success_body,
auth::{AuthenticatedAccessToken, RefreshSessionToken},
http_error::AppError,
request_context::RequestContext,
session_client::mask_ip,
state::AppState,
};
pub async fn auth_sessions(
State(state): State<AppState>,
Extension(request_context): Extension<RequestContext>,
Extension(authenticated): Extension<AuthenticatedAccessToken>,
maybe_refresh_token: Option<Extension<RefreshSessionToken>>,
) -> Result<Json<serde_json::Value>, AppError> {
// 当前设备识别仍然依赖 refresh cookie 命中的原始 token对旧前端行为保持兼容。
let user_id = authenticated.claims().user_id().to_string();
let current_refresh_token_hash = maybe_refresh_token.and_then(|token| {
let token = token.0.token().trim();
if token.is_empty() {
return None;
}
Some(hash_refresh_session_token(token))
});
let sessions = state
.refresh_session_service()
.list_active_sessions_by_user(&user_id, OffsetDateTime::now_utc())
.map_err(map_refresh_session_list_error)?;
Ok(json_success_body(
Some(&request_context),
AuthSessionsResponse {
sessions: sessions
.sessions
.into_iter()
.map(|session| {
let is_current = current_refresh_token_hash
.as_ref()
.is_some_and(|hash| session.refresh_token_hash == *hash);
let client_label = session.client_info.device_display_name.clone();
AuthSessionSummaryPayload {
session_id: session.session_id,
client_type: session.client_info.client_type,
client_runtime: session.client_info.client_runtime,
client_platform: session.client_info.client_platform,
client_label,
device_display_name: session.client_info.device_display_name,
mini_program_app_id: session.client_info.mini_program_app_id,
mini_program_env: session.client_info.mini_program_env,
user_agent: session.client_info.user_agent,
ip_masked: mask_ip(session.client_info.ip.as_deref()),
is_current,
created_at: session.created_at,
last_seen_at: session.last_seen_at,
expires_at: session.expires_at,
}
})
.collect(),
},
))
}
fn map_refresh_session_list_error(error: module_auth::RefreshSessionError) -> AppError {
match error {
module_auth::RefreshSessionError::UserNotFound => {
AppError::from_status(StatusCode::UNAUTHORIZED)
.with_message("当前登录态已失效,请重新登录")
}
module_auth::RefreshSessionError::MissingToken
| module_auth::RefreshSessionError::SessionNotFound
| module_auth::RefreshSessionError::SessionExpired => {
AppError::from_status(StatusCode::UNAUTHORIZED).with_message(error.to_string())
}
module_auth::RefreshSessionError::Store(message) => {
AppError::from_status(StatusCode::INTERNAL_SERVER_ERROR).with_message(message)
}
}
}