import Config from "./Config"; import FastifyCookie from "@fastify/cookie"; import FunkyArray from "funky-array"; import SessionUser from "./SessionUser"; import { FastifyReply, FastifyRequest } from "fastify"; import User from "../entities/User"; import { randomBytes } from "crypto"; import Gauge from "simple-prom/lib/objects/Gauge"; import SimpleProm from "simple-prom"; type Cookies = { [cookieName: string]: string | undefined } export default abstract class Session { public static Sessions = new FunkyArray(); public static SessionExpiryInterval = setInterval(() => { const currentTime = Date.now(); for (const key of Session.Sessions.keys) { const session = Session.Sessions.get(key); if (!session || (session && currentTime >= session.validityPeriod.getTime())) { Session.Sessions.remove(key); } } Session.WebSessionsGauge.Value = Session.Sessions.length; }, 3600000); private static WebSessionsGauge = (() => { if (!SimpleProm.instance) { throw "SimpleProm not initialised"; } const webSessions = SimpleProm.instance.addMetric(new Gauge("multiprobe_web_sessions")); webSessions?.setHelpText("Number of valid web sessions"); return webSessions; })(); public static AssignUserSession(res:FastifyReply, user:User) { const validPeriod = new Date(); validPeriod.setTime(validPeriod.getTime() + Config.session.validity); const key = randomBytes(Config.session.length).toString("hex"); Session.Sessions.set(key, new SessionUser(user.Id, validPeriod)); res.setCookie("MP_SESSION", key, { path: "/", signed: true }); Session.WebSessionsGauge.Value = Session.Sessions.length; } public static Clear(cookies:Cookies, res:FastifyReply) { if ("MP_SESSION" in cookies && typeof(cookies["MP_SESSION"]) === "string") { const key:unknown = FastifyCookie.unsign(cookies["MP_SESSION"], Config.session.secret); Session.Sessions.remove(key as string); res.clearCookie("MP_SESSION"); Session.WebSessionsGauge.Value = Session.Sessions.length; } } public static CheckValiditiy(cookies:Cookies) { if ("MP_SESSION" in cookies && typeof(cookies["MP_SESSION"]) === "string") { const key = FastifyCookie.unsign(cookies["MP_SESSION"], Config.session.secret); if (key.valid && Session.Sessions.has(key.value ?? "badkey")) { return Session.Sessions.get(key.value ?? "badkey"); } } return undefined; } }