84 lines
2.5 KiB
Rust
84 lines
2.5 KiB
Rust
|
//! Handle registration, logins, and managing account data.
|
||
|
pub mod authentication;
|
||
|
pub mod payment;
|
||
|
pub mod referral;
|
||
|
pub mod rpc_keys;
|
||
|
pub mod stats;
|
||
|
pub mod subuser;
|
||
|
|
||
|
use super::errors::{Web3ProxyErrorContext, Web3ProxyResponse};
|
||
|
use crate::app::Web3ProxyApp;
|
||
|
|
||
|
use axum::{
|
||
|
headers::{authorization::Bearer, Authorization},
|
||
|
response::IntoResponse,
|
||
|
Extension, Json, TypedHeader,
|
||
|
};
|
||
|
use axum_macros::debug_handler;
|
||
|
use entities;
|
||
|
use entities::user;
|
||
|
use migration::sea_orm::{self, ActiveModelTrait};
|
||
|
use serde::Deserialize;
|
||
|
use std::sync::Arc;
|
||
|
|
||
|
/// `GET /user` -- Use a bearer token to get the user's profile.
|
||
|
///
|
||
|
/// - the email address of a user if they opted in to get contacted via email
|
||
|
///
|
||
|
/// TODO: this will change as we add better support for secondary users.
|
||
|
#[debug_handler]
|
||
|
pub async fn user_get(
|
||
|
Extension(app): Extension<Arc<Web3ProxyApp>>,
|
||
|
TypedHeader(Authorization(bearer_token)): TypedHeader<Authorization<Bearer>>,
|
||
|
) -> Web3ProxyResponse {
|
||
|
let (user, _semaphore) = app.bearer_is_authorized(bearer_token).await?;
|
||
|
|
||
|
Ok(Json(user).into_response())
|
||
|
}
|
||
|
|
||
|
/// the JSON input to the `post_user` handler.
|
||
|
#[derive(Debug, Deserialize)]
|
||
|
pub struct UserPost {
|
||
|
email: Option<String>,
|
||
|
}
|
||
|
|
||
|
/// `POST /user` -- modify the account connected to the bearer token in the `Authentication` header.
|
||
|
#[debug_handler]
|
||
|
pub async fn user_post(
|
||
|
Extension(app): Extension<Arc<Web3ProxyApp>>,
|
||
|
TypedHeader(Authorization(bearer_token)): TypedHeader<Authorization<Bearer>>,
|
||
|
Json(payload): Json<UserPost>,
|
||
|
) -> Web3ProxyResponse {
|
||
|
let (user, _semaphore) = app.bearer_is_authorized(bearer_token).await?;
|
||
|
|
||
|
let mut user: user::ActiveModel = user.into();
|
||
|
|
||
|
// update the email address
|
||
|
if let Some(x) = payload.email {
|
||
|
// TODO: only Set if no change
|
||
|
if x.is_empty() {
|
||
|
user.email = sea_orm::Set(None);
|
||
|
} else {
|
||
|
// TODO: do some basic validation
|
||
|
// TODO: don't set immediatly, send a confirmation email first
|
||
|
// TODO: compare first? or is sea orm smart enough to do that for us?
|
||
|
user.email = sea_orm::Set(Some(x));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// TODO: what else can we update here? password hash? subscription to newsletter?
|
||
|
|
||
|
let user = if user.is_changed() {
|
||
|
let db_conn = app.db_conn().web3_context("Getting database connection")?;
|
||
|
|
||
|
user.save(&db_conn).await?
|
||
|
} else {
|
||
|
// no changes. no need to touch the database
|
||
|
user
|
||
|
};
|
||
|
|
||
|
let user: user::Model = user.try_into().web3_context("Returning updated user")?;
|
||
|
|
||
|
Ok(Json(user).into_response())
|
||
|
}
|