use pubky_common::auth::grant::GrantClaims;
use crate::actors::auth::relay::AuthRelayMessage;
use crate::errors::{AuthError, Result};
#[derive(Debug)]
pub(crate) struct GrantApproval {
pub(crate) jws: String,
pub(crate) claims: GrantClaims,
}
impl GrantApproval {
pub(crate) fn decode(message: &AuthRelayMessage) -> Result<Self> {
let text = std::str::from_utf8(message.as_bytes())
.map_err(|e| AuthError::Validation(format!("invalid grant payload encoding: {e}")))?;
let claims = GrantClaims::decode(text)
.map_err(|e| AuthError::Validation(format!("invalid grant payload: {e}")))?;
Ok(Self {
jws: text.to_string(),
claims,
})
}
}
#[cfg(test)]
mod tests {
use pubky_common::{
auth::jws::{ClientId, GRANT_JWS_TYP, GrantId, sign_jws},
capabilities::Capabilities,
};
use super::*;
use crate::Keypair;
#[test]
fn decode_verifies_valid_grant() {
let user_keypair = Keypair::random();
let client_keypair = Keypair::random();
let claims = GrantClaims {
iss: user_keypair.public_key(),
client_id: ClientId::new("test.app").unwrap(),
caps: Capabilities::default().to_vec(),
cnf: client_keypair.public_key(),
jti: GrantId::generate(),
iat: 1,
exp: 2,
};
let grant_jws = sign_jws(&user_keypair, GRANT_JWS_TYP, &claims);
let message = AuthRelayMessage::new(grant_jws.clone().into_bytes());
let approval = GrantApproval::decode(&message).unwrap();
assert_eq!(approval.jws, grant_jws);
assert_eq!(approval.claims, claims);
}
}