fix get refresh token handler and update login refresh token

This commit is contained in:
2025-11-28 20:48:46 +01:00
parent c9e338574e
commit 02c11137ff
5 changed files with 63 additions and 26 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -92,7 +92,7 @@ std::panic::set_hook(Box::new(|info| {
let app = create_router(state) let app = create_router(state)
.layer(Extension(jwt_keys)); .layer(Extension(jwt_keys));
let listener = TcpListener::bind("0.0.0.0:8080").await?; let listener = TcpListener::bind("0.0.0.0:7080").await?;
serve(listener, app).into_future().await?; serve(listener, app).into_future().await?;
Ok(()) Ok(())
} }

View File

@@ -436,7 +436,7 @@ pub async fn create_refresh_token(
.map_err(|_| (StatusCode::INTERNAL_SERVER_ERROR, "DB connection error".to_string()))?; .map_err(|_| (StatusCode::INTERNAL_SERVER_ERROR, "DB connection error".to_string()))?;
//TODO: prend id username password de users
// let mut stmt = conn.prepare( // let mut stmt = conn.prepare(
// "SELECT id, password FROM users WHERE username = ?1" // "SELECT id, password FROM users WHERE username = ?1"
@@ -468,7 +468,7 @@ pub async fn create_refresh_token(
//TODO: stmt, querry hotel-id dans hotel-user-link avec l'ID précédant //TODO: get hotel name
let mut stmt = match conn.prepare( let mut stmt = match conn.prepare(
"SELECt hotel_id FROM hotel_user_link WHERE user_id = ?1" "SELECt hotel_id FROM hotel_user_link WHERE user_id = ?1"
) { ) {
@@ -478,10 +478,7 @@ pub async fn create_refresh_token(
//TODO: compiler les hotel id dans un vecteur pour le feed dans le refresh token //TODO: compiler les hotel id dans un vecteur pour le feed dans le refresh token
//Deja fait ? //Deja fait ?
let hotel_ids: Vec<i32> = match stmt
let hotel_ids = match stmt
.query_map(params![&user_id],|row| row.get (0)) .query_map(params![&user_id],|row| row.get (0))
{ {
Ok(rows) => rows.collect::<Result<Vec<_>,_>>() Ok(rows) => rows.collect::<Result<Vec<_>,_>>()
@@ -489,6 +486,13 @@ pub async fn create_refresh_token(
Err(_) => return Err((StatusCode::INTERNAL_SERVER_ERROR, "Error mapping hotel_ids".to_string())), Err(_) => return Err((StatusCode::INTERNAL_SERVER_ERROR, "Error mapping hotel_ids".to_string())),
}; };
let hotel_ids_json = match serde_json::to_string(&hotel_ids) {
Ok(json) => json,
Err(_) => return Err((StatusCode::INTERNAL_SERVER_ERROR, "Error mapping hotel_ids".to_string())),
};
/*.map_err(|_| (StatusCode::INTERNAL_SERVER_ERROR, "Error mapping hotel_ids".to_string())); */
conn.execute( conn.execute(
"INSERT INTO refresh_token (user_id, token_hash, device_id, user_agent, hotel_id_list) "INSERT INTO refresh_token (user_id, token_hash, device_id, user_agent, hotel_id_list)
@@ -498,7 +502,7 @@ pub async fn create_refresh_token(
&hashed_token, &hashed_token,
&device_id_str, &device_id_str,
&user_agent_str, &user_agent_str,
&hotel_ids, &hotel_ids_json,
], ],
).map_err(|e| { ).map_err(|e| {
(StatusCode::INTERNAL_SERVER_ERROR, format!("DB error: {}", e)) (StatusCode::INTERNAL_SERVER_ERROR, format!("DB error: {}", e))
@@ -587,27 +591,35 @@ pub async fn login_refresh_token (
//deserializing the list : //deserializing the list :
//let hotel_ids: Vec<i32> = serde_json::from_str(&stored_value)?; //let hotel_ids: Vec<i32> = serde_json::from_str(&stored_value)?;
let mut stmt = match conn.prepare( let mut stmt = match conn.prepare(
"SELECT user_id, token_hash, hotel_id "SELECT user_id, token_hash, hotel_id_list
FROM refresh_token FROM refresh_token
WHERE device_id = ?1 AND user_agent = ?2" WHERE device_id = ?1 AND user_agent = ?2 "
) { ) {
Ok(s) => s, Ok(s) => s,
Err(_) => return (StatusCode::INTERNAL_SERVER_ERROR, "DB query error").into_response(), Err(_) => return (StatusCode::INTERNAL_SERVER_ERROR, "DB query error").into_response(),
}; };
let rows = match stmt.query_map(params![&device_id_str, &user_agent_str], |row| { let rows = match stmt.query_one(params![&device_id_str, &user_agent_str], |row| {
Ok(( Ok((
row.get::<_, i32>(0)?, // user_id row.get::<_, i32>(0)?, // user_id
row.get::<_, String>(1)?, // token_hash row.get::<_, String>(1)?, // token_hash
row.get::<_, i32>(2)?, // hotel_id row.get::<_, String>(2)?, // hotel_id //FIXME: this is supposed to be vectore maybe ?
)) ))
}) { }) {
Ok(r) => r, Ok(r) => r,
Err(_) => return (StatusCode::INTERNAL_SERVER_ERROR, "DB query error").into_response(), Err(_) => return (StatusCode::INTERNAL_SERVER_ERROR, "DB query error").into_response(),
}; };
//TODO: extraction of the blob
//let json_hotel_ids = rows.2;
let (user_id, saved_hash,json_hotel_ids) = rows;
let hotel_ids: Vec<i32> = match serde_json::from_str(&json_hotel_ids) {
Ok(ids) => ids,
Err(_) => return (StatusCode::INTERNAL_SERVER_ERROR, "Hotel ids are not deserializable to Vec").into_response(),
};
/*
let mut entries = Vec::new(); let mut entries = Vec::new();
for r in rows { for r in rows {
match r { match r {
@@ -615,27 +627,51 @@ pub async fn login_refresh_token (
Err(_) => continue, // ignore corrupt rows Err(_) => continue, // ignore corrupt rows
} }
} }
*/
if entries.is_empty() { if hotel_ids.is_empty() {
return (StatusCode::UNAUTHORIZED, "No matching device").into_response(); return (StatusCode::UNAUTHORIZED, "No matching device").into_response();
} }
if !verify_password(&payload.refresh_token, &saved_hash) {
// skip rows with wrong hash
return (StatusCode::UNAUTHORIZED, "Invelid credentials").into_response();
}
let expiration = match chrono::Utc::now().checked_add_signed(chrono::Duration::hours(15)) {
Some(time) => time.timestamp() as usize,
None => {
// Handle overflow — probably a 500, since this should never happen
return (StatusCode::INTERNAL_SERVER_ERROR, "Time overflow".to_string()).into_response();
}
};
let mut tokens = Vec::new(); let mut tokens = Vec::new();
//FIXME: swap to "for hotel_id in entries" // interator over vector list for hotel_id in hotel_ids {
let claims = serde_json::json!({
"id": user_id,
"hotel_id": hotel_id,
"exp": expiration
});
let token = match encode(&Header::default(), &claims, &keys.encoding) {
Ok(token) => token,
Err(_) => return (StatusCode::INTERNAL_SERVER_ERROR, "JWT creation failed").into_response(),
};
tokens.push(token);
}
/* OLD ITERATION OVER MULTIPLE REFRESH TOKEN
// swap to "for hotel_id in entries" // interator over vector list
for (user_id, token_hash, hotel_id) in entries { for (user_id, token_hash, hotel_id) in entries {
if !verify_password(&payload.refresh_token, &token_hash) { if !verify_password(&payload.refresh_token, &token_hash) {
// skip rows with wrong hash // skip rows with wrong hash
continue; continue;
} }
//FIXME: single expiration //FIXME: single expiration
let expiration = match chrono::Utc::now().checked_add_signed(chrono::Duration::hours(15)) {
Some(time) => time.timestamp() as usize,
None => {
// Handle overflow — probably a 500, since this should never happen
return (StatusCode::INTERNAL_SERVER_ERROR, "Time overflow".to_string()).into_response();
}
};
let claims = serde_json::json!({ let claims = serde_json::json!({
"id": user_id, "id": user_id,
@@ -650,14 +686,15 @@ pub async fn login_refresh_token (
tokens.push(token); tokens.push(token);
} }
*/
if tokens.is_empty() {
if tokens.is_empty() { return (StatusCode::UNAUTHORIZED, "Invalid or mismatched token").into_response();
return (StatusCode::UNAUTHORIZED, "Invalid or mismatched token").into_response(); }
}
//Json(tokens).into_response() //Json(tokens).into_response()
Json(MultiLoginResponse { tokens }).into_response() Json(MultiLoginResponse { tokens }).into_response()
} }
pub async fn logout_from_single_device ( pub async fn logout_from_single_device (