From 45f682a718e6d72ec3a81f7bd51a78c8faf7e298 Mon Sep 17 00:00:00 2001 From: minie4 Date: Thu, 2 Jun 2022 23:18:53 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Store=20auth=20sessions=20in=20data?= =?UTF-8?q?base?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/api/auth.js | 51 ++++++++++++++++++++++++++++++++----- server/prisma/schema.prisma | 6 +++++ 2 files changed, 50 insertions(+), 7 deletions(-) diff --git a/server/api/auth.js b/server/api/auth.js index 4a36385..6e0ea35 100644 --- a/server/api/auth.js +++ b/server/api/auth.js @@ -1,18 +1,26 @@ +import Prisma from "@prisma/client"; +const prisma = new Prisma.PrismaClient(); + +import { log } from "../logs.js"; + export class Auth { - activeSessions = []; constructor() {} - login = (req, res) => { + login = async (req, res) => { if (!req.body.password) { res.redirect("/login"); 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, { + const session = await prisma.session.create({ + data: { + validUntil: new Date(Date.now() + 1000 * 60 * 60 * 24 * 14), // Expires after 14 days + }, + }); + res.cookie("session", session.token, { httpOnly: true, expires: new Date(253402300000000), }); + log("API / Auth", `New session: ${session.token}`); res.redirect("/"); } else { res.redirect("/login"); @@ -20,7 +28,7 @@ export class Auth { } } }; - checkLogin = (req, res, next) => { + checkLogin = async (req, res, next) => { if (!process.env.AUTH_PASSWORD) { next(); return; @@ -29,11 +37,40 @@ export class Auth { res.sendStatus(401); return; } else { - if (!this.activeSessions.includes(req.cookies.session)) { + const session = await prisma.session.findUnique({ + where: { + token: req.cookies.session, + }, + }); + if (!session) { res.sendStatus(401); return; } + // Renew session expiration date + await prisma.session.update({ + where: { + token: session.token, + }, + data: { + validUntil: new Date(Date.now() + 1000 * 60 * 60 * 24 * 14), + }, + }); } next(); }; } + +// Check for expired sessions every hour +setInterval(async () => { + const sessions = await prisma.session.findMany(); + for (const session of sessions) { + if (session.validUntil < new Date()) { + log("API / Auth", `Removed expired session: ${session.token}`); + await prisma.session.delete({ + where: { + token: session.token, + }, + }); + } + } +}, 1000 * 60 * 60); diff --git a/server/prisma/schema.prisma b/server/prisma/schema.prisma index f319f1b..01ae005 100644 --- a/server/prisma/schema.prisma +++ b/server/prisma/schema.prisma @@ -62,3 +62,9 @@ model Class { name String @id @unique regex String } + +model Session { + token String @id @unique @default(uuid()) + createdAt DateTime @default(now()) + validUntil DateTime +}