Tweaks to database for users

This commit is contained in:
2025-04-23 19:49:44 -04:00
parent 3b5514e825
commit ebc1f30f24
5 changed files with 32 additions and 14 deletions

View File

@@ -62,10 +62,12 @@ CREATE INDEX ON metars (observation_time DESC);
CREATE TABLE IF NOT EXISTS users (
email TEXT PRIMARY KEY NOT NULL,
email_verified BOOLEAN NOT NULL DEFAULT false,
password_hash TEXT NOT NULL,
role TEXT NOT NULL,
first_name TEXT NOT NULL,
last_name TEXT NOT NULL,
avatar TEXT,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

View File

@@ -188,10 +188,12 @@ async fn change_password(
let update_user = UpdateUser {
email: None,
email_verified: None,
password: Some(password.into_inner()),
role: None,
first_name: None,
last_name: None,
avatar: None,
};
match update_user.update(&email).await {

View File

@@ -489,8 +489,6 @@ impl Airport {
airport.into()
})
.collect();
Runway::insert_all(&all_runway_rows).await?;
Frequency::insert_all(&all_frequency_rows).await?;
for chunk in airport_rows.chunks(chunk_size) {
let mut query_builder: QueryBuilder<Postgres> = QueryBuilder::new(
@@ -519,6 +517,9 @@ impl Airport {
query.execute(pool).await?;
}
Runway::insert_all(&all_runway_rows).await?;
Frequency::insert_all(&all_frequency_rows).await?;
Ok(())
}
@@ -577,7 +578,7 @@ impl Airport {
column: &str,
field: &'a Option<String>,
) {
if let Some(ref value_str) = field {
if let Some(value_str) = field {
// Split on commas, trim whitespace, and drop empties.
let values: Vec<&str> = value_str
.split(',')
@@ -606,7 +607,7 @@ impl Airport {
field: &'a Option<String>,
) {
// Query column like
if let Some(ref value) = field {
if let Some(value) = field {
if !*has_where {
builder.push(" WHERE ");
*has_where = true;
@@ -627,7 +628,7 @@ impl Airport {
field: &'a Option<String>,
) -> ApiResult<()> {
// Query bounds
if let Some(ref bounds_string) = field {
if let Some(bounds_string) = field {
if !*has_where {
builder.push(" WHERE ");
*has_where = true;

View File

@@ -4,6 +4,7 @@ use actix_cors::Cors;
use actix_web::{App, HttpServer, middleware::Logger, web};
use dotenv::from_filename;
use reqwest::Certificate;
use uuid::Uuid;
use crate::account::hash;
use crate::users::{User, ADMIN_ROLE};
@@ -43,10 +44,12 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
}
let admin_user = User {
email,
email_verified: true,
password_hash,
role: ADMIN_ROLE.to_string(),
first_name: "Admin".to_string(),
last_name: "".to_string(),
avatar: None,
updated_at: Default::default(),
created_at: Default::default(),
};

View File

@@ -21,9 +21,8 @@ impl RegisterRequest {
pub fn to_user(self) -> ApiResult<User> {
let password_hash = hash(&self.password)?;
Ok(User {
id: Uuid::new_v4(),
email: self.email.to_lowercase(),
emailVerified: false,
email_verified: false,
password_hash,
role: USER_ROLE.to_string(),
first_name: self.first_name,
@@ -43,7 +42,6 @@ pub struct LoginRequest {
#[derive(Debug, Serialize)]
pub struct UserResponse {
pub id: Uuid,
pub email_verified: bool,
pub role: String,
pub first_name: String,
@@ -55,8 +53,7 @@ pub struct UserResponse {
impl From<User> for UserResponse {
fn from(user: User) -> Self {
UserResponse {
id: user.id,
email_verified: user.emailVerified,
email_verified: user.email_verified,
role: user.role,
first_name: user.first_name,
last_name: user.last_name,
@@ -67,8 +64,8 @@ impl From<User> for UserResponse {
#[derive(Debug, Deserialize, sqlx::FromRow)]
pub struct UpdateUser {
pub id: Uuid,
pub email: Option<String>,
pub email_verified: Option<bool>,
pub password: Option<String>,
pub role: Option<String>,
pub first_name: Option<String>,
@@ -98,6 +95,11 @@ impl UpdateUser {
query_builder.push("email = ");
query_builder.push_bind(email);
}
if let Some(ref email_verified) = self.email_verified {
push_comma(&mut query_builder);
query_builder.push("email_verified = ");
query_builder.push_bind(email_verified);
}
if let Some(ref password) = self.password {
push_comma(&mut query_builder);
let password_hash = hash(password)?;
@@ -119,6 +121,11 @@ impl UpdateUser {
query_builder.push("last_name = ");
query_builder.push_bind(last_name);
}
if let Some(ref avatar) = self.avatar {
push_comma(&mut query_builder);
query_builder.push("avatar = ");
query_builder.push_bind(avatar);
}
push_comma(&mut query_builder);
query_builder.push("updated_at = ");
query_builder.push_bind(Utc::now());
@@ -136,9 +143,8 @@ impl UpdateUser {
#[derive(Debug, Serialize, Deserialize, sqlx::FromRow)]
pub struct User {
pub id: Uuid,
pub email: String,
pub emailVerified: bool,
pub email_verified: bool,
pub password_hash: String,
pub role: String,
pub first_name: String,
@@ -188,23 +194,27 @@ impl User {
r#"
INSERT INTO {} (
email,
email_verified,
password_hash,
role,
first_name,
last_name,
avatar,
created_at,
updated_at
)
VALUES ($1, $2, $3, $4, $5, $6, $7)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
RETURNING *
"#,
TABLE_NAME,
))
.bind(&self.email)
.bind(&self.email_verified)
.bind(&self.password_hash)
.bind(&self.role)
.bind(&self.first_name)
.bind(&self.last_name)
.bind(&self.avatar)
.bind(self.created_at)
.bind(self.updated_at)
.fetch_one(pool)