New approach to sign up form
[ndcode_site.git] / session_cookie.jst
1 let XDate = require('xdate')
2 let cookie = require('cookie')
3 let crypto = require('crypto')
4
5 return async (env, transaction) => {
6   let cookies = cookie.parse(env.request.headers.cookie || '')
7   let now = Date.now()
8
9   let sessions = await (
10     await transaction.get({})
11   ).get('sessions', {})
12
13   let session_key, session, expires = new XDate(now)
14   if (
15     Object.prototype.hasOwnProperty.call(cookies, 'session_key') &&
16       (
17         session = await sessions.get(session_key = cookies.session_key)
18       ) !== undefined &&
19       now < await session.get('expires', 0)
20   )
21     // if session key is already in database, we know the requester supports
22     // cookies, therefore each access extends the session expiry by 1 month
23     expires.addMonths(1)
24   else {
25     // first request for session, maybe a bot, retain session for only 1 day
26     expires.addDays(1)
27     do {
28       session_key = crypto.randomBytes(16).toString('hex')
29     } while (sessions.has(session_key))
30     session = transaction.LazyObject()
31     sessions.set(session_key, session)
32   }
33
34   await session.set('expires', expires.getTime())
35
36   env.response.setHeader(
37     'Set-Cookie',
38     `session_key=${session_key}; expires=${expires.toUTCString()}; path=/;`
39   )
40   env.session_key = session_key
41
42   return session
43 }