feat(auth): kayıt, giriş, çıkış ve oturum (argon2 + JWT httpOnly cookie)
- Kayıt: kullanıcı + hane + örnek kategori/ödeme türü tek transaction'da - Giriş: beni hatırla (30 gün / oturum), e-posta başına deneme sınırı - AuthUser extractor: cookie'deki JWT'yi doğrular - ValidJson: JSON + doğrulama, Türkçe hata mesajları - api.http: auth istekleri eklendi - Birim testleri: şifre, JWT, deneme sınırı, seed (11 test) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -8,6 +8,7 @@ use axum::{
|
||||
};
|
||||
use serde_json::json;
|
||||
|
||||
#[allow(dead_code)] // NotFound/Forbidden: Faz 1 – Adım 4-5'te kullanılacak
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum AppError {
|
||||
#[error("Kayıt bulunamadı")]
|
||||
@@ -16,6 +17,8 @@ pub enum AppError {
|
||||
BadRequest(String),
|
||||
#[error("Oturum açmanız gerekiyor")]
|
||||
Unauthorized,
|
||||
#[error("E-posta veya şifre hatalı")]
|
||||
InvalidCredentials,
|
||||
#[error("Bu işlem için yetkiniz yok")]
|
||||
Forbidden,
|
||||
#[error("{0}")]
|
||||
@@ -34,6 +37,7 @@ impl AppError {
|
||||
Self::NotFound => (StatusCode::NOT_FOUND, "not_found"),
|
||||
Self::BadRequest(_) => (StatusCode::BAD_REQUEST, "bad_request"),
|
||||
Self::Unauthorized => (StatusCode::UNAUTHORIZED, "unauthorized"),
|
||||
Self::InvalidCredentials => (StatusCode::UNAUTHORIZED, "invalid_credentials"),
|
||||
Self::Forbidden => (StatusCode::FORBIDDEN, "forbidden"),
|
||||
Self::Conflict(_) => (StatusCode::CONFLICT, "conflict"),
|
||||
Self::TooManyRequests => (StatusCode::TOO_MANY_REQUESTS, "too_many_requests"),
|
||||
@@ -64,5 +68,18 @@ impl IntoResponse for AppError {
|
||||
}
|
||||
}
|
||||
|
||||
/// Doğrulama hatası → ilk alanın Türkçe mesajıyla 400.
|
||||
impl From<validator::ValidationErrors> for AppError {
|
||||
fn from(errors: validator::ValidationErrors) -> Self {
|
||||
let message = errors
|
||||
.field_errors()
|
||||
.values()
|
||||
.flat_map(|list| list.iter())
|
||||
.find_map(|e| e.message.as_ref().map(|m| m.to_string()))
|
||||
.unwrap_or_else(|| "Girilen bilgiler geçersiz".into());
|
||||
AppError::BadRequest(message)
|
||||
}
|
||||
}
|
||||
|
||||
/// Route fonksiyonlarında kısa dönüş tipi: `AppResult<Json<T>>`
|
||||
pub type AppResult<T> = Result<T, AppError>;
|
||||
|
||||
Reference in New Issue
Block a user