let crypto = require('crypto')
let XDate = require('xdate')
+// note: this routine is "almost" idempotent
+// it will return the same session key each time
+// expiry may be increased slightly at each call
return async (env, transaction) => {
let sessions = await (
await transaction.get({})
).get('sessions', {})
- // do not generate a new session key for multiple calls per request
- if (env.session_key !== undefined)
- return /*await*/ sessions.get(env.session_key, {})
-
let cookies = cookie.parse(env.request.headers.cookie || '')
let now = Date.now()
let session, expires = new XDate(now)
if (
Object.prototype.hasOwnProperty.call(cookies, 'session_key') &&
- (
- session = await sessions.get(env.session_key = cookies.session_key)
- ) !== undefined &&
+ (session = await sessions.get(cookies.session_key)) !== undefined &&
now < await session.get('expires', 0)
- )
+ ) {
// if session key is already in database, we know the requester supports
// cookies, therefore each access extends the session expiry by 1 month
+ env.session_key = cookies.session_key
expires.addMonths(1)
+ }
else {
// first request for session, maybe a bot, retain session for only 1 day
+ if (!Object.prototype.hasOwnProperty.call(env, 'session_key')) {
+ do {
+ env.session_key = crypto.randomBytes(16).toString('hex')
+ } while (sessions.has(env.session_key))
+ }
+ session = await sessions.get(env.session_key, {})
expires.addDays(1)
- do {
- env.session_key = crypto.randomBytes(16).toString('hex')
- } while (sessions.has(env.session_key))
- session = transaction.LazyObject()
- sessions.set(env.session_key, session)
}
await session.set('expires', expires.getTime())