(fix) user_id now retrieving from JWT not from URL
This commit is contained in:
parent
80ed37647b
commit
4d0ad0226f
3 changed files with 86 additions and 78 deletions
31
src/route.rs
31
src/route.rs
|
|
@ -1,10 +1,16 @@
|
|||
// src/route.rs
|
||||
// CORRECT VERSION - keeps your protected_routes pattern
|
||||
|
||||
use axum::{
|
||||
middleware,
|
||||
routing::{get, post},
|
||||
Router,
|
||||
};
|
||||
|
||||
use crate::{auth, state::AppState};
|
||||
|
||||
pub mod handlers;
|
||||
|
||||
use axum::{middleware, routing::{get, post}, Router};
|
||||
use crate::{state::AppState, auth};
|
||||
|
||||
pub fn router(app_state: AppState) -> Router {
|
||||
// Public routes (no auth required)
|
||||
let public_routes = Router::new()
|
||||
|
|
@ -12,31 +18,30 @@ pub fn router(app_state: AppState) -> Router {
|
|||
.route("/api/auth/register", post(auth::handlers::register_handler))
|
||||
.route("/api/auth/login", post(auth::handlers::login_handler));
|
||||
|
||||
// Protected routes (auth required)
|
||||
// Protected routes (auth required) - user_id extracted from JWT in handlers
|
||||
let protected_routes = Router::new()
|
||||
.route("/api/auth/me", get(auth::handlers::me_handler))
|
||||
.route("/api/consent/{bank}/{user_id}",
|
||||
.route("/api/consent/{bank}", // ← Removed {user_id} - get from JWT!
|
||||
post(handlers::create_consent_handler)
|
||||
.get(handlers::get_consent_handler)
|
||||
.delete(handlers::delete_consent_handler)
|
||||
.get(handlers::get_consent_handler)
|
||||
.delete(handlers::delete_consent_handler)
|
||||
)
|
||||
.route("/api/accounts/{bank}/{user_id}",
|
||||
.route("/api/accounts/{bank}", // ← Removed {user_id} - get from JWT!
|
||||
get(handlers::get_accounts_handler)
|
||||
)
|
||||
.route("/api/transactions/{bank}/{user_id}/{account_id}",
|
||||
.route("/api/transactions/{bank}/{account_id}", // ← Removed {user_id}
|
||||
get(handlers::get_transactions_handler)
|
||||
)
|
||||
.route("/api/transactions/{bank_user_id}",
|
||||
get(handlers::get_all_transactions_handler) // ← Новый эндпоинт
|
||||
.route("/api/transactions", // ← Get all transactions (user from JWT)
|
||||
get(handlers::get_all_transactions_handler)
|
||||
)
|
||||
.route("/api/balances/{bank}/{account_id}",
|
||||
get(handlers::get_balances_handler)
|
||||
)
|
||||
.layer(middleware::from_fn(auth::auth_middleware));
|
||||
.layer(middleware::from_fn(auth::auth_middleware)); // ← Your existing middleware
|
||||
|
||||
// Merge both
|
||||
public_routes
|
||||
.merge(protected_routes)
|
||||
.with_state(app_state)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,9 @@ use crate::{
|
|||
db,
|
||||
};
|
||||
|
||||
use crate::auth::jwt::Claims;
|
||||
use tracing::info;
|
||||
use axum::Extension;
|
||||
|
||||
// --- Health Check ---
|
||||
|
||||
|
|
@ -48,29 +50,33 @@ struct ConsentCreatedResponse {
|
|||
|
||||
pub async fn create_consent_handler(
|
||||
State(state): State<AppState>,
|
||||
Path((bank_code, user_id)): Path<(String, String)>,
|
||||
Path(bank_code): Path<String>, // ← Only bank_code now
|
||||
Extension(claims): Extension<Claims>, // ← Get user_id from JWT!
|
||||
) -> impl IntoResponse {
|
||||
let user_id = &claims.bank_user_id; // ← Extract from JWT
|
||||
|
||||
let bank = bank_code.parse::<Bank>()
|
||||
.map_err(|_| (StatusCode::BAD_REQUEST, Json(json!({
|
||||
"error": "Invalid bank code. Use: vbank, abank, or sbank"
|
||||
}))))?;
|
||||
|
||||
// Rest stays the same - just use `user_id` variable
|
||||
let client = state.banking_clients.get_client(bank);
|
||||
|
||||
let consent_response = client
|
||||
.request_consent(&user_id)
|
||||
.request_consent(user_id) // ← Use extracted user_id
|
||||
.await
|
||||
.map_err(map_banking_error)?;
|
||||
|
||||
let expires_at = chrono::DateTime::parse_from_rfc3339(&consent_response.created_at)
|
||||
.ok()
|
||||
.map(|dt| dt.with_timezone(&chrono::Utc))
|
||||
.unwrap_or_else(|| chrono::Utc::now()) // fallback to now if parse fails
|
||||
.unwrap_or_else(|| chrono::Utc::now())
|
||||
+ chrono::Duration::days(365);
|
||||
|
||||
db::consents::store_consent(
|
||||
&state.db_pool,
|
||||
&user_id,
|
||||
user_id, // ← Use extracted user_id
|
||||
bank.code(),
|
||||
&consent_response.consent_id,
|
||||
expires_at,
|
||||
|
|
@ -94,14 +100,17 @@ pub async fn create_consent_handler(
|
|||
|
||||
pub async fn get_consent_handler(
|
||||
State(state): State<AppState>,
|
||||
Path((bank_code, user_id)): Path<(String, String)>,
|
||||
Path(bank_code): Path<String>, // ← Only bank_code now
|
||||
Extension(claims): Extension<Claims>, // ← Get user_id from JWT!
|
||||
) -> impl IntoResponse {
|
||||
let user_id = &claims.bank_user_id; // ← Extract from JWT
|
||||
|
||||
let bank = bank_code.parse::<Bank>()
|
||||
.map_err(|_| (StatusCode::BAD_REQUEST, Json(json!({
|
||||
"error": "Invalid bank code"
|
||||
}))))?;
|
||||
|
||||
db::consents::get_valid_consent(&state.db_pool, &user_id, bank.code())
|
||||
db::consents::get_valid_consent(&state.db_pool, user_id, bank.code())
|
||||
.await
|
||||
.map_err(|e| (
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
|
|
@ -121,12 +130,15 @@ pub async fn get_consent_handler(
|
|||
|
||||
pub async fn get_accounts_handler(
|
||||
State(state): State<AppState>,
|
||||
Path((bank_code, user_id)): Path<(String, String)>,
|
||||
Path(bank_code): Path<String>, // ← Only bank_code now
|
||||
Extension(claims): Extension<Claims>, // ← Get user_id from JWT!
|
||||
) -> Result<Json<serde_json::Value>, (StatusCode, Json<serde_json::Value>)> {
|
||||
let user_id = &claims.bank_user_id; // ← Extract from JWT
|
||||
|
||||
let bank = bank_code.parse::<Bank>()
|
||||
.map_err(|_| (StatusCode::BAD_REQUEST, Json(json!({ "error": "Invalid bank code" }))))?;
|
||||
|
||||
let consent_id = db::consents::get_valid_consent(&state.db_pool, &user_id, bank.code())
|
||||
let consent_id = db::consents::get_valid_consent(&state.db_pool, user_id, bank.code())
|
||||
.await
|
||||
.map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, Json(json!({ "error": e.to_string() }))))?
|
||||
.ok_or_else(|| (
|
||||
|
|
@ -136,16 +148,16 @@ pub async fn get_accounts_handler(
|
|||
|
||||
let client = state.banking_clients.get_client(bank);
|
||||
|
||||
let accounts_response = client.get_accounts(&user_id, &consent_id)
|
||||
let accounts_response = client.get_accounts(user_id, &consent_id)
|
||||
.await
|
||||
.map_err(map_banking_error)?;
|
||||
|
||||
// ✨ NEW: Save accounts to database
|
||||
// ✨ Save accounts to database
|
||||
for account in &accounts_response.data.account {
|
||||
let _ = db::accounts::store_account(
|
||||
&state.db_pool,
|
||||
&account.account_id,
|
||||
&user_id,
|
||||
user_id, // ← Use extracted user_id
|
||||
bank.code(),
|
||||
account.status.as_deref().unwrap_or("unknown"),
|
||||
&account.currency,
|
||||
|
|
@ -171,13 +183,16 @@ pub struct TransactionQuery {
|
|||
|
||||
pub async fn get_transactions_handler(
|
||||
State(state): State<AppState>,
|
||||
Path((bank_code, user_id, account_id)): Path<(String, String, String)>,
|
||||
Path((bank_code, account_id)): Path<(String, String)>, // ← Changed: no user_id
|
||||
Query(params): Query<TransactionQuery>,
|
||||
Extension(claims): Extension<Claims>, // ← Get user_id from JWT!
|
||||
) -> Result<Json<serde_json::Value>, (StatusCode, Json<serde_json::Value>)> {
|
||||
let user_id = &claims.bank_user_id; // ← Extract from JWT
|
||||
|
||||
let bank = bank_code.parse::<Bank>()
|
||||
.map_err(|_| (StatusCode::BAD_REQUEST, Json(json!({ "error": "Invalid bank code" }))))?;
|
||||
|
||||
let consent_id = db::consents::get_valid_consent(&state.db_pool, &user_id, bank.code())
|
||||
let consent_id = db::consents::get_valid_consent(&state.db_pool, user_id, bank.code())
|
||||
.await
|
||||
.map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, Json(json!({ "error": e.to_string() }))))?
|
||||
.ok_or_else(|| (
|
||||
|
|
@ -191,7 +206,7 @@ pub async fn get_transactions_handler(
|
|||
.await
|
||||
.map_err(map_banking_error)?;
|
||||
|
||||
// ✨ NEW: Save all transactions to cache
|
||||
// ✨ Save all transactions to cache
|
||||
for tx in &transactions_response.data.transaction {
|
||||
let _ = db::transactions::store_transaction(
|
||||
&state.db_pool,
|
||||
|
|
@ -202,8 +217,8 @@ pub async fn get_transactions_handler(
|
|||
&tx.amount.currency,
|
||||
&tx.credit_debit_indicator,
|
||||
&tx.status,
|
||||
tx.booking_date_time, // Already DateTime<Utc>
|
||||
tx.value_date_time, // Already Option<DateTime<Utc>>
|
||||
tx.booking_date_time,
|
||||
tx.value_date_time,
|
||||
&tx.transaction_information,
|
||||
tx.bank_transaction_code.as_ref().map(|b| b.code.as_str()),
|
||||
).await;
|
||||
|
|
@ -214,9 +229,10 @@ pub async fn get_transactions_handler(
|
|||
|
||||
pub async fn get_all_transactions_handler(
|
||||
State(state): State<AppState>,
|
||||
Path(bank_user_id): Path<String>,
|
||||
Query(params): Query<TransactionQuery>, // ← Добавили query params
|
||||
Query(params): Query<TransactionQuery>,
|
||||
Extension(claims): Extension<Claims>, // ← Add this
|
||||
) -> Result<Json<serde_json::Value>, (StatusCode, Json<serde_json::Value>)> {
|
||||
let bank_user_id = &claims.bank_user_id;
|
||||
let page = params.page.unwrap_or(1);
|
||||
let limit = params.limit.unwrap_or(20); // Default: 20 на странице для ленты
|
||||
|
||||
|
|
@ -300,12 +316,15 @@ pub async fn get_all_transactions_handler(
|
|||
|
||||
pub async fn delete_consent_handler(
|
||||
State(state): State<AppState>,
|
||||
Path((bank_code, user_id)): Path<(String, String)>,
|
||||
Path(bank_code): Path<String>, // ← Only bank_code now
|
||||
Extension(claims): Extension<Claims>, // ← Get user_id from JWT!
|
||||
) -> impl IntoResponse {
|
||||
let user_id = &claims.bank_user_id; // ← Extract from JWT
|
||||
|
||||
let bank = bank_code.parse::<Bank>()
|
||||
.map_err(|_| (StatusCode::BAD_REQUEST, Json(json!({ "error": "Invalid bank code" }))))?;
|
||||
|
||||
let consent_id = db::consents::get_valid_consent(&state.db_pool, &user_id, bank.code())
|
||||
let consent_id = db::consents::get_valid_consent(&state.db_pool, user_id, bank.code())
|
||||
.await
|
||||
.map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, Json(json!({ "error": e.to_string() }))))?
|
||||
.ok_or_else(|| (StatusCode::NOT_FOUND, Json(json!({ "error": "Consent not found" }))))?;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue