fix: allow dots in usernames; BCrypt fallback in password verifier for v1 migrations

This commit is contained in:
2026-05-15 02:56:18 +02:00
parent 555bcea307
commit f7350847c5
3 changed files with 10 additions and 2 deletions

View File

@@ -13,4 +13,5 @@ tokio = { workspace = true }
serde = { workspace = true } serde = { workspace = true }
jsonwebtoken = "9" jsonwebtoken = "9"
argon2 = "0.5" argon2 = "0.5"
bcrypt = "0.15"
rand = "0.8" rand = "0.8"

View File

@@ -76,6 +76,10 @@ impl PasswordHasher for Argon2PasswordHasher {
} }
async fn verify(&self, plain: &str, hash: &PasswordHash) -> Result<bool, DomainError> { async fn verify(&self, plain: &str, hash: &PasswordHash) -> Result<bool, DomainError> {
if hash.0.starts_with("$2") {
return bcrypt::verify(plain, &hash.0)
.map_err(|e| DomainError::Internal(e.to_string()));
}
use argon2::{password_hash::PasswordHash as ArgonHash, Argon2, PasswordVerifier}; use argon2::{password_hash::PasswordHash as ArgonHash, Argon2, PasswordVerifier};
let parsed = ArgonHash::new(&hash.0).map_err(|e| DomainError::Internal(e.to_string()))?; let parsed = ArgonHash::new(&hash.0).map_err(|e| DomainError::Internal(e.to_string()))?;
Ok(Argon2::default() Ok(Argon2::default()

View File

@@ -44,9 +44,12 @@ impl Username {
if s.is_empty() || s.len() > 32 { if s.is_empty() || s.len() > 32 {
return Err(DomainError::InvalidInput("username: 1-32 chars".into())); return Err(DomainError::InvalidInput("username: 1-32 chars".into()));
} }
if !s.chars().all(|c| c.is_alphanumeric() || c == '_') { if !s
.chars()
.all(|c| c.is_alphanumeric() || c == '_' || c == '.')
{
return Err(DomainError::InvalidInput( return Err(DomainError::InvalidInput(
"username: alphanumeric or underscore only".into(), "username: alphanumeric, underscore, or dot only".into(),
)); ));
} }
Ok(Self(s)) Ok(Self(s))