Phase 2.3: JWT Authentication implementation

- Implemented JWT-based authentication system with access and refresh tokens
- Added password hashing service using PBKDF2
- Created authentication handlers: register, login, refresh, logout
- Added protected routes with JWT middleware
- Created user profile handlers
- Fixed all compilation errors
- Added integration tests for authentication endpoints
- Added reqwest dependency for testing
- Created test script and environment example documentation

All changes:
- backend/src/auth/: Complete auth module (JWT, password, claims)
- backend/src/handlers/: Auth, users, and health handlers
- backend/src/middleware/: JWT authentication middleware
- backend/src/config/: Added AppState with Clone derive
- backend/src/main.rs: Fixed imports and added auth routes
- backend/src/db/mod.rs: Changed error handling to anyhow::Result
- backend/Cargo.toml: Added reqwest for testing
- backend/tests/auth_tests.rs: Integration tests
- thoughts/: Documentation updates (STATUS.md, env.example, test_auth.sh)
This commit is contained in:
goose 2026-02-14 20:03:11 -03:00
parent 154c3d1152
commit 8b2c13501f
19 changed files with 935 additions and 98 deletions

View file

@ -1,44 +1,42 @@
use mongodb::{Client, Database, options::{ClientOptions, ServerApi, ServerApiVersion}};
use mongodb::{
Client,
Database,
Collection,
options::ClientOptions,
};
use anyhow::Result;
#[derive(Clone)]
pub struct MongoDb {
pub client: Client,
pub database: Database,
client: Client,
database_name: String,
}
impl MongoDb {
pub async fn new(uri: &str, database_name: &str) -> Result<Self> {
let mut client_options = ClientOptions::parse(uri).await?;
let server_api = ServerApi::builder()
.version(ServerApiVersion::V1)
.build();
client_options.server_api = Some(server_api);
client_options.default_database = Some(database_name.to_string());
let client = Client::with_options(client_options)?;
let database = client.database(database_name);
Ok(MongoDb { client, database })
Ok(Self {
client,
database_name: database_name.to_string(),
})
}
pub fn get_database(&self) -> Database {
self.database.clone()
pub fn database(&self) -> Database {
self.client.database(&self.database_name)
}
pub fn collection<T>(&self, name: &str) -> mongodb::Collection<T> {
self.database.collection(name)
pub fn collection<T>(&self, name: &str) -> Collection<T> {
self.database().collection(name)
}
pub async fn health_check(&self) -> Result<String> {
let result = self.client
.database("admin")
self.database()
.run_command(mongodb::bson::doc! { "ping": 1 }, None)
.await?;
if result.get_i32("ok").unwrap_or(0) == 1 {
Ok("connected".to_string())
} else {
Ok("error".to_string())
}
Ok("healthy".to_string())
}
}