diff --git a/src/api/core/accounts.rs b/src/api/core/accounts.rs index 033a023b..473c0c86 100644 --- a/src/api/core/accounts.rs +++ b/src/api/core/accounts.rs @@ -1072,14 +1072,11 @@ impl<'r> FromRequest<'r> for KnownDevice { #[get("/devices")] async fn get_all_devices(headers: Headers, mut conn: DbConn) -> JsonResult { - let devices = Device::find_by_user(&headers.user.uuid, &mut conn).await; + let devices = Device::find_with_auth_request_by_user(&headers.user.uuid, &mut conn).await; + let devices = devices.iter().map(|device| device.to_json()).collect::>(); Ok(Json(json!({ - "data": devices - .iter() - .map(|device| { - device.to_json() - }).collect::>(), + "data": devices, "continuationToken": null, "object": "list" }))) diff --git a/src/db/models/auth_request.rs b/src/db/models/auth_request.rs index dd4f098a..2a93185e 100644 --- a/src/db/models/auth_request.rs +++ b/src/db/models/auth_request.rs @@ -1,8 +1,9 @@ use super::{DeviceId, OrganizationId, UserId}; -use crate::crypto::ct_eq; +use crate::{crypto::ct_eq, util::format_date}; use chrono::{NaiveDateTime, Utc}; use derive_more::{AsRef, Deref, Display, From}; use macros::UuidFromParam; +use serde_json::Value; db_object! { #[derive(Debug, Identifiable, Queryable, Insertable, AsChangeset, Deserialize, Serialize)] @@ -64,6 +65,13 @@ impl AuthRequest { authentication_date: None, } } + + pub fn to_json_for_pending_device(&self) -> Value { + json!({ + "id": self.uuid, + "creationDate": format_date(&self.creation_date), + }) + } } use crate::db::DbConn; @@ -133,6 +141,19 @@ impl AuthRequest { }} } + pub async fn find_by_user_and_requested_device( + user_uuid: &UserId, + device_uuid: &DeviceId, + conn: &mut DbConn, + ) -> Option { + db_run! {conn: { + auth_requests::table + .filter(auth_requests::user_uuid.eq(user_uuid)) + .filter(auth_requests::request_device_identifier.eq(device_uuid)) + .first::(conn).ok().from_db() + }} + } + pub async fn find_created_before(dt: &NaiveDateTime, conn: &mut DbConn) -> Vec { db_run! {conn: { auth_requests::table diff --git a/src/db/models/device.rs b/src/db/models/device.rs index 0569448d..74ef46d2 100644 --- a/src/db/models/device.rs +++ b/src/db/models/device.rs @@ -2,7 +2,7 @@ use chrono::{NaiveDateTime, Utc}; use derive_more::{Display, From}; use serde_json::Value; -use super::UserId; +use super::{AuthRequest, UserId}; use crate::{crypto, util::format_date, CONFIG}; use macros::IdFromParam; @@ -24,7 +24,6 @@ db_object! { pub push_token: Option, pub refresh_token: String, - pub twofactor_remember: Option, } } @@ -58,7 +57,6 @@ impl Device { "identifier": self.push_uuid, "creationDate": format_date(&self.created_at), "isTrusted": false, - "devicePendingAuthRequest": null, "object":"device" }) } @@ -139,6 +137,36 @@ impl Device { } } +pub struct DeviceWithAuthRequest { + pub device: Device, + pub pending_auth_request: Option, +} + +impl DeviceWithAuthRequest { + pub fn to_json(&self) -> Value { + let auth_request = match &self.pending_auth_request { + Some(auth_request) => auth_request.to_json_for_pending_device(), + None => Value::Null, + }; + json!({ + "id": self.device.uuid, + "name": self.device.name, + "type": self.device.atype, + "identifier": self.device.push_uuid, + "creationDate": format_date(&self.device.created_at), + "devicePendingAuthRequest": auth_request, + "isTrusted": false, + "object": "device", + }) + } + + pub fn from(c: Device, a: Option) -> Self { + Self { + device: c, + pending_auth_request: a, + } + } +} use crate::db::DbConn; use crate::api::EmptyResult; @@ -185,6 +213,16 @@ impl Device { }} } + pub async fn find_with_auth_request_by_user(user_uuid: &UserId, conn: &mut DbConn) -> Vec { + let devices = Self::find_by_user(user_uuid, conn).await; + let mut result = Vec::new(); + for device in devices { + let auth_request = AuthRequest::find_by_user_and_requested_device(user_uuid, &device.uuid, conn).await; + result.push(DeviceWithAuthRequest::from(device, auth_request)); + } + result + } + pub async fn find_by_user(user_uuid: &UserId, conn: &mut DbConn) -> Vec { db_run! { conn: { devices::table