use crate::error::AppError;
pub fn check_issuer_binding(vm: &str, issuer_did: &str) -> Result<(), AppError> {
match vm.split_once('#') {
Some((base, fragment)) if !fragment.is_empty() && base == issuer_did => Ok(()),
Some((_, fragment)) if !fragment.is_empty() => Err(AppError::Validation(
"proof verificationMethod is not under the credential's issuer".to_string(),
)),
_ => Err(AppError::Validation(
"proof verificationMethod is not a DID URL naming a verification method".to_string(),
)),
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn issuer_binding_is_exact_and_needs_a_fragment() {
check_issuer_binding("did:web:a.example#key-0", "did:web:a.example").expect("bound");
assert!(check_issuer_binding("did:web:b.example#key-0", "did:web:a.example").is_err());
assert!(check_issuer_binding("did:web:a.example", "did:web:a.example").is_err());
assert!(check_issuer_binding("did:web:a.example#", "did:web:a.example").is_err());
assert!(check_issuer_binding("#key-0", "did:web:a.example").is_err());
assert!(check_issuer_binding("did:web:a.example:x#key-0", "did:web:a.example").is_err());
let err = check_issuer_binding("did:web:b.example#key-0", "did:web:a.example")
.unwrap_err()
.to_string();
assert!(
!err.contains("a.example"),
"no identifiers in the refusal: {err}"
);
}
}