Remove duplicate session key generation if session_cookie() called repeatedly
authorNick Downing <nick@ndcode.org>
Tue, 18 Jan 2022 00:05:57 +0000 (11:05 +1100)
committerNick Downing <nick@ndcode.org>
Tue, 18 Jan 2022 00:20:09 +0000 (19:20 -0500)
_lib/session_cookie.jst

index 01618ea..7f14413 100644 (file)
@@ -3,37 +3,37 @@ let cookie = require('cookie')
 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())