From 65ae64b63816212a204c894bc61dadc455e6ea3d Mon Sep 17 00:00:00 2001 From: Nick Downing Date: Thu, 27 Jan 2022 22:57:56 +1100 Subject: [PATCH] Make get_session() readonly and throw an exception if session cannot be found rather than trying to create it, make get_account() throw an exception if not signed in, make get_navigation() and the related navbar logic throw useful exceptions if the navigation tree doesn't exist or doesn't the match site pages, make get_nodemailer throw useful exceptions if the nodemailer data doesn't exist --- _lib/get_account.jst | 19 +++++++++++--- _lib/get_navigation.jst | 16 ++++++++++++ _lib/get_nodemailer.jst | 15 ++++++++++- _lib/get_session.jst | 16 ++++++------ _lib/navbar.jst | 25 ++++++++++++++++++- _lib/page.jst | 2 +- api/account/change_details/get.json.jst | 9 +------ api/account/change_details/get_draft.json.jst | 2 +- api/account/change_details/set.json.jst | 9 +------ api/account/change_details/set_draft.json.jst | 2 +- api/account/change_password.json.jst | 9 +------ api/account/sign_in.json.jst | 4 +-- api/account/sign_out.json.jst | 2 +- api/account/sign_up/create_account.json.jst | 2 +- api/account/sign_up/get_draft.json.jst | 2 +- api/account/sign_up/set_draft.json.jst | 2 +- api/contact/get_draft.json.jst | 2 +- api/contact/set_draft.json.jst | 2 +- api/errors.json | 6 ++++- api/feedback/get_draft.json.jst | 2 +- api/feedback/set_draft.json.jst | 2 +- api/globals/get.json.jst | 9 +------ api/globals/set.json.jst | 9 +------ api/navigation/get.json.jst | 9 +------ api/navigation/set.json.jst | 9 +------ api/nodemailers/get.json.jst | 9 +------ api/nodemailers/set.json.jst | 9 +------ api/verification_image.png.jst | 2 +- contact/index.html.jst | 2 +- my_account/index.html.jst | 14 +++++------ my_account/password_reset/index.html.jst | 2 +- .../send_verification_email/index.html.jst | 2 +- my_account/sign_up/index.html.jst | 2 +- my_account/verify_email/index.html.jst | 2 +- my_account/verify_password/index.html.jst | 2 +- 35 files changed, 119 insertions(+), 113 deletions(-) diff --git a/_lib/get_account.jst b/_lib/get_account.jst index e80b85e..f5af367 100644 --- a/_lib/get_account.jst +++ b/_lib/get_account.jst @@ -1,7 +1,20 @@ +let jst_server = (await import('@ndcode/jst_server')).default + return async (root, session) => { let signed_in_as = await session.get_json('signed_in_as') if (signed_in_as === undefined) - return undefined - let accounts = await root.get('accounts', {}) - return await accounts.get(signed_in_as, {}) + throw new jst_server.Problem( + 'Unauthorized', + 'Please sign in first.', + 401 + ) + let accounts = await root.get('accounts') + let account = accounts.get(signed_in_as) + if (account === undefined) + throw new jst_server.Problem( + 'Account expired', + 'Database is inconsistent, please sign out and recreate your account.' + 507 + ) + return account } diff --git a/_lib/get_navigation.jst b/_lib/get_navigation.jst index 17ec41b..fc0de7c 100644 --- a/_lib/get_navigation.jst +++ b/_lib/get_navigation.jst @@ -1,8 +1,24 @@ +let jst_server = (await import('@ndcode/jst_server')).default + return async (root, component_names) => { let p = await root.get('navigation') + if (p === undefined) + throw new jst_server.Problem( + 'Navigation error', + 'Please import the navigation tree into the database.', + 508 + ) for (let i = 0; i < component_names.length; ++i) { let children = await p.get('children') p = await children.get(component_names[i]) + if (p === undefined) + throw new jst_server.Problem( + 'Navigation error', + `Can't find the path "${ + component_names.slice(0, i + 1).map(name => '/' + name).join('') + }" in the navigation tree.`, + 508 + ) } return p } diff --git a/_lib/get_nodemailer.jst b/_lib/get_nodemailer.jst index 9506236..fefa21a 100644 --- a/_lib/get_nodemailer.jst +++ b/_lib/get_nodemailer.jst @@ -1,6 +1,19 @@ +let jst_server = (await import('@ndcode/jst_server')).default let nodemailer = require('nodemailer') return async (root, name) => { let nodemailers = await root.get('nodemailers') - return nodemailer.createTransport(await nodemailers.get_json(name)) + if (nodemailers === undefined) + throw new Problem( + 'Nodemailer error', + 'Please import the nodemailers data into the database.', + 509 + ) + let _nodemailer = await nodemailers.get_json(name) + throw new Problem( + 'Nodemailer error', + `Can't find the nodemailer "${name}" in the nodemailers data.', + 509 + ) + return nodemailer.createTransport(_nodemailer) } diff --git a/_lib/get_session.jst b/_lib/get_session.jst index 06fec33..d72d2ab 100644 --- a/_lib/get_session.jst +++ b/_lib/get_session.jst @@ -1,15 +1,15 @@ -let XDate = require('xdate') +let jst_server = (await import('@ndcode/jst_server')).default return async (env, root) => { - let sessions = await root.get('sessions', {}) + let sessions = await root.get('sessions') let session = await sessions.get(env.session_key) - if (session === undefined) { + if (session === undefined || env.now >= await session.get_json('expires')) // this should never happen, but could happen if we take more than a day // to process an incoming request, and database is cleaned in the meantime - let expires = new XDate(env.now) - expires.addDays(1) - session = Transaction.json_to_logjson({expires: expires.getTime()}) - sessions.set(env.session_key, session) - } + throw new jst_server.Problem( + 'Session expired', + 'We took too long to process an incoming request, please try again.' + 506 + ) return session } diff --git a/_lib/navbar.jst b/_lib/navbar.jst index 318c6f1..be95539 100644 --- a/_lib/navbar.jst +++ b/_lib/navbar.jst @@ -1,4 +1,5 @@ let assert = require('assert') +let jst_server = (await import('@ndcode/jst_server')).default let XDate = require('xdate') let arrays_equal = @@ -46,20 +47,42 @@ return async (env, head, body, scripts) => { copyright = await globals.get_json('copyright') let navigation = await root.get('navigation') - + if (navigation === undefined) + throw new jst_server.Problem( + 'Navigation error', + 'Please import the navigation tree into the database.', + 508 + ) + + // this code is taken from get_navigation.jst and instrumented let p = navigation component_titles = [await p.get_json('title')] // Home for (let i = 0; i < component_names.length; ++i) { let children = await p.get('children') p = await children.get(component_names[i]) + if (navigation === undefined) + throw new jst_server.Problem( + 'Navigation error', + `Can't find the path "${ + component_names.slice(0, i + 1).map(name => '/' + name).join('') + }" in the navigation tree.`, + 508 + ) component_titles.push(await p.get_json('title')) } + // similar to above but walks the top level laterally (not deeply) menu_names = await navigation.get_json('menu') let children = await navigation.get('children') menu_titles = [await navigation.get_json('title')] // Home for (let i = 0; i < menu_names.length; ++i) { let child = await children.get(menu_names[i]) + if (child === undefined) + throw new jst_server.Problem( + 'Navigation error', + `Can't find the path "/${menu_names[i]}" in the navigation tree.` + 508 + ) menu_titles.push(await child.get('title')) } diff --git a/_lib/page.jst b/_lib/page.jst index 18e5cc2..d07619c 100644 --- a/_lib/page.jst +++ b/_lib/page.jst @@ -9,7 +9,7 @@ return async (env, head, body, scripts) => { // initialize env.session_key, set cookie in env.response let transaction = await env.site.database.Transaction() try { - let root = await transaction.get({}) + let root = await transaction.get() let session = await get_session(env, root) let pageviews = await root.get('pageviews', {}) diff --git a/api/account/change_details/get.json.jst b/api/account/change_details/get.json.jst index 19fb032..49b0cd9 100644 --- a/api/account/change_details/get.json.jst +++ b/api/account/change_details/get.json.jst @@ -13,17 +13,10 @@ return async env => { async () => { let transaction = await env.site.database.Transaction() try { - let root = await transaction.get({}) + let root = await transaction.get() let session = await get_session(env, root) let account = await get_account(root, session) - if (account === undefined) - throw new jst_server.Problem( - 'Unauthorized', - 'Please sign in first.', - 401 - ) - return { given_names: await account.get_json('given_names'), family_name: await account.get_json('family_name'), diff --git a/api/account/change_details/get_draft.json.jst b/api/account/change_details/get_draft.json.jst index 2f25eb2..c8e8031 100644 --- a/api/account/change_details/get_draft.json.jst +++ b/api/account/change_details/get_draft.json.jst @@ -9,7 +9,7 @@ return async env => { async () => { let transaction = await env.site.database.Transaction() try { - let root = await transaction.get({}) + let root = await transaction.get() let session = await get_session(env, root) let change_details_draft = await session.get_json('change_details_draft') diff --git a/api/account/change_details/set.json.jst b/api/account/change_details/set.json.jst index e3de45c..bc276f6 100644 --- a/api/account/change_details/set.json.jst +++ b/api/account/change_details/set.json.jst @@ -25,17 +25,10 @@ return async env => { let transaction = await env.site.database.Transaction() try { - let root = await transaction.get({}) + let root = await transaction.get() let session = await get_session(env, root) let account = await get_account(root, session) - if (account === undefined) - 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) account.set_json('contact_me', details.contact_me) diff --git a/api/account/change_details/set_draft.json.jst b/api/account/change_details/set_draft.json.jst index 67e2f3e..6bb9f32 100644 --- a/api/account/change_details/set_draft.json.jst +++ b/api/account/change_details/set_draft.json.jst @@ -20,7 +20,7 @@ return async env => { let transaction = await env.site.database.Transaction() try { - let root = await transaction.get({}) + let root = await transaction.get() let session = await get_session(env, root) if (details) { diff --git a/api/account/change_password.json.jst b/api/account/change_password.json.jst index 2bba98a..5adc47c 100644 --- a/api/account/change_password.json.jst +++ b/api/account/change_password.json.jst @@ -24,17 +24,10 @@ return async env => { let transaction = await env.site.database.Transaction() try { - let root = await transaction.get({}) + let root = await transaction.get() let session = await get_session(env, root) let account = await get_account(root, session) - if (account === undefined) - throw new jst_server.Problem( - 'Unauthorized', - 'Please sign in first.', - 401 - ) - if (old_password !== await account.get_json('password')) throw new jst_server.Problem( 'Incorrect password', diff --git a/api/account/sign_in.json.jst b/api/account/sign_in.json.jst index e35392f..87961f5 100644 --- a/api/account/sign_in.json.jst +++ b/api/account/sign_in.json.jst @@ -21,7 +21,8 @@ return async env => { let transaction = await env.site.database.Transaction() try { - let root = await transaction.get({}) + let root = await transaction.get() + let session = await get_session(env, root) let accounts = await root.get('accounts', {}) let account = await accounts.get(email) @@ -42,7 +43,6 @@ return async env => { 425 ) - let session = await get_session(env, root) session.set_json('signed_in_as', email) await transaction.commit() } diff --git a/api/account/sign_out.json.jst b/api/account/sign_out.json.jst index eaeedf1..992cfa0 100644 --- a/api/account/sign_out.json.jst +++ b/api/account/sign_out.json.jst @@ -11,7 +11,7 @@ return async env => { async () => { let transaction = await env.site.database.Transaction() try { - let root = await transaction.get({}) + let root = await transaction.get() let session = await get_session(env, root) session.delete('signed_in_as') await transaction.commit() diff --git a/api/account/sign_up/create_account.json.jst b/api/account/sign_up/create_account.json.jst index 2eb3efe..42c0b92 100644 --- a/api/account/sign_up/create_account.json.jst +++ b/api/account/sign_up/create_account.json.jst @@ -32,7 +32,7 @@ return async env => { let transaction = await env.site.database.Transaction() try { - let root = await transaction.get({}) + let root = await transaction.get() let session = await get_session(env, root) let captcha = await session.get('captcha') diff --git a/api/account/sign_up/get_draft.json.jst b/api/account/sign_up/get_draft.json.jst index d648a6a..d9616cb 100644 --- a/api/account/sign_up/get_draft.json.jst +++ b/api/account/sign_up/get_draft.json.jst @@ -9,7 +9,7 @@ return async env => { async () => { let transaction = await env.site.database.Transaction() try { - let root = await transaction.get({}) + let root = await transaction.get() let session = await get_session(env, root) let sign_up_draft = await session.get_json('sign_up_draft') diff --git a/api/account/sign_up/set_draft.json.jst b/api/account/sign_up/set_draft.json.jst index ac20f8e..c09cdd5 100644 --- a/api/account/sign_up/set_draft.json.jst +++ b/api/account/sign_up/set_draft.json.jst @@ -21,7 +21,7 @@ return async env => { let transaction = await env.site.database.Transaction() try { - let root = await transaction.get({}) + let root = await transaction.get() let session = await get_session(env, root) if (details) { diff --git a/api/contact/get_draft.json.jst b/api/contact/get_draft.json.jst index 05ab1f1..b106653 100644 --- a/api/contact/get_draft.json.jst +++ b/api/contact/get_draft.json.jst @@ -9,7 +9,7 @@ return async env => { async () => { let transaction = await env.site.database.Transaction() try { - let root = await transaction.get({}) + let root = await transaction.get() let session = await get_session(env, root) let contact_draft = await session.get_json('contact_draft') diff --git a/api/contact/set_draft.json.jst b/api/contact/set_draft.json.jst index a515d67..2261f28 100644 --- a/api/contact/set_draft.json.jst +++ b/api/contact/set_draft.json.jst @@ -22,7 +22,7 @@ return async env => { let transaction = await env.site.database.Transaction() try { - let root = await transaction.get({}) + let root = await transaction.get() let session = await get_session(env, root) if (details) { diff --git a/api/errors.json b/api/errors.json index 53b7c9f..81f27b8 100644 --- a/api/errors.json +++ b/api/errors.json @@ -30,5 +30,9 @@ "502": "Bad gateway", "503": "Service unavailable", "504": "Gateway timeout", - "505": "HTTP version not supported" + "505": "HTTP version not supported", + "506": "Session expired", + "507": "Account expired", + "508": "Navigation error", + "509": "Nodemailer error" } diff --git a/api/feedback/get_draft.json.jst b/api/feedback/get_draft.json.jst index 210982a..52b2196 100644 --- a/api/feedback/get_draft.json.jst +++ b/api/feedback/get_draft.json.jst @@ -9,7 +9,7 @@ return async env => { async () => { let transaction = await env.site.database.Transaction() try { - let root = await transaction.get({}) + let root = await transaction.get() let session = await get_session(env, root) let feedback_draft = await session.get_json('feedback_draft') diff --git a/api/feedback/set_draft.json.jst b/api/feedback/set_draft.json.jst index 546a473..cd93d13 100644 --- a/api/feedback/set_draft.json.jst +++ b/api/feedback/set_draft.json.jst @@ -18,7 +18,7 @@ return async env => { let transaction = await env.site.database.Transaction() try { - let root = await transaction.get({}) + let root = await transaction.get() let session = await get_session(env, root) if (details) { diff --git a/api/globals/get.json.jst b/api/globals/get.json.jst index b8c52a5..47e07b9 100644 --- a/api/globals/get.json.jst +++ b/api/globals/get.json.jst @@ -1,5 +1,4 @@ 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') @@ -13,16 +12,10 @@ return async env => { async () => { let transaction = await env.site.database.Transaction() try { - let root = await transaction.get({}) + let root = await transaction.get() let session = await get_session(env, root) let account = await get_account(root, session) - if (account === undefined) - throw new jst_server.Problem( - 'Unauthorized', - 'Please sign in first.', - 401 - ) if (!await account.get_json('administrator')) throw new jst_server.Problem( 'Unauthorized', diff --git a/api/globals/set.json.jst b/api/globals/set.json.jst index 64d385d..70c684a 100644 --- a/api/globals/set.json.jst +++ b/api/globals/set.json.jst @@ -1,5 +1,4 @@ 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') @@ -26,16 +25,10 @@ return async env => { let transaction = await env.site.database.Transaction() try { - let root = await transaction.get({}) + let root = await transaction.get() let session = await get_session(env, root) let account = await get_account(root, session) - if (account === undefined) - throw new jst_server.Problem( - 'Unauthorized', - 'Please sign in first.', - 401 - ) if (!await account.get_json('administrator')) throw new jst_server.Problem( 'Unauthorized', diff --git a/api/navigation/get.json.jst b/api/navigation/get.json.jst index ac842d8..0ce121c 100644 --- a/api/navigation/get.json.jst +++ b/api/navigation/get.json.jst @@ -1,5 +1,4 @@ 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') @@ -13,16 +12,10 @@ return async env => { async () => { let transaction = await env.site.database.Transaction() try { - let root = await transaction.get({}) + let root = await transaction.get() let session = await get_session(env, root) let account = await get_account(root, session) - if (account === undefined) - throw new jst_server.Problem( - 'Unauthorized', - 'Please sign in first.', - 401 - ) if (!await account.get_json('administrator')) throw new jst_server.Problem( 'Unauthorized', diff --git a/api/navigation/set.json.jst b/api/navigation/set.json.jst index 696c90f..6ef4a88 100644 --- a/api/navigation/set.json.jst +++ b/api/navigation/set.json.jst @@ -1,5 +1,4 @@ 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') @@ -16,16 +15,10 @@ return async env => { let transaction = await env.site.database.Transaction() try { - let root = await transaction.get({}) + let root = await transaction.get() let session = await get_session(env, root) let account = await get_account(root, session) - if (account === undefined) - throw new jst_server.Problem( - 'Unauthorized', - 'Please sign in first.', - 401 - ) if (!await account.get_json('administrator')) throw new jst_server.Problem( 'Unauthorized', diff --git a/api/nodemailers/get.json.jst b/api/nodemailers/get.json.jst index 8030196..656a4d1 100644 --- a/api/nodemailers/get.json.jst +++ b/api/nodemailers/get.json.jst @@ -1,5 +1,4 @@ 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') @@ -13,16 +12,10 @@ return async env => { async () => { let transaction = await env.site.database.Transaction() try { - let root = await transaction.get({}) + let root = await transaction.get() let session = await get_session(env, root) let account = await get_account(root, session) - if (account === undefined) - throw new jst_server.Problem( - 'Unauthorized', - 'Please sign in first.', - 401 - ) if (!await account.get_json('administrator')) throw new jst_server.Problem( 'Unauthorized', diff --git a/api/nodemailers/set.json.jst b/api/nodemailers/set.json.jst index ab57981..38d9000 100644 --- a/api/nodemailers/set.json.jst +++ b/api/nodemailers/set.json.jst @@ -1,5 +1,4 @@ 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') @@ -16,16 +15,10 @@ return async env => { let transaction = await env.site.database.Transaction() try { - let root = await transaction.get({}) + let root = await transaction.get() let session = await get_session(env, root) let account = await get_account(root, session) - if (account === undefined) - throw new jst_server.Problem( - 'Unauthorized', - 'Please sign in first.', - 401 - ) if (!await account.get_json('administrator')) throw new jst_server.Problem( 'Unauthorized', diff --git a/api/verification_image.png.jst b/api/verification_image.png.jst index 0866545..3a41041 100644 --- a/api/verification_image.png.jst +++ b/api/verification_image.png.jst @@ -10,7 +10,7 @@ return async env => { let transaction = await env.site.database.Transaction() try { - let root = await transaction.get({}) + let root = await transaction.get() let session = await get_session(env, root) // store captcha text in the session for validation when form submitted diff --git a/contact/index.html.jst b/contact/index.html.jst index df384b5..c12edde 100644 --- a/contact/index.html.jst +++ b/contact/index.html.jst @@ -12,7 +12,7 @@ return async env => { let placeholder let contact_draft try { - let root = await transaction.get({}) + let root = await transaction.get() let session = await get_session(env, root) placeholder = await get_placeholder(env, session) diff --git a/my_account/index.html.jst b/my_account/index.html.jst index d03c303..11b72f1 100644 --- a/my_account/index.html.jst +++ b/my_account/index.html.jst @@ -18,22 +18,22 @@ return async env => { let placeholder let signed_in_as, details, change_details_draft try { - let root = await transaction.get({}) + let root = await transaction.get() let session = await get_session(env, root) placeholder = await get_placeholder(env, session) signed_in_as = await session.get_json('signed_in_as') - - account = await get_account(root, session) - details = - account === undefined ? - null : - { + if (signed_in_as === undefined) + details = null + else { + account = await get_account(root, session) + details = { given_names: await account.get_json('given_names'), family_name: await account.get_json('family_name'), contact_me: await account.get_json('contact_me') } + } change_details_draft = await session.get_json('change_details_draft') if (change_details_draft === undefined || env.now >= change_details_draft.expires) diff --git a/my_account/password_reset/index.html.jst b/my_account/password_reset/index.html.jst index 1ed05fa..e06abce 100644 --- a/my_account/password_reset/index.html.jst +++ b/my_account/password_reset/index.html.jst @@ -11,7 +11,7 @@ return async env => { let transaction = await env.site.database.Transaction() let placeholder try { - let root = await transaction.get({}) + let root = await transaction.get() let session = await get_session(env, root) placeholder = await get_placeholder(env, session) await transaction.commit() diff --git a/my_account/send_verification_email/index.html.jst b/my_account/send_verification_email/index.html.jst index 55d3b11..935071e 100644 --- a/my_account/send_verification_email/index.html.jst +++ b/my_account/send_verification_email/index.html.jst @@ -11,7 +11,7 @@ return async env => { let transaction = await env.site.database.Transaction() let placeholder try { - let root = await transaction.get({}) + let root = await transaction.get() let session = await get_session(env, root) placeholder = await get_placeholder(env, session) await transaction.commit() diff --git a/my_account/sign_up/index.html.jst b/my_account/sign_up/index.html.jst index 3ce5eae..27eb438 100644 --- a/my_account/sign_up/index.html.jst +++ b/my_account/sign_up/index.html.jst @@ -15,7 +15,7 @@ return async env => { let placeholder let sign_up_draft try { - let root = await transaction.get({}) + let root = await transaction.get() let session = await get_session(env, root) placeholder = await get_placeholder(env, session) diff --git a/my_account/verify_email/index.html.jst b/my_account/verify_email/index.html.jst index 23bc712..e618f33 100644 --- a/my_account/verify_email/index.html.jst +++ b/my_account/verify_email/index.html.jst @@ -11,7 +11,7 @@ return async env => { let transaction = await env.site.database.Transaction() let placeholder try { - let root = await transaction.get({}) + let root = await transaction.get() let session = await get_session(env, root) placeholder = await get_placeholder(env, session) transaction.commit() diff --git a/my_account/verify_password/index.html.jst b/my_account/verify_password/index.html.jst index a9f46bd..7b42eb1 100644 --- a/my_account/verify_password/index.html.jst +++ b/my_account/verify_password/index.html.jst @@ -11,7 +11,7 @@ return async env => { let transaction = await env.site.database.Transaction() let placeholder try { - let root = await transaction.get({}) + let root = await transaction.get() let session = await get_session(env, root) placeholder = await get_placeholder(env, session) await transaction.commit() -- 2.34.1