diff --git a/native/native_rust_library/src/identity.rs b/native/native_rust_library/src/identity.rs --- a/native/native_rust_library/src/identity.rs +++ b/native/native_rust_library/src/identity.rs @@ -1,5 +1,6 @@ use grpc_clients::identity::get_unauthenticated_client; -use grpc_clients::identity::protos::unauth::Empty; +use grpc_clients::identity::protos::unauth::{AuthResponse, Empty}; +use serde::Serialize; use crate::utils::jsi_callbacks::{ handle_bool_result_as_callback, handle_string_result_as_callback, @@ -9,14 +10,14 @@ pub mod exact_user_search; pub mod farcaster; -pub mod wallet_registration; +pub mod registration; pub mod ffi { use super::*; pub use exact_user_search::ffi::*; pub use farcaster::ffi::*; - pub use wallet_registration::ffi::*; + pub use registration::ffi::*; pub fn generate_nonce(promise_id: u32) { RUNTIME.spawn(async move { @@ -33,6 +34,65 @@ } } +// helper structs + +pub struct AuthInfo { + pub user_id: String, + pub device_id: String, + pub access_token: String, +} + +pub struct PasswordUserInfo { + pub username: String, + pub password: String, + pub key_payload: String, + pub key_payload_signature: String, + pub content_prekey: String, + pub content_prekey_signature: String, + pub notif_prekey: String, + pub notif_prekey_signature: String, + pub content_one_time_keys: Vec, + pub notif_one_time_keys: Vec, + pub farcaster_id: Option, +} + +pub struct WalletUserInfo { + pub siwe_message: String, + pub siwe_signature: String, + pub key_payload: String, + pub key_payload_signature: String, + pub content_prekey: String, + pub content_prekey_signature: String, + pub notif_prekey: String, + pub notif_prekey_signature: String, + pub content_one_time_keys: Vec, + pub notif_one_time_keys: Vec, + pub farcaster_id: Option, +} + +#[derive(Serialize)] +#[serde(rename_all = "camelCase")] +pub struct UserIDAndDeviceAccessToken { + #[serde(rename = "userID")] + user_id: String, + access_token: String, +} + +impl From for UserIDAndDeviceAccessToken { + fn from(value: AuthResponse) -> Self { + let AuthResponse { + user_id, + access_token, + } = value; + Self { + user_id, + access_token, + } + } +} + +// API implementation helpers + async fn fetch_nonce() -> Result { let mut identity_client = get_unauthenticated_client( IDENTITY_SOCKET_ADDR, diff --git a/native/native_rust_library/src/identity/registration.rs b/native/native_rust_library/src/identity/registration.rs new file mode 100644 --- /dev/null +++ b/native/native_rust_library/src/identity/registration.rs @@ -0,0 +1,200 @@ +use crate::{ + utils::jsi_callbacks::handle_string_result_as_callback, Error, CODE_VERSION, + DEVICE_TYPE, IDENTITY_SOCKET_ADDR, RUNTIME, +}; +use comm_opaque2::client::Registration; +use grpc_clients::identity::{ + get_unauthenticated_client, + protos::unauth::{ + DeviceKeyUpload, IdentityKeyInfo, Prekey, RegistrationFinishRequest, + RegistrationStartRequest, WalletAuthRequest, + }, +}; +use tracing::instrument; + +use super::{ + farcaster::farcaster_id_string_to_option, PasswordUserInfo, + UserIDAndDeviceAccessToken, WalletUserInfo, +}; + +pub mod ffi { + use super::*; + + #[instrument] + pub fn register_password_user( + username: String, + password: String, + key_payload: String, + key_payload_signature: String, + content_prekey: String, + content_prekey_signature: String, + notif_prekey: String, + notif_prekey_signature: String, + content_one_time_keys: Vec, + notif_one_time_keys: Vec, + farcaster_id: String, + promise_id: u32, + ) { + RUNTIME.spawn(async move { + let password_user_info = PasswordUserInfo { + username, + password, + key_payload, + key_payload_signature, + content_prekey, + content_prekey_signature, + notif_prekey, + notif_prekey_signature, + content_one_time_keys, + notif_one_time_keys, + farcaster_id: farcaster_id_string_to_option(&farcaster_id), + }; + let result = register_password_user_helper(password_user_info).await; + handle_string_result_as_callback(result, promise_id); + }); + } + + #[instrument] + pub fn register_wallet_user( + siwe_message: String, + siwe_signature: String, + key_payload: String, + key_payload_signature: String, + content_prekey: String, + content_prekey_signature: String, + notif_prekey: String, + notif_prekey_signature: String, + content_one_time_keys: Vec, + notif_one_time_keys: Vec, + farcaster_id: String, + promise_id: u32, + ) { + RUNTIME.spawn(async move { + let wallet_user_info = WalletUserInfo { + siwe_message, + siwe_signature, + key_payload, + key_payload_signature, + content_prekey, + content_prekey_signature, + notif_prekey, + notif_prekey_signature, + content_one_time_keys, + notif_one_time_keys, + farcaster_id: farcaster_id_string_to_option(&farcaster_id), + }; + let result = register_wallet_user_helper(wallet_user_info).await; + handle_string_result_as_callback(result, promise_id); + }); + } +} + +async fn register_password_user_helper( + password_user_info: PasswordUserInfo, +) -> Result { + let mut client_registration = Registration::new(); + let opaque_registration_request = client_registration + .start(&password_user_info.password) + .map_err(crate::handle_error)?; + let registration_start_request = RegistrationStartRequest { + opaque_registration_request, + username: password_user_info.username, + device_key_upload: Some(DeviceKeyUpload { + device_key_info: Some(IdentityKeyInfo { + payload: password_user_info.key_payload, + payload_signature: password_user_info.key_payload_signature, + social_proof: None, + }), + content_upload: Some(Prekey { + prekey: password_user_info.content_prekey, + prekey_signature: password_user_info.content_prekey_signature, + }), + notif_upload: Some(Prekey { + prekey: password_user_info.notif_prekey, + prekey_signature: password_user_info.notif_prekey_signature, + }), + one_time_content_prekeys: password_user_info.content_one_time_keys, + one_time_notif_prekeys: password_user_info.notif_one_time_keys, + device_type: DEVICE_TYPE.into(), + }), + farcaster_id: password_user_info.farcaster_id, + }; + + let mut identity_client = get_unauthenticated_client( + IDENTITY_SOCKET_ADDR, + CODE_VERSION, + DEVICE_TYPE.as_str_name().to_lowercase(), + ) + .await?; + let response = identity_client + .register_password_user_start(registration_start_request) + .await?; + + let registration_start_response = response.into_inner(); + + let opaque_registration_upload = client_registration + .finish( + &password_user_info.password, + ®istration_start_response.opaque_registration_response, + ) + .map_err(crate::handle_error)?; + + let registration_finish_request = RegistrationFinishRequest { + session_id: registration_start_response.session_id, + opaque_registration_upload, + }; + + let registration_finish_response = identity_client + .register_password_user_finish(registration_finish_request) + .await? + .into_inner(); + let user_id_and_access_token = + UserIDAndDeviceAccessToken::from(registration_finish_response); + Ok(serde_json::to_string(&user_id_and_access_token)?) +} + +async fn register_wallet_user_helper( + wallet_user_info: WalletUserInfo, +) -> Result { + let registration_request = WalletAuthRequest { + siwe_message: wallet_user_info.siwe_message, + siwe_signature: wallet_user_info.siwe_signature, + device_key_upload: Some(DeviceKeyUpload { + device_key_info: Some(IdentityKeyInfo { + payload: wallet_user_info.key_payload, + payload_signature: wallet_user_info.key_payload_signature, + social_proof: None, // The SIWE message and signature are the social proof + }), + content_upload: Some(Prekey { + prekey: wallet_user_info.content_prekey, + prekey_signature: wallet_user_info.content_prekey_signature, + }), + notif_upload: Some(Prekey { + prekey: wallet_user_info.notif_prekey, + prekey_signature: wallet_user_info.notif_prekey_signature, + }), + one_time_content_prekeys: wallet_user_info.content_one_time_keys, + one_time_notif_prekeys: wallet_user_info.notif_one_time_keys, + device_type: DEVICE_TYPE.into(), + }), + farcaster_id: wallet_user_info.farcaster_id, + }; + + let mut identity_client = get_unauthenticated_client( + IDENTITY_SOCKET_ADDR, + CODE_VERSION, + DEVICE_TYPE.as_str_name().to_lowercase(), + ) + .await?; + + let registration_response = identity_client + .register_wallet_user(registration_request) + .await? + .into_inner(); + + let user_id_and_access_token = UserIDAndDeviceAccessToken { + user_id: registration_response.user_id, + access_token: registration_response.access_token, + }; + Ok(serde_json::to_string(&user_id_and_access_token)?) +} diff --git a/native/native_rust_library/src/identity/wallet_registration.rs b/native/native_rust_library/src/identity/wallet_registration.rs deleted file mode 100644 --- a/native/native_rust_library/src/identity/wallet_registration.rs +++ /dev/null @@ -1,97 +0,0 @@ -use crate::{ - identity::farcaster::farcaster_id_string_to_option, - utils::jsi_callbacks::handle_string_result_as_callback, Error, - UserIDAndDeviceAccessToken, WalletUserInfo, CODE_VERSION, DEVICE_TYPE, - IDENTITY_SOCKET_ADDR, RUNTIME, -}; -use grpc_clients::identity::{ - get_unauthenticated_client, - protos::unauth::{ - DeviceKeyUpload, IdentityKeyInfo, Prekey, WalletAuthRequest, - }, -}; -use tracing::instrument; - -pub mod ffi { - use super::*; - - #[instrument] - pub fn register_wallet_user( - siwe_message: String, - siwe_signature: String, - key_payload: String, - key_payload_signature: String, - content_prekey: String, - content_prekey_signature: String, - notif_prekey: String, - notif_prekey_signature: String, - content_one_time_keys: Vec, - notif_one_time_keys: Vec, - farcaster_id: String, - promise_id: u32, - ) { - RUNTIME.spawn(async move { - let wallet_user_info = WalletUserInfo { - siwe_message, - siwe_signature, - key_payload, - key_payload_signature, - content_prekey, - content_prekey_signature, - notif_prekey, - notif_prekey_signature, - content_one_time_keys, - notif_one_time_keys, - farcaster_id: farcaster_id_string_to_option(&farcaster_id), - }; - let result = register_wallet_user_helper(wallet_user_info).await; - handle_string_result_as_callback(result, promise_id); - }); - } -} - -async fn register_wallet_user_helper( - wallet_user_info: WalletUserInfo, -) -> Result { - let registration_request = WalletAuthRequest { - siwe_message: wallet_user_info.siwe_message, - siwe_signature: wallet_user_info.siwe_signature, - device_key_upload: Some(DeviceKeyUpload { - device_key_info: Some(IdentityKeyInfo { - payload: wallet_user_info.key_payload, - payload_signature: wallet_user_info.key_payload_signature, - social_proof: None, // The SIWE message and signature are the social proof - }), - content_upload: Some(Prekey { - prekey: wallet_user_info.content_prekey, - prekey_signature: wallet_user_info.content_prekey_signature, - }), - notif_upload: Some(Prekey { - prekey: wallet_user_info.notif_prekey, - prekey_signature: wallet_user_info.notif_prekey_signature, - }), - one_time_content_prekeys: wallet_user_info.content_one_time_keys, - one_time_notif_prekeys: wallet_user_info.notif_one_time_keys, - device_type: DEVICE_TYPE.into(), - }), - farcaster_id: wallet_user_info.farcaster_id, - }; - - let mut identity_client = get_unauthenticated_client( - IDENTITY_SOCKET_ADDR, - CODE_VERSION, - DEVICE_TYPE.as_str_name().to_lowercase(), - ) - .await?; - - let registration_response = identity_client - .register_wallet_user(registration_request) - .await? - .into_inner(); - - let user_id_and_access_token = UserIDAndDeviceAccessToken { - user_id: registration_response.user_id, - access_token: registration_response.access_token, - }; - Ok(serde_json::to_string(&user_id_and_access_token)?) -} 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 @@ -10,9 +10,8 @@ UploadOneTimeKeysRequest, }; use grpc_clients::identity::protos::unauth::{ - AuthResponse, DeviceKeyUpload, DeviceType, Empty, IdentityKeyInfo, + DeviceKeyUpload, DeviceType, Empty, IdentityKeyInfo, OpaqueLoginFinishRequest, OpaqueLoginStartRequest, Prekey, - RegistrationFinishRequest, RegistrationStartRequest, SecondaryDeviceKeysUploadRequest, WalletAuthRequest, }; use grpc_clients::identity::{get_auth_client, get_unauthenticated_client}; @@ -30,7 +29,9 @@ mod utils; use crate::argon2_tools::compute_backup_key_str; -use crate::identity::farcaster::farcaster_id_string_to_option; +use crate::identity::{ + AuthInfo, PasswordUserInfo, UserIDAndDeviceAccessToken, WalletUserInfo, +}; use crate::utils::jsi_callbacks::{ handle_string_result_as_callback, handle_void_result_as_callback, }; @@ -469,145 +470,6 @@ Ok(serde_json::to_string(&keyserver_keys)?) } -struct AuthInfo { - user_id: String, - device_id: String, - access_token: String, -} - -#[instrument] -fn register_password_user( - username: String, - password: String, - key_payload: String, - key_payload_signature: String, - content_prekey: String, - content_prekey_signature: String, - notif_prekey: String, - notif_prekey_signature: String, - content_one_time_keys: Vec, - notif_one_time_keys: Vec, - farcaster_id: String, - promise_id: u32, -) { - RUNTIME.spawn(async move { - let password_user_info = PasswordUserInfo { - username, - password, - key_payload, - key_payload_signature, - content_prekey, - content_prekey_signature, - notif_prekey, - notif_prekey_signature, - content_one_time_keys, - notif_one_time_keys, - farcaster_id: farcaster_id_string_to_option(&farcaster_id), - }; - let result = register_password_user_helper(password_user_info).await; - handle_string_result_as_callback(result, promise_id); - }); -} - -struct PasswordUserInfo { - username: String, - password: String, - key_payload: String, - key_payload_signature: String, - content_prekey: String, - content_prekey_signature: String, - notif_prekey: String, - notif_prekey_signature: String, - content_one_time_keys: Vec, - notif_one_time_keys: Vec, - farcaster_id: Option, -} - -#[derive(Serialize)] -#[serde(rename_all = "camelCase")] -struct UserIDAndDeviceAccessToken { - #[serde(rename = "userID")] - user_id: String, - access_token: String, -} - -impl From for UserIDAndDeviceAccessToken { - fn from(value: AuthResponse) -> Self { - let AuthResponse { - user_id, - access_token, - } = value; - Self { - user_id, - access_token, - } - } -} - -async fn register_password_user_helper( - password_user_info: PasswordUserInfo, -) -> Result { - let mut client_registration = Registration::new(); - let opaque_registration_request = client_registration - .start(&password_user_info.password) - .map_err(handle_error)?; - let registration_start_request = RegistrationStartRequest { - opaque_registration_request, - username: password_user_info.username, - device_key_upload: Some(DeviceKeyUpload { - device_key_info: Some(IdentityKeyInfo { - payload: password_user_info.key_payload, - payload_signature: password_user_info.key_payload_signature, - social_proof: None, - }), - content_upload: Some(Prekey { - prekey: password_user_info.content_prekey, - prekey_signature: password_user_info.content_prekey_signature, - }), - notif_upload: Some(Prekey { - prekey: password_user_info.notif_prekey, - prekey_signature: password_user_info.notif_prekey_signature, - }), - one_time_content_prekeys: password_user_info.content_one_time_keys, - one_time_notif_prekeys: password_user_info.notif_one_time_keys, - device_type: DEVICE_TYPE.into(), - }), - farcaster_id: password_user_info.farcaster_id, - }; - - let mut identity_client = get_unauthenticated_client( - IDENTITY_SOCKET_ADDR, - CODE_VERSION, - DEVICE_TYPE.as_str_name().to_lowercase(), - ) - .await?; - let response = identity_client - .register_password_user_start(registration_start_request) - .await?; - - let registration_start_response = response.into_inner(); - - let opaque_registration_upload = client_registration - .finish( - &password_user_info.password, - ®istration_start_response.opaque_registration_response, - ) - .map_err(handle_error)?; - - let registration_finish_request = RegistrationFinishRequest { - session_id: registration_start_response.session_id, - opaque_registration_upload, - }; - - let registration_finish_response = identity_client - .register_password_user_finish(registration_finish_request) - .await? - .into_inner(); - let user_id_and_access_token = - UserIDAndDeviceAccessToken::from(registration_finish_response); - Ok(serde_json::to_string(&user_id_and_access_token)?) -} - #[instrument] fn log_in_password_user( username: String, @@ -701,20 +563,6 @@ Ok(serde_json::to_string(&user_id_and_access_token)?) } -struct WalletUserInfo { - siwe_message: String, - siwe_signature: String, - key_payload: String, - key_payload_signature: String, - content_prekey: String, - content_prekey_signature: String, - notif_prekey: String, - notif_prekey_signature: String, - content_one_time_keys: Vec, - notif_one_time_keys: Vec, - farcaster_id: Option, -} - #[instrument] fn log_in_wallet_user( siwe_message: String,