feat(auth): implement user registration and login with JWT authentication
- Added `bcrypt`, `jsonwebtoken`, and `once_cell` dependencies to manage password hashing and JWT handling. - Created `Claims` struct for JWT claims and implemented token generation in the login route. - Implemented user registration and authentication logic in the `auth` module. - Updated error handling to include validation errors. - Created new routes for user registration and login, and integrated them into the main router. - Added tests for the authentication flow, including registration and login scenarios. - Updated user model to include a password hash field. - Refactored user creation logic to include password validation. - Adjusted feed and user routes to utilize JWT for authentication.
This commit is contained in:
60
thoughts-backend/tests/api/auth.rs
Normal file
60
thoughts-backend/tests/api/auth.rs
Normal file
@@ -0,0 +1,60 @@
|
||||
use crate::api::main::setup;
|
||||
use axum::http::StatusCode;
|
||||
use http_body_util::BodyExt;
|
||||
use serde_json::{json, Value};
|
||||
use utils::testing::{make_jwt_request, make_post_request};
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_auth_flow() {
|
||||
std::env::set_var("AUTH_SECRET", "test-secret");
|
||||
let app = setup().await;
|
||||
|
||||
let register_body = json!({
|
||||
"username": "testuser",
|
||||
"password": "password123"
|
||||
})
|
||||
.to_string();
|
||||
let response =
|
||||
make_post_request(app.router.clone(), "/auth/register", register_body, None).await;
|
||||
assert_eq!(response.status(), StatusCode::CREATED);
|
||||
let body = response.into_body().collect().await.unwrap().to_bytes();
|
||||
let v: Value = serde_json::from_slice(&body).unwrap();
|
||||
assert_eq!(v["username"], "testuser");
|
||||
assert!(v["id"].is_number());
|
||||
|
||||
let response = make_post_request(
|
||||
app.router.clone(),
|
||||
"/auth/register",
|
||||
json!({
|
||||
"username": "testuser",
|
||||
"password": "password456"
|
||||
})
|
||||
.to_string(),
|
||||
None,
|
||||
)
|
||||
.await;
|
||||
assert_eq!(response.status(), StatusCode::BAD_REQUEST);
|
||||
|
||||
let login_body = json!({
|
||||
"username": "testuser",
|
||||
"password": "password123"
|
||||
})
|
||||
.to_string();
|
||||
let response = make_post_request(app.router.clone(), "/auth/login", login_body, None).await;
|
||||
assert_eq!(response.status(), StatusCode::OK);
|
||||
let body = response.into_body().collect().await.unwrap().to_bytes();
|
||||
let v: Value = serde_json::from_slice(&body).unwrap();
|
||||
let token = v["token"].as_str().expect("token not found").to_string();
|
||||
assert!(!token.is_empty());
|
||||
|
||||
let bad_login_body = json!({
|
||||
"username": "testuser",
|
||||
"password": "wrongpassword"
|
||||
})
|
||||
.to_string();
|
||||
let response = make_post_request(app.router.clone(), "/auth/login", bad_login_body, None).await;
|
||||
assert_eq!(response.status(), StatusCode::NOT_FOUND);
|
||||
|
||||
let response = make_jwt_request(app.router.clone(), "/feed", "GET", None, &token).await;
|
||||
assert_eq!(response.status(), StatusCode::OK);
|
||||
}
|
Reference in New Issue
Block a user