P0 blockers: - Fix migration numbering conflict and duplicate indexes - Change comments.post_id FK to ON DELETE CASCADE - Restrict public post detail endpoint to published posts only - Fix rate-limiting IP extraction and fallback to ConnectInfo - Harden HTML sanitizer: deny unknown URL schemes, restrict data URIs - Remove session token from login response body - Enforce image pixel/dimension limits on upload and serving P1 high-risk: - Validate uploads by magic bytes and decode GIF/WebP - Add pagination/rate-limiting to search, tag posts, and comments - Make first-admin registration and slug uniqueness check atomic - HTML-escape comment author fields - Improve HTML minify cache key and skip admin/error responses - Add mobile navigation menu P2 accessibility/quality: - Associate form labels with inputs - Key PostDetail article by slug to re-init scripts on navigation - Improve image viewer keyboard accessibility - Make theme toggle SSR-friendly and add aria-label - Invalidate slug 404 cache on create and pending count on new comment - Deduplicate tags case-insensitively P3 cleanup: - Remove unused tower-http dependency, expand make clean - Configure DB pool timeouts and verified recycling - Run background cleanup tasks immediately on startup - Use SHA-256 for stable disk cache keys - Log DB errors with Display instead of Debug - Update README migration instructions All tests pass (321), clippy clean, dx check clean.
33 lines
1.1 KiB
Rust
33 lines
1.1 KiB
Rust
//! IP 与用户代理信息定期清理后台任务。
|
|
//!
|
|
//! 仅在 `server` feature 启用时编译,每天运行一次。
|
|
|
|
use std::time::Duration;
|
|
|
|
use tokio::time::interval;
|
|
|
|
use crate::db::pool::get_conn;
|
|
|
|
/// 启动 IP 信息清理循环,每天将 90 天前的评论的 `ip_address` 与 `user_agent` 置空。
|
|
pub async fn run_purge() {
|
|
// 每天触发一次
|
|
let mut ticker = interval(Duration::from_secs(86400));
|
|
loop {
|
|
match get_conn().await {
|
|
Ok(client) => {
|
|
// 仅清理 90 天前且仍保留 IP 的评论
|
|
if let Err(e) = client
|
|
.execute("UPDATE comments SET ip_address = NULL, user_agent = NULL WHERE created_at < NOW() - INTERVAL '90 days' AND ip_address IS NOT NULL", &[])
|
|
.await
|
|
{
|
|
tracing::error!("IP purge error: {:?}", e);
|
|
}
|
|
}
|
|
Err(e) => {
|
|
tracing::error!("Failed to get DB connection for IP purge: {:?}", e);
|
|
}
|
|
}
|
|
ticker.tick().await;
|
|
}
|
|
}
|