diff --git a/keyserver/addons/rust-node-addon/src/identity_client/login.rs b/keyserver/addons/rust-node-addon/src/identity_client/login.rs --- a/keyserver/addons/rust-node-addon/src/identity_client/login.rs +++ b/keyserver/addons/rust-node-addon/src/identity_client/login.rs @@ -48,6 +48,7 @@ }), onetime_content_prekeys: content_one_time_keys, onetime_notif_prekeys: notif_one_time_keys, + device_type: DeviceType::Keyserver.into(), }), }; diff --git a/keyserver/addons/rust-node-addon/src/identity_client/mod.rs b/keyserver/addons/rust-node-addon/src/identity_client/mod.rs --- a/keyserver/addons/rust-node-addon/src/identity_client/mod.rs +++ b/keyserver/addons/rust-node-addon/src/identity_client/mod.rs @@ -10,8 +10,8 @@ use identity_client::identity_client_service_client::IdentityClientServiceClient; use identity_client::{ - AddReservedUsernamesRequest, DeviceKeyUpload, IdentityKeyInfo, PreKey, - RegistrationFinishRequest, RegistrationStartRequest, + AddReservedUsernamesRequest, DeviceKeyUpload, DeviceType, IdentityKeyInfo, + PreKey, RegistrationFinishRequest, RegistrationStartRequest, RemoveReservedUsernameRequest, }; use lazy_static::lazy_static; diff --git a/keyserver/addons/rust-node-addon/src/identity_client/register_user.rs b/keyserver/addons/rust-node-addon/src/identity_client/register_user.rs --- a/keyserver/addons/rust-node-addon/src/identity_client/register_user.rs +++ b/keyserver/addons/rust-node-addon/src/identity_client/register_user.rs @@ -42,6 +42,7 @@ }), onetime_content_prekeys: content_one_time_keys, onetime_notif_prekeys: notif_one_time_keys, + device_type: DeviceType::Keyserver.into(), }; let registration_start_request = Request::new(RegistrationStartRequest { opaque_registration_request, diff --git a/native/native_rust_library/src/lib.rs b/native/native_rust_library/src/lib.rs --- a/native/native_rust_library/src/lib.rs +++ b/native/native_rust_library/src/lib.rs @@ -18,7 +18,7 @@ use crypto_tools::generate_device_id; use identity::identity_client_service_client::IdentityClientServiceClient; use identity::{ - DeviceKeyUpload, IdentityKeyInfo, OpaqueLoginFinishRequest, + DeviceKeyUpload, DeviceType, IdentityKeyInfo, OpaqueLoginFinishRequest, OpaqueLoginStartRequest, PreKey, RegistrationFinishRequest, RegistrationStartRequest, WalletLoginRequest, }; @@ -231,6 +231,7 @@ }), onetime_content_prekeys: password_user_info.content_onetime_keys, onetime_notif_prekeys: password_user_info.notif_onetime_keys, + device_type: DeviceType::Native.into(), }), }; @@ -321,6 +322,7 @@ }), onetime_content_prekeys: password_user_info.content_onetime_keys, onetime_notif_prekeys: password_user_info.notif_onetime_keys, + device_type: DeviceType::Native.into(), }), }; @@ -420,6 +422,7 @@ }), onetime_content_prekeys: wallet_user_info.content_onetime_keys, onetime_notif_prekeys: wallet_user_info.notif_onetime_keys, + device_type: DeviceType::Native.into(), }), }; diff --git a/services/commtest/src/identity/device.rs b/services/commtest/src/identity/device.rs --- a/services/commtest/src/identity/device.rs +++ b/services/commtest/src/identity/device.rs @@ -5,7 +5,8 @@ } use proto::{ identity_client_service_client::IdentityClientServiceClient, DeviceKeyUpload, - IdentityKeyInfo, PreKey, RegistrationFinishRequest, RegistrationStartRequest, + DeviceType, IdentityKeyInfo, PreKey, RegistrationFinishRequest, + RegistrationStartRequest, }; pub struct DeviceInfo { @@ -50,6 +51,7 @@ }), onetime_content_prekeys: Vec::new(), onetime_notif_prekeys: Vec::new(), + device_type: DeviceType::Keyserver.into(), }), }; diff --git a/services/identity/src/client_service.rs b/services/identity/src/client_service.rs --- a/services/identity/src/client_service.rs +++ b/services/identity/src/client_service.rs @@ -4,6 +4,7 @@ use std::str::FromStr; +use crate::database::{self, Device}; use crate::error::Error as DBError; use crate::{ client_service::client_proto::{ @@ -80,6 +81,7 @@ pub notif_prekey: String, pub notif_prekey_signature: String, pub notif_onetime_keys: Vec, + pub device_type: database::Device, } #[derive(derive_more::Constructor)] @@ -139,6 +141,7 @@ }), onetime_content_prekeys, onetime_notif_prekeys, + device_type, }), } = message { @@ -160,6 +163,8 @@ notif_prekey, notif_prekey_signature, notif_onetime_keys: onetime_notif_prekeys, + device_type: Device::try_from(device_type) + .map_err(handle_db_error)?, }, }; let session_id = generate_uuid(); @@ -238,6 +243,7 @@ }), onetime_content_prekeys, onetime_notif_prekeys, + device_type, }), .. } = message @@ -260,8 +266,11 @@ notif_prekey, notif_prekey_signature, notif_onetime_keys: onetime_notif_prekeys, + device_type: Device::try_from(device_type) + .map_err(handle_db_error)?, }, }; + let session_id = generate_uuid(); self .cache @@ -470,6 +479,7 @@ }), onetime_content_prekeys, onetime_notif_prekeys, + device_type, }), } = message { @@ -498,6 +508,8 @@ notif_prekey, notif_prekey_signature, notif_onetime_keys: onetime_notif_prekeys, + device_type: Device::try_from(device_type) + .map_err(handle_db_error)?, }, }; let session_id = generate_uuid(); @@ -602,6 +614,7 @@ }), onetime_content_prekeys, onetime_notif_prekeys, + device_type, }), } = message { @@ -618,6 +631,8 @@ notif_prekey, notif_prekey_signature, notif_onetime_keys: onetime_notif_prekeys, + device_type: Device::try_from(device_type) + .map_err(handle_db_error)?, }, social_proof, ) 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 @@ -66,16 +66,38 @@ } } +#[derive(Clone, Copy)] pub enum Device { - Client, - Keyserver, + // Numeric values should match the protobuf definition + Keyserver = 0, + Native, + Web, +} + +impl TryFrom for Device { + type Error = crate::error::Error; + + fn try_from(value: i32) -> Result { + match value { + 0 => Ok(Device::Keyserver), + 1 => Ok(Device::Native), + 2 => Ok(Device::Web), + _ => Err(Error::Attribute(DBItemError { + attribute_name: USERS_TABLE_DEVICES_MAP_DEVICE_TYPE_ATTRIBUTE_NAME + .to_string(), + attribute_value: Some(AttributeValue::N(value.to_string())), + attribute_error: DBItemAttributeError::InvalidValue, + })), + } + } } impl Display for Device { fn fmt(&self, f: &mut Formatter) -> FmtResult { match self { - Device::Client => write!(f, "client"), Device::Keyserver => write!(f, "keyserver"), + Device::Native => write!(f, "native"), + Device::Web => write!(f, "web"), } } } @@ -1001,7 +1023,7 @@ let mut device_info = HashMap::from([ ( USERS_TABLE_DEVICES_MAP_DEVICE_TYPE_ATTRIBUTE_NAME.to_string(), - AttributeValue::S(Device::Client.to_string()), + AttributeValue::S(flattened_device_key_upload.device_type.to_string()), ), ( USERS_TABLE_DEVICES_MAP_KEY_PAYLOAD_ATTRIBUTE_NAME.to_string(), 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 @@ -48,4 +48,6 @@ IncorrectType, #[display(...)] InvalidTimestamp(chrono::ParseError), + #[display(...)] + InvalidValue, } diff --git a/shared/protos/identity_client.proto b/shared/protos/identity_client.proto --- a/shared/protos/identity_client.proto +++ b/shared/protos/identity_client.proto @@ -104,6 +104,12 @@ // One-time Prekeys are "consumed" after first use, so many need to // be provide to avoid exhausting them. +enum DeviceType { + Keyserver = 0; + Native = 1; + Web = 2; +} + // Bundle of information needed for creating an initial message using X3DH message DeviceKeyUpload { IdentityKeyInfo deviceKeyInfo = 1; @@ -111,6 +117,7 @@ PreKey notifUpload = 3; repeated string onetimeContentPrekeys = 4; repeated string onetimeNotifPrekeys = 5; + DeviceType deviceType = 6; } // Request for registering a new user