use affinidi_messaging_didcomm::{DIDCommAgent, Message, UnpackResult};
use serde::{de::DeserializeOwned, Serialize};
use trust_tasks_rs::{Payload, TrustTask};
use crate::error::DidcommError;
use crate::handler::DidcommHandler;
pub const ENVELOPE_TYPE: &str = "https://trusttasks.org/binding/didcomm/0.1/envelope";
pub fn pack_trust_task<P>(
doc: &TrustTask<P>,
agent: &DIDCommAgent,
sender_did: &str,
recipient_did: &str,
) -> Result<String, DidcommError>
where
P: Payload + Serialize,
{
let body = serde_json::to_value(doc).map_err(DidcommError::SerialiseBody)?;
let msg = Message::new(ENVELOPE_TYPE, body)
.from(sender_did.to_string())
.to(vec![recipient_did.to_string()])
.thid(doc.id.clone());
let wire = agent.pack_authcrypt(&msg, sender_did, recipient_did)?;
Ok(wire)
}
pub fn unpack_trust_task<P>(
wire: &str,
agent: &DIDCommAgent,
expected_sender_did: Option<&str>,
) -> Result<(TrustTask<P>, DidcommHandler), DidcommError>
where
P: Payload + DeserializeOwned,
{
let (message, peer_did, local_did) = match agent.unpack(wire, expected_sender_did)? {
UnpackResult::Encrypted {
message,
authenticated: true,
sender_kid: Some(sender_kid),
recipient_kid,
..
} => (
message,
did_from_kid(&sender_kid),
Some(did_from_kid(&recipient_kid).unwrap_or(recipient_kid)),
),
UnpackResult::Encrypted { .. } | UnpackResult::Plaintext(_) => {
return Err(DidcommError::UnauthenticatedSender);
}
UnpackResult::Signed {
message,
signer_kid: Some(signer_kid),
} => (message, did_from_kid(&signer_kid), None),
UnpackResult::Signed { .. } => {
return Err(DidcommError::UnauthenticatedSender);
}
_ => return Err(DidcommError::UnauthenticatedSender),
};
if message.typ != ENVELOPE_TYPE {
return Err(DidcommError::WrongEnvelopeType(message.typ.clone()));
}
let doc: TrustTask<P> =
serde_json::from_value(message.body).map_err(DidcommError::InvalidBody)?;
let handler = DidcommHandler::new(local_did, peer_did);
Ok((doc, handler))
}
fn did_from_kid(kid: &str) -> Option<String> {
kid.split_once('#').map(|(did, _)| did.to_string())
}