turned on WAL on db, fix force update of passwords
This commit is contained in:
@@ -66,13 +66,19 @@ pub async fn add_user_to_conv(
|
||||
Err(_) => return (StatusCode::INTERNAL_SERVER_ERROR, "prepare failed".to_string())
|
||||
};
|
||||
|
||||
if !statement.exists(params![user_id, payload.conv_id])
|
||||
.map_err(|_| (StatusCode::INTERNAL_SERVER_ERROR, "Query failed".to_string())).unwrap()
|
||||
{
|
||||
// Early exit if not creator
|
||||
return ((StatusCode::FORBIDDEN, "Not the creator".to_string()));
|
||||
}
|
||||
match statement.exists(params![user_id, payload.conv_id]) {
|
||||
Ok(true) => {
|
||||
//user is creator
|
||||
}
|
||||
Ok(false) => {
|
||||
//user is not the creator
|
||||
return (StatusCode::FORBIDDEN, "Not the creato of the conversation".to_string())
|
||||
}
|
||||
Err(_) => {
|
||||
return(StatusCode::INTERNAL_SERVER_ERROR, "Query failed".to_string())
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for target_id in &payload.users {
|
||||
let rows_inserted = match conn.execute(
|
||||
@@ -114,13 +120,19 @@ pub async fn send_message(
|
||||
Err(_) => return (StatusCode::INTERNAL_SERVER_ERROR, "prepare failed".to_string())
|
||||
};
|
||||
|
||||
if !statement.exists(params![user_id, payload.conv_id])
|
||||
.map_err(|_| (StatusCode::INTERNAL_SERVER_ERROR, "Query failed".to_string()))
|
||||
.unwrap()
|
||||
{
|
||||
// Early exit if not creator
|
||||
return ((StatusCode::FORBIDDEN, "Not part of the conversation".to_string()));
|
||||
match statement.exists(params![user_id, payload.conv_id]) {
|
||||
Ok(true) => {
|
||||
// user is part of the conversation — continue
|
||||
}
|
||||
Ok(false) => {
|
||||
// early exit: not part of the conversation
|
||||
return (StatusCode::FORBIDDEN, "Not part of the conversation".to_string());
|
||||
}
|
||||
Err(_) => {
|
||||
// query failed
|
||||
return (StatusCode::INTERNAL_SERVER_ERROR, "Query failed".to_string());
|
||||
}
|
||||
}
|
||||
|
||||
let result = conn.execute(
|
||||
"INSERT INTO message (sender_id, content, conversation_id) VALUES (?1, ?2, ?3)",
|
||||
@@ -209,11 +221,15 @@ pub async fn get_message(
|
||||
sent_at: row.get(3)?,
|
||||
})
|
||||
}
|
||||
).map_err(|_| (StatusCode::INTERNAL_SERVER_ERROR, "Query failed".to_string()))?
|
||||
.collect::<Result<Vec<_>, _>>()
|
||||
.map_err(|_| (StatusCode::INTERNAL_SERVER_ERROR, "Collect failed".to_string()))?;
|
||||
)
|
||||
.map_err(|_| (StatusCode::INTERNAL_SERVER_ERROR, "Query failed".to_string()))?
|
||||
.collect::<Result<Vec<_>, _>>()
|
||||
.map_err(|_| (StatusCode::INTERNAL_SERVER_ERROR, "Collect failed".to_string()))?;
|
||||
|
||||
Ok((StatusCode::OK, serde_json::to_string(&messages).unwrap()))
|
||||
let response = serde_json::to_string(&messages)
|
||||
.map_err(|_| (StatusCode::INTERNAL_SERVER_ERROR, "Serialisation failed"));
|
||||
|
||||
Ok((StatusCode::OK, response ))
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ use crate::utils::auth::JwtKeys;
|
||||
|
||||
|
||||
|
||||
#[tokio::main]
|
||||
#[tokio::main(flavor = "multi_thread", worker_threads = 8)]
|
||||
async fn main() -> std::io::Result<()> {
|
||||
|
||||
|
||||
|
||||
@@ -77,13 +77,12 @@ pub async fn clean_db_update(
|
||||
match result {
|
||||
Ok(room_number) => {
|
||||
// --- broadcast to all WS clients in the hotel ---
|
||||
|
||||
if let Err(err) = conn.execute(
|
||||
"INSERT INTO room_history (room_id, room_number, status) VALUES (?1, ?2, ?3)",
|
||||
params![&room_id, &room_number, &payload.status],
|
||||
) {
|
||||
return (StatusCode::INTERNAL_SERVER_ERROR, format!("Failed to insert history: {err}"));
|
||||
}
|
||||
"INSERT INTO room_history (room_id, room_number, status) VALUES (?1, ?2, ?3)",
|
||||
params![&room_id, &room_number, &payload.status],
|
||||
) {
|
||||
return (StatusCode::INTERNAL_SERVER_ERROR, format!("Failed to insert history: {err}"));
|
||||
}
|
||||
if let Some(hotel_users) = state.ws_map.get(&hotel_id) {
|
||||
let update_msg = json!({
|
||||
"room_id": room_id,
|
||||
|
||||
@@ -106,10 +106,15 @@ fn hash_password(password: &str) -> anyhow::Result<String> {
|
||||
|
||||
// Verify an incoming password against stored hash
|
||||
fn verify_password(password: &str, stored_hash: &str) -> bool {
|
||||
let parsed_hash = PasswordHash::new(stored_hash).unwrap();
|
||||
|
||||
let parsed_hash = match PasswordHash::new(&stored_hash) {
|
||||
Ok(hash) => hash,
|
||||
Err(_) => return false,
|
||||
};
|
||||
|
||||
Argon2::default()
|
||||
.verify_password(password.as_bytes(), &parsed_hash)
|
||||
.is_ok()
|
||||
.verify_password(password.as_bytes(), &parsed_hash).is_ok()
|
||||
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
@@ -155,6 +160,133 @@ pub async fn register_user (
|
||||
Ok((StatusCode::CREATED, "User registered successfully"))
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct ForceUpdatePasswordValues{
|
||||
username: String,
|
||||
newpassword: String,
|
||||
hotel_id: i32,
|
||||
admin_pass: String,
|
||||
}
|
||||
|
||||
//pub struct ForceUpdatePasswordPayload (pub ForceUpdatePasswordValues);
|
||||
|
||||
pub async fn ForceUpdatePassword(
|
||||
State(state): State<AppState>,
|
||||
Json(payload): Json<ForceUpdatePasswordValues>,
|
||||
) -> impl IntoResponse {
|
||||
|
||||
let conn = match state.logs_pool.get() {
|
||||
Ok(c) => c,
|
||||
Err(_) => return (StatusCode::INTERNAL_SERVER_ERROR, "DB, conn failed").into_response()
|
||||
};
|
||||
|
||||
let user_row = match conn.query_row(
|
||||
"SELECT id FROM users WHERE username = ?1 AND hotel_id = ?2",
|
||||
params![&payload.username, &payload.hotel_id],
|
||||
|row|{
|
||||
let user_id: i32 = row.get(0)?;
|
||||
//let hotel_id: i32 = row.get(1)?;
|
||||
Ok((user_id))
|
||||
},
|
||||
).optional() {
|
||||
Ok(opt) => opt,
|
||||
Err(_) => return (StatusCode::INTERNAL_SERVER_ERROR, "DB query error")
|
||||
.into_response(),
|
||||
};
|
||||
|
||||
let (user_id) = match user_row {
|
||||
Some(u) => u,
|
||||
None => return (StatusCode::UNAUTHORIZED, "Not correct user")
|
||||
.into_response(),
|
||||
};
|
||||
|
||||
let admin_check: String = "my_admin_password".to_string();
|
||||
|
||||
if &payload.admin_pass != &admin_check {
|
||||
return (StatusCode::UNAUTHORIZED, "Invalid Amin Password").into_response()
|
||||
};
|
||||
|
||||
|
||||
let hashed_password = match hash_password(&payload.newpassword) {
|
||||
Ok(h) => h,
|
||||
Err(_) => return (StatusCode::INTERNAL_SERVER_ERROR, "Password hashing failed").into_response(),
|
||||
};
|
||||
|
||||
let result = conn.execute(
|
||||
"UPDATE users SET password = ?1 WHERE id = ?2",
|
||||
params![&hashed_password, &user_id],
|
||||
);
|
||||
|
||||
match result {
|
||||
Ok(rows) if rows > 0 => (StatusCode::OK, "Password updated").into_response(),
|
||||
Ok(_) => (StatusCode::NOT_FOUND, "User not found").into_response(),
|
||||
Err(_) => (StatusCode::INTERNAL_SERVER_ERROR, "Failed to update password").into_response(),
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct UpdatePasswordValues{
|
||||
username: String,
|
||||
current_password: String,
|
||||
newpassword: String,
|
||||
hotel_id: i32,
|
||||
|
||||
}
|
||||
|
||||
pub async fn UpdatePassword(
|
||||
State(state): State<AppState>,
|
||||
Json(payload): Json<UpdatePasswordValues>,
|
||||
) -> impl IntoResponse {
|
||||
|
||||
let conn = match state.logs_pool.get() {
|
||||
Ok(c) => c,
|
||||
Err(_) => return (StatusCode::INTERNAL_SERVER_ERROR, "DB, conn failed").into_response()
|
||||
};
|
||||
|
||||
let user_row = match conn.query_row(
|
||||
"SELECT password, id FROM users WHERE username = ?1 AND current_password = ?2",
|
||||
params![&payload.username, &payload.current_password],
|
||||
|row|{
|
||||
let password: String = row.get(0)?;
|
||||
let id: i32 = row.get(1)?;
|
||||
Ok((password, id))
|
||||
},
|
||||
).optional() {
|
||||
Ok(opt) => opt,
|
||||
Err(_) => return (StatusCode::INTERNAL_SERVER_ERROR, "DB query error")
|
||||
.into_response(),
|
||||
};
|
||||
|
||||
let (password, user_id) = match user_row {
|
||||
Some(u) => u,
|
||||
None => return (StatusCode::UNAUTHORIZED, "Not correct user")
|
||||
.into_response(),
|
||||
};
|
||||
|
||||
if verify_password( &payload.current_password, &password ) {
|
||||
return (StatusCode::UNAUTHORIZED, "Invalid Password").into_response()
|
||||
};
|
||||
|
||||
|
||||
let hashed_password = match hash_password(&payload.newpassword) {
|
||||
Ok(h) => h,
|
||||
Err(_) => return (StatusCode::INTERNAL_SERVER_ERROR, "Password hashing failed").into_response(),
|
||||
};
|
||||
|
||||
let result = conn.execute(
|
||||
"UPDATE users SET password = ?1 WHERE id = ?2",
|
||||
params![&hashed_password, &user_id],
|
||||
);
|
||||
|
||||
match result {
|
||||
Ok(rows) if rows > 0 => (StatusCode::OK, "Password updated").into_response(),
|
||||
Ok(_) => (StatusCode::NOT_FOUND, "User not found").into_response(),
|
||||
Err(_) => (StatusCode::INTERNAL_SERVER_ERROR, "Failed to update password").into_response(),
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
pub struct LoginValues {
|
||||
username : String,
|
||||
@@ -227,11 +359,14 @@ pub async fn clean_auth_loging(
|
||||
return (StatusCode::UNAUTHORIZED, "Invelid credentials").into_response();
|
||||
}
|
||||
|
||||
let expiration = chrono::Utc::now()
|
||||
.checked_add_signed(chrono::Duration::hours(15))
|
||||
.unwrap()
|
||||
.timestamp() as usize;
|
||||
|
||||
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!({
|
||||
"id": user_id,
|
||||
@@ -251,6 +386,11 @@ pub async fn clean_auth_loging(
|
||||
Json(LoginResponse { token }).into_response()
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
fn internal_error<E: std::fmt::Display>(err: E) -> (StatusCode, String) {
|
||||
(StatusCode::INTERNAL_SERVER_ERROR, format!("Internal error: {}", err))
|
||||
}
|
||||
@@ -15,6 +15,8 @@ pub fn utils_routes() -> Router<AppState> {
|
||||
.route("/register", put(register_user))
|
||||
.route("/ws/", get(ws_handler))
|
||||
.route("/tokentest", put(token_tester))
|
||||
.route("/force_update_password", put(ForceUpdatePassword))
|
||||
.route("/update_password", put(UpdatePassword))
|
||||
|
||||
//.with_state(state)
|
||||
}
|
||||
Reference in New Issue
Block a user