use affinidi_messaging_didcomm::Message;
use affinidi_messaging_didcomm_service::{
DIDCommResponse, DIDCommServiceError, Extension, HandlerContext, MESSAGE_PICKUP_STATUS_TYPE,
MessagePolicy, RequestLogging, Router, TRUST_PING_TYPE, handler_fn, ignore_handler,
trust_ping_handler,
};
use serde_json::Value;
use tracing::warn;
use did_hosting_common::server::problem_report::log_problem_report;
use crate::server::AppState;
use crate::trust_tasks::{Via, dispatch_inbound_document};
pub fn build_watcher_router(state: AppState) -> Result<Router, DIDCommServiceError> {
Ok(Router::new()
.extension(state)
.route(TRUST_PING_TYPE, handler_fn(trust_ping_handler))?
.route(MESSAGE_PICKUP_STATUS_TYPE, handler_fn(ignore_handler))?
.route(
trust_tasks_didcomm::ENVELOPE_TYPE,
handler_fn(handle_trust_tasks_envelope),
)?
.fallback(handler_fn(handle_fallback))
.layer(
MessagePolicy::new()
.require_encrypted(true)
.require_sender_did(true),
)
.layer(RequestLogging))
}
async fn handle_trust_tasks_envelope(
ctx: HandlerContext,
message: Message,
Extension(state): Extension<AppState>,
) -> Result<Option<DIDCommResponse>, DIDCommServiceError> {
let Some((typ, body)) =
run_trust_tasks_envelope(&state, ctx.sender_did.as_deref(), &message).await
else {
return Ok(None);
};
Ok(Some(
DIDCommResponse::new(typ, body).thid(message.id.clone()),
))
}
pub async fn run_trust_tasks_envelope(
state: &AppState,
sender: Option<&str>,
message: &Message,
) -> Option<(String, Value)> {
let doc: trust_tasks_rs::TrustTask<Value> = match serde_json::from_value(message.body.clone()) {
Ok(d) => d,
Err(e) => {
warn!(
sender,
error = %e,
"trust-tasks envelope: inner body is not a Trust Task document"
);
return None;
}
};
let reply = dispatch_inbound_document(state, Via::Didcomm, sender, doc).await?;
Some((trust_tasks_didcomm::ENVELOPE_TYPE.to_string(), reply))
}
async fn handle_fallback(
ctx: HandlerContext,
message: Message,
) -> Result<Option<DIDCommResponse>, DIDCommServiceError> {
let sender = ctx.sender_did.as_deref();
if log_problem_report("watcher", sender, &message) {
return Ok(None);
}
warn!(
sender = sender.unwrap_or("unknown"),
msg_type = %message.typ,
"unknown DIDComm message type — ignoring"
);
Ok(None)
}