diff --git a/services/identity/src/database.rs b/services/identity/src/database.rs --- a/services/identity/src/database.rs +++ b/services/identity/src/database.rs @@ -1043,10 +1043,11 @@ mut user: AttributeMap, get_one_time_keys: bool, ) -> Result, Error> { + let user_id: String = user.take_attr(USERS_TABLE_PARTITION_KEY)?; let devices: AttributeMap = user.take_attr(USERS_TABLE_DEVICES_ATTRIBUTE)?; - let mut devices_response = HashMap::with_capacity(devices.len()); + let mut devices_response = self.get_keys_for_user_devices(user_id).await?; for (device_id_key, device_info) in devices { let device_info_map = AttributeMap::try_from_attr(&device_id_key, Some(device_info))?; @@ -1062,6 +1063,15 @@ continue; } + // Excluding info already taken from device list response + if devices_response + .get(&device_id_key) + .map(|device| device.contains_key(&attribute_name)) + .unwrap_or(false) + { + continue; + } + let attribute_value_str = String::try_from_attr(&attribute_name, Some(attribute_value))?; device_info_string_map.insert(attribute_name, attribute_value_str); 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 @@ -21,6 +21,13 @@ constants::{ devices_table::{self, *}, USERS_TABLE, USERS_TABLE_DEVICELIST_TIMESTAMP_ATTRIBUTE_NAME, + USERS_TABLE_DEVICES_MAP_CONTENT_PREKEY_ATTRIBUTE_NAME, + USERS_TABLE_DEVICES_MAP_CONTENT_PREKEY_SIGNATURE_ATTRIBUTE_NAME, + USERS_TABLE_DEVICES_MAP_KEY_PAYLOAD_ATTRIBUTE_NAME, + USERS_TABLE_DEVICES_MAP_KEY_PAYLOAD_SIGNATURE_ATTRIBUTE_NAME, + USERS_TABLE_DEVICES_MAP_NOTIF_PREKEY_ATTRIBUTE_NAME, + USERS_TABLE_DEVICES_MAP_NOTIF_PREKEY_SIGNATURE_ATTRIBUTE_NAME, + USERS_TABLE_DEVICES_MAP_SOCIAL_PROOF_ATTRIBUTE_NAME, USERS_TABLE_PARTITION_KEY, }, ddb_utils::AttributesOptionExt, @@ -441,6 +448,62 @@ .map_err(Error::from) } + /// Returns all devices' keys for the given user. Response is in the same format + /// as [DatabaseClient::get_keys_for_user] for compatibility reasons. + pub async fn get_keys_for_user_devices( + &self, + user_id: impl Into, + ) -> Result { + let user_devices = self.get_current_devices(user_id).await?; + + let user_devices_keys: super::Devices = user_devices + .into_iter() + .map(|device| { + // convert this to the map type returned by DatabaseClient::get_keys_for_user + let mut device_keys: super::DeviceKeys = HashMap::from([ + ( + USERS_TABLE_DEVICES_MAP_KEY_PAYLOAD_ATTRIBUTE_NAME.to_string(), + device.device_key_info.key_payload, + ), + ( + USERS_TABLE_DEVICES_MAP_KEY_PAYLOAD_SIGNATURE_ATTRIBUTE_NAME + .to_string(), + device.device_key_info.key_payload_signature, + ), + ( + USERS_TABLE_DEVICES_MAP_CONTENT_PREKEY_ATTRIBUTE_NAME.to_string(), + device.content_prekey.pre_key, + ), + ( + USERS_TABLE_DEVICES_MAP_CONTENT_PREKEY_SIGNATURE_ATTRIBUTE_NAME + .to_string(), + device.content_prekey.pre_key_signature, + ), + ( + USERS_TABLE_DEVICES_MAP_NOTIF_PREKEY_ATTRIBUTE_NAME.to_string(), + device.notif_prekey.pre_key, + ), + ( + USERS_TABLE_DEVICES_MAP_NOTIF_PREKEY_SIGNATURE_ATTRIBUTE_NAME + .to_string(), + device.notif_prekey.pre_key_signature, + ), + ]); + + if let Some(social_proof) = device.device_key_info.social_proof { + device_keys.insert( + USERS_TABLE_DEVICES_MAP_SOCIAL_PROOF_ATTRIBUTE_NAME.to_string(), + social_proof, + ); + } + + (device.device_id, device_keys) + }) + .collect(); + + Ok(user_devices_keys) + } + pub async fn update_device_prekeys( &self, user_id: impl Into,