Добавил возможность удалять пользователей и менять им пароли

This commit is contained in:
Artem VV 2023-05-19 21:15:26 +07:00
parent a287fec381
commit 8a7231cdd2
5 changed files with 239 additions and 0 deletions

View file

@ -68,6 +68,27 @@ export async function createUser(login: string, password: string) {
return user;
}
export async function updateUserPassword(login: string, newPassword: string) {
const user = await client.users.update({
where: {
login: login,
},
data: {
pass: toHex(blake3(newPassword)),
},
});
return user;
}
export async function deleteUser(login: string) {
const user = await client.users.delete({
where: {
login: login,
},
});
return user;
}
export async function createSession(user: users) {
const session = await client.user_session.create({
data: {
@ -144,3 +165,19 @@ export async function getArticle(articleId: number) {
return article;
}
export async function searchUsers(params: { login?: string; isAdmin?: boolean; fullName?: string }) {
const users = await client.users.findMany({
where: {
login: {
contains: params.login,
},
is_admin: params.isAdmin,
fullName: params.fullName,
},
orderBy: {
id: "asc",
},
});
return users;
}

View file

@ -0,0 +1,46 @@
import type { APIContext } from "astro";
import { deleteUser, getSessionUser } from "../../db";
import { Prisma } from "@prisma/client";
export async function post({ request, cookies }: APIContext) {
const response: { ok: boolean; reason?: string } = {
ok: true,
};
try {
const sessId = cookies.get("session").value!;
const user = (await getSessionUser(sessId))!;
if (!user.is_admin) {
throw new Error("Доступно только администраторам");
}
const formData = await request.formData();
const login = formData.get("login");
if (login === null) {
throw new Error("Не предоставлены данные для удаления пользователя");
}
if (login.toString() === user.login) {
throw new Error("Невозможно удалить самого себя");
}
const deletedUser = await deleteUser(login.toString());
if (deletedUser === null) {
throw new Error("Не удалось удалить пользователя");
}
response.ok = true;
} catch (e: any) {
response.ok = false;
if (e instanceof Prisma.PrismaClientKnownRequestError) {
response.reason = `Неизвестная ошибка базы данных. Код ${e.code}`;
} else if (e instanceof Error) {
response.reason = e.message.trim();
} else {
response.reason = e.toString().trim();
}
}
return {
body: JSON.stringify(response),
};
}

View file

@ -0,0 +1,43 @@
import type { APIContext } from "astro";
import { updateUserPassword, getSessionUser } from "../../db";
import { Prisma } from "@prisma/client";
export async function post({ request, cookies }: APIContext) {
const response: { ok: boolean; reason?: string } = {
ok: true,
};
try {
const sessId = cookies.get("session").value!;
const user = (await getSessionUser(sessId))!;
if (!user.is_admin) {
throw new Error("Доступно только администраторам");
}
const formData = await request.formData();
const login = formData.get("login");
const password = formData.get("password");
if (login === null || password === null) {
throw new Error("Не предоставлены данные для обновления пароля");
}
const updatedUser = await updateUserPassword(login.toString(), password.toString());
if (updatedUser === null) {
throw new Error("Не удалось обновить пароль");
}
response.ok = true;
} catch (e: any) {
response.ok = false;
if (e instanceof Prisma.PrismaClientKnownRequestError) {
response.reason = `Неизвестная ошибка базы данных. Код ${e.code}`;
} else if (e instanceof Error) {
response.reason = e.message.trim();
} else {
response.reason = e.toString().trim();
}
}
return {
body: JSON.stringify(response),
};
}

112
src/pages/users.astro Normal file
View file

@ -0,0 +1,112 @@
---
import Layout from "../layouts/Layout.astro";
import { getUserSession, searchUsers, getSessionUser } from "../db";
import Navbar from "../components/Navbar.astro";
if (Astro.cookies.has("session")) {
const sessId = Astro.cookies.get("session").value!;
const dbSess = await getUserSession(sessId);
if (dbSess === null) {
Astro.cookies.delete("session");
return Astro.redirect("/login");
}
} else {
return Astro.redirect("/login");
}
const sessId = Astro.cookies.get("session").value!;
const user = (await getSessionUser(sessId))!;
if (!user.is_admin) {
return Astro.redirect("/");
}
const users = await searchUsers({});
---
<Layout title="Пользователи">
<main>
<Navbar is_user_admin={user.is_admin} />
<div class="container mt-4 d-flex flex-column gap-4">
{
users.map((e) => (
<div class="card flex-grow-1">
<div class="card-body">
<h5 class="card-title">{e.fullName}</h5>
<h6 class="card-subtitle mb-2 text-muted">{e.login}</h6>
<button type="button" class="btn btn-primary btn-sm" onclick={`doChangePassword("${e.login}")`}>
Изменить пароль
</button>
<a href={`/user/${e.id}`} class="btn btn-primary btn-sm">
Открыть профиль
</a>
<a href={`/timetable?userId=${e.id}`} class="btn btn-primary btn-sm">
Редактировать расписание
</a>
<button type="button" class="btn btn-danger btn-sm" onclick={`doDeleteUser("${e.login}")`}>
Удалить пользователя
</button>
</div>
</div>
))
}
</div>
</main>
</Layout>
<script is:inline>
async function doChangePassword(login) {
const newPassword = prompt("Введите новый пароль пользователя");
if (newPassword === null) return;
try {
const fd = new FormData();
fd.append("login", login);
fd.append("password", newPassword);
const resp = await fetch("/userapi/updatePassword", {
method: "POST",
body: fd,
});
const json = await resp.json();
if (json.ok) {
alert("Успех");
} else {
throw new Error(json.reason);
}
} catch (e) {
console.error(e);
if (e instanceof Error) {
alert(e.message);
} else {
alert("Неизвестная ошибка");
}
}
}
async function doDeleteUser(login) {
const confirmLogin = prompt(`Это действие невозможно отменить. \nВведите логин пользователя '${login}' для подтверждения`);
if (confirmLogin !== login) return;
try {
const fd = new FormData();
fd.append("login", login);
const resp = await fetch("/userapi/deleteUser", {
method: "POST",
body: fd,
});
const json = await resp.json();
if (json.ok) {
location.reload();
} else {
throw new Error(json.reason);
}
} catch (e) {
console.error(e);
if (e instanceof Error) {
alert(e.message);
} else {
alert("Неизвестная ошибка");
}
}
}
</script>