use crate::crypto;
use crate::http::RestClient;
use base64::{engine::general_purpose::URL_SAFE_NO_PAD, Engine};
#[derive(Debug, thiserror::Error)]
pub enum RespondError {
#[error("derive shared key: {0}")]
DeriveShared(String),
#[error("encrypt user key: {0}")]
Encrypt(String),
#[error("post bundle: {0}")]
Post(#[from] crate::http::HttpError),
}
pub async fn respond(
client: &RestClient,
target_device_id: &str,
peer_pub_b64: &str,
user_master_key_b64: &str,
) -> Result<(), RespondError> {
let (eph_priv_b64, eph_pub_b64) = crypto::generate_ephemeral_keypair();
let shared = crypto::derive_shared_key(&eph_priv_b64, peer_pub_b64)
.map_err(RespondError::DeriveShared)?;
let raw_master = URL_SAFE_NO_PAD
.decode(user_master_key_b64)
.map_err(|e| RespondError::Encrypt(format!("master key decode: {}", e)))?;
let encrypted = crypto::encrypt(&shared, &raw_master).map_err(RespondError::Encrypt)?;
client
.post_key_bundle(target_device_id, &eph_pub_b64, &encrypted)
.await?;
Ok(())
}