use argon2::{
password_hash::{rand_core::OsRng, SaltString},
Argon2, Params, PasswordHash, PasswordHasher, PasswordVerifier,
};
use ayun_core::{errors::ContainerError, traits::InstanceTrait, Container};
pub type Error = ayun_core::Error;
pub type Result<T, E = Error> = ayun_core::Result<T, E>;
pub struct Hash {
inner: Argon2<'static>,
}
impl InstanceTrait for Hash {
fn register(_: &Container) -> Result<Self, ContainerError>
where
Self: Sized,
{
let argon2 = Argon2::new(
argon2::Algorithm::Argon2id,
argon2::Version::V0x13,
Params::default(),
);
Ok(Self::new(argon2))
}
}
impl Hash {
fn new(inner: Argon2<'static>) -> Self {
Self { inner }
}
pub fn make(&self, value: &str) -> Result<String, Error> {
let salt = SaltString::generate(&mut OsRng);
Ok(self
.inner
.hash_password(value.as_bytes(), &salt)?
.to_string())
}
pub fn check(&self, value: &str, hashed: &str) -> bool {
let Ok(hashed) = PasswordHash::new(hashed) else {
return false;
};
self.inner
.verify_password(value.as_bytes(), &hashed)
.is_ok()
}
}