use argon2::{ Argon2, PasswordHash, PasswordVerifier, password_hash::{PasswordHasher, SaltString, rand_core::OsRng}, }; use jsonwebtoken::{self as jwt, DecodingKey, EncodingKey, Header, Validation}; use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize)] pub struct JwtClaims { pub sub: i64, pub iat: i64, pub exp: i64, } pub fn create_password(password: &str) -> argon2::password_hash::Result { Ok(Argon2::default() .hash_password(password.as_bytes(), &SaltString::generate(&mut OsRng))? .to_string()) } pub fn validate_password( password: &str, password_hash: &str, ) -> argon2::password_hash::Result { Ok(Argon2::default() .verify_password(password.as_bytes(), &PasswordHash::new(password_hash)?) .is_ok()) } pub fn create_jwt(claims: &JwtClaims, secret: &str) -> jwt::errors::Result { jwt::encode( &Header::default(), claims, &EncodingKey::from_secret(secret.as_bytes()), ) } pub fn validate_jwt(token: &str, secret: &str) -> jwt::errors::Result { let mut validation = Validation::default(); validation.set_required_spec_claims(&["exp"]); validation.validate_exp = true; validation.leeway = 0; Ok(jwt::decode( token, &DecodingKey::from_secret(secret.as_bytes()), &validation, )? .claims) }