Use jst_server.Problem everywhere, make /_lib/post_request.jst use jst_server's new...
authorNick Downing <nick@ndcode.org>
Tue, 25 Jan 2022 23:44:34 +0000 (10:44 +1100)
committerNick Downing <nick@ndcode.org>
Tue, 25 Jan 2022 23:55:47 +0000 (10:55 +1100)
25 files changed:
_lib/Problem.jst [deleted file]
_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/globals/get.json.jst
api/globals/set.json.jst
api/nodemailers/get.json.jst
api/nodemailers/set.json.jst
link.sh
package.json

diff --git a/_lib/Problem.jst b/_lib/Problem.jst
deleted file mode 100644 (file)
index 3b017c2..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-class Problem {
-  constructor(title, detail, status) {
-    this.title = title
-    this.detail = detail
-    this.status = status
-  }
-
-  // note: Javascript errors return status 400 (Bad request) in the client
-  // version of Problem, 500 (Internal server error) in the server version
-  static from(error) {
-    return (
-      error instanceof Problem ?
-        error :
-        new Problem(
-          'Internal server error',
-          (error.stack || error.message),
-          500
-        )
-    )
-  }
-}
-
-return Problem
index 484f1b9..1757f86 100644 (file)
@@ -1,70 +1,32 @@
+let jst_server = (await import('@ndcode/jst_server')).default
 let stream_buffers = require('stream-buffers')
 
 return async (env, handler) => {
-  let Problem = await _require('/_lib/Problem.jst')
-
-  let result
-  try {
-    if (env.request.method !== 'POST') {
-      env.response.setHeader('Allow', 'POST')
-      throw new Problem(
-        'Method not allowed',
-        `The endpoint "${env.parsed_url.path}" requires a POST request.`,
-        405
-      )
-    }
-
-    let write_stream = new stream_buffers.WritableStreamBuffer()
-    let data = new Promise(
-      (resolve, reject) => {
-        write_stream.
-        on('finish', () => {resolve(write_stream.getContents())}).
-        on('error', () => {reject()})
-      }
+  if (env.request.method !== 'POST') {
+    env.response.setHeader('Allow', 'POST')
+    throw new jst_server.Problem(
+      'Method not allowed',
+      `The endpoint "${env.parsed_url.path}" requires a POST request.`,
+      405
     )
-    env.request.pipe(write_stream)
-    let args = JSON.parse((await data).toString('utf-8'))
-    console.log('endpoint', env.parsed_url.path, 'args', JSON.stringify(args))
-
-    result = await handler(...args)
-    if (result === undefined)
-      result = null
-    console.log('endpoint', env.parsed_url.path, 'result', JSON.stringify(result))
   }
-  catch (error) {
-    let problem =
-      error instanceof Problem ?
-        error :
-        new Problem(
-          // title
-          'Internal server error',
-          // details
-          (error.stack || error.message).toString()
-          // status
-          500
-        )
-    console.log('endpoint', env.parsed_url.path, 'problem', problem.detail)
 
-    env.mime_type = 'application/problem+json; charset=utf-8'
-    env.site.serve(
-      env,
-      problem.status,
-      Buffer.from(
-        JSON.stringify(
-          {
-            title: problem.title,
-            detail: problem.detail,
-            status: problem.status
-          },
-          null,
-          2
-        ) + '\n',
-        'utf-8'
-      ),
-      'post_request.jst'
-    )
-    return
-  }
+  let write_stream = new stream_buffers.WritableStreamBuffer()
+  let data = new Promise(
+    (resolve, reject) => {
+      write_stream.
+      on('finish', () => {resolve(write_stream.getContents())}).
+      on('error', () => {reject()})
+    }
+  )
+  env.request.pipe(write_stream)
+  let args = JSON.parse((await data).toString('utf-8'))
+  console.log('endpoint', env.parsed_url.path, 'args', JSON.stringify(args))
+
+  let result = await handler(...args)
+  if (result === undefined)
+    result = null
+  console.log('endpoint', env.parsed_url.path, 'result', JSON.stringify(result))
 
   env.site.serve(
     env,
index 80892b6..19fb032 100644 (file)
@@ -1,10 +1,10 @@
+let jst_server = (await import('@ndcode/jst_server')).default
 let XDate = require('xdate')
 
 return async env => {
   let get_account = await _require('/_lib/get_account.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')
 
   await post_request(
     // env
@@ -18,7 +18,11 @@ return async env => {
 
         let account = await get_account(root, session)
         if (account === undefined)
-          throw new Problem('Unauthorized', 'Please sign in first.', 401)
+          throw new jst_server.Problem(
+            'Unauthorized',
+            'Please sign in first.',
+            401
+          )
 
         return {
           given_names: await account.get_json('given_names'),
index 1afa16e..a168014 100644 (file)
@@ -1,9 +1,9 @@
+let jst_server = (await import('@ndcode/jst_server')).default
 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(
     // env
index 109e84e..e3de45c 100644 (file)
@@ -1,10 +1,10 @@
+let jst_server = (await import('@ndcode/jst_server')).default
 let XDate = require('xdate')
 
 return async env => {
   let get_account = await _require('/_lib/get_account.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')
 
   await post_request(
     // env
@@ -17,7 +17,7 @@ return async env => {
         contact_me: details.contact_me ? true : false
       }
       if (details.given_names.length === 0)
-        throw new Problem(
+        throw new jst_server.Problem(
           'Bad request',
           'Minimum length check failed',
           400
@@ -30,7 +30,11 @@ return async env => {
 
         let account = await get_account(root, session)
         if (account === undefined)
-          throw new Problem('Unauthorized', 'Please sign in first.', 401)
+          throw new jst_server.Problem(
+            'Unauthorized',
+            'Please sign in first.',
+            401
+          )
 
         account.set_json('given_names', details.given_names)
         account.set_json('family_name', details.family_name)
index ada7fe1..76503c6 100644 (file)
@@ -1,9 +1,9 @@
+let jst_server = (await import('@ndcode/jst_server')).default
 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(
     // env
index 6c06323..2bba98a 100644 (file)
@@ -1,11 +1,11 @@
 let crypto = require('crypto')
+let jst_server = (await import('@ndcode/jst_server')).default
 let XDate = require('xdate')
 
 return async env => {
   let get_account = await _require('/_lib/get_account.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')
 
   await post_request(
     // env
@@ -16,7 +16,7 @@ return async env => {
       old_password = old_password.slice(0, 256)
       new_password = new_password.slice(0, 256)
       if (old_password.length < 8 || new_password.length < 8)
-        throw new Problem(
+        throw new jst_server.Problem(
           'Bad request',
           'Minimum length check failed',
           400
@@ -29,10 +29,14 @@ return async env => {
 
         let account = await get_account(root, session)
         if (account === undefined)
-          throw new Problem('Unauthorized', 'Please sign in first.', 401)
+          throw new jst_server.Problem(
+            'Unauthorized',
+            'Please sign in first.',
+            401
+          )
 
         if (old_password !== await account.get_json('password'))
-          throw new Problem(
+          throw new jst_server.Problem(
             'Incorrect password',
             `Provided old password did not match the expected value.`,
             426
index fbefab4..ec15432 100644 (file)
@@ -1,10 +1,10 @@
 let crypto = require('crypto')
+let jst_server = (await import('@ndcode/jst_server')).default
 let XDate = require('xdate')
 
 return async env => {
   let get_nodemailer = await _require('/_lib/get_nodemailer.jst')
   let post_request = await _require('/_lib/post_request.jst')
-  let Problem = await _require('/_lib/Problem.jst')
 
   await post_request(
     // env
@@ -15,7 +15,7 @@ return async env => {
       email = email.slice(0, 256).toLowerCase()
       password = password.slice(0, 256)
       if (email.length === 0 || password.length < 8)
-        throw new Problem(
+        throw new jst_server.Problem(
           'Bad request',
           'Minimum length check failed',
           400
@@ -31,7 +31,7 @@ return async env => {
         let accounts = await root.get('accounts', {})
         let account = await accounts.get(email)
         if (account === undefined)
-          throw new Problem(
+          throw new jst_server.Problem(
             'Account does not exist',
             `Please create the account for "${email}" before attempting to reset its password.`
             421
index 30a5bd1..e35392f 100644 (file)
@@ -1,7 +1,8 @@
+let jst_server = (await import('@ndcode/jst_server')).default
+
 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(
     // env
@@ -12,7 +13,7 @@ return async env => {
       email = email.slice(0, 256).toLowerCase()
       password = password.slice(0, 256)
       if (email.length === 0 || password.length < 8)
-        throw new Problem(
+        throw new jst_server.Problem(
           'Bad request',
           'Minimum length check failed',
           400
@@ -28,14 +29,14 @@ return async env => {
           account === undefined ||
             password !== await account.get_json('password')
         )
-          throw new Problem(
+          throw new jst_server.Problem(
             'Unauthorized',
             'Email and password combination was incorrect.'
             401
           )
 
         if (!await account.get_json('email_verified'))
-          throw new Problem(
+          throw new jst_server.Problem(
             'Email not yet verified',
             'Please verify your email address via email link before trying to sign in.',
             425
index 70287a3..eaeedf1 100644 (file)
@@ -1,7 +1,8 @@
+let jst_server = (await import('@ndcode/jst_server')).default
+
 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(
     // env
index 2685f30..2eb3efe 100644 (file)
@@ -1,9 +1,9 @@
+let jst_server = (await import('@ndcode/jst_server')).default
 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(
     // env
@@ -24,7 +24,7 @@ return async env => {
           details.given_names.length === 0 ||
           details.password.length < 8
       )
-        throw new Problem(
+        throw new jst_server.Problem(
           'Bad request',
           'Minimum length check failed',
           400
@@ -40,7 +40,7 @@ return async env => {
           captcha === undefined ||
             XDate.now() >= await captcha.get_json('expires')
         )
-          throw new Problem(
+          throw new jst_server.Problem(
             'No verification image in session',
             `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
@@ -50,7 +50,7 @@ return async env => {
         if (verification_code !== captcha_text) {
           console.log(`verification code mismatch, \"${verification_code}\" should be \"${captcha_text}\"`)
 
-          throw new Problem(
+          throw new jst_server.Problem(
             'Verification code mismatch',
             `The provided verification code "${verification_code}" did not match the verification image.`,
             419
@@ -59,7 +59,7 @@ return async env => {
 
         let accounts = await root.get('accounts', {})
         if (accounts.has(details.email))
-          throw new Problem(
+          throw new jst_server.Problem(
             'Account already exists',
             `The email "${details.email}" already has an account registered.`,
             420
index cf696b8..9649f6c 100644 (file)
@@ -1,9 +1,9 @@
+let jst_server = (await import('@ndcode/jst_server')).default
 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(
     // env
index c1d052f..5b45149 100644 (file)
@@ -1,10 +1,10 @@
 let crypto = require('crypto')
+let jst_server = (await import('@ndcode/jst_server')).default
 let XDate = require('xdate')
 
 return async env => {
   let get_nodemailer = await _require('/_lib/get_nodemailer.jst')
   let post_request = await _require('/_lib/post_request.jst')
-  let Problem = await _require('/_lib/Problem.jst')
 
   await post_request(
     // env
@@ -14,7 +14,7 @@ return async env => {
       // coerce and/or validate
       email = email.slice(0, 256).toLowerCase()
       if (email.length === 0)
-        throw new Problem(
+        throw new jst_server.Problem(
           'Bad request',
           'Minimum length check failed',
           400
@@ -30,14 +30,14 @@ return async env => {
         let accounts = await root.get('accounts', {})
         let account = await accounts.get(email)
         if (account === undefined)
-          throw new Problem(
+          throw new jst_server.Problem(
             'Account does not exist',
             `Please create the account for "${email}" before attempting to send an email verification link.`
             421
           )
 
         if (await account.get_json('email_verified'))
-          throw new Problem(
+          throw new jst_server.Problem(
             'Email already verified',
             `Your email "${email}" is already verified. You can now sign in.`
             422
index b777ac7..ac20f8e 100644 (file)
@@ -1,9 +1,9 @@
+let jst_server = (await import('@ndcode/jst_server')).default
 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(
     // env
index 2517749..c0f2fc3 100644 (file)
@@ -1,9 +1,9 @@
 let crypto = require('crypto')
+let jst_server = (await import('@ndcode/jst_server')).default
 let XDate = require('xdate')
 
 return async env => {
   let post_request = await _require('/_lib/post_request.jst')
-  let Problem = await _require('/_lib/Problem.jst')
 
   await post_request(
     // env
@@ -14,7 +14,7 @@ return async env => {
       email = email.slice(0, 256).toLowerCase()
       link_code = link_code.slice(0, 256).toLowerCase()
       if (email.length === 0 || link_code.length < 32)
-        throw new Problem(
+        throw new jst_server.Problem(
           'Bad request',
           'Minimum length check failed',
           400
@@ -26,14 +26,14 @@ return async env => {
         let accounts = await root.get('accounts', {})
         let account = await accounts.get(email)
         if (account === undefined)
-          throw new Problem(
+          throw new jst_server.Problem(
             'Account does not exist',
             `Please create the account for "${email}" before attempting to verify the email verification link.`
             421
           )
 
         if (await account.get_json('email_verified'))
-          throw new Problem(
+          throw new jst_server.Problem(
             'Email already verified',
             `Your email "${email}" is already verified. You can now sign in.`
             422
@@ -44,13 +44,13 @@ return async env => {
           verify_email === undefined ||
             XDate.now() >= await verify_email.get_json('expires')
         )
-          throw new Problem(
+          throw new jst_server.Problem(
             'Link code missing',
             `Email verification link code for account "${email}" does not exist or has expired.`,
             423
           )
         if (link_code !== await verify_email.get_json('link_code'))
-          throw new Problem(
+          throw new jst_server.Problem(
             'Link code mismatch',
             `Provided email verification link code "${link_code}" does not match expected value.`,
             423
index ca0d76a..7b7ea25 100644 (file)
@@ -1,9 +1,9 @@
 let crypto = require('crypto')
+let jst_server = (await import('@ndcode/jst_server')).default
 let XDate = require('xdate')
 
 return async env => {
   let post_request = await _require('/_lib/post_request.jst')
-  let Problem = await _require('/_lib/Problem.jst')
 
   await post_request(
     // env
@@ -14,7 +14,7 @@ return async env => {
       email = email.slice(0, 256).toLowerCase()
       link_code = link_code.slice(0, 256).toLowerCase()
       if (email.length === 0 || link_code.length < 32)
-        throw new Problem(
+        throw new jst_server.Problem(
           'Bad request',
           'Minimum length check failed',
           400
@@ -26,7 +26,7 @@ return async env => {
         let accounts = await root.get('accounts', {})
         let account = await accounts.get(email)
         if (account === undefined)
-          throw new Problem(
+          throw new jst_server.Problem(
             'Account does not exist',
             `Please create the account for "${email}" before attempting to verify the password reset link.`
             421
@@ -37,13 +37,13 @@ return async env => {
           verify_password === undefined ||
             XDate.now() >= await verify_password.get_json('expires')
         )
-          throw new Problem(
+          throw new jst_server.Problem(
             'Link code missing',
             `Password reset link code for account "${email}" does not exist or has expired.`,
             423
           )
         if (link_code !== await verify_password.get_json('link_code'))
-          throw new Problem(
+          throw new jst_server.Problem(
             'Link code mismatch',
             `Provided password reset link code "${link_code}" does not match expected value.`,
             423
index af5502a..da507fa 100644 (file)
@@ -1,9 +1,9 @@
+let jst_server = (await import('@ndcode/jst_server')).default
 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(
     // env
index 137210d..daa735b 100644 (file)
@@ -1,9 +1,9 @@
+let jst_server = (await import('@ndcode/jst_server')).default
 let XDate = require('xdate')
 
 return async env => {
   let get_nodemailer = await _require('/_lib/get_nodemailer.jst')
   let post_request = await _require('/_lib/post_request.jst')
-  let Problem = await _require('/_lib/Problem.jst')
 
   await post_request(
     // env
@@ -23,7 +23,7 @@ return async env => {
           details.email.length === 0 ||
           details.message.length === 0
       )
-        throw new Problem(
+        throw new jst_server.Problem(
           'Bad request',
           'Minimum length check failed',
           400
index 2f8af42..a515d67 100644 (file)
@@ -1,9 +1,9 @@
+let jst_server = (await import('@ndcode/jst_server')).default
 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(
     // env
index 155fab4..b8c52a5 100644 (file)
@@ -1,10 +1,10 @@
+let jst_server = (await import('@ndcode/jst_server')).default
 let XDate = require('xdate')
 
 return async env => {
   let get_account = await _require('/_lib/get_account.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')
 
   await post_request(
     // env
@@ -18,9 +18,17 @@ return async env => {
 
         let account = await get_account(root, session)
         if (account === undefined)
-          throw new Problem('Unauthorized', 'Please sign in first.', 401)
+          throw new jst_server.Problem(
+            'Unauthorized',
+            'Please sign in first.',
+            401
+          )
         if (!await account.get_json('administrator'))
-          throw new Problem('Unauthorized', 'Not administrator.', 401)
+          throw new jst_server.Problem(
+            'Unauthorized',
+            'Not administrator.',
+            401
+          )
 
         return /*await*/ root.get_json('globals', {})
       }
index 5949fe2..e1bea58 100644 (file)
@@ -1,9 +1,9 @@
+let jst_server = (await import('@ndcode/jst_server')).default
 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(
     // env
@@ -30,9 +30,17 @@ return async env => {
 
         let account = await get_account(root, session)
         if (account === undefined)
-          throw new Problem('Unauthorized', 'Please sign in first.', 401)
+          throw new jst_server.Problem(
+            'Unauthorized',
+            'Please sign in first.',
+            401
+          )
         if (!await account.get_json('administrator'))
-          throw new Problem('Unauthorized', 'Not administrator.', 401)
+          throw new jst_server.Problem(
+            'Unauthorized',
+            'Not administrator.',
+            401
+          )
 
         root.set_json('globals', globals)
         await transaction.commit()
index 2aa640c..8030196 100644 (file)
@@ -1,10 +1,10 @@
+let jst_server = (await import('@ndcode/jst_server')).default
 let XDate = require('xdate')
 
 return async env => {
   let get_account = await _require('/_lib/get_account.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')
 
   await post_request(
     // env
@@ -18,9 +18,17 @@ return async env => {
 
         let account = await get_account(root, session)
         if (account === undefined)
-          throw new Problem('Unauthorized', 'Please sign in first.', 401)
+          throw new jst_server.Problem(
+            'Unauthorized',
+            'Please sign in first.',
+            401
+          )
         if (!await account.get_json('administrator'))
-          throw new Problem('Unauthorized', 'Not administrator.', 401)
+          throw new jst_server.Problem(
+            'Unauthorized',
+            'Not administrator.',
+            401
+          )
 
         return /*await*/ root.get_json('nodemailers', {})
       }
index 808fe5b..ab57981 100644 (file)
@@ -1,10 +1,10 @@
+let jst_server = (await import('@ndcode/jst_server')).default
 let XDate = require('xdate')
 
 return async env => {
   let get_account = await _require('/_lib/get_account.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')
 
   await post_request(
     // env
@@ -21,9 +21,17 @@ return async env => {
 
         let account = await get_account(root, session)
         if (account === undefined)
-          throw new Problem('Unauthorized', 'Please sign in first.', 401)
+          throw new jst_server.Problem(
+            'Unauthorized',
+            'Please sign in first.',
+            401
+          )
         if (!await account.get_json('administrator'))
-          throw new Problem('Unauthorized', 'Not administrator.', 401)
+          throw new jst_server.Problem(
+            'Unauthorized',
+            'Not administrator.',
+            401
+          )
 
         root.set_json('nodemailers', nodemailers)
         await transaction.commit()
diff --git a/link.sh b/link.sh
index de4f402..8eec3cd 100755 (executable)
--- a/link.sh
+++ b/link.sh
@@ -1,5 +1,5 @@
 #!/bin/sh
 rm -rf node_modules package-lock.json
-npm link @ndcode/logjson @ndcode/nodemailer_cache @ndcode/zettair_cache
+npm link @ndcode/jst_server @ndcode/logjson @ndcode/zettair_cache
 npm install
 npm link
index f31e278..4792a60 100644 (file)
@@ -4,6 +4,7 @@
   "description": "Example website using JavaScript Template system",
   "directories": {},
   "dependencies": {
+    "@ndcode/jst_server": "^0.1.0",
     "@ndcode/logjson": "^0.1.0",
     "@ndcode/zettair_cache": "^0.1.0",
     "captchagen": "^1.2.0",