Fix MongoDB DateTime serialization issues - Replace chrono::DateTime with mongodb::bson::DateTime in models - Update API responses to use timestamp_millis() for JSON serialization - Fix User, Share model DateTime fields - Update all handler responses to return i64 timestamps - This fixes the Kind: invalid type: map, expected RFC 3339 error
Some checks failed
Lint and Build / Lint (push) Failing after 5s
Lint and Build / Build (push) Has been skipped
Lint and Build / Docker Build (push) Has been skipped

This commit is contained in:
goose 2026-02-26 09:22:36 -03:00
parent 1e914089d5
commit 3a6bcbd94d
5 changed files with 25 additions and 20 deletions

View file

@ -9,10 +9,13 @@ pub async fn health_check(State(state): State<AppState>) -> Json<Value> {
"error"
};
// Use timestamp_millis for consistency with other endpoints
let timestamp = mongodb::bson::DateTime::now().timestamp_millis();
Json(json!({
"status": "ok",
"database": status,
"timestamp": chrono::Utc::now().to_rfc3339()
"timestamp": timestamp
}))
}

View file

@ -32,8 +32,8 @@ pub struct ShareResponse {
pub resource_type: String,
pub resource_id: Option<String>,
pub permissions: Vec<String>,
pub expires_at: Option<String>,
pub created_at: String,
pub expires_at: Option<i64>,
pub created_at: i64,
pub active: bool,
}
@ -47,8 +47,8 @@ impl TryFrom<Share> for ShareResponse {
resource_type: share.resource_type,
resource_id: share.resource_id.map(|id| id.to_string()),
permissions: share.permissions.into_iter().map(|p| p.to_string()).collect(),
expires_at: share.expires_at.map(|dt| dt.to_rfc3339()),
created_at: share.created_at.to_rfc3339(),
expires_at: share.expires_at.map(|dt| dt.timestamp_millis()),
created_at: share.created_at.timestamp_millis(),
active: share.active,
})
}
@ -136,7 +136,7 @@ pub async fn create_share(
// Calculate expiration
let expires_at = req.expires_days.map(|days| {
chrono::Utc::now() + chrono::Duration::days(days as i64)
mongodb::bson::DateTime::now().saturating_add_millis(days as i64 * 24 * 60 * 60 * 1000)
});
let share = Share::new(
@ -289,7 +289,7 @@ pub async fn update_share(
}
if let Some(days) = req.expires_days {
share.expires_at = Some(chrono::Utc::now() + chrono::Duration::days(days as i64));
share.expires_at = Some(mongodb::bson::DateTime::now().saturating_add_millis(days as i64 * 24 * 60 * 60 * 1000));
}
match state.db.update_share(&share).await {

View file

@ -20,8 +20,8 @@ pub struct UserProfileResponse {
pub id: String,
pub email: String,
pub username: String,
pub created_at: String,
pub last_active: String,
pub created_at: i64,
pub last_active: i64,
pub email_verified: bool,
}
@ -33,8 +33,8 @@ impl TryFrom<User> for UserProfileResponse {
id: user.id.map(|id| id.to_string()).unwrap_or_default(),
email: user.email,
username: user.username,
created_at: user.created_at.to_rfc3339(),
last_active: user.last_active.to_rfc3339(),
created_at: user.created_at.timestamp_millis(),
last_active: user.last_active.timestamp_millis(),
email_verified: user.email_verified,
})
}

View file

@ -1,6 +1,7 @@
use mongodb::bson::{doc, oid::ObjectId};
use mongodb::Collection;
use serde::{Deserialize, Serialize};
use mongodb::bson::DateTime;
use super::permission::Permission;
@ -15,8 +16,8 @@ pub struct Share {
pub resource_id: Option<ObjectId>,
pub permissions: Vec<Permission>,
#[serde(skip_serializing_if = "Option::is_none")]
pub expires_at: Option<chrono::DateTime<chrono::Utc>>,
pub created_at: chrono::DateTime<chrono::Utc>,
pub expires_at: Option<DateTime>,
pub created_at: DateTime,
pub active: bool,
}
@ -27,7 +28,7 @@ impl Share {
resource_type: String,
resource_id: Option<ObjectId>,
permissions: Vec<Permission>,
expires_at: Option<chrono::DateTime<chrono::Utc>>,
expires_at: Option<DateTime>,
) -> Self {
Self {
id: None,
@ -37,14 +38,14 @@ impl Share {
resource_id,
permissions,
expires_at,
created_at: chrono::Utc::now(),
created_at: DateTime::now(),
active: true,
}
}
pub fn is_expired(&self) -> bool {
if let Some(expires) = self.expires_at {
chrono::Utc::now() > expires
DateTime::now() > expires
} else {
false
}

View file

@ -2,6 +2,7 @@ use mongodb::bson::{doc, oid::ObjectId};
use mongodb::Collection;
use serde::{Deserialize, Serialize};
use mongodb::bson::DateTime;
use crate::auth::password::verify_password;
#[derive(Debug, Clone, Serialize, Deserialize)]
@ -26,10 +27,10 @@ pub struct User {
pub token_version: i32,
/// When the user was created
pub created_at: chrono::DateTime<chrono::Utc>,
pub created_at: DateTime,
/// Last time the user was active
pub last_active: chrono::DateTime<chrono::Utc>,
pub last_active: DateTime,
/// Email verification status
pub email_verified: bool,
@ -40,7 +41,7 @@ pub struct User {
/// When the verification token expires
#[serde(skip_serializing_if = "Option::is_none")]
pub verification_expires: Option<chrono::DateTime<chrono::Utc>>,
pub verification_expires: Option<DateTime>,
}
impl User {
@ -64,7 +65,7 @@ impl User {
None
};
let now = chrono::Utc::now();
let now = DateTime::now();
let recovery_enabled = recovery_phrase_hash.is_some();
Ok(User {