You've already forked AstralRinth
forked from didirus/AstralRinth
Allow admins to view user email (#3261)
This commit is contained in:
61
apps/frontend/src/pages/admin/user_email.vue
Normal file
61
apps/frontend/src/pages/admin/user_email.vue
Normal file
@@ -0,0 +1,61 @@
|
||||
<template>
|
||||
<div class="normal-page no-sidebar">
|
||||
<h1>User account request</h1>
|
||||
<div class="normal-page__content">
|
||||
<div class="card flex flex-col gap-3">
|
||||
<div class="flex flex-col gap-2">
|
||||
<label for="name">
|
||||
<span class="text-lg font-semibold text-contrast">
|
||||
User email
|
||||
<span class="text-brand-red">*</span>
|
||||
</span>
|
||||
</label>
|
||||
<input
|
||||
id="name"
|
||||
v-model="userEmail"
|
||||
type="email"
|
||||
maxlength="64"
|
||||
:placeholder="`Enter user email...`"
|
||||
autocomplete="off"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<ButtonStyled color="brand">
|
||||
<button @click="getUserFromEmail">
|
||||
<MailIcon aria-hidden="true" />
|
||||
Get user account
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ButtonStyled } from "@modrinth/ui";
|
||||
import { MailIcon } from "@modrinth/assets";
|
||||
|
||||
const userEmail = ref("");
|
||||
|
||||
async function getUserFromEmail() {
|
||||
startLoading();
|
||||
|
||||
try {
|
||||
const result = await useBaseFetch(`user_email?email=${encodeURIComponent(userEmail.value)}`, {
|
||||
method: "GET",
|
||||
apiVersion: 3,
|
||||
});
|
||||
|
||||
await navigateTo(`/user/${result.username}`);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
addNotification({
|
||||
group: "main",
|
||||
title: "An error occurred",
|
||||
text: err.data.description,
|
||||
type: "error",
|
||||
});
|
||||
}
|
||||
stopLoading();
|
||||
}
|
||||
</script>
|
||||
22
apps/labrinth/.sqlx/query-68619337ef34b588af21a40e5a60b54ce3a1dad45fb50bbc24a3ea34d2506578.json
generated
Normal file
22
apps/labrinth/.sqlx/query-68619337ef34b588af21a40e5a60b54ce3a1dad45fb50bbc24a3ea34d2506578.json
generated
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n SELECT id FROM users\n WHERE LOWER(email) = LOWER($1)\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "id",
|
||||
"type_info": "Int8"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "68619337ef34b588af21a40e5a60b54ce3a1dad45fb50bbc24a3ea34d2506578"
|
||||
}
|
||||
@@ -28,6 +28,7 @@ use crate::{
|
||||
pub fn config(cfg: &mut web::ServiceConfig) {
|
||||
cfg.route("user", web::get().to(user_auth_get));
|
||||
cfg.route("users", web::get().to(users_get));
|
||||
cfg.route("user_email", web::get().to(admin_user_email));
|
||||
|
||||
cfg.service(
|
||||
web::scope("user")
|
||||
@@ -44,6 +45,62 @@ pub fn config(cfg: &mut web::ServiceConfig) {
|
||||
);
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct UserEmailQuery {
|
||||
pub email: String,
|
||||
}
|
||||
|
||||
pub async fn admin_user_email(
|
||||
req: HttpRequest,
|
||||
pool: web::Data<PgPool>,
|
||||
redis: web::Data<RedisPool>,
|
||||
session_queue: web::Data<AuthQueue>,
|
||||
email: web::Query<UserEmailQuery>,
|
||||
) -> Result<HttpResponse, ApiError> {
|
||||
let user = get_user_from_headers(
|
||||
&req,
|
||||
&**pool,
|
||||
&redis,
|
||||
&session_queue,
|
||||
Some(&[Scopes::SESSION_ACCESS]),
|
||||
)
|
||||
.await
|
||||
.map(|x| x.1)?;
|
||||
|
||||
if !user.role.is_admin() {
|
||||
return Err(ApiError::CustomAuthentication(
|
||||
"You do not have permission to get a user from their email!"
|
||||
.to_string(),
|
||||
));
|
||||
}
|
||||
|
||||
let user_id = sqlx::query!(
|
||||
"
|
||||
SELECT id FROM users
|
||||
WHERE LOWER(email) = LOWER($1)
|
||||
",
|
||||
email.email
|
||||
)
|
||||
.fetch_optional(&**pool)
|
||||
.await?
|
||||
.map(|x| x.id)
|
||||
.ok_or_else(|| {
|
||||
ApiError::InvalidInput(
|
||||
"The email provided is not associated with a user!".to_string(),
|
||||
)
|
||||
})?;
|
||||
|
||||
let user =
|
||||
User::get_id(crate::database::models::UserId(user_id), &**pool, &redis)
|
||||
.await?;
|
||||
|
||||
if let Some(user) = user {
|
||||
Ok(HttpResponse::Ok().json(user))
|
||||
} else {
|
||||
Err(ApiError::NotFound)
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn projects_list(
|
||||
req: HttpRequest,
|
||||
info: web::Path<(String,)>,
|
||||
|
||||
Reference in New Issue
Block a user