diff --git a/services/identity/src/database/device_list.rs b/services/identity/src/database/device_list.rs --- a/services/identity/src/database/device_list.rs +++ b/services/identity/src/database/device_list.rs @@ -746,6 +746,57 @@ Ok(user_devices_keys) } + #[tracing::instrument(skip_all)] + pub async fn find_device_by_id( + &self, + device_id: &str, + ) -> Result, Error> { + let response = self + .client + .query() + .table_name(devices_table::NAME) + .index_name(devices_table::DEVICE_ID_INDEX_NAME) + .key_condition_expression("#item_id = :device_id_attr") + .expression_attribute_names("#item_id", devices_table::ATTR_ITEM_ID) + .expression_attribute_values( + ":device_id_attr", + DeviceIDAttribute(device_id.to_string()).into(), + ) + .send() + .await + .map_err(|err| { + error!( + errorType = error_types::DEVICE_LIST_DB_LOG, + "Failed to query for device ID: {:?}", err + ); + Error::AwsSdk(err.into()) + })?; + + let Some(mut results) = response.items else { + debug!("Query by deviceID returned empty response"); + return Ok(None); + }; + + if results.len() > 1 { + error!( + errorType = error_types::DEVICE_LIST_DB_LOG, + "Devices table contains more than one device with ID: {}", device_id + ); + return Err(Error::IllegalState); + } + + let Some(user_id) = results + .pop() + .map(|mut attrs| attrs.take_attr::(devices_table::ATTR_USER_ID)) + .transpose()? + else { + debug!("No device found with ID: {}", device_id); + return Ok(None); + }; + + self.get_device_data(user_id, device_id).await + } + #[tracing::instrument(skip_all)] pub async fn update_device_prekeys( &self, diff --git a/services/identity/src/error.rs b/services/identity/src/error.rs --- a/services/identity/src/error.rs +++ b/services/identity/src/error.rs @@ -29,6 +29,8 @@ #[display(...)] MaxRetriesExceeded, #[display(...)] + IllegalState, + #[display(...)] InvalidFormat, #[display(...)] NotEnoughOneTimeKeys,