const crypto = require('crypto'); class SessionError extends Error {}; function SessionManager (){ // default session length - you might want to // set this to something small during development const CookieMaxAgeMs = 600000; // keeping the session data inside a closure to keep them protected const sessions = {}; // might be worth thinking about why we create these functions // as anonymous functions (per each instance) and not as prototype methods this.createSession = (response, username, maxAge = CookieMaxAgeMs) => { const token = crypto.randomBytes(15).toString('hex'); const sessionObj = { username: username, created: new Date(), maxAge: maxAge }; response.cookie("cpen322-session", token, { maxAge }); sessions[token] = sessionObj; setTimeout(() => { delete sessions[token]; }, maxAge); }; this.deleteSession = (request) => { if(request.session && sessions[request.session]){ delete sessions[request.session]; } delete request.username; delete request.session; }; this.middleware = (request, response, next) => { // AI used to generate regex rule to select cookie const tokenString = request.headers.cookie; const match = tokenString ? tokenString.match(/cpen322-session=([^;]*)/) : null; const token = match ? match[1] : null; if(!token || !(sessions[token])) { next(new SessionError("Session not found")); return; } request.username = sessions[token].username; request.session = token; next(); }; // this function is used by the test script. // you can use it if you want. this.getUsername = (token) => ((token in sessions) ? sessions[token].username : null); }; // SessionError class is available to other modules as "SessionManager.Error" SessionManager.Error = SessionError; module.exports = SessionManager;