Major refactoring of get_session(), get_account(), get_nodemailer(), introduces ...
authorNick Downing <nick@ndcode.org>
Mon, 24 Jan 2022 00:41:01 +0000 (11:41 +1100)
committerNick Downing <nick@ndcode.org>
Mon, 24 Jan 2022 00:57:53 +0000 (11:57 +1100)
45 files changed:
_config/site.jst
_lib/get_account.jst
_lib/get_globals.jst [deleted file]
_lib/get_nodemailer.jst
_lib/get_session.jst
_lib/navbar.jst
_lib/page.jst
_lib/post_request.jst
api/account/change_details/get.json.jst
api/account/change_details/get_draft.json.jst
api/account/change_details/set.json.jst
api/account/change_details/set_draft.json.jst
api/account/change_password.json.jst
api/account/password_reset.json.jst
api/account/sign_in.json.jst
api/account/sign_out.json.jst
api/account/sign_up/create_account.json.jst
api/account/sign_up/get_draft.json.jst
api/account/sign_up/send_email_verification_link.json.jst
api/account/sign_up/set_draft.json.jst
api/account/sign_up/verify_email.json.jst
api/account/verify_password.json.jst
api/contact/get_draft.json.jst
api/contact/send_enquiry.json.jst
api/contact/set_draft.json.jst
api/feedback.json.jst
api/globals/get.json.jst
api/globals/set.json.jst
api/nodemailer/get.json.jst
api/nodemailer/set.json.jst
api/verification_image.png.jst
blog/20220114/index.html.jst
blog/index.html.jst
contact/index.html.jst
index.html.jst
jsdoc.dir.jst
my_account/index.html.jst
my_account/password_reset/index.html.jst
my_account/send_verification_email/index.html.jst
my_account/sign_up/index.html.jst
my_account/verify_email/index.html.jst
my_account/verify_password/index.html.jst
projects/index.html.jst
search/index.html.jst
sphinx.dir.jst

index 6871bc0..9e37c6d 100644 (file)
@@ -116,9 +116,8 @@ return async (resources, root, prev_site) => {
       env.now = XDate.now()
       let transaction = await this.database.Transaction()
       try {
-        let sessions = await (
-          await transaction.get({})
-        ).get('sessions', {})
+        let root = await transaction.get({})
+        let sessions = await root.get('sessions', {})
 
         let cookies = cookie.parse(env.request.headers.cookie || '')
         let session, expires = new XDate(env.now)
index 6a44637..d810b70 100644 (file)
@@ -1,12 +1,7 @@
-return async (env, transaction, session) => {
-  let accounts = await (
-    await transaction.get({})
-  ).get('accounts', {})
-
+return async (root, session) => {
   let signed_in_as = await session.get('signed_in_as', null)
-  return (
-    signed_in_as !== null ?
-      await accounts.get(signed_in_as, {}) :
-      undefined
-  )
+  if (signed_in_as === null)
+    return undefined
+  let accounts = await root.get('accounts', {})
+  return await accounts.get(signed_in_as, {})
 }
diff --git a/_lib/get_globals.jst b/_lib/get_globals.jst
deleted file mode 100644 (file)
index 73cd7f3..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-return async (env, transaction) => {
-  return /*await*/ (
-    await transaction.get({})
-  ).get('globals', {})
-}
index 18a568c..572fc6a 100644 (file)
@@ -1,11 +1,6 @@
 let nodemailer = require('nodemailer')
 
-return async (env, transaction, name) => {
-  return nodemailer.createTransport(
-    await (
-      await (
-        await transaction.get({})
-      ).get('nodemailer')
-    ).get_json(name)
-  )
+return async (root, name) => {
+  let _nodemailer = await root.get('nodemailer')
+  return nodemailer.createTransport(await _nodemailer.get_json(name))
 }
index c532c8e..06fec33 100644 (file)
@@ -1,10 +1,7 @@
 let XDate = require('xdate')
 
-return async (env, transaction) => {
-  let sessions = await (
-    await transaction.get({})
-  ).get('sessions', {})
-
+return async (env, root) => {
+  let sessions = await root.get('sessions', {})
   let session = await sessions.get(env.session_key)
   if (session === undefined) {
     // this should never happen, but could happen if we take more than a day
index b7c32d0..4636c52 100644 (file)
@@ -3,7 +3,6 @@ let XDate = require('xdate')
 
 return async (env, head, body, scripts) => {
   //let cart = await _require('/online_store/cart.jst')
-  let get_globals = await _require('/_lib/get_globals.jst')
   let get_session = await _require('/_lib/get_session.jst')
   //let icon_cart_small = await env.site.get_min_svg('/_svg/icon_cart_small.svg')
   let icon_search_mono = await env.site.get_min_svg('/_svg/icon_search_mono.svg')
@@ -14,15 +13,18 @@ return async (env, head, body, scripts) => {
   // initialize env.cart
   //await cart(env)
 
-  let transaction = await env.site.Transaction()
-  let signed_in_as, site_title, copyright
+  let transaction = await env.site.database.Transaction()
+  let signed_in_as
+  let site_title, copyright
   try {
-    let session = await get_session(env, transaction)
-    signed_in_as = session.get_json('signed_in_as', null)
+    let root = await transaction.get({})
 
-    let globals = await get_globals(env, transaction)
-    site_title = globals.get_json('site_title')
-    copyright = globals.get_json('copyright')
+    let session = await get_session(env, root)
+    signed_in_as = await session.get_json('signed_in_as', null)
+
+    let globals = await root.get('globals', {})
+    site_title = await globals.get_json('site_title')
+    copyright = await globals.get_json('copyright')
   }
   finally {
     transaction.rollback()
@@ -84,7 +86,7 @@ return async (env, head, body, scripts) => {
                 else
                   a#sign-out(href="#" style="display: none;") {'Sign out'}
               }
-  
+
               form(action="/search/index.html") {
                 div.input-group {
                   input.form-control(name="query" type="text" placeholder="Search" aria-describedby="search-button") {}
@@ -96,7 +98,7 @@ return async (env, head, body, scripts) => {
                 }
               }
             }
-  
+
             //div.'col-sm-1'.vbottom {
             //  // a nested div is used to avoid hover colour on the padding
             //  div.nav-li-a(style="text-align: center;") {
index 1599f30..18e5cc2 100644 (file)
@@ -8,27 +8,31 @@ return async (env, head, body, scripts) => {
 
   // initialize env.session_key, set cookie in env.response
   let transaction = await env.site.database.Transaction()
-  let session = await get_session(env, transaction)
+  try {
+    let root = await transaction.get({})
+    let session = await get_session(env, root)
 
-  let pageview = await (
-    await (
-      await transaction.get({})
-    ).get('pageviews', {})
-  ).get(env.parsed_url.pathname, {})
-  pageview.set('visits', (await pageview.get('visits') || 0) + 1)
+    let pageviews = await root.get('pageviews', {})
+    let pageview = await pageviews.get(env.parsed_url.pathname, {})
+    pageview.set('visits', (await pageview.get('visits') || 0) + 1)
 
-  let session_pageviews = await session.get('pageviews', {})
-  let i = await session_pageviews.get(env.parsed_url.pathname)
-  if (i === undefined) {
-    pageview.set(
-      'unique_visits',
-      (await pageview.get('unique_visits') || 0) + 1
-    )
-    i = 0
-  }
-  session_pageviews.set(env.parsed_url.pathname, i + 1)
+    let session_pageviews = await session.get('pageviews', {})
+    let i = await session_pageviews.get(env.parsed_url.pathname)
+    if (i === undefined) {
+      pageview.set(
+        'unique_visits',
+        (await pageview.get('unique_visits') || 0) + 1
+      )
+      i = 0
+    }
+    session_pageviews.set(env.parsed_url.pathname, i + 1)
 
-  await transaction.commit()
+    await transaction.commit()
+  }
+  catch (error) {
+    transaction.rollback()
+    throw error
+  }
 
   let _out = []
   _out.push('<!doctype html>')
index 9df0ecd..484f1b9 100644 (file)
@@ -65,7 +65,7 @@ return async (env, handler) => {
     )
     return
   }
-  
+
   env.site.serve(
     env,
     200,
index d3a78ca..80892b6 100644 (file)
@@ -13,26 +13,21 @@ return async env => {
     async () => {
       let transaction = await env.site.database.Transaction()
       try {
-        let account = await get_account(
-          env,
-          transaction,
-          await get_session(env, transaction)
-        )
+        let root = await transaction.get({})
+        let session = await get_session(env, root)
+
+        let account = await get_account(root, session)
         if (account === undefined)
           throw new Problem('Unauthorized', 'Please sign in first.', 401)
 
-        let details = {
+        return {
           given_names: await account.get_json('given_names'),
           family_name: await account.get_json('family_name'),
           contact_me: await account.get_json('contact_me')
         }
-
-        await transaction.commit()
-        return details
       }
-      catch (error) {
+      finally {
         transaction.rollback()
-        throw error
       }
     }
   )
index 41aa970..1afa16e 100644 (file)
@@ -12,11 +12,11 @@ return async env => {
     async () => {
       let transaction = await env.site.database.Transaction()
       try {
-        // initialize env.session_key, set cookie in env.response
-        let session = await get_session(env, transaction)
+        let root = await transaction.get({})
+        let session = await get_session(env, root)
 
         let change_details_draft = await session.get('change_details_draft')
-        let details =
+        return (
           change_details_draft !== undefined &&
             XDate.now() < await change_details_draft.get_json('expires') ?
             {
@@ -25,13 +25,10 @@ return async env => {
               contact_me: await change_details_draft.get_json('contact_me')
             } :
             null
-
-        await transaction.commit()
-        return details
+        )
       }
-      catch (error) {
+      finally {
         transaction.rollback()
-        throw error
       }
     }
   )
index 0000541..109e84e 100644 (file)
@@ -25,11 +25,10 @@ return async env => {
 
       let transaction = await env.site.database.Transaction()
       try {
-        let account = await get_account(
-          env,
-          transaction,
-          await get_session(env, transaction)
-        )
+        let root = await transaction.get({})
+        let session = await get_session(env, root)
+
+        let account = await get_account(root, session)
         if (account === undefined)
           throw new Problem('Unauthorized', 'Please sign in first.', 401)
 
index f6bc528..ada7fe1 100644 (file)
@@ -20,8 +20,8 @@ return async env => {
 
       let transaction = await env.site.database.Transaction()
       try {
-        // initialize env.session_key, set cookie in env.response
-        let session = await get_session(env, transaction)
+        let root = await transaction.get({})
+        let session = await get_session(env, root)
 
         if (details) {
           let expires = new XDate()
index 6192e03..6c06323 100644 (file)
@@ -24,11 +24,10 @@ return async env => {
 
       let transaction = await env.site.database.Transaction()
       try {
-        let account = await get_account(
-          env,
-          transaction,
-          await get_session(env, transaction)
-        )
+        let root = await transaction.get({})
+        let session = await get_session(env, root)
+
+        let account = await get_account(root, session)
         if (account === undefined)
           throw new Problem('Unauthorized', 'Please sign in first.', 401)
 
index 54eff78..fbefab4 100644 (file)
@@ -2,9 +2,7 @@ let crypto = require('crypto')
 let XDate = require('xdate')
 
 return async env => {
-  let get_globals = await _require('/_lib/get_globals.jst')
   let get_nodemailer = await _require('/_lib/get_nodemailer.jst')
-  let get_session = await _require('/_lib/get_session.jst')
   let post_request = await _require('/_lib/post_request.jst')
   let Problem = await _require('/_lib/Problem.jst')
 
@@ -25,17 +23,13 @@ return async env => {
 
       let transaction = await env.site.database.Transaction()
       let link_code
-      let nodemailer, noreply_from, noreply_signature
+      let nodemailer
+      let noreply_from, noreply_signature
       let given_names, family_name
       try {
-        // initialize env.session_key, set cookie in env.response
-        await get_session(env, transaction)
-
-        let account = await (
-          await (
-            await transaction.get({})
-          ).get('accounts', {})
-        ).get(email)
+        let root = await transaction.get({})
+        let accounts = await root.get('accounts', {})
+        let account = await accounts.get(email)
         if (account === undefined)
           throw new Problem(
             'Account does not exist',
@@ -51,8 +45,9 @@ return async env => {
           {password, link_code, expires: expires.getTime()}
         )
 
-        nodemailer = await get_nodemailer(env, transaction, 'noreply')
-        let globals = await get_globals(env, transaction)
+        nodemailer = await get_nodemailer(root, 'noreply')
+
+        let globals = await root.get('globals', {})
         site_url = await globals.get_json('site_url')
         noreply_from = await globals.get_json('noreply_from')
         noreply_signature = await globals.get_json('noreply_signature')
index a25211e..30a5bd1 100644 (file)
@@ -20,14 +20,10 @@ return async env => {
 
       let transaction = await env.site.database.Transaction()
       try {
-        // initialize env.session_key, set cookie in env.response
-        let session = await get_session(env, transaction)
+        let root = await transaction.get({})
 
-        let account = await (
-          await (
-            await transaction.get({})
-          ).get('accounts', {})
-        ).get(email)
+        let accounts = await root.get('accounts', {})
+        let account = await accounts.get(email)
         if (
           account === undefined ||
             password !== await account.get_json('password')
@@ -45,6 +41,7 @@ return async env => {
             425
           )
 
+        let session = await get_session(env, root)
         session.set_json('signed_in_as', email)
         await transaction.commit()
       }
index a382816..a7cd216 100644 (file)
@@ -10,8 +10,8 @@ return async env => {
     async () => {
       let transaction = await env.site.database.Transaction()
       try {
-        // initialize env.session_key, set cookie in env.response
-        let session = await get_session(env, transaction)
+        let root = await transaction.get({})
+        let session = await get_session(env, root)
 
         session.set('signed_in_as', null)
         await transaction.commit()
index 4c30fc9..2685f30 100644 (file)
@@ -32,8 +32,8 @@ return async env => {
 
       let transaction = await env.site.database.Transaction()
       try {
-        // initialize env.session_key, set cookie in env.response
-        let session = await get_session(env, transaction)
+        let root = await transaction.get({})
+        let session = await get_session(env, root)
 
         let captcha = await session.get('captcha')
         if (
@@ -45,7 +45,7 @@ return async env => {
             `Please call the "/api/verification_image.png" endpoint to create a verification image, in same session as the "/api/account/sign_up/create_account.json" call and less than one hour prior.`,
             418
           )
-        
+
         let captcha_text = await captcha.get_json('text')
         if (verification_code !== captcha_text) {
           console.log(`verification code mismatch, \"${verification_code}\" should be \"${captcha_text}\"`)
@@ -57,10 +57,7 @@ return async env => {
           )
         }
 
-        let accounts = await (
-          await transaction.get({})
-        ).get('accounts', {})
-
+        let accounts = await root.get('accounts', {})
         if (accounts.has(details.email))
           throw new Problem(
             'Account already exists',
index db872bd..829cbe3 100644 (file)
@@ -12,11 +12,11 @@ return async env => {
     async () => {
       let transaction = await env.site.database.Transaction()
       try {
-        // initialize env.session_key, set cookie in env.response
-        let session = await get_session(env, transaction)
+        let root = await transaction.get({})
+        let session = await get_session(env, root)
 
         let sign_up_draft = await session.get('sign_up_draft')
-        let details =
+        return (
           sign_up_draft !== undefined &&
             XDate.now() < await sign_up_draft.get_json('expires') ?
             {
@@ -26,13 +26,10 @@ return async env => {
               contact_me: await sign_up_draft.get_json('contact_me')
             } :
             null
-
-        await transaction.commit()
-        return details
+        )
       }
-      catch (error) {
+      finally {
         transaction.rollback()
-        throw error
       }
     }
   )
index 0f60056..c1d052f 100644 (file)
@@ -2,9 +2,7 @@ let crypto = require('crypto')
 let XDate = require('xdate')
 
 return async env => {
-  let get_globals = await _require('/_lib/get_globals.jst')
   let get_nodemailer = await _require('/_lib/get_nodemailer.jst')
-  let get_session = await _require('/_lib/get_session.jst')
   let post_request = await _require('/_lib/post_request.jst')
   let Problem = await _require('/_lib/Problem.jst')
 
@@ -24,17 +22,13 @@ return async env => {
 
       let transaction = await env.site.database.Transaction()
       let link_code
-      let nodemailer, site_url, noreply_from, noreply_signature
+      let nodemailer
+      let site_url, noreply_from, noreply_signature
       let given_names, family_name
       try {
-        // initialize env.session_key, set cookie in env.response
-        await get_session(env, transaction)
-
-        let account = await (
-          await (
-            await transaction.get({})
-          ).get('accounts', {})
-        ).get(email)
+        let root = await transaction.get({})
+        let accounts = await root.get('accounts', {})
+        let account = await accounts.get(email)
         if (account === undefined)
           throw new Problem(
             'Account does not exist',
@@ -57,8 +51,9 @@ return async env => {
           {link_code, expires: expires.getTime()}
         )
 
-        nodemailer = await get_nodemailer(env, transaction, 'noreply')
-        let globals = await get_globals(env, transaction)
+        nodemailer = await get_nodemailer(root, 'noreply')
+
+        let globals = await root.get('globals', {})
         site_url = await globals.get_json('site_url')
         noreply_from = await globals.get_json('noreply_from')
         noreply_signature = await globals.get_json('noreply_signature')
index 103c6ee..b777ac7 100644 (file)
@@ -21,8 +21,8 @@ return async env => {
 
       let transaction = await env.site.database.Transaction()
       try {
-        // initialize env.session_key, set cookie in env.response
-        let session = await get_session(env, transaction)
+        let root = await transaction.get({})
+        let session = await get_session(env, root)
 
         if (details) {
           let expires = new XDate()
index 0e4a932..2517749 100644 (file)
@@ -3,7 +3,6 @@ let XDate = require('xdate')
 
 return async env => {
   let post_request = await _require('/_lib/post_request.jst')
-  let get_session = await _require('/_lib/get_session.jst')
   let Problem = await _require('/_lib/Problem.jst')
 
   await post_request(
@@ -23,14 +22,9 @@ return async env => {
 
       let transaction = await env.site.database.Transaction()
       try {
-        // initialize env.session_key, set cookie in env.response
-        await get_session(env, transaction)
-
-        let account = await (
-          await (
-            await transaction.get({})
-          ).get('accounts', {})
-        ).get(email)
+        let root = await transaction.get({})
+        let accounts = await root.get('accounts', {})
+        let account = await accounts.get(email)
         if (account === undefined)
           throw new Problem(
             'Account does not exist',
@@ -64,7 +58,6 @@ return async env => {
 
         await account.delete('verify_email')
         await account.set('email_verified', true)
-
         await transaction.commit()
       }
       catch (error) {
index 8f456ae..ca0d76a 100644 (file)
@@ -3,7 +3,6 @@ let XDate = require('xdate')
 
 return async env => {
   let post_request = await _require('/_lib/post_request.jst')
-  let get_session = await _require('/_lib/get_session.jst')
   let Problem = await _require('/_lib/Problem.jst')
 
   await post_request(
@@ -23,14 +22,9 @@ return async env => {
 
       let transaction = await env.site.database.Transaction()
       try {
-        // initialize env.session_key, set cookie in env.response
-        await get_session(env, transaction)
-
-        let account = await (
-          await (
-            await transaction.get({})
-          ).get('accounts', {})
-        ).get(email)
+        let root = await transaction.get({})
+        let accounts = await root.get('accounts', {})
+        let account = await accounts.get(email)
         if (account === undefined)
           throw new Problem(
             'Account does not exist',
index 4e55931..af5502a 100644 (file)
@@ -12,11 +12,11 @@ return async env => {
     async () => {
       let transaction = await env.site.database.Transaction()
       try {
-        // initialize env.session_key, set cookie in env.response
-        let session = await get_session(env, transaction)
+        let root = await transaction.get({})
+        let session = await get_session(env, root)
 
         let contact_draft = await session.get('contact_draft')
-        let details =
+        return (
           contact_draft !== undefined &&
             XDate.now() < await contact_draft.get_json('expires') ?
             {
@@ -27,13 +27,10 @@ return async env => {
               message: await contact_draft.get_json('message')
             } :
             null
-
-        await transaction.commit()
-        return details
+        )
       }
-      catch (error) {
+      finally {
         transaction.rollback()
-        throw error
       }
     }
   )
index edf8f55..137210d 100644 (file)
@@ -1,9 +1,7 @@
 let XDate = require('xdate')
 
 return async env => {
-  let get_globals = await _require('/_lib/get_globals.jst')
   let get_nodemailer = await _require('/_lib/get_nodemailer.jst')
-  let get_session = await _require('/_lib/get_session.jst')
   let post_request = await _require('/_lib/post_request.jst')
   let Problem = await _require('/_lib/Problem.jst')
 
@@ -32,21 +30,19 @@ return async env => {
         )
 
       let transaction = await env.site.database.Transaction()
-      let nodemailer, contact_from, contact_to
+      let nodemailer
+      let contact_from, contact_to
       try {
-        // initialize env.session_key, set cookie in env.response
-        get_session(env, transaction)
+        let root = await transaction.get({})
 
-        nodemailer = await get_nodemailer(env, transaction, 'contact')
-        let globals = await get_globals(env, transaction)
+        nodemailer = await get_nodemailer(root, 'contact')
+
+        let globals = await root.get('globals', {})
         contact_from = await globals.get_json('contact_from')
         contact_to = await globals.get_json('contact_to')
-
-        await transaction.commit()
       }
-      catch (error) {
+      finally {
         transaction.rollback()
-        throw error
       }
 
       let name =
index d0b19ea..2f8af42 100644 (file)
@@ -22,8 +22,8 @@ return async env => {
 
       let transaction = await env.site.database.Transaction()
       try {
-        // initialize env.session_key, set cookie in env.response
-        let session = await get_session(env, transaction)
+        let root = await transaction.get({})
+        let session = await get_session(env, root)
 
         if (details) {
           let expires = new XDate()
index 2be476d..4d3ea47 100644 (file)
@@ -2,7 +2,6 @@ let XDate = require('xdate')
 
 return async env => {
   let get_nodemailer = await _require('/_lib/get_nodemailer.jst')
-  let get_session = await _require('/_lib/get_session.jst')
   let post_request = await _require('/_lib/post_request.jst')
 
   await post_request(
@@ -21,21 +20,19 @@ return async env => {
         )
 
       let transaction = await env.site.database.Transaction()
-      let nodemailer, feedback_from, feedback_to
+      let nodemailer
+      let feedback_from, feedback_to
       try {
-        // initialize env.session_key, set cookie in env.response
-        await get_session(env, transaction)
+        let root = await transaction.get({})
 
-        nodemailer = await get_nodemailer(env, transaction, 'feedback')
-        let globals = await get_globals(env, transaction)
+        nodemailer = await get_nodemailer(root, 'feedback')
+
+        let globals = await root.get('globals', {})
         feedback_from = await globals.get_json('feedback_from')
         feedback_to = await globals.get_json('feedback_to')
-
-        await transaction.commit()
       }
-      catch (error) {
+      finally {
         transaction.rollback()
-        throw error
       }
 
       await nodemailer.sendMail(
index a87a59b..155fab4 100644 (file)
@@ -13,24 +13,19 @@ return async env => {
     async () => {
       let transaction = await env.site.database.Transaction()
       try {
-        let account = await get_account(
-          env,
-          transaction,
-          await get_session(env, transaction)
-        )
+        let root = await transaction.get({})
+        let session = await get_session(env, root)
+
+        let account = await get_account(root, session)
         if (account === undefined)
           throw new Problem('Unauthorized', 'Please sign in first.', 401)
         if (!await account.get_json('administrator'))
           throw new Problem('Unauthorized', 'Not administrator.', 401)
 
-        globals = await (await transaction.get({})).get_json('globals', {})
-
-        await transaction.commit()
-        return globals
+        return /*await*/ root.get_json('globals', {})
       }
-      catch (error) {
+      finally {
         transaction.rollback()
-        throw error
       }
     }
   )
index 9d2e304..5949fe2 100644 (file)
@@ -25,17 +25,16 @@ return async env => {
 
       let transaction = await env.site.database.Transaction()
       try {
-        let account = await get_account(
-          env,
-          transaction,
-          await get_session(env, transaction)
-        )
+        let root = await transaction.get({})
+        let session = await get_session(env, root)
+
+        let account = await get_account(root, session)
         if (account === undefined)
           throw new Problem('Unauthorized', 'Please sign in first.', 401)
         if (!await account.get_json('administrator'))
           throw new Problem('Unauthorized', 'Not administrator.', 401)
 
-        ;(await transaction.get({})).set_json('globals', globals)
+        root.set_json('globals', globals)
         await transaction.commit()
       }
       catch (error) {
index a9e0a8f..2aa421d 100644 (file)
@@ -13,27 +13,19 @@ return async env => {
     async () => {
       let transaction = await env.site.database.Transaction()
       try {
-        let account = await get_account(
-          env,
-          transaction,
-          await get_session(env, transaction)
-        )
+        let root = await transaction.get({})
+        let session = await get_session(env, root)
+
+        let account = await get_account(root, session)
         if (account === undefined)
           throw new Problem('Unauthorized', 'Please sign in first.', 401)
-
         if (!await account.get_json('administrator'))
           throw new Problem('Unauthorized', 'Not administrator.', 401)
 
-        nodemailer = await (
-          await transaction.get({})
-        ).get_json('nodemailer', {})
-
-        await transaction.commit()
-        return nodemailer
+        return /*await*/ root.get_json('nodemailer', {})
       }
-      catch (error) {
+      finally {
         transaction.rollback()
-        throw error
       }
     }
   )
index 292529b..623c002 100644 (file)
@@ -16,18 +16,16 @@ return async env => {
 
       let transaction = await env.site.database.Transaction()
       try {
-        let account = await get_account(
-          env,
-          transaction,
-          await get_session(env, transaction)
-        )
+        let root = await transaction.get({})
+        let session = await get_session(env, root)
+
+        let account = await get_account(root, session)
         if (account === undefined)
           throw new Problem('Unauthorized', 'Please sign in first.', 401)
-
         if (!await account.get_json('administrator'))
           throw new Problem('Unauthorized', 'Not administrator.', 401)
 
-        ;(await transaction.get({})).set_json('nodemailer', nodemailer)
+        root.set_json('nodemailer', nodemailer)
         await transaction.commit()
       }
       catch (error) {
index c0bc7ed..0866545 100644 (file)
@@ -8,19 +8,25 @@ return async env => {
   let captcha = captchagen.create()
   captcha.generate()
 
-  // initialize env.session_key, set cookie in env.response
   let transaction = await env.site.database.Transaction()
-  let session = await get_session(env, transaction)
+  try {
+    let root = await transaction.get({})
+    let session = await get_session(env, root)
 
-  // store captcha text in the session for validation when form submitted
-  let expires = new XDate()
-  expires.addHours(1)
-  session.set_json(
-    'captcha',
-    {text: captcha.text(), expires: expires.getTime()}
-  )
+    // store captcha text in the session for validation when form submitted
+    let expires = new XDate(env.now)
+    expires.addHours(1)
+    session.set_json(
+      'captcha',
+      {text: captcha.text(), expires: expires.getTime()}
+    )
 
-  await transaction.commit()
+    await transaction.commit()
+  }
+  catch (error) {
+    transaction.rollback()
+    throw error
+  }
 
   // serve the png file
   env.caching = false
index 00320b1..d1cead1 100644 (file)
@@ -1,5 +1,5 @@
 return async env => {
-  let post = await _require('/_lib/post.jst') 
+  let post = await _require('/_lib/post.jst')
 
   await post(
     env,
@@ -152,7 +152,7 @@ return async env => {
         i {'reference'}
         ' to the just-written element, rather than the full text of the element itself:'
       }
+
       pre {
         `[
   "Hello",
@@ -447,10 +447,10 @@ return async env => {
         ' or '
         tt {'Object'}
         ' as not conflicting.'
-      }    
+      }
 
       p {'Currently there is a bit of a risk that if I do not implement good try/catch handling in my code, then a webserver request will crash, leaving the webserver running but the mutex in ‘held’ state. This would hang the webserver, requiring a manual restart. I could implement some sort of disaster recovery, but there is probably no point at this time, I will simply use try/catch and make sure transactions are rolled back if not completed.'}
+
       h4 {'Conclusion'}
 
       p {'The log-structured format provides a useful way of maintaining huge JSON files. It remains to complete the documentation and release the source code and NPM package. It also remains to implement a stress test of my website, once up and running, to simulate thousands of user accounts and multiple logins to the same account all performing transactions simultaneously. Therefore, things are still experimental at this stage. I enjoy writing this blog to update on those experiments.'}
index 94ce83b..3345d9f 100644 (file)
@@ -2,7 +2,7 @@ return async env => {
   let breadcrumbs = await _require('/_lib/breadcrumbs.jst')
   let menu = await env.site.get_menu('/blog/_menu.json')
   let navbar = await _require('/_lib/navbar.jst')
+
   await navbar(
     env,
     async _out => {},
index db92d12..888226f 100644 (file)
@@ -2,16 +2,17 @@ let XDate = require('xdate')
 
 return async env => {
   let breadcrumbs = await _require('/_lib/breadcrumbs.jst')
+  let get_session = await _require('/_lib/get_session.jst')
   let icon_cross = await env.site.get_min_svg('/_svg/icon_cross.svg')
   let icon_tick = await env.site.get_min_svg('/_svg/icon_tick.svg')
   let navbar = await _require('/_lib/navbar.jst')
-  let get_session = await _require('/_lib/get_session.jst')
 
   // preload draft details if any
-  let transaction = await env.site.database.Transaction(), draft_details
+  let transaction = await env.site.database.Transaction()
+  let draft_details
   try {
-    // initialize env.session_key, set cookie in env.response
-    let session = await get_session(env, transaction)
+    let root = await transaction.get({})
+    let session = await get_session(env, root)
 
     let contact_draft = await session.get('contact_draft')
     draft_details =
@@ -26,12 +27,9 @@ return async env => {
           message: await contact_draft.get_json('message')
         } :
         null
-
-    await transaction.commit()
   }
-  catch (error) {
+  finally {
     transaction.rollback()
-    throw error
   }
   console.log('draft_details', JSON.stringify(draft_details))
 
index 91e814f..c806094 100644 (file)
@@ -1,7 +1,7 @@
 return async env => {
   let breadcrumbs = await _require('/_lib/breadcrumbs.jst')
   let navbar = await _require('/_lib/navbar.jst')
+
   await navbar(
     env,
     // head
index 35f8d86..6587a97 100644 (file)
@@ -1,6 +1,6 @@
 let serve_html = async (env, pathname) => {
   // read HTML file
-  let data 
+  let data
   try {
     data = await env.site.min_html_cache.get(pathname)
   }
@@ -53,4 +53,4 @@ return async (env, pathname, components) => {
   )
     return
   return /*await*/ env.site.serve_path(env, pathname, components)
-} 
+}
index fc7f0d5..403ba6f 100644 (file)
@@ -13,10 +13,12 @@ return async env => {
   let transaction = await env.site.database.Transaction()
   let signed_in_as, details, draft_details
   try {
-    let session = await get_session(env, transaction)
+    let root = await transaction.get({})
+
+    let session = await get_session(env, root)
     signed_in_as = await session.get_json('signed_in_as', null)
 
-    let account = await get_account(env, transaction, session)
+    let account = await get_account(root, session)
     if (account !== undefined) {
       details = {
         given_names: await account.get_json('given_names'),
@@ -35,11 +37,9 @@ return async env => {
           } :
           null
     }
-    await transaction.commit()
   }
-  catch (error) {
+  finally {
     transaction.rollback()
-    throw error
   }
   console.log(
     'details',
@@ -253,7 +253,7 @@ return async env => {
                 step_1_dirty = true
                 document.getElementById('step-1-revert').disabled = false
                 document.getElementById('step-1-save').disabled = false
-    
+
                 if (!draft_timeout_running) {
                   draft_timeout_running = true
                   setTimeout(draft_timeout_handler, 5000)
@@ -279,7 +279,7 @@ return async env => {
                   $('#step-1-cross').hide()
                   $('#step-1-spinner').show()
 
-                  let details      
+                  let details
                   try {
                     details = await api_account_change_details_get()
                   }
@@ -296,7 +296,7 @@ return async env => {
                           400
                         )
                     console.log(problem.detail)
-      
+
                     $('#step-1-tick').hide()
                     $('#step-1-cross').show()
                     $('#step-1-spinner').hide()
@@ -336,7 +336,7 @@ return async env => {
                   $('#step-1-tick').hide()
                   $('#step-1-cross').hide()
                   $('#step-1-spinner').show()
-      
+
                   try {
                     await api_account_change_details_set(
                       {
@@ -359,7 +359,7 @@ return async env => {
                           400
                         )
                     console.log(problem.detail)
-      
+
                     $('#step-1-tick').hide()
                     $('#step-1-cross').show()
                     $('#step-1-spinner').hide()
@@ -421,7 +421,7 @@ return async env => {
                   $('#step-2-tick').hide()
                   $('#step-2-cross').hide()
                   $('#step-2-spinner').show()
-      
+
                   try {
                     await api_account_change_password(
                       // old_password
@@ -443,7 +443,7 @@ return async env => {
                           400
                         )
                     console.log(problem.detail)
-      
+
                     $('#step-2-tick').hide()
                     $('#step-2-cross').show()
                     $('#step-2-spinner').hide()
index b66e431..3e9a639 100644 (file)
@@ -5,7 +5,6 @@ return async env => {
   let icon_cross = await env.site.get_min_svg('/_svg/icon_cross.svg')
   let icon_tick = await env.site.get_min_svg('/_svg/icon_tick.svg')
   let navbar = await _require('/_lib/navbar.jst')
-  let get_session = await _require('/_lib/get_session.jst')
 
   // preload draft details if any
   let details = {}
@@ -107,7 +106,7 @@ return async env => {
 
         let step_1 = async () => {
           if (
-            !document.getElementById('email').reportValidity() || 
+            !document.getElementById('email').reportValidity() ||
               !document.getElementById('password').reportValidity()
           ) {
             $('#step-1-tick').hide()
index 15793df..f5fec01 100644 (file)
@@ -3,7 +3,6 @@ return async env => {
   let icon_cross = await env.site.get_min_svg('/_svg/icon_cross.svg')
   let icon_tick = await env.site.get_min_svg('/_svg/icon_tick.svg')
   let navbar = await _require('/_lib/navbar.jst')
-  let get_session = await _require('/_lib/get_session.jst')
 
   // preload draft details if any
   let details = {}
index 10be9f6..c7ef86f 100644 (file)
@@ -2,16 +2,17 @@ let XDate = require('xdate')
 
 return async env => {
   let breadcrumbs = await _require('/_lib/breadcrumbs.jst')
+  let get_session = await _require('/_lib/get_session.jst')
   let icon_cross = await env.site.get_min_svg('/_svg/icon_cross.svg')
   let icon_tick = await env.site.get_min_svg('/_svg/icon_tick.svg')
   let navbar = await _require('/_lib/navbar.jst')
-  let get_session = await _require('/_lib/get_session.jst')
 
   // preload draft details if any
-  let transaction = await env.site.database.Transaction(), draft_details
+  let transaction = await env.site.database.Transaction()
+  let draft_details
   try {
-    // initialize env.session_key, set cookie in env.response
-    let session = await get_session(env, transaction)
+    let root = await transaction.get({})
+    let session = await get_session(env, root)
 
     let sign_up_draft = await session.get('sign_up_draft')
     draft_details =
@@ -24,12 +25,9 @@ return async env => {
           contact_me: await sign_up_draft.get_json('contact_me')
         } :
         null
-
-    await transaction.commit()
   }
-  catch (error) {
+  finally {
     transaction.rollback()
-    throw error
   }
   console.log('draft_details', JSON.stringify(draft_details))
 
index 63e9a1f..4e27a61 100644 (file)
@@ -3,7 +3,6 @@ return async env => {
   let icon_cross = await env.site.get_min_svg('/_svg/icon_cross.svg')
   let icon_tick = await env.site.get_min_svg('/_svg/icon_tick.svg')
   let navbar = await _require('/_lib/navbar.jst')
-  let get_session = await _require('/_lib/get_session.jst')
 
   // preload draft details if any
   let details = {}
index 480db52..2c8034a 100644 (file)
@@ -3,7 +3,6 @@ return async env => {
   let icon_cross = await env.site.get_min_svg('/_svg/icon_cross.svg')
   let icon_tick = await env.site.get_min_svg('/_svg/icon_tick.svg')
   let navbar = await _require('/_lib/navbar.jst')
-  let get_session = await _require('/_lib/get_session.jst')
 
   // preload draft details if any
   let details = {}
index 9e65ac3..f47050d 100644 (file)
@@ -3,7 +3,7 @@ return async env => {
   let icon_jst = await env.site.get_min_svg('/_svg/icon_jst.svg')
   let navbar = await _require('/_lib/navbar.jst')
   let icon_pitree = await env.site.get_min_svg('/_svg/icon_pitree.svg')
+
   await navbar(
     env,
     // head
index 246531a..a066789 100644 (file)
@@ -19,7 +19,7 @@ return async env => {
     async _out => {
       async function breadcrumbs_str(pathname) {
         assert(pathname.slice(0, 1) === '/')
-      
+
         // find names of path components
         console.log('pathname', pathname)
         let components = ['Home']
@@ -37,7 +37,7 @@ return async env => {
           components.push(menu.entries[menu.index[dir]].name)
         }
 
-        return components.join(' > ')      
+        return components.join(' > ')
       }
 
       await breadcrumbs(env, _out)
@@ -46,7 +46,7 @@ return async env => {
         'Query: '
         strong {`${query}`}
       }
-    
+
       if (search.results.length) {
         p {`Showing results ${first + 1}–${first + search.results.length} of ${search.total_results}`}
 
index 0856b4e..8c8870e 100644 (file)
@@ -1,6 +1,6 @@
 let serve_html = async (env, pathname) => {
   // read HTML file
-  let data 
+  let data
   try {
     data = await env.site.min_html_cache.get(pathname)
   }
@@ -57,4 +57,4 @@ return async (env, pathname, components) => {
   )
     return
   return /*await*/ env.site.serve_path(env, pathname, components)
-} 
+}