use affinidi_data_integrity::{DataIntegrityProof, DidKeyResolver, VerifyOptions};
use serde_json::Value;
use trust_tasks_rs::TrustTask;
#[derive(Debug)]
pub enum DiProofError {
NoProof,
NotDataIntegrity,
NoDid,
VerifyFailed(String),
}
impl std::fmt::Display for DiProofError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::NoProof => write!(f, "document has no proof"),
Self::NotDataIntegrity => write!(f, "proof is not a Data Integrity proof"),
Self::NoDid => write!(f, "proof verificationMethod carries no DID"),
Self::VerifyFailed(e) => write!(f, "proof verification failed: {e}"),
}
}
}
pub async fn verify_trust_task_proof(doc: &TrustTask<Value>) -> Result<String, DiProofError> {
let proof = doc.proof.as_ref().ok_or(DiProofError::NoProof)?;
let di: DataIntegrityProof = serde_json::to_value(proof)
.ok()
.and_then(|v| serde_json::from_value(v).ok())
.ok_or(DiProofError::NotDataIntegrity)?;
let signer_did = di
.verification_method
.split('#')
.next()
.unwrap_or_default()
.to_string();
if signer_did.is_empty() {
return Err(DiProofError::NoDid);
}
let mut unsigned = doc.clone();
unsigned.proof = None;
di.verify(&unsigned, &DidKeyResolver, VerifyOptions::new())
.await
.map_err(|e| DiProofError::VerifyFailed(e.to_string()))?;
Ok(signer_did)
}