Add basic auth functionality

This commit is contained in:
2022-05-04 01:38:25 +02:00
parent 856e514da7
commit 6261dbb04c
5 changed files with 147 additions and 0 deletions

68
login.html Normal file
View File

@ -0,0 +1,68 @@
<!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>

32
server/api/auth.js Normal file
View File

@ -0,0 +1,32 @@
export class Auth {
activeSessions = [];
constructor() {}
login = (req, res) => {
if (!req.body.password) {
res.status(401).sendFile("login.html", { root: "../" });
return;
} else {
if (req.body.password == process.env.AUTH_PASSWORD) {
const sessionId = Math.random().toString(36).slice(-8);
this.activeSessions.push(sessionId);
res.cookie("session", sessionId, { httpOnly: true });
res.redirect("/");
} else {
res.status(401).sendFile("login.html", { root: "../" });
return;
}
}
};
checkLogin = (req, res, next) => {
if (!req.cookies.session) {
res.status(401).sendFile("login.html", { root: "../" });
return;
} else {
if (!this.activeSessions.includes(req.cookies.session)) {
res.status(401).sendFile("login.html", { root: "../" });
return;
}
}
next();
};
}

View File

@ -5,12 +5,18 @@ import {
getHistory,
getClasses,
} from "./api/index.js";
import { Auth } from "./api/auth.js";
import { Parser } from "./parser/index.js";
import cors from "cors";
import cookieParser from "cookie-parser";
const app = express();
const port = process.env.PORT || 3000;
app.use(cors());
app.use(cookieParser());
app.use(express.urlencoded({ extended: true }));
const auth = new Auth();
if (!process.env.DSB_USER || !process.env.DSB_PASSWORD) {
console.error("Error: DSB Auth environment variables missing!");
@ -22,6 +28,9 @@ const parser = new Parser(
process.env.UPDATE_INTERVAL || 1 * 60 * 1000
);
app.post("/login", auth.login);
app.use(auth.checkLogin);
app.get("/api/timetable", getTimetable);
app.get("/api/substitutions", getSubstitutions);
app.get("/api/history", getHistory);

View File

@ -12,6 +12,7 @@
"@prisma/client": "^3.13.0",
"axios": "^0.27.2",
"cheerio": "^1.0.0-rc.10",
"cookie-parser": "^1.4.6",
"cors": "^2.8.5",
"express": "^4.18.1"
}
@ -193,6 +194,26 @@
"node": ">= 0.6"
}
},
"node_modules/cookie-parser": {
"version": "1.4.6",
"resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.6.tgz",
"integrity": "sha512-z3IzaNjdwUC2olLIB5/ITd0/setiaFMLYiZJle7xg5Fe9KWAceil7xszYfHHBtDFYLSgJduS2Ty0P1uJdPDJeA==",
"dependencies": {
"cookie": "0.4.1",
"cookie-signature": "1.0.6"
},
"engines": {
"node": ">= 0.8.0"
}
},
"node_modules/cookie-parser/node_modules/cookie": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz",
"integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/cookie-signature": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
@ -1007,6 +1028,22 @@
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
"integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw=="
},
"cookie-parser": {
"version": "1.4.6",
"resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.6.tgz",
"integrity": "sha512-z3IzaNjdwUC2olLIB5/ITd0/setiaFMLYiZJle7xg5Fe9KWAceil7xszYfHHBtDFYLSgJduS2Ty0P1uJdPDJeA==",
"requires": {
"cookie": "0.4.1",
"cookie-signature": "1.0.6"
},
"dependencies": {
"cookie": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz",
"integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA=="
}
}
},
"cookie-signature": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",

View File

@ -13,6 +13,7 @@
"@prisma/client": "^3.13.0",
"axios": "^0.27.2",
"cheerio": "^1.0.0-rc.10",
"cookie-parser": "^1.4.6",
"cors": "^2.8.5",
"express": "^4.18.1"
}