fix: update user timestamp after data modifications
This commit is contained in:
parent
ae6d52a638
commit
eb64650594
4 changed files with 46 additions and 3 deletions
19
src/db.rs
19
src/db.rs
|
|
@ -1,11 +1,28 @@
|
||||||
use crate::error::AppError;
|
use crate::error::AppError;
|
||||||
|
use chrono::Utc;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use worker::{D1Database, D1PreparedStatement, Env};
|
use worker::{query, D1Database, D1PreparedStatement, Env};
|
||||||
|
|
||||||
pub fn get_db(env: &Arc<Env>) -> Result<D1Database, AppError> {
|
pub fn get_db(env: &Arc<Env>) -> Result<D1Database, AppError> {
|
||||||
env.d1("vault1").map_err(AppError::Worker)
|
env.d1("vault1").map_err(AppError::Worker)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Update the user's `updated_at` field to the current timestamp.
|
||||||
|
/// This should be called after any operation that modifies user data (ciphers, folders, etc.)
|
||||||
|
pub async fn touch_user_updated_at(db: &D1Database, user_id: &str) -> Result<(), AppError> {
|
||||||
|
let now = Utc::now().format("%Y-%m-%dT%H:%M:%S%.3fZ").to_string();
|
||||||
|
query!(
|
||||||
|
db,
|
||||||
|
"UPDATE users SET updated_at = ?1 WHERE id = ?2",
|
||||||
|
now,
|
||||||
|
user_id
|
||||||
|
)
|
||||||
|
.map_err(|_| AppError::Database)?
|
||||||
|
.run()
|
||||||
|
.await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// Execute D1 statements in batches, allowing batch_size 0 to run everything at once.
|
/// Execute D1 statements in batches, allowing batch_size 0 to run everything at once.
|
||||||
pub async fn execute_in_batches(
|
pub async fn execute_in_batches(
|
||||||
db: &D1Database,
|
db: &D1Database,
|
||||||
|
|
|
||||||
|
|
@ -79,6 +79,8 @@ pub async fn create_cipher(
|
||||||
.run()
|
.run()
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
db::touch_user_updated_at(&db, &claims.sub).await?;
|
||||||
|
|
||||||
Ok(Json(cipher))
|
Ok(Json(cipher))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -155,6 +157,8 @@ pub async fn update_cipher(
|
||||||
.run()
|
.run()
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
db::touch_user_updated_at(&db, &claims.sub).await?;
|
||||||
|
|
||||||
Ok(Json(cipher))
|
Ok(Json(cipher))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -187,6 +191,8 @@ pub async fn soft_delete_cipher(
|
||||||
.run()
|
.run()
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
db::touch_user_updated_at(&db, &claims.sub).await?;
|
||||||
|
|
||||||
Ok(Json(()))
|
Ok(Json(()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -217,6 +223,8 @@ pub async fn soft_delete_ciphers_bulk(
|
||||||
|
|
||||||
db::execute_in_batches(&db, statements, batch_size).await?;
|
db::execute_in_batches(&db, statements, batch_size).await?;
|
||||||
|
|
||||||
|
db::touch_user_updated_at(&db, &claims.sub).await?;
|
||||||
|
|
||||||
Ok(Json(()))
|
Ok(Json(()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -240,6 +248,8 @@ pub async fn hard_delete_cipher(
|
||||||
.run()
|
.run()
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
db::touch_user_updated_at(&db, &claims.sub).await?;
|
||||||
|
|
||||||
Ok(Json(()))
|
Ok(Json(()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -268,6 +278,8 @@ pub async fn hard_delete_ciphers_bulk(
|
||||||
|
|
||||||
db::execute_in_batches(&db, statements, batch_size).await?;
|
db::execute_in_batches(&db, statements, batch_size).await?;
|
||||||
|
|
||||||
|
db::touch_user_updated_at(&db, &claims.sub).await?;
|
||||||
|
|
||||||
Ok(Json(()))
|
Ok(Json(()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -306,6 +318,8 @@ pub async fn restore_cipher(
|
||||||
.await?
|
.await?
|
||||||
.ok_or(AppError::NotFound("Cipher not found".to_string()))?;
|
.ok_or(AppError::NotFound("Cipher not found".to_string()))?;
|
||||||
|
|
||||||
|
db::touch_user_updated_at(&db, &claims.sub).await?;
|
||||||
|
|
||||||
Ok(Json(cipher_db.into()))
|
Ok(Json(cipher_db.into()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -364,6 +378,8 @@ pub async fn restore_ciphers_bulk(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
db::touch_user_updated_at(&db, &claims.sub).await?;
|
||||||
|
|
||||||
Ok(Json(BulkRestoreResponse {
|
Ok(Json(BulkRestoreResponse {
|
||||||
data: restored_ciphers,
|
data: restored_ciphers,
|
||||||
object: "list".to_string(),
|
object: "list".to_string(),
|
||||||
|
|
@ -435,5 +451,7 @@ pub async fn create_cipher_simple(
|
||||||
.run()
|
.run()
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
db::touch_user_updated_at(&db, &claims.sub).await?;
|
||||||
|
|
||||||
Ok(Json(cipher))
|
Ok(Json(cipher))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ use uuid::Uuid;
|
||||||
use worker::{query, Env};
|
use worker::{query, Env};
|
||||||
|
|
||||||
use crate::auth::Claims;
|
use crate::auth::Claims;
|
||||||
use crate::db;
|
use crate::db::{self, touch_user_updated_at};
|
||||||
use crate::error::AppError;
|
use crate::error::AppError;
|
||||||
use crate::models::folder::{CreateFolderRequest, Folder, FolderResponse};
|
use crate::models::folder::{CreateFolderRequest, Folder, FolderResponse};
|
||||||
use axum::extract::Path;
|
use axum::extract::Path;
|
||||||
|
|
@ -41,6 +41,8 @@ pub async fn create_folder(
|
||||||
.run()
|
.run()
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
touch_user_updated_at(&db, &claims.sub).await?;
|
||||||
|
|
||||||
let response = FolderResponse {
|
let response = FolderResponse {
|
||||||
id: folder.id,
|
id: folder.id,
|
||||||
name: folder.name,
|
name: folder.name,
|
||||||
|
|
@ -69,6 +71,8 @@ pub async fn delete_folder(
|
||||||
.run()
|
.run()
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
touch_user_updated_at(&db, &claims.sub).await?;
|
||||||
|
|
||||||
Ok(Json(()))
|
Ok(Json(()))
|
||||||
}
|
}
|
||||||
#[worker::send]
|
#[worker::send]
|
||||||
|
|
@ -113,6 +117,8 @@ pub async fn update_folder(
|
||||||
.run()
|
.run()
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
touch_user_updated_at(&db, &claims.sub).await?;
|
||||||
|
|
||||||
let response = FolderResponse {
|
let response = FolderResponse {
|
||||||
id: folder.id,
|
id: folder.id,
|
||||||
name: folder.name,
|
name: folder.name,
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ use uuid::Uuid;
|
||||||
use worker::{query, D1PreparedStatement, Env};
|
use worker::{query, D1PreparedStatement, Env};
|
||||||
|
|
||||||
use crate::auth::Claims;
|
use crate::auth::Claims;
|
||||||
use crate::db;
|
use crate::db::{self, touch_user_updated_at};
|
||||||
use crate::error::AppError;
|
use crate::error::AppError;
|
||||||
use crate::models::cipher::{Cipher, CipherData};
|
use crate::models::cipher::{Cipher, CipherData};
|
||||||
use crate::models::folder::Folder;
|
use crate::models::folder::Folder;
|
||||||
|
|
@ -125,5 +125,7 @@ pub async fn import_data(
|
||||||
// Execute cipher inserts in batches
|
// Execute cipher inserts in batches
|
||||||
db::execute_in_batches(&db, cipher_statements, batch_size).await?;
|
db::execute_in_batches(&db, cipher_statements, batch_size).await?;
|
||||||
|
|
||||||
|
touch_user_updated_at(&db, &claims.sub).await?;
|
||||||
|
|
||||||
Ok(Json(()))
|
Ok(Json(()))
|
||||||
}
|
}
|
||||||
Loading…
Reference in a new issue