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:
2026-11-11 23:37:52 +03:00
parent 4103b90e4b
commit d6136959b1
27 changed files with 1573 additions and 32 deletions
+31
View File
@@ -0,0 +1,31 @@
//! Özel extractor'lar.
use axum::{
Json,
extract::{FromRequest, Request},
};
use serde::de::DeserializeOwned;
use validator::Validate;
use crate::error::AppError;
/// `Json<T>` gibi çalışır, ek olarak `validator` kurallarını da kontrol eder.
/// Hatalı JSON veya geçersiz alanlarda Türkçe 400 hatası döner.
pub struct ValidJson<T>(pub T);
impl<T, S> FromRequest<S> for ValidJson<T>
where
T: DeserializeOwned + Validate,
S: Send + Sync,
{
type Rejection = AppError;
async fn from_request(req: Request, state: &S) -> Result<Self, AppError> {
let Json(value) = Json::<T>::from_request(req, state).await.map_err(|e| {
tracing::debug!(error = %e, "JSON okunamadı");
AppError::BadRequest("Gönderilen veri okunamadı veya eksik alan var".into())
})?;
value.validate()?;
Ok(Self(value))
}
}