mirror of
https://github.com/dani-garcia/vaultwarden.git
synced 2025-12-16 04:09:03 +00:00
allow saving device without updating updated_at
This commit is contained in:
parent
b953411dd5
commit
293e1b8beb
@ -1409,7 +1409,7 @@ async fn put_device_token(device_id: DeviceId, data: Json<PushToken>, headers: H
|
||||
}
|
||||
|
||||
device.push_token = Some(token);
|
||||
if let Err(e) = device.save(&conn).await {
|
||||
if let Err(e) = device.save(true, &conn).await {
|
||||
err!(format!("An error occurred while trying to save the device push token: {e}"));
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
use chrono::{NaiveDateTime, Utc};
|
||||
use chrono::Utc;
|
||||
use num_traits::FromPrimitive;
|
||||
use rocket::{
|
||||
form::{Form, FromForm},
|
||||
@ -147,7 +147,7 @@ async fn _refresh_login(data: ConnectData, conn: &DbConn, ip: &ClientIp) -> Json
|
||||
}
|
||||
Ok((mut device, auth_tokens)) => {
|
||||
// Save to update `device.updated_at` to track usage and toggle new status
|
||||
device.save(conn).await?;
|
||||
device.save(true, conn).await?;
|
||||
|
||||
let result = json!({
|
||||
"refresh_token": auth_tokens.refresh_token(),
|
||||
@ -267,9 +267,10 @@ async fn _sso_login(
|
||||
}
|
||||
Some((mut user, sso_user)) => {
|
||||
let mut device = get_device(&data, conn, &user).await?;
|
||||
|
||||
// Save to update `device.updated_at` to track usage and toggle new status
|
||||
device.save(conn).await?;
|
||||
if !device.is_new() {
|
||||
// Update `device.updated_at` only if it's not a new device
|
||||
device.save(true, conn).await?;
|
||||
}
|
||||
|
||||
let twofactor_token = twofactor_auth(&mut user, &data, &mut device, ip, client_version, conn).await?;
|
||||
|
||||
@ -317,7 +318,7 @@ async fn _sso_login(
|
||||
auth_user.expires_in,
|
||||
)?;
|
||||
|
||||
authenticated_response(&user, &mut device, auth_tokens, twofactor_token, &now, conn, ip).await
|
||||
authenticated_response(&user, &mut device, auth_tokens, twofactor_token, conn, ip).await
|
||||
}
|
||||
|
||||
async fn _password_login(
|
||||
@ -434,15 +435,16 @@ async fn _password_login(
|
||||
}
|
||||
|
||||
let mut device = get_device(&data, conn, &user).await?;
|
||||
|
||||
// Save to update `device.updated_at` to track usage and toggle new status
|
||||
device.save(conn).await?;
|
||||
if !device.is_new() {
|
||||
// Update `device.updated_at` only if it's not a new device
|
||||
device.save(true, conn).await?;
|
||||
}
|
||||
|
||||
let twofactor_token = twofactor_auth(&mut user, &data, &mut device, ip, client_version, conn).await?;
|
||||
|
||||
let auth_tokens = auth::AuthTokens::new(&device, &user, AuthMethod::Password, data.client_id);
|
||||
|
||||
authenticated_response(&user, &mut device, auth_tokens, twofactor_token, &now, conn, ip).await
|
||||
authenticated_response(&user, &mut device, auth_tokens, twofactor_token, conn, ip).await
|
||||
}
|
||||
|
||||
async fn authenticated_response(
|
||||
@ -450,12 +452,12 @@ async fn authenticated_response(
|
||||
device: &mut Device,
|
||||
auth_tokens: auth::AuthTokens,
|
||||
twofactor_token: Option<String>,
|
||||
now: &NaiveDateTime,
|
||||
conn: &DbConn,
|
||||
ip: &ClientIp,
|
||||
) -> JsonResult {
|
||||
if CONFIG.mail_enabled() && device.is_new() {
|
||||
if let Err(e) = mail::send_new_device_logged_in(&user.email, &ip.ip.to_string(), now, device).await {
|
||||
let now = Utc::now().naive_utc();
|
||||
if let Err(e) = mail::send_new_device_logged_in(&user.email, &ip.ip.to_string(), &now, device).await {
|
||||
error!("Error sending new device email: {e:#?}");
|
||||
|
||||
if CONFIG.require_device_email() {
|
||||
@ -475,7 +477,7 @@ async fn authenticated_response(
|
||||
}
|
||||
|
||||
// Save to update `device.updated_at` to track usage and toggle new status
|
||||
device.save(conn).await?;
|
||||
device.save(true, conn).await?;
|
||||
|
||||
let master_password_policy = master_password_policy(user, conn).await;
|
||||
|
||||
@ -592,7 +594,7 @@ async fn _user_api_key_login(
|
||||
let access_claims = auth::LoginJwtClaims::default(&device, &user, &AuthMethod::UserApiKey, data.client_id);
|
||||
|
||||
// Save to update `device.updated_at` to track usage and toggle new status
|
||||
device.save(conn).await?;
|
||||
device.save(true, conn).await?;
|
||||
|
||||
info!("User {} logged in successfully via API key. IP: {}", user.email, ip.ip);
|
||||
|
||||
@ -655,7 +657,12 @@ async fn get_device(data: &ConnectData, conn: &DbConn, user: &User) -> ApiResult
|
||||
// Find device or create new
|
||||
match Device::find_by_uuid_and_user(&device_id, &user.uuid, conn).await {
|
||||
Some(device) => Ok(device),
|
||||
None => Device::new(device_id, user.uuid.clone(), device_name, device_type, conn).await,
|
||||
None => {
|
||||
let mut device = Device::new(device_id, user.uuid.clone(), device_name, device_type);
|
||||
// save device without updating `device.updated_at`
|
||||
device.save(false, conn).await?;
|
||||
Ok(device)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -128,7 +128,7 @@ pub async fn register_push_device(device: &mut Device, conn: &DbConn) -> EmptyRe
|
||||
err!(format!("An error occurred while proceeding registration of a device: {e}"));
|
||||
}
|
||||
|
||||
if let Err(e) = device.save(conn).await {
|
||||
if let Err(e) = device.save(true, conn).await {
|
||||
err!(format!("An error occurred while trying to save the (registered) device push uuid: {e}"));
|
||||
}
|
||||
|
||||
|
||||
@ -1223,7 +1223,7 @@ pub async fn refresh_tokens(
|
||||
};
|
||||
|
||||
// Save to update `updated_at`.
|
||||
device.save(conn).await?;
|
||||
device.save(true, conn).await?;
|
||||
|
||||
let user = match User::find_by_uuid(&device.user_uuid, conn).await {
|
||||
None => err!("Impossible to find user"),
|
||||
|
||||
@ -35,6 +35,25 @@ pub struct Device {
|
||||
|
||||
/// Local methods
|
||||
impl Device {
|
||||
pub fn new(uuid: DeviceId, user_uuid: UserId, name: String, atype: i32) -> Self {
|
||||
let now = Utc::now().naive_utc();
|
||||
|
||||
Self {
|
||||
uuid,
|
||||
created_at: now,
|
||||
updated_at: now,
|
||||
|
||||
user_uuid,
|
||||
name,
|
||||
atype,
|
||||
|
||||
push_uuid: Some(PushId(get_uuid())),
|
||||
push_token: None,
|
||||
refresh_token: crypto::encode_random_bytes::<64>(&BASE64URL),
|
||||
twofactor_remember: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_json(&self) -> Value {
|
||||
json!({
|
||||
"id": self.uuid,
|
||||
@ -110,38 +129,21 @@ impl DeviceWithAuthRequest {
|
||||
}
|
||||
use crate::db::DbConn;
|
||||
|
||||
use crate::api::{ApiResult, EmptyResult};
|
||||
use crate::api::EmptyResult;
|
||||
use crate::error::MapResult;
|
||||
|
||||
/// Database methods
|
||||
impl Device {
|
||||
pub async fn new(uuid: DeviceId, user_uuid: UserId, name: String, atype: i32, conn: &DbConn) -> ApiResult<Device> {
|
||||
let now = Utc::now().naive_utc();
|
||||
pub async fn save(&mut self, update_time: bool, conn: &DbConn) -> EmptyResult {
|
||||
if update_time {
|
||||
self.updated_at = Utc::now().naive_utc();
|
||||
}
|
||||
|
||||
let device = Self {
|
||||
uuid,
|
||||
created_at: now,
|
||||
updated_at: now,
|
||||
|
||||
user_uuid,
|
||||
name,
|
||||
atype,
|
||||
|
||||
push_uuid: Some(PushId(get_uuid())),
|
||||
push_token: None,
|
||||
refresh_token: crypto::encode_random_bytes::<64>(&BASE64URL),
|
||||
twofactor_remember: None,
|
||||
};
|
||||
|
||||
device.inner_save(conn).await.map(|()| device)
|
||||
}
|
||||
|
||||
async fn inner_save(&self, conn: &DbConn) -> EmptyResult {
|
||||
db_run! { conn:
|
||||
sqlite, mysql {
|
||||
crate::util::retry(||
|
||||
diesel::replace_into(devices::table)
|
||||
.values(self)
|
||||
.values(&*self)
|
||||
.execute(conn),
|
||||
10,
|
||||
).map_res("Error saving device")
|
||||
@ -149,7 +151,7 @@ impl Device {
|
||||
postgresql {
|
||||
crate::util::retry(||
|
||||
diesel::insert_into(devices::table)
|
||||
.values(self)
|
||||
.values(&*self)
|
||||
.on_conflict((devices::uuid, devices::user_uuid))
|
||||
.do_update()
|
||||
.set(self)
|
||||
@ -160,12 +162,6 @@ impl Device {
|
||||
}
|
||||
}
|
||||
|
||||
// Should only be called after user has passed authentication
|
||||
pub async fn save(&mut self, conn: &DbConn) -> EmptyResult {
|
||||
self.updated_at = Utc::now().naive_utc();
|
||||
self.inner_save(conn).await
|
||||
}
|
||||
|
||||
pub async fn delete_all_by_user(user_uuid: &UserId, conn: &DbConn) -> EmptyResult {
|
||||
db_run! { conn: {
|
||||
diesel::delete(devices::table.filter(devices::user_uuid.eq(user_uuid)))
|
||||
|
||||
Loading…
Reference in New Issue
Block a user