UNPKG

authkit-js

Version:

Express auth toolkit (JWT, Sessions with Redis, Google/GitHub OAuth) in JavaScript

56 lines (50 loc) 2.16 kB
const { cookieOptions, makeId } = require('../utils/cookies'); class SessionStrategy { constructor(cfg) { if (!cfg || !cfg.store) throw new Error('SessionStrategy: store required'); this.store = cfg.store; this.opts = cfg.opts || {}; this.cookieCfg = Object.assign({ names: { session: 'sid', csrf: '_csrf' }, sameSite: 'lax' }, cfg.cookie || {}); this.serialize = cfg.serializeUser || (async (u) => u); this.deserialize = cfg.deserializeUser || (async (data) => data); } async login(res, user) { const sid = makeId(24); const data = await this.serialize(user); const ttl = this.opts.ttlSec != null ? this.opts.ttlSec : 24 * 60 * 60; await this.store.set(sid, data, ttl); const c = cookieOptions(this.cookieCfg); const names = this.cookieCfg.names; res.cookie(names.session, sid, { ...c, maxAge: ttl * 1000 }); const csrf = makeId(16); res.cookie(names.csrf, csrf, { ...c, httpOnly: false, maxAge: ttl * 1000 }); return { sessionId: sid, csrf }; } async authenticate(req) { const names = this.cookieCfg.names; const sid = req.cookies && req.cookies[names.session]; if (!sid) return null; const data = await this.store.get(sid); if (!data) return null; const user = await this.deserialize(data); if (!user) return null; return { user, sessionId: sid }; } async assertCsrf(req) { const names = this.cookieCfg.names; const sid = req.cookies && req.cookies[names.session]; const cookieCsrf = req.cookies && req.cookies[names.csrf]; const headerCsrf = req.headers && (req.headers['x-csrf-token'] || req.headers['X-CSRF-Token']); if (!sid || !cookieCsrf || !headerCsrf || cookieCsrf !== headerCsrf) { const err = new Error('CSRF validation failed'); err.status = 400; throw err; } } async logout(req, res) { const names = this.cookieCfg.names; const sid = req.cookies && req.cookies[names.session]; if (sid) await this.store.del(sid); res.clearCookie(names.session); res.clearCookie(names.csrf); } } module.exports = { SessionStrategy };