feat(auth): implement JWT authentication and user registration

- Added JWT authentication with token generation and validation.
- Introduced user registration functionality with email and password.
- Integrated Argon2 for password hashing.
- Created SQLite user repository for user data persistence.
- Updated application context to include user repository and configuration settings.
- Added environment variable support for JWT secret and registration allowance.
- Enhanced error handling for unauthorized access and validation errors.
- Updated presentation layer to handle login and registration requests.
This commit is contained in:
2026-05-04 10:43:07 +02:00
parent 98ad1b19fa
commit 1f8b24fec2
29 changed files with 599 additions and 85 deletions

View File

@@ -0,0 +1,39 @@
use chrono::{DateTime, Utc};
use uuid::Uuid;
use domain::{errors::DomainError, value_objects::Email};
use crate::{commands::LoginCommand, context::AppContext};
pub struct LoginResult {
pub token: String,
pub user_id: Uuid,
pub email: String,
pub expires_at: DateTime<Utc>,
}
pub async fn execute(ctx: &AppContext, cmd: LoginCommand) -> Result<LoginResult, DomainError> {
let email = Email::new(cmd.email)?;
let user = ctx
.user_repository
.find_by_email(&email)
.await?
.ok_or_else(|| DomainError::Unauthorized("Invalid credentials".into()))?;
let valid = ctx
.password_hasher
.verify(&cmd.password, user.password_hash())
.await?;
if !valid {
return Err(DomainError::Unauthorized("Invalid credentials".into()));
}
let generated = ctx.auth_service.generate_token(user.id()).await?;
Ok(LoginResult {
token: generated.token,
user_id: user.id().value(),
email: user.email().value().to_string(),
expires_at: generated.expires_at,
})
}