use matrix_sdk::Client;
#[derive(Clone, Debug, PartialEq)]
pub enum VerificationState {
Idle,
Requested {
flow_id: String,
from_user: String,
},
KeysExchanged {
flow_id: String,
emojis: Vec<(String, String)>,
},
Confirmed {
flow_id: String,
},
Done {
flow_id: String,
},
Cancelled {
flow_id: String,
reason: String,
},
}
impl Default for VerificationState {
fn default() -> Self {
Self::Idle
}
}
pub async fn accept_verification_request(
client: &Client,
flow_id: &str,
from_user: &str,
) -> Result<(), String> {
let user_id = matrix_sdk::ruma::OwnedUserId::try_from(from_user)
.map_err(|e| format!("Invalid user ID: {e}"))?;
let encryption = client.encryption();
let request = encryption
.get_verification_request(&user_id, flow_id)
.await
.ok_or_else(|| "Verification request not found".to_string())?;
request
.accept()
.await
.map_err(|e| format!("Failed to accept verification: {e}"))?;
tracing::info!("Accepted verification request {flow_id} from {from_user}");
Ok(())
}
pub async fn confirm_sas_verification(
client: &Client,
flow_id: &str,
from_user: &str,
) -> Result<(), String> {
let user_id = matrix_sdk::ruma::OwnedUserId::try_from(from_user)
.map_err(|e| format!("Invalid user ID: {e}"))?;
let encryption = client.encryption();
if let Some(verification) = encryption.get_verification(&user_id, flow_id).await {
if let Some(sas) = verification.sas() {
sas.confirm()
.await
.map_err(|e| format!("Failed to confirm SAS: {e}"))?;
tracing::info!("SAS verification confirmed for {flow_id}");
return Ok(());
}
}
Err("SAS verification not found".to_string())
}
pub async fn cancel_verification(
client: &Client,
flow_id: &str,
from_user: &str,
) -> Result<(), String> {
let user_id = matrix_sdk::ruma::OwnedUserId::try_from(from_user)
.map_err(|e| format!("Invalid user ID: {e}"))?;
let encryption = client.encryption();
if let Some(request) = encryption.get_verification_request(&user_id, flow_id).await {
request
.cancel()
.await
.map_err(|e| format!("Failed to cancel verification: {e}"))?;
tracing::info!("Cancelled verification {flow_id}");
return Ok(());
}
Err("Verification request not found".to_string())
}
pub async fn request_verification(
client: &Client,
user_id_str: &str,
) -> Result<String, String> {
let user_id = matrix_sdk::ruma::OwnedUserId::try_from(user_id_str)
.map_err(|e| format!("Invalid user ID: {e}"))?;
let encryption = client.encryption();
let identity = encryption
.get_user_identity(&user_id)
.await
.map_err(|e| format!("Failed to get user identity: {e}"))?
.ok_or_else(|| "User identity not found".to_string())?;
let request = identity
.request_verification()
.await
.map_err(|e| format!("Failed to request verification: {e}"))?;
let flow_id = request.flow_id().to_string();
tracing::info!("Requested verification with {user_id}, flow_id: {flow_id}");
Ok(flow_id)
}
pub async fn get_sas_emojis(
client: &Client,
flow_id: &str,
from_user: &str,
) -> Result<Vec<(String, String)>, String> {
let user_id = matrix_sdk::ruma::OwnedUserId::try_from(from_user)
.map_err(|e| format!("Invalid user ID: {e}"))?;
let encryption = client.encryption();
if let Some(verification) = encryption.get_verification(&user_id, flow_id).await {
if let Some(sas) = verification.sas() {
if let Some(emojis) = sas.emoji() {
let emoji_list: Vec<(String, String)> = emojis
.iter()
.map(|e| (e.symbol.to_string(), e.description.to_string()))
.collect();
return Ok(emoji_list);
}
}
}
Err("SAS emojis not available yet".to_string())
}