Поправил регистрацию и авторизацию, сделал unique логин пользователя в схеме

This commit is contained in:
Artem VV 2023-05-19 21:15:25 +07:00
parent 811856fee4
commit f721d16ace
5 changed files with 105 additions and 34 deletions

View file

@ -54,7 +54,7 @@ model timetable {
model users { model users {
id Int @id(map: "pk_users") @default(autoincrement()) id Int @id(map: "pk_users") @default(autoincrement())
login String @db.VarChar(25) login String @unique @db.VarChar(25)
pass String? @db.VarChar(100) pass String? @db.VarChar(100)
is_admin Boolean? @default(false) is_admin Boolean? @default(false)
timetable timetable[] timetable timetable[]

View file

@ -1,34 +1,41 @@
import type { APIContext } from "astro"; import type { APIContext } from "astro";
import { createSession, getUserFromAuth } from "../../db"; import { createSession, getUserFromAuth } from "../../db";
import { Prisma } from "@prisma/client";
export async function post({ request, redirect, cookies }: APIContext) { export async function post({ request, cookies }: APIContext) {
const response: { ok: boolean; reason?: string } = { const response: { ok: boolean; reason?: string } = {
ok: true, ok: true,
}; };
try {
const formData = await request.formData();
const login = formData.get("login");
const password = formData.get("password");
if (login === null || password === null) {
throw new Error("Не предоставлены данные для входа");
}
const formData = await request.formData();
const login = formData.get("login");
const password = formData.get("password");
if (login === null || password === null) {
response.ok = false;
response.reason = "Не предоставлены данные для входа";
} else {
const user = await getUserFromAuth(login!.toString(), password!.toString()); const user = await getUserFromAuth(login!.toString(), password!.toString());
if (user === null) { if (user === null) {
response.ok = false; throw new Error("Неправильная связка логин/пароль");
response.reason = "Неправильная связка логин/пароль"; }
const session = await createSession(user!);
if (session === null) {
throw new Error("Не удалось создать сессию для пользователя");
}
response.ok = true;
cookies.set("session", session.id, {
path: "/",
});
} 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 { } else {
const session = await createSession(user!); response.reason = e.toString().trim();
if (session !== null) {
response.ok = true;
cookies.set("session", session.id, {
path: "/",
});
} else {
response.ok = false;
response.reason = "Не удалось создать сессию для пользователя";
}
} }
} }

View file

@ -1,25 +1,39 @@
import type { APIContext } from "astro"; import type { APIContext } from "astro";
import { createUser } from "../../db"; import { createUser } from "../../db";
import { Prisma } from "@prisma/client";
export async function post({ request }: APIContext) { export async function post({ request }: APIContext) {
const response: { ok: boolean; reason?: string } = { const response: { ok: boolean; reason?: string } = {
ok: true, ok: true,
}; };
const formData = await request.formData(); try {
const login = formData.get("login"); const formData = await request.formData();
const password = formData.get("password"); const login = formData.get("login");
if (login === null || password === null) { const password = formData.get("password");
response.ok = false; if (login === null || password === null) {
response.reason = "Не предоставлены данные для регистрации"; throw new Error("Не предоставлены данные для регистрации");
} else { }
const user = await createUser(login!.toString(), password!.toString()); const user = await createUser(login!.toString(), password!.toString());
if (user === null) { if (user === null) {
response.ok = false; throw new Error("Невозможно зарегистрировать пользователя");
response.reason = "Невозможно зарегистрировать пользователя"; }
response.ok = true;
} catch (e: any) {
response.ok = false;
if (e instanceof Prisma.PrismaClientKnownRequestError) {
if (e.code === "P2002") {
response.reason = "Пользователь с таким логином уже существует";
} else {
response.reason = `Неизвестная ошибка базы данных. Код ${e.code}`;
}
} else if (e instanceof Error) {
response.reason = e.message.trim();
} else { } else {
response.ok = true; response.reason = e.toString().trim();
} }
} }

View file

@ -23,7 +23,7 @@ if (Astro.cookies.has("session")) {
<h2 class="p-3">Вход</h2> <h2 class="p-3">Вход</h2>
</div> </div>
<div class="card-body"> <div class="card-body">
<form method="POST" action="/gate/login"> <form method="POST" onsubmit="doLogin(this); return false;">
<div class="mb-4"> <div class="mb-4">
<label for="login" class="form-label">Логин</label> <label for="login" class="form-label">Логин</label>
<input type="text" class="form-control" id="login" id="login" name="login" required /> <input type="text" class="form-control" id="login" id="login" name="login" required />
@ -45,4 +45,29 @@ if (Astro.cookies.has("session")) {
</main> </main>
</Layout> </Layout>
<script is:inline>
async function doLogin(form) {
try {
const fd = new FormData(form);
const resp = await fetch("/gate/login", {
method: "POST",
body: fd,
});
const json = await resp.json();
if (json.ok) {
location.href = "/";
} else {
throw new Error(json.reason);
}
} catch (e) {
console.error(e);
if (e instanceof Error) {
alert(e.message);
} else {
alert("Неизвестная ошибка");
}
}
}
</script>
<style></style> <style></style>

View file

@ -23,7 +23,7 @@ if (Astro.cookies.has("session")) {
<h2 class="p-3">Регистрация</h2> <h2 class="p-3">Регистрация</h2>
</div> </div>
<div class="card-body"> <div class="card-body">
<form method="POST" action="/gate/register"> <form method="POST" onsubmit="doRegistration(this); return false;">
<div class="mb-4"> <div class="mb-4">
<label for="login" class="form-label">Логин</label> <label for="login" class="form-label">Логин</label>
<input type="text" class="form-control" id="login" id="login" name="login" required /> <input type="text" class="form-control" id="login" id="login" name="login" required />
@ -45,4 +45,29 @@ if (Astro.cookies.has("session")) {
</main> </main>
</Layout> </Layout>
<script is:inline>
async function doRegistration(form) {
try {
const fd = new FormData(form);
const resp = await fetch("/gate/register", {
method: "POST",
body: fd,
});
const json = await resp.json();
if (json.ok) {
location.href = "/";
} else {
throw new Error(json.reason);
}
} catch (e) {
console.error(e);
if (e instanceof Error) {
alert(e.message);
} else {
alert("Неизвестная ошибка");
}
}
}
</script>
<style></style> <style></style>