Move account-related APIs down one level into /api/account and the former /api/sign_u...
authorNick Downing <nick@ndcode.org>
Sun, 16 Jan 2022 11:05:39 +0000 (22:05 +1100)
committerNick Downing <nick@ndcode.org>
Sun, 16 Jan 2022 11:06:28 +0000 (22:06 +1100)
17 files changed:
_lib/navbar.jst
_lib/post_request.jst
api/account/password_reset.json.jst [moved from api/password_reset.json.jst with 98% similarity]
api/account/sign_in.json.jst [moved from api/sign_in.json.jst with 97% similarity]
api/account/sign_out.json.jst [moved from api/sign_out.json.jst with 95% similarity]
api/account/sign_up/create_account.json.jst [moved from api/sign_up/create_account.json.jst with 95% similarity]
api/account/sign_up/get_draft.json.jst [moved from api/sign_up/get_draft.json.jst with 93% similarity]
api/account/sign_up/send_email_verification_link.json.jst [moved from api/sign_up/send_email_verification_link.json.jst with 88% similarity]
api/account/sign_up/set_draft.json.jst [moved from api/sign_up/set_draft.json.jst with 90% similarity]
api/account/sign_up/verify_email.json.jst [moved from api/sign_up/verify_email.json.jst with 97% similarity]
api/account/verify_password.json.jst [moved from api/verify_password.json.jst with 97% similarity]
api/feedback.json.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

index a993c46..db455b4 100644 (file)
@@ -294,15 +294,15 @@ return async (env, head, body, scripts) => {
 
       script {
         let sign_in = async (...arguments) => api_call(
-          '/api/sign_in.json',
+          '/api/account/sign_in.json',
           ...arguments
         )
         let sign_out = async (...arguments) => api_call(
-          '/api/sign_out.json',
+          '/api/account/sign_out.json',
           ...arguments
         )
         let feedback = async (...arguments) => api_call(
-          '/api/feedback.json',
+          '/api/account/feedback.json',
           ...arguments
         )
 
index 59c780e..73fa773 100644 (file)
@@ -1,6 +1,6 @@
 let stream_buffers = require('stream-buffers')
 
-return async (env, endpoint, handler) => {
+return async (env, handler) => {
   let Problem = await _require('/_lib/Problem.jst')
 
   let result
@@ -24,12 +24,12 @@ return async (env, endpoint, handler) => {
     )
     env.request.pipe(write_stream)
     let arguments = JSON.parse((await data).toString())
-    console.log('endpoint', endpoint, 'arguments', JSON.stringify(arguments))
+    console.log('endpoint', env.parsed_url.path, 'arguments', JSON.stringify(arguments))
 
     result = await handler(...arguments)
     if (result === undefined)
       result = null
-    console.log('endpoint', endpoint, 'result', JSON.stringify(result))
+    console.log('endpoint', env.parsed_url.path, 'result', JSON.stringify(result))
   }
   catch (error) {
     let problem =
@@ -43,7 +43,7 @@ return async (env, endpoint, handler) => {
           // status
           500
         )
-    console.log('endpoint', endpoint, 'problem', problem.detail)
+    console.log('endpoint', env.parsed_url.path, 'problem', problem.detail)
 
     env.mime_type = 'application/problem+json; charset=utf-8'
     env.site.serve(
similarity index 98%
rename from api/password_reset.json.jst
rename to api/account/password_reset.json.jst
index b439a17..cb11270 100644 (file)
@@ -14,8 +14,6 @@ return async env => {
   await post_request(
     // env
     env,
-    // endpoint
-    '/api/password_reset.json',
     // handler
     async (email, password) => {
       // coerce and/or validate
similarity index 97%
rename from api/sign_in.json.jst
rename to api/account/sign_in.json.jst
index bf3b02e..b963f97 100644 (file)
@@ -12,8 +12,6 @@ return async env => {
   await post_request(
     // env
     env,
-    // endpoint
-    '/api/sign_in.json',
     // handler
     async (email, password) => {
       // coerce and/or validate
similarity index 95%
rename from api/sign_out.json.jst
rename to api/account/sign_out.json.jst
index 264fb3c..3ddf3c8 100644 (file)
@@ -12,8 +12,6 @@ return async env => {
   await post_request(
     // env
     env,
-    // endpoint
-    '/api/sign_out.json',
     // handler
     async () => {
       let transaction = await env.site.database.Transaction()
similarity index 95%
rename from api/sign_up/create_account.json.jst
rename to api/account/sign_up/create_account.json.jst
index bb96f5c..85c4ef7 100644 (file)
@@ -8,8 +8,6 @@ return async env => {
   await post_request(
     // env
     env,
-    // endpoint
-    '/api/sign_up/create_account.json',
     // handler
     async (verification_code, details) => {
       // coerce and/or validate
@@ -41,7 +39,7 @@ return async env => {
         if (captcha === undefined || XDate.now() >= captcha.get('expires'))
           throw new 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/sign_up/create_account.json" call and less than one hour prior.`,
+            `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
           )
         
similarity index 93%
rename from api/sign_up/get_draft.json.jst
rename to api/account/sign_up/get_draft.json.jst
index 44f20f0..197fd24 100644 (file)
@@ -9,8 +9,6 @@ return async env => {
   await post_request(
     // env
     env,
-    // endpoint
-    '/api/sign_up/get_draft.json',
     // handler
     async () => {
       let transaction = await env.site.database.Transaction()
@@ -14,8 +14,6 @@ return async env => {
   await post_request(
     // env
     env,
-    // endpoint
-    '/api/sign_up/send_verification_email.json',
     // handler
     async email => {
       // coerce and/or validate
@@ -40,10 +38,21 @@ return async env => {
         if (account === undefined)
           throw new Problem(
             'Account does not exist',
-            `Please create the account for "${email}" before attempting to send a email verification link.`
+            `Please create the account for "${email}" before attempting to send an email verification link.`
             421
           )
 
+        if (
+          await logjson.logjson_to_json(
+            await account.get('email_verified')
+          )
+        )
+          throw new Problem(
+            'Email already verified',
+            `Your email "${email}" is already verified. You can now sign in.`
+            422
+          )
+
         let link_code = crypto.randomBytes(16).toString('hex')
         let expires = new XDate()
         expires.addDays(1)
similarity index 90%
rename from api/sign_up/set_draft.json.jst
rename to api/account/sign_up/set_draft.json.jst
index e7d2457..f7ca03b 100644 (file)
@@ -8,8 +8,6 @@ return async env => {
   await post_request(
     // env
     env,
-    // endpoint
-    '/api/sign_up/set_draft.json',
     // handler
     async details => {
       // coerce and/or validate
@@ -17,7 +15,6 @@ return async env => {
         email: details.email.slice(0, 256).toLowerCase(),
         given_names: details.given_names.slice(0, 256),
         family_name: details.family_name.slice(0, 256),
-        password: details.password.slice(0, 256),
         contact_me: details.contact_me ? true : false
       }
 
similarity index 97%
rename from api/sign_up/verify_email.json.jst
rename to api/account/sign_up/verify_email.json.jst
index 8ff628a..1fe908c 100644 (file)
@@ -10,8 +10,6 @@ return async env => {
   await post_request(
     // env
     env,
-    // endpoint
-    '/api/sign_up/verify_email.json',
     // handler
     async (email, link_code) => {
       // coerce and/or validate
similarity index 97%
rename from api/verify_password.json.jst
rename to api/account/verify_password.json.jst
index bb36a53..0d5359d 100644 (file)
@@ -10,8 +10,6 @@ return async env => {
   await post_request(
     // env
     env,
-    // endpoint
-    '/api/verify_password.json',
     // handler
     async (email, link_code) => {
       // coerce and/or validate
index 860f3e2..30761c6 100644 (file)
@@ -12,8 +12,6 @@ return async env => {
   await post_request(
     // env
     env,
-    // endpoint
-    '/api/feedback.json',
     // handler
     async (page, message) => {
       // coerce and/or validate
index 0e74ab5..ffae545 100644 (file)
@@ -101,7 +101,7 @@ return async env => {
 
       script {
         let password_reset = async (...arguments) => api_call(
-          '/api/password_reset.json',
+          '/api/account/password_reset.json',
           ...arguments
         )
 
index cc03ade..32f6c75 100644 (file)
@@ -95,7 +95,7 @@ return async env => {
 
       script {
         let sign_up_send_email_verification_link = async (...arguments) => api_call(
-          '/api/sign_up/send_email_verification_link.json',
+          '/api/account/sign_up/send_email_verification_link.json',
           ...arguments
         )
 
index 9f10481..228b5b0 100644 (file)
@@ -78,7 +78,7 @@ return async env => {
                 div.col-md-6 {
                   div.form-group {
                     label.form-label(for="password") {'Password *'}
-                    input.form-control#password(type="password" value=details.password || '' placeholder="New password" required="required" minlength=8 maxlength=256) {}
+                    input.form-control#password(type="password" placeholder="New password" required="required" minlength=8 maxlength=256) {}
                   }
                 }
               }
@@ -182,36 +182,33 @@ return async env => {
 
       script {
         let sign_up_create_account = async (...arguments) => api_call(
-          '/api/sign_up/create_account.json',
+          '/api/account/sign_up/create_account.json',
           ...arguments
         )
         //let sign_up_get_draft = async (...arguments) => api_call(
-        //  '/api/sign_up/get_draft.json',
+        //  '/api/account/sign_up/get_draft.json',
         //  ...arguments
         //)
         let sign_up_set_draft = async (...arguments) => api_call(
-          '/api/sign_up/set_draft.json',
+          '/api/account/sign_up/set_draft.json',
           ...arguments
         )
         let sign_up_send_email_verification_link = async (...arguments) => api_call(
-          '/api/sign_up/send_email_verification_link.json',
+          '/api/account/sign_up/send_email_verification_link.json',
           ...arguments
         )
 
-        let coerce_details = () => {
-          return {
-            email: document.getElementById('email').value.slice(0, 256).toLowerCase(),
-            given_names: document.getElementById('given-names').value.slice(0, 256),
-            family_name: document.getElementById('family-name').value.slice(0, 256),
-            password: document.getElementById('password').value.slice(0, 256),
-            contact_me: document.getElementById('contact-me').checked ? true : false
-          }
-        }
-
         let draft_timeout_running = false
         let draft_timeout_handler = async () => {
           draft_timeout_running = false
-          await sign_up_set_draft(coerce_details())
+          await sign_up_set_draft(
+            {
+              email: document.getElementById('email').value.slice(0, 256).toLowerCase(),
+              given_names: document.getElementById('given-names').value.slice(0, 256),
+              family_name: document.getElementById('family-name').value.slice(0, 256),
+              contact_me: document.getElementById('contact-me').checked ? true : false
+            }
+          )
           //console.log('draft', await sign_up_get_draft())
         }
         let draft_change_handler = () => {
@@ -221,6 +218,7 @@ return async env => {
           }
         }
 
+        let details
         let step_1 = async () => {
           if (
             !document.getElementById('given-names').reportValidity() ||
@@ -237,10 +235,17 @@ return async env => {
           $('#step-1-tick').show()
           $('#step-1-cross').hide()
           //$('#step-1-spinner').hide()
+
+          details = {
+            email: document.getElementById('email').value.slice(0, 256).toLowerCase(),
+            given_names: document.getElementById('given-names').value.slice(0, 256),
+            family_name: document.getElementById('family-name').value.slice(0, 256),
+            password: document.getElementById('password').value.slice(0, 256),
+            contact_me: document.getElementById('contact-me').checked ? true : false
+          }
           return true
         }
 
-        let step_2_details = ''
         let step_2 = async () => {
           $('#step-2-tick').hide()
           $('#step-2-cross').hide()
@@ -248,12 +253,11 @@ return async env => {
           document.getElementById('step-2').scrollIntoView()
 
           try {
-            step_2_details = coerce_details()
             await sign_up_create_account(
               // verification_code
               document.getElementById('verification-code').value.slice(0, 6).toLowerCase(),
               // details
-              step_2_details
+              details
             )
           }
           catch (error) {
@@ -280,7 +284,7 @@ return async env => {
           $('#step-2-tick').show()
           $('#step-2-cross').hide()
           $('#step-2-spinner').hide()
-          document.getElementById('step-2-message').textContent = `Your account with email "${step_2_details.email}" has been created.`
+          document.getElementById('step-2-message').textContent = `Your account with email "${details.email}" has been created.`
           return true
         }
 
@@ -291,7 +295,7 @@ return async env => {
           document.getElementById('step-3').scrollIntoView()
 
           try {
-            await sign_up_send_email_verification_link(step_2_details.email)
+            await sign_up_send_email_verification_link(details.email)
           }
           catch (error) {
             let problem =
@@ -318,7 +322,7 @@ return async env => {
           $('#step-3-cross').hide()
           $('#step-3-spinner').hide()
 
-          document.getElementById('step-3-message').textContent = `Email verification link has been sent to "${step_2_details.email}". Please check your email for next steps.`
+          document.getElementById('step-3-message').textContent = `Email verification link has been sent to "${details.email}". Please check your email for next steps.`
           return true
         }
 
index e61683d..142e10e 100644 (file)
@@ -109,7 +109,7 @@ return async env => {
 
       script {
         let sign_up_verify_email = async (...arguments) => api_call(
-          '/api/sign_up/verify_email.json',
+          '/api/account/sign_up/verify_email.json',
           ...arguments
         )
 
index a61916d..7fecc81 100644 (file)
@@ -109,7 +109,7 @@ return async env => {
 
       script {
         let verify_password = async (...arguments) => api_call(
-          '/api/verify_password.json',
+          '/api/account/verify_password.json',
           ...arguments
         )