A Deno-powered backend service for Plants vs. Zombies: MODDED. [Read-only GitHub mirror] docs.pvzm.net
express typescript expressjs plant deno jspvz pvzm game online backend plants-vs-zombies zombie javascript plants modded vs plantsvszombies openapi pvz noads
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

replace memorystore

Clay dfdfa9ad 5aab93d5

+91
+91
modules/server/auth.ts
··· 1 1 import session from "express-session"; 2 2 import passport from "passport"; 3 3 import { Strategy as GitHubStrategy } from "passport-github2"; 4 + import { Database } from "@db/sqlite"; 4 5 5 6 import type { ServerConfig } from "./config.ts"; 6 7 8 + class SqliteSessionStore extends session.Store { 9 + db: Database; 10 + 11 + constructor(dbPath: string) { 12 + super(); 13 + this.db = new Database(dbPath); 14 + this.db.exec( 15 + `CREATE TABLE IF NOT EXISTS sessions ( 16 + sid TEXT PRIMARY KEY, 17 + sess TEXT NOT NULL, 18 + expire INTEGER NOT NULL 19 + ); 20 + CREATE INDEX IF NOT EXISTS idx_sessions_expire ON sessions(expire);`, 21 + ); 22 + } 23 + 24 + private cleanupExpired(nowMs: number) { 25 + try { 26 + this.db.prepare("DELETE FROM sessions WHERE expire < ?").run(nowMs); 27 + } catch { 28 + // best-effort cleanup 29 + } 30 + } 31 + 32 + private computeExpireMs(sess: any): number { 33 + const cookie = sess?.cookie; 34 + if (cookie?.expires) { 35 + const d = new Date(cookie.expires); 36 + if (!Number.isNaN(d.getTime())) return d.getTime(); 37 + } 38 + const maxAge = typeof cookie?.maxAge === "number" ? cookie.maxAge : null; 39 + if (maxAge !== null) return Date.now() + maxAge; 40 + return Date.now() + 24 * 60 * 60 * 1000; 41 + } 42 + 43 + get(sid: string, cb: (err?: any, session?: any | null) => void) { 44 + try { 45 + const nowMs = Date.now(); 46 + const row = this.db.prepare("SELECT sess, expire FROM sessions WHERE sid = ?").get(sid) as 47 + | { sess: string; expire: number } 48 + | undefined; 49 + if (!row) return cb(null, null); 50 + if (row.expire < nowMs) { 51 + this.db.prepare("DELETE FROM sessions WHERE sid = ?").run(sid); 52 + return cb(null, null); 53 + } 54 + return cb(null, JSON.parse(row.sess)); 55 + } catch (err) { 56 + return cb(err); 57 + } 58 + } 59 + 60 + set(sid: string, sess: any, cb: (err?: any) => void) { 61 + try { 62 + const nowMs = Date.now(); 63 + this.cleanupExpired(nowMs); 64 + const expire = this.computeExpireMs(sess); 65 + this.db.prepare( 66 + "INSERT INTO sessions (sid, sess, expire) VALUES (?, ?, ?) ON CONFLICT(sid) DO UPDATE SET sess=excluded.sess, expire=excluded.expire", 67 + ).run(sid, JSON.stringify(sess), expire); 68 + return cb(null); 69 + } catch (err) { 70 + return cb(err); 71 + } 72 + } 73 + 74 + destroy(sid: string, cb: (err?: any) => void) { 75 + try { 76 + this.db.prepare("DELETE FROM sessions WHERE sid = ?").run(sid); 77 + return cb(null); 78 + } catch (err) { 79 + return cb(err); 80 + } 81 + } 82 + 83 + touch(sid: string, sess: any, cb: (err?: any) => void) { 84 + try { 85 + const nowMs = Date.now(); 86 + this.cleanupExpired(nowMs); 87 + const expire = this.computeExpireMs(sess); 88 + this.db.prepare("UPDATE sessions SET expire = ? WHERE sid = ?").run(expire, sid); 89 + return cb(null); 90 + } catch (err) { 91 + return cb(err); 92 + } 93 + } 94 + } 95 + 7 96 export function setupSession(app: any, config: ServerConfig) { 97 + const store = new SqliteSessionStore(config.dbPath); 8 98 app.use( 9 99 session({ 100 + store, 10 101 secret: config.sessionSecret, 11 102 resave: false, 12 103 saveUninitialized: false,