diff --git a/login.html b/login.html
new file mode 100644
index 0000000..b0d6d13
--- /dev/null
+++ b/login.html
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+ Login - Timetable V2
+
+
+
+
+ Timetable V2
+
+
+
+
diff --git a/server/api/auth.js b/server/api/auth.js
new file mode 100644
index 0000000..962606e
--- /dev/null
+++ b/server/api/auth.js
@@ -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();
+ };
+}
diff --git a/server/index.js b/server/index.js
index 0035ac7..ce65066 100644
--- a/server/index.js
+++ b/server/index.js
@@ -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);
diff --git a/server/package-lock.json b/server/package-lock.json
index 3db61f9..2b065a9 100644
--- a/server/package-lock.json
+++ b/server/package-lock.json
@@ -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",
diff --git a/server/package.json b/server/package.json
index 52669f3..9b7cf80 100644
--- a/server/package.json
+++ b/server/package.json
@@ -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"
}