( options?: SessionOptions )
| 266 | * Inherits all options from `SessionOptions` |
| 267 | */ |
| 268 | export function SessionManager( |
| 269 | options?: SessionOptions |
| 270 | ): (req: IncomingMessage, res: ServerResponse) => Promise<Session> { |
| 271 | const opts: SessionOptions = options || ({} as SessionOptions) |
| 272 | |
| 273 | const generateId = opts.genid || generateSessionId |
| 274 | |
| 275 | const name = opts.name || opts.key || 'micro.sid' |
| 276 | |
| 277 | const store = opts.store || new MemoryStore() |
| 278 | |
| 279 | let resaveSession = opts.resave |
| 280 | |
| 281 | if (resaveSession === undefined) resaveSession = true |
| 282 | |
| 283 | const rolling = opts.rolling |
| 284 | |
| 285 | const cookieOptions = opts.cookie |
| 286 | |
| 287 | let saveUninitialized = opts.saveUninitialized |
| 288 | |
| 289 | if (saveUninitialized === undefined) saveUninitialized = true |
| 290 | |
| 291 | if (opts.unset && opts.unset !== 'destroy' && opts.unset !== 'keep') |
| 292 | throw new TypeError('unset option must be either destroy or keep') |
| 293 | |
| 294 | let secret: string[] |
| 295 | if (typeof opts.secret === 'string') secret = [opts.secret] |
| 296 | else secret = opts.secret |
| 297 | |
| 298 | if (!secret) throw new TypeError('session requires options.secret') |
| 299 | |
| 300 | if (process.env.NODE_ENV === 'production' && opts.store instanceof MemoryStore) |
| 301 | console.warn('MemoryStore should not be used in production') |
| 302 | |
| 303 | let storeReady = true |
| 304 | |
| 305 | store.on('disconnect', () => (storeReady = false)) |
| 306 | store.on('connect', () => (storeReady = false)) |
| 307 | |
| 308 | store.generate = (req: ReqAndSessionInfo) => { |
| 309 | req.sessionID = generateId(req) |
| 310 | req.sessionStore = store |
| 311 | req.session = new Session(req, {}) |
| 312 | req.session.cookie = new Cookie(cookieOptions) |
| 313 | } |
| 314 | |
| 315 | const storeImplementsTouch = typeof store.touch === 'function' |
| 316 | |
| 317 | return (req: IncomingMessage, res: ServerResponse): Promise<Session> => { |
| 318 | return new Promise((resolve, reject) => { |
| 319 | if (!storeReady) { |
| 320 | resolve(undefined) |
| 321 | return |
| 322 | } |
| 323 | |
| 324 | // pathname mismatch |
| 325 | const originalPath = url.parse(req.url as string).pathname || '/' |
no test coverage detected