Development

This commit is contained in:
Matthew Grotke 2026-05-27 22:04:04 -04:00
parent eed1d295dc
commit d9f3bd8289
45 changed files with 635 additions and 666 deletions

View file

@ -1,10 +1,13 @@
from pathlib import Path
from flask import Blueprint, request, session, redirect, flash
import json, os, secrets
from datetime import datetime, timezone, timedelta
from auth import require_level
from config_utils import ACCOUNTS_FILE
bp = Blueprint('accountverifyemail', __name__)
_PAGE = Path(__file__).parent.name
bp = Blueprint(_PAGE, __name__)
@ -20,29 +23,29 @@ def _save_accounts(data):
json.dump(data, f, indent=2)
@bp.route('/action/verify_email', methods=['POST'])
@bp.route('/action/accountverifyemail/email_verify', methods=['POST'])
@require_level('nothing')
def verify_email():
def email_verify():
# Abort if already logged in
if session.get('access_level', 'nothing') != 'nothing':
return redirect('/view/view_overview')
return redirect('/overview')
pending = session.get('pending_create_account')
if not pending:
flash('No pending account creation found. Please start over.', 'error')
return redirect('/view/view_createaccount')
return redirect('/accountcreate')
expires = datetime.fromisoformat(pending['expires'])
if datetime.now(tz=timezone.utc) > expires:
session.pop('pending_create_account', None)
flash('Verification code has expired. Please start over.', 'error')
return redirect('/view/view_createaccount')
return redirect('/accountcreate')
submitted = request.form.get('code', '').strip()
if submitted != pending['code']:
flash('Incorrect verification code.', 'error')
return redirect('/view/view_verifyemail')
return redirect(f'/{_PAGE}')
data = _load_accounts()
accounts = data.get('accounts', [])
@ -54,12 +57,12 @@ def verify_email():
if account is None:
session.pop('pending_create_account', None)
flash('Account no longer exists. Contact your manager.', 'error')
return redirect('/view/view_createaccount')
return redirect('/accountcreate')
if account.get('hashed_password'):
session.pop('pending_create_account', None)
flash('This account is already set up. Please log in.', 'error')
return redirect('/view/view_login')
return redirect('/accountlogin')
now = datetime.now(tz=timezone.utc).strftime('%Y-%m-%dT%H:%M:%SZ')
account['hashed_password'] = pending['hashed_password']
@ -77,15 +80,15 @@ def verify_email():
session['timezone'] = pending['timezone']
session.permanent = True
return redirect('/view/view_overview')
return redirect('/overview')
@bp.route('/action/resend_verification')
@bp.route('/action/accountverifyemail/email_resend')
@require_level('nothing')
def resend_verification():
def email_resend():
# Abort if already logged in
if session.get('access_level', 'nothing') != 'nothing':
return redirect('/view/view_overview')
return redirect('/overview')
from pages.accountcreate.action import _send_verification_email, CODE_TTL_MIN
@ -93,7 +96,7 @@ def resend_verification():
if not pending:
flash('No pending account creation found. Please start over.', 'error')
return redirect('/view/view_createaccount')
return redirect('/accountcreate')
code = f'{secrets.randbelow(1000000):06d}'
expires = (datetime.now(tz=timezone.utc) + timedelta(minutes=CODE_TTL_MIN)).isoformat()
@ -102,11 +105,11 @@ def resend_verification():
_send_verification_email(pending['email'], code)
except Exception as exc:
flash(f'Could not resend verification email: {exc}', 'error')
return redirect('/view/view_verifyemail')
return redirect(f'/{_PAGE}')
pending['code'] = code
pending['expires'] = expires
session['pending_create_account'] = pending
flash('A new verification code has been sent.', 'success')
return redirect('/view/view_verifyemail')
return redirect(f'/{_PAGE}')

View file

@ -1,5 +1,4 @@
{
"id": "view_verifyemail",
"client_requirement": "client_is_nothing=",
"items": [
{
@ -19,7 +18,7 @@
},
{
"type": "form",
"action": "/action/verify_email",
"action": "/action/accountverifyemail/email_verify",
"method": "post",
"items": [
{
@ -32,7 +31,7 @@
},
{
"type": "button_primary",
"action": "/action/verify_email",
"action": "/action/accountverifyemail/email_verify",
"method": "post",
"text": "Verify",
"class": "btn-full"
@ -43,7 +42,7 @@
"type": "p",
"text": "Didn't receive it?",
"link": {
"action": "/action/resend_verification",
"action": "/action/accountverifyemail/email_resend",
"text": "Resend code"
}
},
@ -51,7 +50,7 @@
"type": "p",
"text": "Wrong email?",
"link": {
"action": "/view/view_createaccount",
"action": "/accountcreate",
"text": "Start over"
}
}
@ -76,7 +75,7 @@
},
{
"type": "button_primary",
"action": "/view/view_overview",
"action": "/overview",
"text": "Go to Overview"
}
]