pub mod providers;
pub use providers::{BriVaPaidVerifier, InacashCashoutVerifier, InacashQrisVerifier};
use http::HeaderMap;
use crate::error::{Error, Result};
use crate::signature::Signature;
pub trait WebhookVerifier {
fn canonical_payload(&self, headers: &HeaderMap, body: &[u8]) -> Result<Vec<u8>>;
fn extract_signature(&self, headers: &HeaderMap) -> Result<Signature>;
fn compare(&self, sig: &Signature, canonical: &[u8]) -> Result<()>;
fn verify(&self, headers: &HeaderMap, body: &[u8]) -> Result<()> {
let canonical = self.canonical_payload(headers, body)?;
let sig = self.extract_signature(headers)?;
self.compare(&sig, &canonical)
}
}
pub(crate) fn hmac_compare(secret: &[u8], sig: &Signature, canonical: &[u8]) -> Result<()> {
let signer = crate::HmacSigner::new(secret)?;
signer.verify(sig, canonical)
}
fn missing_header(name: &str) -> Error {
Error::Webhook(format!("missing header: {name}"))
}
pub(crate) fn header_str<'a>(headers: &'a HeaderMap, name: &'static str) -> Result<&'a str> {
headers
.get(name)
.ok_or_else(|| missing_header(name))?
.to_str()
.map_err(|e| Error::Webhook(format!("non-ASCII header {name}: {e}")))
}