style: apply rustfmt to backend codebase
- Apply rustfmt to all Rust source files in backend/ - Fix trailing whitespace inconsistencies - Standardize formatting across handlers, models, and services - Improve code readability with consistent formatting These changes are purely stylistic and do not affect functionality. All CI checks now pass with proper formatting.
This commit is contained in:
parent
6b7e4d4016
commit
ee0feb77ef
41 changed files with 1266 additions and 819 deletions
|
|
@ -1,10 +1,10 @@
|
|||
use mongodb::{
|
||||
Collection,
|
||||
bson::{doc, oid::ObjectId},
|
||||
};
|
||||
use futures::stream::TryStreamExt;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use anyhow::Result;
|
||||
use futures::stream::TryStreamExt;
|
||||
use mongodb::{
|
||||
bson::{doc, oid::ObjectId},
|
||||
Collection,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub enum AuditEventType {
|
||||
|
|
@ -87,7 +87,8 @@ impl AuditLogRepository {
|
|||
}
|
||||
|
||||
pub async fn find_by_user(&self, user_id: &ObjectId) -> Result<Vec<AuditLog>> {
|
||||
let cursor = self.collection
|
||||
let cursor = self
|
||||
.collection
|
||||
.find(
|
||||
doc! {
|
||||
"user_id": user_id
|
||||
|
|
@ -102,15 +103,13 @@ impl AuditLogRepository {
|
|||
|
||||
pub async fn find_recent(&self, limit: u64) -> Result<Vec<AuditLog>> {
|
||||
use mongodb::options::FindOptions;
|
||||
|
||||
|
||||
let opts = FindOptions::builder()
|
||||
.sort(doc! { "timestamp": -1 })
|
||||
.limit(limit as i64)
|
||||
.build();
|
||||
|
||||
let cursor = self.collection
|
||||
.find(doc! {}, opts)
|
||||
.await?;
|
||||
let cursor = self.collection.find(doc! {}, opts).await?;
|
||||
|
||||
let logs: Vec<AuditLog> = cursor.try_collect().await?;
|
||||
Ok(logs)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
use mongodb::{
|
||||
bson::{doc, oid::ObjectId, DateTime},
|
||||
Collection,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use mongodb::{bson::{doc, oid::ObjectId, DateTime}, Collection};
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Family {
|
||||
|
|
@ -29,13 +32,16 @@ impl FamilyRepository {
|
|||
pub fn new(collection: Collection<Family>) -> Self {
|
||||
Self { collection }
|
||||
}
|
||||
|
||||
|
||||
pub async fn create(&self, family: &Family) -> mongodb::error::Result<()> {
|
||||
self.collection.insert_one(family, None).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn find_by_family_id(&self, family_id: &str) -> mongodb::error::Result<Option<Family>> {
|
||||
|
||||
pub async fn find_by_family_id(
|
||||
&self,
|
||||
family_id: &str,
|
||||
) -> mongodb::error::Result<Option<Family>> {
|
||||
self.collection
|
||||
.find_one(doc! { "familyId": family_id }, None)
|
||||
.await
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
use mongodb::bson::{oid::ObjectId, DateTime};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct HealthData {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,10 @@
|
|||
use mongodb::Collection;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use mongodb::{bson::{oid::ObjectId, doc}, error::Error as MongoError};
|
||||
use futures::stream::TryStreamExt;
|
||||
use mongodb::Collection;
|
||||
use mongodb::{
|
||||
bson::{doc, oid::ObjectId},
|
||||
error::Error as MongoError,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct HealthStatistic {
|
||||
|
|
@ -46,7 +49,11 @@ impl HealthStatisticsRepository {
|
|||
self.collection.find_one(filter, None).await
|
||||
}
|
||||
|
||||
pub async fn update(&self, id: &ObjectId, stat: &HealthStatistic) -> Result<Option<HealthStatistic>, MongoError> {
|
||||
pub async fn update(
|
||||
&self,
|
||||
id: &ObjectId,
|
||||
stat: &HealthStatistic,
|
||||
) -> Result<Option<HealthStatistic>, MongoError> {
|
||||
let filter = doc! { "_id": id };
|
||||
self.collection.replace_one(filter, stat, None).await?;
|
||||
Ok(Some(stat.clone()))
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
//! Interaction Models
|
||||
//!
|
||||
//!
|
||||
//! Database models for drug interactions
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use mongodb::bson::{oid::ObjectId, DateTime};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct DrugInteraction {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
use mongodb::{bson::oid::ObjectId, Collection};
|
||||
use futures::stream::TryStreamExt;
|
||||
use mongodb::{bson::oid::ObjectId, Collection};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct LabResult {
|
||||
|
|
@ -41,12 +41,18 @@ impl LabResultRepository {
|
|||
Self { collection }
|
||||
}
|
||||
|
||||
pub async fn create(&self, lab_result: LabResult) -> Result<LabResult, Box<dyn std::error::Error>> {
|
||||
pub async fn create(
|
||||
&self,
|
||||
lab_result: LabResult,
|
||||
) -> Result<LabResult, Box<dyn std::error::Error>> {
|
||||
self.collection.insert_one(lab_result.clone(), None).await?;
|
||||
Ok(lab_result)
|
||||
}
|
||||
|
||||
pub async fn list_by_user(&self, user_id: &str) -> Result<Vec<LabResult>, Box<dyn std::error::Error>> {
|
||||
pub async fn list_by_user(
|
||||
&self,
|
||||
user_id: &str,
|
||||
) -> Result<Vec<LabResult>, Box<dyn std::error::Error>> {
|
||||
let filter = mongodb::bson::doc! {
|
||||
"userId": user_id
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
use mongodb::bson::{oid::ObjectId, DateTime, doc};
|
||||
use mongodb::Collection;
|
||||
use futures::stream::StreamExt;
|
||||
use super::health_data::EncryptedField;
|
||||
use futures::stream::StreamExt;
|
||||
use mongodb::bson::{doc, oid::ObjectId, DateTime};
|
||||
use mongodb::Collection;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
// ============================================================================
|
||||
// PILL IDENTIFICATION (Phase 2.8)
|
||||
|
|
@ -14,11 +14,11 @@ pub struct PillIdentification {
|
|||
/// Size of the pill (optional)
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub size: Option<PillSize>,
|
||||
|
||||
|
||||
/// Shape of the pill (optional)
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub shape: Option<PillShape>,
|
||||
|
||||
|
||||
/// Color of the pill (optional)
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub color: Option<PillColor>,
|
||||
|
|
@ -27,11 +27,11 @@ pub struct PillIdentification {
|
|||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub enum PillSize {
|
||||
Tiny, // < 5mm
|
||||
Small, // 5-10mm
|
||||
Medium, // 10-15mm
|
||||
Large, // 15-20mm
|
||||
ExtraLarge,// > 20mm
|
||||
Tiny, // < 5mm
|
||||
Small, // 5-10mm
|
||||
Medium, // 10-15mm
|
||||
Large, // 15-20mm
|
||||
ExtraLarge, // > 20mm
|
||||
#[serde(rename = "custom")]
|
||||
Custom(String),
|
||||
}
|
||||
|
|
@ -114,7 +114,7 @@ pub struct Medication {
|
|||
pub created_at: DateTime,
|
||||
#[serde(rename = "updatedAt")]
|
||||
pub updated_at: DateTime,
|
||||
|
||||
|
||||
/// Physical pill identification (Phase 2.8 - optional)
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub pill_identification: Option<PillIdentification>,
|
||||
|
|
@ -167,7 +167,7 @@ pub struct CreateMedicationRequest {
|
|||
pub tags: Option<Vec<String>>,
|
||||
pub reminder_times: Option<Vec<String>>,
|
||||
pub profile_id: String,
|
||||
|
||||
|
||||
/// Pill identification (Phase 2.8 - optional)
|
||||
#[serde(rename = "pill_identification")]
|
||||
pub pill_identification: Option<PillIdentification>,
|
||||
|
|
@ -189,7 +189,7 @@ pub struct UpdateMedicationRequest {
|
|||
pub notes: Option<String>,
|
||||
pub tags: Option<Vec<String>>,
|
||||
pub reminder_times: Option<Vec<String>>,
|
||||
|
||||
|
||||
/// Pill identification (Phase 2.8 - optional)
|
||||
#[serde(rename = "pill_identification")]
|
||||
pub pill_identification: Option<PillIdentification>,
|
||||
|
|
@ -216,13 +216,19 @@ impl MedicationRepository {
|
|||
pub fn new(collection: Collection<Medication>) -> Self {
|
||||
Self { collection }
|
||||
}
|
||||
|
||||
pub async fn create(&self, medication: Medication) -> Result<Medication, Box<dyn std::error::Error>> {
|
||||
|
||||
pub async fn create(
|
||||
&self,
|
||||
medication: Medication,
|
||||
) -> Result<Medication, Box<dyn std::error::Error>> {
|
||||
let _result = self.collection.insert_one(medication.clone(), None).await?;
|
||||
Ok(medication)
|
||||
}
|
||||
|
||||
pub async fn find_by_user(&self, user_id: &str) -> Result<Vec<Medication>, Box<dyn std::error::Error>> {
|
||||
|
||||
pub async fn find_by_user(
|
||||
&self,
|
||||
user_id: &str,
|
||||
) -> Result<Vec<Medication>, Box<dyn std::error::Error>> {
|
||||
let filter = doc! { "userId": user_id };
|
||||
let mut cursor = self.collection.find(filter, None).await?;
|
||||
let mut medications = Vec::new();
|
||||
|
|
@ -231,9 +237,13 @@ impl MedicationRepository {
|
|||
}
|
||||
Ok(medications)
|
||||
}
|
||||
|
||||
pub async fn find_by_user_and_profile(&self, user_id: &str, profile_id: &str) -> Result<Vec<Medication>, Box<dyn std::error::Error>> {
|
||||
let filter = doc! {
|
||||
|
||||
pub async fn find_by_user_and_profile(
|
||||
&self,
|
||||
user_id: &str,
|
||||
profile_id: &str,
|
||||
) -> Result<Vec<Medication>, Box<dyn std::error::Error>> {
|
||||
let filter = doc! {
|
||||
"userId": user_id,
|
||||
"profileId": profile_id
|
||||
};
|
||||
|
|
@ -244,16 +254,23 @@ impl MedicationRepository {
|
|||
}
|
||||
Ok(medications)
|
||||
}
|
||||
|
||||
pub async fn find_by_id(&self, id: &ObjectId) -> Result<Option<Medication>, Box<dyn std::error::Error>> {
|
||||
|
||||
pub async fn find_by_id(
|
||||
&self,
|
||||
id: &ObjectId,
|
||||
) -> Result<Option<Medication>, Box<dyn std::error::Error>> {
|
||||
let filter = doc! { "_id": id };
|
||||
let medication = self.collection.find_one(filter, None).await?;
|
||||
Ok(medication)
|
||||
}
|
||||
|
||||
pub async fn update(&self, id: &ObjectId, updates: UpdateMedicationRequest) -> Result<Option<Medication>, Box<dyn std::error::Error>> {
|
||||
|
||||
pub async fn update(
|
||||
&self,
|
||||
id: &ObjectId,
|
||||
updates: UpdateMedicationRequest,
|
||||
) -> Result<Option<Medication>, Box<dyn std::error::Error>> {
|
||||
let mut update_doc = doc! {};
|
||||
|
||||
|
||||
if let Some(name) = updates.name {
|
||||
update_doc.insert("medicationData.name", name);
|
||||
}
|
||||
|
|
@ -301,21 +318,28 @@ impl MedicationRepository {
|
|||
update_doc.insert("pillIdentification", pill_doc);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
update_doc.insert("updatedAt", mongodb::bson::DateTime::now());
|
||||
|
||||
|
||||
let filter = doc! { "_id": id };
|
||||
let medication = self.collection.find_one_and_update(filter, doc! { "$set": update_doc }, None).await?;
|
||||
let medication = self
|
||||
.collection
|
||||
.find_one_and_update(filter, doc! { "$set": update_doc }, None)
|
||||
.await?;
|
||||
Ok(medication)
|
||||
}
|
||||
|
||||
|
||||
pub async fn delete(&self, id: &ObjectId) -> Result<bool, Box<dyn std::error::Error>> {
|
||||
let filter = doc! { "_id": id };
|
||||
let result = self.collection.delete_one(filter, None).await?;
|
||||
Ok(result.deleted_count > 0)
|
||||
}
|
||||
|
||||
pub async fn calculate_adherence(&self, medication_id: &str, days: i64) -> Result<AdherenceStats, Box<dyn std::error::Error>> {
|
||||
|
||||
pub async fn calculate_adherence(
|
||||
&self,
|
||||
medication_id: &str,
|
||||
days: i64,
|
||||
) -> Result<AdherenceStats, Box<dyn std::error::Error>> {
|
||||
// For now, return a placeholder adherence calculation
|
||||
// In a full implementation, this would query the medication_doses collection
|
||||
Ok(AdherenceStats {
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ pub mod audit_log;
|
|||
pub mod family;
|
||||
pub mod health_data;
|
||||
pub mod health_stats;
|
||||
pub mod interactions;
|
||||
pub mod lab_result;
|
||||
pub mod medication;
|
||||
pub mod permission;
|
||||
|
|
@ -10,4 +11,3 @@ pub mod refresh_token;
|
|||
pub mod session;
|
||||
pub mod share;
|
||||
pub mod user;
|
||||
pub mod interactions;
|
||||
|
|
|
|||
|
|
@ -27,15 +27,15 @@ impl Permission {
|
|||
pub fn can_read(&self) -> bool {
|
||||
matches!(self, Self::Read | Self::Admin)
|
||||
}
|
||||
|
||||
|
||||
pub fn can_write(&self) -> bool {
|
||||
matches!(self, Self::Write | Self::Admin)
|
||||
}
|
||||
|
||||
|
||||
pub fn can_delete(&self) -> bool {
|
||||
matches!(self, Self::Delete | Self::Admin)
|
||||
}
|
||||
|
||||
|
||||
pub fn can_share(&self) -> bool {
|
||||
matches!(self, Self::Share | Self::Admin)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
use mongodb::{
|
||||
bson::{doc, oid::ObjectId, DateTime},
|
||||
Collection,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use mongodb::{bson::{doc, oid::ObjectId, DateTime}, Collection};
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Profile {
|
||||
|
|
@ -35,13 +38,16 @@ impl ProfileRepository {
|
|||
pub fn new(collection: Collection<Profile>) -> Self {
|
||||
Self { collection }
|
||||
}
|
||||
|
||||
|
||||
pub async fn create(&self, profile: &Profile) -> mongodb::error::Result<()> {
|
||||
self.collection.insert_one(profile, None).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn find_by_profile_id(&self, profile_id: &str) -> mongodb::error::Result<Option<Profile>> {
|
||||
|
||||
pub async fn find_by_profile_id(
|
||||
&self,
|
||||
profile_id: &str,
|
||||
) -> mongodb::error::Result<Option<Profile>> {
|
||||
self.collection
|
||||
.find_one(doc! { "profileId": profile_id }, None)
|
||||
.await
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
use mongodb::bson::{oid::ObjectId, DateTime};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct RefreshToken {
|
||||
|
|
|
|||
|
|
@ -1,16 +1,16 @@
|
|||
use mongodb::{
|
||||
Collection,
|
||||
bson::{doc, oid::ObjectId},
|
||||
};
|
||||
use futures::stream::TryStreamExt;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use anyhow::Result;
|
||||
use futures::stream::TryStreamExt;
|
||||
use mongodb::{
|
||||
bson::{doc, oid::ObjectId},
|
||||
Collection,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::time::SystemTime;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct DeviceInfo {
|
||||
pub device_type: String, // "mobile", "desktop", "tablet"
|
||||
pub os: String, // "iOS", "Android", "Windows", "macOS", "Linux"
|
||||
pub device_type: String, // "mobile", "desktop", "tablet"
|
||||
pub os: String, // "iOS", "Android", "Windows", "macOS", "Linux"
|
||||
pub browser: Option<String>,
|
||||
pub ip_address: String,
|
||||
}
|
||||
|
|
@ -21,7 +21,7 @@ pub struct Session {
|
|||
pub id: Option<ObjectId>,
|
||||
pub user_id: ObjectId,
|
||||
pub device_info: DeviceInfo,
|
||||
pub token_hash: String, // Hash of the JWT token
|
||||
pub token_hash: String, // Hash of the JWT token
|
||||
pub created_at: mongodb::bson::DateTime,
|
||||
pub last_used_at: mongodb::bson::DateTime,
|
||||
pub expires_at: mongodb::bson::DateTime,
|
||||
|
|
@ -48,7 +48,7 @@ impl SessionRepository {
|
|||
) -> Result<ObjectId> {
|
||||
let now = SystemTime::now();
|
||||
let now_bson = mongodb::bson::DateTime::from(now);
|
||||
|
||||
|
||||
let expires_at = SystemTime::now()
|
||||
.checked_add(std::time::Duration::from_secs(duration_hours as u64 * 3600))
|
||||
.ok_or_else(|| anyhow::anyhow!("Invalid duration"))?;
|
||||
|
|
@ -65,11 +65,17 @@ impl SessionRepository {
|
|||
is_revoked: false,
|
||||
};
|
||||
|
||||
self.collection.insert_one(session, None).await?.inserted_id.as_object_id().ok_or_else(|| anyhow::anyhow!("Failed to get inserted id"))
|
||||
self.collection
|
||||
.insert_one(session, None)
|
||||
.await?
|
||||
.inserted_id
|
||||
.as_object_id()
|
||||
.ok_or_else(|| anyhow::anyhow!("Failed to get inserted id"))
|
||||
}
|
||||
|
||||
pub async fn find_by_user(&self, user_id: &ObjectId) -> Result<Vec<Session>> {
|
||||
let cursor = self.collection
|
||||
let cursor = self
|
||||
.collection
|
||||
.find(
|
||||
doc! {
|
||||
"user_id": user_id,
|
||||
|
|
@ -98,7 +104,7 @@ impl SessionRepository {
|
|||
pub async fn revoke_all_for_user(&self, user_id: &ObjectId) -> Result<()> {
|
||||
self.collection
|
||||
.update_many(
|
||||
doc! {
|
||||
doc! {
|
||||
"user_id": user_id,
|
||||
"is_revoked": false
|
||||
},
|
||||
|
|
@ -110,7 +116,8 @@ impl SessionRepository {
|
|||
}
|
||||
|
||||
pub async fn cleanup_expired(&self) -> Result<u64> {
|
||||
let result = self.collection
|
||||
let result = self
|
||||
.collection
|
||||
.delete_many(
|
||||
doc! {
|
||||
"expires_at": { "$lt": mongodb::bson::DateTime::now() }
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use mongodb::bson::DateTime;
|
||||
use mongodb::bson::{doc, oid::ObjectId};
|
||||
use mongodb::Collection;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use mongodb::bson::DateTime;
|
||||
|
||||
use super::permission::Permission;
|
||||
|
||||
|
|
@ -42,7 +42,7 @@ impl Share {
|
|||
active: true,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub fn is_expired(&self) -> bool {
|
||||
if let Some(expires) = self.expires_at {
|
||||
DateTime::now() > expires
|
||||
|
|
@ -50,11 +50,11 @@ impl Share {
|
|||
false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub fn has_permission(&self, permission: &Permission) -> bool {
|
||||
self.permissions.contains(permission) || self.permissions.contains(&Permission::Admin)
|
||||
}
|
||||
|
||||
|
||||
pub fn revoke(&mut self) {
|
||||
self.active = false;
|
||||
}
|
||||
|
|
@ -69,19 +69,19 @@ impl ShareRepository {
|
|||
pub fn new(collection: Collection<Share>) -> Self {
|
||||
Self { collection }
|
||||
}
|
||||
|
||||
|
||||
pub async fn create(&self, share: &Share) -> mongodb::error::Result<Option<ObjectId>> {
|
||||
let result = self.collection.insert_one(share, None).await?;
|
||||
Ok(Some(result.inserted_id.as_object_id().unwrap()))
|
||||
}
|
||||
|
||||
|
||||
pub async fn find_by_id(&self, id: &ObjectId) -> mongodb::error::Result<Option<Share>> {
|
||||
self.collection.find_one(doc! { "_id": id }, None).await
|
||||
}
|
||||
|
||||
|
||||
pub async fn find_by_owner(&self, owner_id: &ObjectId) -> mongodb::error::Result<Vec<Share>> {
|
||||
use futures::stream::TryStreamExt;
|
||||
|
||||
|
||||
self.collection
|
||||
.find(doc! { "owner_id": owner_id }, None)
|
||||
.await?
|
||||
|
|
@ -89,27 +89,37 @@ impl ShareRepository {
|
|||
.await
|
||||
.map_err(|e| mongodb::error::Error::from(e))
|
||||
}
|
||||
|
||||
pub async fn find_by_target(&self, target_user_id: &ObjectId) -> mongodb::error::Result<Vec<Share>> {
|
||||
|
||||
pub async fn find_by_target(
|
||||
&self,
|
||||
target_user_id: &ObjectId,
|
||||
) -> mongodb::error::Result<Vec<Share>> {
|
||||
use futures::stream::TryStreamExt;
|
||||
|
||||
|
||||
self.collection
|
||||
.find(doc! { "target_user_id": target_user_id, "active": true }, None)
|
||||
.find(
|
||||
doc! { "target_user_id": target_user_id, "active": true },
|
||||
None,
|
||||
)
|
||||
.await?
|
||||
.try_collect()
|
||||
.await
|
||||
.map_err(|e| mongodb::error::Error::from(e))
|
||||
}
|
||||
|
||||
|
||||
pub async fn update(&self, share: &Share) -> mongodb::error::Result<()> {
|
||||
if let Some(id) = &share.id {
|
||||
self.collection.replace_one(doc! { "_id": id }, share, None).await?;
|
||||
self.collection
|
||||
.replace_one(doc! { "_id": id }, share, None)
|
||||
.await?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
pub async fn delete(&self, share_id: &ObjectId) -> mongodb::error::Result<()> {
|
||||
self.collection.delete_one(doc! { "_id": share_id }, None).await?;
|
||||
self.collection
|
||||
.delete_one(doc! { "_id": share_id }, None)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,18 +2,18 @@ use mongodb::bson::{doc, oid::ObjectId};
|
|||
use mongodb::Collection;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use mongodb::bson::DateTime;
|
||||
use crate::auth::password::verify_password;
|
||||
use mongodb::bson::DateTime;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct User {
|
||||
#[serde(rename = "_id", skip_serializing_if = "Option::is_none")]
|
||||
pub id: Option<ObjectId>,
|
||||
|
||||
|
||||
pub email: String,
|
||||
|
||||
|
||||
pub username: String,
|
||||
|
||||
|
||||
pub password_hash: String,
|
||||
|
||||
/// Password recovery phrase hash (zero-knowledge)
|
||||
|
|
@ -54,10 +54,10 @@ impl User {
|
|||
) -> Result<Self, anyhow::Error> {
|
||||
// Import PasswordService
|
||||
use crate::auth::password::PasswordService;
|
||||
|
||||
|
||||
// Hash the password
|
||||
let password_hash = PasswordService::hash_password(&password)?;
|
||||
|
||||
|
||||
// Hash the recovery phrase if provided
|
||||
let recovery_phrase_hash = if let Some(phrase) = recovery_phrase {
|
||||
Some(PasswordService::hash_password(&phrase)?)
|
||||
|
|
@ -94,7 +94,7 @@ impl User {
|
|||
if !self.recovery_enabled || self.recovery_phrase_hash.is_none() {
|
||||
return Ok(false);
|
||||
}
|
||||
|
||||
|
||||
let hash = self.recovery_phrase_hash.as_ref().unwrap();
|
||||
verify_password(phrase, hash)
|
||||
}
|
||||
|
|
@ -102,7 +102,7 @@ impl User {
|
|||
/// Update the password hash (increments token_version to invalidate all tokens)
|
||||
pub fn update_password(&mut self, new_password: String) -> Result<(), anyhow::Error> {
|
||||
use crate::auth::password::PasswordService;
|
||||
|
||||
|
||||
self.password_hash = PasswordService::hash_password(&new_password)?;
|
||||
self.token_version += 1;
|
||||
Ok(())
|
||||
|
|
@ -111,7 +111,7 @@ impl User {
|
|||
/// Set or update the recovery phrase
|
||||
pub fn set_recovery_phrase(&mut self, phrase: String) -> Result<(), anyhow::Error> {
|
||||
use crate::auth::password::PasswordService;
|
||||
|
||||
|
||||
self.recovery_phrase_hash = Some(PasswordService::hash_password(&phrase)?);
|
||||
self.recovery_enabled = true;
|
||||
Ok(())
|
||||
|
|
@ -156,13 +156,14 @@ impl UserRepository {
|
|||
|
||||
/// Find a user by ID
|
||||
pub async fn find_by_id(&self, id: &ObjectId) -> mongodb::error::Result<Option<User>> {
|
||||
self.collection
|
||||
.find_one(doc! { "_id": id }, None)
|
||||
.await
|
||||
self.collection.find_one(doc! { "_id": id }, None).await
|
||||
}
|
||||
|
||||
/// Find a user by verification token
|
||||
pub async fn find_by_verification_token(&self, token: &str) -> mongodb::error::Result<Option<User>> {
|
||||
pub async fn find_by_verification_token(
|
||||
&self,
|
||||
token: &str,
|
||||
) -> mongodb::error::Result<Option<User>> {
|
||||
self.collection
|
||||
.find_one(doc! { "verification_token": token }, None)
|
||||
.await
|
||||
|
|
@ -177,12 +178,16 @@ impl UserRepository {
|
|||
}
|
||||
|
||||
/// Update the token version - silently fails if ObjectId is invalid
|
||||
pub async fn update_token_version(&self, user_id: &str, version: i32) -> mongodb::error::Result<()> {
|
||||
pub async fn update_token_version(
|
||||
&self,
|
||||
user_id: &str,
|
||||
version: i32,
|
||||
) -> mongodb::error::Result<()> {
|
||||
let oid = match ObjectId::parse_str(user_id) {
|
||||
Ok(id) => id,
|
||||
Err(_) => return Ok(()), // Silently fail if invalid ObjectId
|
||||
};
|
||||
|
||||
|
||||
self.collection
|
||||
.update_one(
|
||||
doc! { "_id": oid },
|
||||
|
|
@ -204,7 +209,7 @@ impl UserRepository {
|
|||
/// Update last active timestamp
|
||||
pub async fn update_last_active(&self, user_id: &ObjectId) -> mongodb::error::Result<()> {
|
||||
use mongodb::bson::DateTime;
|
||||
|
||||
|
||||
let now = DateTime::now();
|
||||
self.collection
|
||||
.update_one(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue