backend: remove user api
This commit is contained in:
parent
117efffea2
commit
1b0e5d53c2
@ -7,7 +7,7 @@ const password = defineModel("password");
|
|||||||
const errorMessage = ref(null);
|
const errorMessage = ref(null);
|
||||||
|
|
||||||
async function login() {
|
async function login() {
|
||||||
await fetch(import.meta.hot ? "http://localhost:54600/api/v1/login_user" : "/api/v1/login_user", {
|
await fetch(import.meta.hot ? "http://localhost:54600/api/v1/user/login" : "/api/v1/user/login", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
|
@ -9,13 +9,12 @@ const is_admin = ref(null);
|
|||||||
const errorMessage = ref(null);
|
const errorMessage = ref(null);
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
const asd = await fetch(import.meta.hot ? "http://localhost:54600/api/v1/me" : "/api/v1/me", {
|
const asd = await fetch(import.meta.hot ? "http://localhost:54600/api/v1/user/profile" : "/api/v1/user/profile", {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
},
|
},
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
mode: "cors",
|
|
||||||
})
|
})
|
||||||
.then(async response => {
|
.then(async response => {
|
||||||
const isJson = response.headers.get('content-type')?.includes('application/json');
|
const isJson = response.headers.get('content-type')?.includes('application/json');
|
||||||
@ -26,9 +25,9 @@ onMounted(async () => {
|
|||||||
return Promise.reject(error);
|
return Promise.reject(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
name.value = data.data.user.name;
|
name.value = data.user.name;
|
||||||
email.value = data.data.user.email;
|
email.value = data.user.email;
|
||||||
is_admin.value = data.data.user.is_admin;
|
is_admin.value = data.user.is_admin;
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
errorMessage.value = error;
|
errorMessage.value = error;
|
||||||
|
0
crates/frontend/src/views/NotFound.vue
Normal file
0
crates/frontend/src/views/NotFound.vue
Normal file
@ -4,6 +4,7 @@ use serde_json::json;
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum AuthError<E> {
|
pub enum AuthError<E> {
|
||||||
InternalError(E),
|
InternalError(E),
|
||||||
|
InternalE,
|
||||||
MissingCredentials,
|
MissingCredentials,
|
||||||
InvalidCredentials,
|
InvalidCredentials,
|
||||||
MissingToken,
|
MissingToken,
|
||||||
@ -15,6 +16,7 @@ impl<E: std::error::Error> IntoResponse for AuthError<E> {
|
|||||||
fn into_response(self) -> axum::response::Response {
|
fn into_response(self) -> axum::response::Response {
|
||||||
let (status, message) = match self {
|
let (status, message) = match self {
|
||||||
Self::InternalError(e) => (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()),
|
Self::InternalError(e) => (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()),
|
||||||
|
Self::InternalE => (StatusCode::INTERNAL_SERVER_ERROR, "Internal E".to_string()),
|
||||||
Self::MissingCredentials => {
|
Self::MissingCredentials => {
|
||||||
(StatusCode::BAD_REQUEST, "Missing credentials".to_string())
|
(StatusCode::BAD_REQUEST, "Missing credentials".to_string())
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,7 @@ pub fn routes(state: Arc<AppState>) -> Router {
|
|||||||
Router::new()
|
Router::new()
|
||||||
.route("/v1/healthcheck", get(healthcheck))
|
.route("/v1/healthcheck", get(healthcheck))
|
||||||
.route("/v1/user/register", post(user::register))
|
.route("/v1/user/register", post(user::register))
|
||||||
|
.route("/v1/user/remove", post(user::remove))
|
||||||
.route("/v1/user/login", post(user::login))
|
.route("/v1/user/login", post(user::login))
|
||||||
.route("/v1/user/logout", get(user::logout))
|
.route("/v1/user/logout", get(user::logout))
|
||||||
.route("/v1/user/profile", get(user::profile).route_layer(jwt))
|
.route("/v1/user/profile", get(user::profile).route_layer(jwt))
|
||||||
|
@ -34,6 +34,11 @@ pub struct FilteredUser {
|
|||||||
pub is_admin: bool,
|
pub is_admin: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(serde::Deserialize)]
|
||||||
|
pub struct RemoveUser {
|
||||||
|
pub id: String,
|
||||||
|
}
|
||||||
|
|
||||||
impl FilteredUser {
|
impl FilteredUser {
|
||||||
pub fn from(user: &User) -> Self {
|
pub fn from(user: &User) -> Self {
|
||||||
FilteredUser {
|
FilteredUser {
|
||||||
@ -67,11 +72,34 @@ pub async fn register(
|
|||||||
.map_err(AuthError::InternalError)?;
|
.map_err(AuthError::InternalError)?;
|
||||||
|
|
||||||
Ok(Json(json!({
|
Ok(Json(json!({
|
||||||
"status": "success",
|
"status": StatusCode::OK.to_string(),
|
||||||
"user": FilteredUser::from(&user)
|
"user": FilteredUser::from(&user)
|
||||||
})))
|
})))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn remove(
|
||||||
|
State(state): State<Arc<AppState>>,
|
||||||
|
Json(body): Json<RemoveUser>,
|
||||||
|
) -> Result<impl IntoResponse, AuthError<impl std::error::Error>> {
|
||||||
|
let user = User::find(
|
||||||
|
&state.database,
|
||||||
|
User::by_id(uuid::Uuid::parse_str(&body.id).map_err(|_| AuthError::InvalidCredentials)?),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.map_err(AuthError::InternalError)?;
|
||||||
|
|
||||||
|
let user = match user {
|
||||||
|
Some(user) => user,
|
||||||
|
None => return Err(AuthError::MissingUser),
|
||||||
|
};
|
||||||
|
|
||||||
|
User::remove(&state.database, user)
|
||||||
|
.await
|
||||||
|
.map_err(|_| AuthError::InternalE)?;
|
||||||
|
|
||||||
|
Ok(Json(json!({"status": StatusCode::OK.to_string()})))
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn login(
|
pub async fn login(
|
||||||
State(state): State<Arc<AppState>>,
|
State(state): State<Arc<AppState>>,
|
||||||
Json(body): Json<LoginUser>,
|
Json(body): Json<LoginUser>,
|
||||||
|
@ -90,15 +90,15 @@ impl User {
|
|||||||
|
|
||||||
pub fn by_email(email: String) -> BoxedQuery<'static> {
|
pub fn by_email(email: String) -> BoxedQuery<'static> {
|
||||||
users::table
|
users::table
|
||||||
.select(User::as_select())
|
|
||||||
.into_boxed()
|
.into_boxed()
|
||||||
|
.select(User::as_select())
|
||||||
.filter(users::email.eq(email))
|
.filter(users::email.eq(email))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn by_id(id: uuid::Uuid) -> BoxedQuery<'static> {
|
pub fn by_id(id: uuid::Uuid) -> BoxedQuery<'static> {
|
||||||
users::table
|
users::table
|
||||||
.select(User::as_select())
|
|
||||||
.into_boxed()
|
.into_boxed()
|
||||||
|
.select(User::as_select())
|
||||||
.filter(users::id.eq(id))
|
.filter(users::id.eq(id))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,6 +116,19 @@ impl User {
|
|||||||
Ok(user)
|
Ok(user)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused_variables)]
|
pub async fn remove(
|
||||||
pub fn remove(pool: Pool, email: String) {}
|
pool: &Pool,
|
||||||
|
user: User,
|
||||||
|
) -> Result<(), DatabaseError<impl std::error::Error>> {
|
||||||
|
let connection = pool.get().await.map_err(DatabaseError::Connection)?;
|
||||||
|
connection
|
||||||
|
.interact(move |connection| {
|
||||||
|
diesel::delete(users::table.filter(users::id.eq(user.id))).execute(connection)
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.map_err(|_| DatabaseError::Interaction)?
|
||||||
|
.map_err(|_| DatabaseError::Interaction)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user