Use (Transaction|LazyValue).get_json() instead of logjson.logjson_to_json() and ...
[ndcode_site.git] / _lib / session_cookie.jst
1 let cookie = require('cookie')
2 let crypto = require('crypto')
3 let XDate = require('xdate')
4
5 // note: this routine is "almost" idempotent
6 // it will return the same session key each time
7 // expiry may be increased slightly at each call
8 return async (env, transaction) => {
9   let sessions = await (
10     await transaction.get({})
11   ).get('sessions', {})
12
13   let cookies = cookie.parse(env.request.headers.cookie || '')
14   let now = Date.now()
15
16   let session, expires = new XDate(now)
17   if (
18     Object.prototype.hasOwnProperty.call(cookies, 'session_key') &&
19       (session = await sessions.get(cookies.session_key)) !== undefined &&
20       now < await session.get('expires', 0)
21   ) {
22     // if session key is already in database, we know the requester supports
23     // cookies, therefore each access extends the session expiry by 1 month
24     env.session_key = cookies.session_key
25     expires.addMonths(1)
26   }
27   else {
28     // first request for session, maybe a bot, retain session for only 1 day
29     if (!Object.prototype.hasOwnProperty.call(env, 'session_key')) {
30       do {
31         env.session_key = crypto.randomBytes(16).toString('hex')
32       } while (sessions.has(env.session_key))
33     }
34     session = await sessions.get(env.session_key, {})
35     expires.addDays(1)
36   }
37
38   await session.set('expires', expires.getTime())
39   env.response.setHeader(
40     'Set-Cookie',
41     `session_key=${env.session_key}; expires=${expires.toUTCString()}; path=/;`
42   )
43
44   env.signed_in_as = await session.get_json('signed_in_as', null)
45   return session
46 }