env and docker fixes
This commit is contained in:
@@ -235,7 +235,7 @@ pub struct UpdatePasswordValues{
|
||||
username: String,
|
||||
current_password: String,
|
||||
newpassword: String,
|
||||
hotel_id: i32,
|
||||
//hotel_id: i32,
|
||||
|
||||
}
|
||||
|
||||
@@ -296,7 +296,7 @@ pub async fn UpdatePassword(
|
||||
pub struct LoginValues {
|
||||
username : String,
|
||||
password : String,
|
||||
hotel_id: i32,
|
||||
//hotel_id: i32,
|
||||
}
|
||||
|
||||
pub struct LoginPayload(pub LoginValues);
|
||||
@@ -320,7 +320,7 @@ struct Claims{
|
||||
id: i32,
|
||||
hotel_id: i32,
|
||||
//display_name
|
||||
username: String,
|
||||
//username: String,
|
||||
exp: usize,
|
||||
}
|
||||
|
||||
@@ -376,7 +376,7 @@ pub async fn clean_auth_loging(
|
||||
let claims = serde_json::json!({
|
||||
"id": user_id,
|
||||
"hotel_id": hotel_id,
|
||||
"username": payload.username,
|
||||
//"username": payload.username,
|
||||
"exp": expiration
|
||||
});
|
||||
|
||||
@@ -400,6 +400,7 @@ pub struct CreateRefreshTokenValue {
|
||||
|
||||
}
|
||||
|
||||
//TODO: refactor this to impl IntoResponse ans not Result
|
||||
#[axum::debug_handler]
|
||||
pub async fn create_refresh_token(
|
||||
State(state): State<AppState>,
|
||||
@@ -417,7 +418,6 @@ pub async fn create_refresh_token(
|
||||
let salt = SaltString::generate(&mut OsRng);
|
||||
let mut bytes = [0u8; 64];
|
||||
OsRng.fill_bytes(&mut bytes);
|
||||
|
||||
let raw_token = Uuid::new_v4().to_string();
|
||||
|
||||
let hashed_token = argon2
|
||||
@@ -504,19 +504,16 @@ pub async fn login_refresh_token (
|
||||
Ok(opt) => opt,
|
||||
Err(_) => return (StatusCode::INTERNAL_SERVER_ERROR, "DB query error").into_response(),
|
||||
};
|
||||
|
||||
|
||||
let (user_id, token_hash, hotel_id) = match device_row {
|
||||
Some(tuple) => tuple,
|
||||
None => return (StatusCode::UNAUTHORIZED, "No matching device").into_response(),
|
||||
};
|
||||
|
||||
|
||||
if !verify_password(&payload.refresh_token, &token_hash) {
|
||||
return (StatusCode::UNAUTHORIZED, "Invalid or mismatched token").into_response();
|
||||
}
|
||||
|
||||
|
||||
let expiration = match chrono::Utc::now().checked_add_signed(chrono::Duration::hours(15)) {
|
||||
Some(time) => time.timestamp() as usize,
|
||||
None => {
|
||||
@@ -543,6 +540,98 @@ pub async fn login_refresh_token (
|
||||
Json(LoginResponse { token }).into_response()
|
||||
}
|
||||
|
||||
pub async fn logout_from_single_device (
|
||||
State(state): State<AppState>,
|
||||
Extension(keys): Extension<JwtKeys>,
|
||||
user_agent: Option<TypedHeader<UserAgent>>,
|
||||
Json(payload): Json<LoginRefreshTokenValues>
|
||||
) -> impl IntoResponse {
|
||||
|
||||
let user_agent_str = user_agent
|
||||
.map(|ua| ua.to_string())
|
||||
.unwrap_or_else(|| "Unknown".to_string());
|
||||
|
||||
let device_id_str = payload.device_id.to_string();
|
||||
|
||||
let conn = match state.logs_pool.get() {
|
||||
Ok(c) => c,
|
||||
Err(_) => return (StatusCode::INTERNAL_SERVER_ERROR, "DB connection error").into_response(),
|
||||
};
|
||||
|
||||
let device_row = match conn.query_row(
|
||||
"SELECT user_id, token_hash, hotel_id, id FROM refresh_token WHERE device_id = ?1 AND user_agent = ?2 AND revoke = 0 ",
|
||||
params![&device_id_str, &user_agent_str],
|
||||
|row| {
|
||||
let user_id: i32 = row.get(0)?;
|
||||
let token_hash: String = row.get(1)?;
|
||||
let hotel_id: i32 = row.get(2)?;
|
||||
let id:i32 = row.get(3)?;
|
||||
//let displayname: String = row.get(3)?;
|
||||
Ok((user_id, token_hash, hotel_id,id))
|
||||
},
|
||||
).optional() {
|
||||
Ok(opt) => opt,
|
||||
Err(_) => return (StatusCode::INTERNAL_SERVER_ERROR, "DB query error").into_response(),
|
||||
};
|
||||
|
||||
let (user_id, token_hash, hotel_id, token_id) = match device_row {
|
||||
Some(tuple) => tuple,
|
||||
None => return (StatusCode::UNAUTHORIZED, "No matching device").into_response(),
|
||||
};
|
||||
|
||||
if !verify_password(&payload.refresh_token, &token_hash) {
|
||||
return (StatusCode::UNAUTHORIZED, "Invalid or mismatched token").into_response();
|
||||
}
|
||||
|
||||
let revoked: Result<String, rusqlite::Error> = conn.query_row(
|
||||
"UPDATE refresh_token SET revoked = 1 WHERE id = ?1 RETURNING device_id",
|
||||
params![&token_id],
|
||||
|row| row.get(0),
|
||||
);
|
||||
|
||||
return (StatusCode::OK, format!("Token deleted for device id {}", &device_id_str)).into_response()
|
||||
|
||||
}
|
||||
|
||||
pub async fn logout_from_all_devices (
|
||||
State(state): State<AppState>,
|
||||
Extension(keys): Extension<JwtKeys>,
|
||||
AuthClaims { user_id, hotel_id }: AuthClaims,
|
||||
Json(payload): Json<LoginRefreshTokenValues>
|
||||
) -> impl IntoResponse {
|
||||
|
||||
|
||||
|
||||
let device_id_str = payload.device_id.to_string();
|
||||
|
||||
let conn = match state.logs_pool.get() {
|
||||
Ok(c) => c,
|
||||
Err(_) => return (StatusCode::INTERNAL_SERVER_ERROR, "DB connection error").into_response(),
|
||||
};
|
||||
|
||||
let result = conn.execute(
|
||||
"UPDATE refresh_token SET revoked = 1 WHERE user_id = ?1 AND revoked = 0",
|
||||
params![&user_id],
|
||||
);
|
||||
|
||||
match result {
|
||||
Ok(count) if count > 0 => {
|
||||
(StatusCode::OK, format!("Revoked {} active tokens", count)).into_response()
|
||||
}
|
||||
Ok(_) => (StatusCode::NOT_FOUND, "No active tokens to revoke").into_response(),
|
||||
Err(_) => (
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
"Database update error".to_string(),
|
||||
)
|
||||
.into_response(),
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
fn internal_error<E: std::fmt::Display>(err: E) -> (StatusCode, String) {
|
||||
(StatusCode::INTERNAL_SERVER_ERROR, format!("Internal error: {}", err))
|
||||
}
|
||||
Reference in New Issue
Block a user