use std::sync::Arc;
use foundation_auth::shared::jwt::{
JwtAlgorithm, JwtSigningKey, JwtVerifier, JwtVerifierConfig, PublicKeySource,
};
use foundation_db::core::storage_provider::AsyncQueryStore;
use crate::core::auth::ISSUER;
#[derive(Clone)]
pub struct KeychainContext {
db: Arc<dyn AsyncQueryStore>,
signing_key: Arc<JwtSigningKey>,
verifier: Arc<JwtVerifier>,
}
impl KeychainContext {
#[must_use]
pub fn new(db: Arc<dyn AsyncQueryStore>) -> Self {
Self::with_signing_key(db, JwtSigningKey::generate_ed25519())
}
#[must_use]
pub fn with_signing_key(db: Arc<dyn AsyncQueryStore>, signing_key: JwtSigningKey) -> Self {
let verifier = build_verifier(&signing_key).expect("derive verifier from signing key");
Self {
db,
signing_key: Arc::new(signing_key),
verifier: Arc::new(verifier),
}
}
#[must_use]
pub fn db(&self) -> &dyn AsyncQueryStore {
self.db.as_ref()
}
#[must_use]
pub fn signing_key(&self) -> &JwtSigningKey {
&self.signing_key
}
#[must_use]
pub fn verifier(&self) -> &JwtVerifier {
&self.verifier
}
}
fn build_verifier(signing_key: &JwtSigningKey) -> Result<JwtVerifier, foundation_auth::shared::jwt::JwtError> {
let pem = signing_key.public_key_pem()?;
JwtVerifier::from_config(JwtVerifierConfig {
allowed_algorithms: vec![JwtAlgorithm::EdDSA, JwtAlgorithm::RS256, JwtAlgorithm::ES256],
issuer: Some(ISSUER.to_string()),
audience: None,
key_id: None,
public_key: PublicKeySource::Pem(pem),
})
}