use serde_json::{Value, json};
use trust_tasks_rs::TrustTask;
use crate::auth::AuthClaims;
use crate::server::AppState;
use super::helpers::{TrustTaskOutcome, success_response};
pub(super) async fn handle_ping(
state: &AppState,
_auth: &AuthClaims,
doc: TrustTask<Value>,
) -> TrustTaskOutcome {
let protocols: Vec<&str> = {
let services = &state.config.read().await.services;
let mut p = Vec::new();
if services.tsp {
p.push("tsp");
}
if services.didcomm {
p.push("didcomm");
}
if services.rest {
p.push("rest");
}
p
};
let mut body = json!({
"serverTime": chrono::Utc::now().to_rfc3339(),
"status": "ok",
"protocols": protocols,
});
if let Some(nonce) = doc.payload.get("nonce").and_then(Value::as_str) {
body["nonce"] = json!(nonce);
}
success_response(&doc, body)
}
#[cfg(test)]
mod tests {
use super::*;
use crate::test_support::build_signing_test_app_state;
use serde_json::json;
fn ping_doc(nonce: Option<&str>) -> TrustTask<Value> {
let payload = match nonce {
Some(n) => json!({ "nonce": n }),
None => json!({}),
};
TrustTask::new(
"urn:uuid:test-ping".to_string(),
vta_sdk::trust_tasks::TASK_MESSAGING_PING_0_1
.parse()
.unwrap(),
payload,
)
}
#[tokio::test]
async fn ping_is_session_less_and_echoes_nonce() {
let (state, _dir) = build_signing_test_app_state().await;
let auth = crate::auth::AuthClaims {
did: "did:key:zPinger".into(),
role: crate::acl::Role::Reader,
allowed_contexts: vec![],
session_id: "didcomm:did:key:zPinger".into(),
access_expires_at: 0,
amr: vec!["did".into()],
acr: "aal1".into(),
};
let out = handle_ping(&state, &auth, ping_doc(Some("abc123"))).await;
assert_eq!(out.status, axum::http::StatusCode::OK);
let doc: Value = serde_json::from_slice(&out.body).expect("reply is JSON");
assert_eq!(doc["payload"]["status"], "ok");
assert_eq!(doc["payload"]["nonce"], "abc123");
assert!(doc["payload"]["serverTime"].is_string());
}
}