Use Vue-based login page

This commit is contained in:
2022-05-05 14:39:41 +02:00
parent 825f9fcd50
commit 64196eeab2
8 changed files with 80 additions and 77 deletions

View File

@ -1,68 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Login - Timetable V2</title>
<style>
body,
html {
margin: 0;
height: 100%;
width: 100%;
overflow: hidden;
}
body {
background-color: #353535;
}
main {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
font-family: Arial, Helvetica, sans-serif;
color: #bdbdbd;
height: 80%;
}
form {
display: flex;
flex-direction: column;
gap: 10px;
}
input {
border: 0px;
outline: none;
background-color: #3a3737;
padding: 5px 5px;
margin: 5px 0;
border: 2px solid #34631f;
border-radius: 5px;
color: #bdbdbd;
}
button {
outline: none;
padding: 5px 5px;
border: 2px solid #1f5b63;
border-radius: 5px;
color: #bdbdbd;
background-color: #242121;
}
</style>
</head>
<body>
<main>
<h1>Timetable V2</h1>
<form action="/login" method="POST">
<input
type="password"
name="password"
autocomplete="current-password"
placeholder="Password"
/>
<button type="submit">Login</button>
</form>
</main>
</body>
</html>

View File

@ -3,7 +3,7 @@ export class Auth {
constructor() {}
login = (req, res) => {
if (!req.body.password) {
res.status(401).sendFile("login.html", { root: "../" });
res.redirect("/login");
return;
} else {
if (req.body.password == process.env.AUTH_PASSWORD) {
@ -15,18 +15,18 @@ export class Auth {
});
res.redirect("/");
} else {
res.status(401).sendFile("login.html", { root: "../" });
res.redirect("/login");
return;
}
}
};
checkLogin = (req, res, next) => {
if (!req.cookies.session) {
res.status(401).sendFile("login.html", { root: "../" });
res.sendStatus(401);
return;
} else {
if (!this.activeSessions.includes(req.cookies.session)) {
res.status(401).sendFile("login.html", { root: "../" });
res.sendStatus(401);
return;
}
}

View File

@ -29,13 +29,16 @@ const parser = new Parser(
);
app.post("/login", auth.login);
app.use(auth.checkLogin);
app.use("/api", auth.checkLogin);
app.get("/api/check", (_req, res) => {
res.sendStatus(200);
});
app.get("/api/timetable", getTimetable);
app.get("/api/substitutions", getSubstitutions);
app.get("/api/history", getHistory);
app.get("/api/classes", getClasses);
app.get("/api/*", (req, res) => {
app.get("/api/*", (_req, res) => {
res.sendStatus(400);
});

View File

@ -7,9 +7,9 @@ import DateSelector from "./components/date-selector.vue";
<template>
<TitleBar />
<DateSelector v-show="$route.name != 'Settings'" />
<DateSelector v-show="$route.name != 'Settings' && $route.name != 'Login'" />
<RouterView />
<BottomNavbar />
<BottomNavbar v-show="$route.name != 'Login'" />
</template>
<style>

View File

@ -11,7 +11,7 @@ const routeName = computed(() => route.name);
<div class="titlebar">
<span class="title">{{ routeName }}</span>
<div class="settings">
<RouterLink to="/settings">
<RouterLink to="/settings" v-show="$route.name != 'Login'">
<MenuIcon />
</RouterLink>
</div>

View File

@ -3,6 +3,7 @@ import TimetableView from "../views/TimetableView.vue";
import SubstitutionView from "../views/SubstitutionView.vue";
import HistoryView from "../views/HistoryView.vue";
import SettingsView from "../views/SettingsView.vue";
import LoginView from "../views/LoginView.vue";
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
@ -31,6 +32,11 @@ const router = createRouter({
name: "Settings",
component: SettingsView,
},
{
path: "/login",
name: "Login",
component: LoginView,
},
],
});

View File

@ -1,5 +1,6 @@
import { computed } from "@vue/reactivity";
import { ref, watch } from "vue";
import router from "./router";
export const substitutionFilter = ref(
localStorage.getItem("substitutionFilter") || "all"
@ -62,6 +63,10 @@ export const parsedTimetable = computed(() => {
export async function fetchData() {
const baseUrl = "/api";
const checkResponse = await fetch(`${baseUrl}/check`);
if (checkResponse.status != 200) router.push("/login");
const timetableResponse = await fetch(
`${baseUrl}/timetable?class=${timetableClass.value}`
);

57
src/views/LoginView.vue Normal file
View File

@ -0,0 +1,57 @@
<template>
<div class="login">
<h1>Timetable V2</h1>
<form action="/login" method="POST">
<input
type="password"
name="password"
autocomplete="current-password"
placeholder="Password"
/>
<button type="submit">Login</button>
</form>
</div>
</template>
<style scoped>
.login {
padding: 65px 10px 80px 10px;
}
body {
background-color: #353535;
}
.login {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
font-family: Arial, Helvetica, sans-serif;
color: #bdbdbd;
height: 80%;
}
form {
display: flex;
flex-direction: column;
gap: 10px;
}
input {
border: 0px;
outline: none;
background-color: #3a3737;
padding: 5px 5px;
margin: 5px 0;
border: 2px solid #34631f;
border-radius: 5px;
color: #bdbdbd;
}
button {
outline: none;
padding: 5px 5px;
border: 2px solid #1f5b63;
border-radius: 5px;
color: #bdbdbd;
background-color: #242121;
}
</style>