fix(hooks): address code quality issues in comment_storage

- Fix is_expired: use js_sys::Date::now() on WASM, avoid format-parse roundtrip
- Make error fallback safe (expire on error)
- Restrict escape_html visibility to pub(crate)
- Only write storage in load_pending_comments when pruning actually occurs
This commit is contained in:
xfy 2026-06-11 14:28:27 +08:00
parent fccd4c05ff
commit 0f3d9fc25c

View File

@ -52,18 +52,24 @@ fn write_storage(key: &str, value: &str) {
} }
} }
fn now_iso() -> String { fn now_millis() -> i64 {
Utc::now().to_rfc3339() #[cfg(target_arch = "wasm32")]
{
js_sys::Date::now() as i64
}
#[cfg(not(target_arch = "wasm32"))]
{
chrono::Utc::now().timestamp_millis()
}
} }
fn is_expired(stored_at: &str) -> bool { fn is_expired(stored_at: &str) -> bool {
let Ok(dt) = DateTime::parse_from_rfc3339(stored_at) else { let Ok(dt) = DateTime::parse_from_rfc3339(stored_at) else {
return true; return true;
}; };
let Ok(now) = DateTime::parse_from_rfc3339(&now_iso()) else { let now_ms = now_millis();
return false; let stored_ms = dt.timestamp_millis();
}; (now_ms - stored_ms) > (TTL_DAYS * 24 * 60 * 60 * 1000)
(now - dt).num_days() > TTL_DAYS
} }
pub fn save_author(name: &str, email: &str, url: &str) { pub fn save_author(name: &str, email: &str, url: &str) {
@ -107,11 +113,14 @@ pub fn load_pending_comments(post_id: i32) -> Vec<PendingComment> {
.filter(|c| !is_expired(&c.stored_at)) .filter(|c| !is_expired(&c.stored_at))
.collect(); .collect();
let pruned = non_expired.len() != comments.len();
if !non_expired.is_empty() { if !non_expired.is_empty() {
map.insert(key, non_expired.clone()); map.insert(key, non_expired.clone());
} }
if let Ok(json) = serde_json::to_string(&map) { if pruned || non_expired.is_empty() {
write_storage(PENDING_KEY, &json); if let Ok(json) = serde_json::to_string(&map) {
write_storage(PENDING_KEY, &json);
}
} }
non_expired non_expired
@ -173,7 +182,7 @@ fn load_all_pending() -> PendingMap {
serde_json::from_str(&json).unwrap_or_default() serde_json::from_str(&json).unwrap_or_default()
} }
pub fn escape_html(input: &str) -> String { pub(crate) fn escape_html(input: &str) -> String {
input input
.replace('&', "&amp;") .replace('&', "&amp;")
.replace('<', "&lt;") .replace('<', "&lt;")