linuxrouter/docker/routlin-dash/app/pages/accountverifyemail/action.py

136 lines
4.4 KiB
Python
Raw Permalink Normal View History

2026-05-27 22:04:04 -04:00
from pathlib import Path
2026-05-17 03:26:01 -04:00
from flask import Blueprint, request, session, redirect, flash
2026-06-10 14:23:47 -04:00
import time, secrets
2026-06-07 00:21:08 -04:00
import auth
import config_utils
2026-05-17 03:26:01 -04:00
2026-05-27 22:04:04 -04:00
_PAGE = Path(__file__).parent.name
bp = Blueprint(_PAGE, __name__)
2026-05-17 03:26:01 -04:00
2026-05-27 22:04:04 -04:00
@bp.route('/action/accountverifyemail/email_verify', methods=['POST'])
2026-06-07 00:21:08 -04:00
@auth.require_level('nothing')
2026-05-27 22:04:04 -04:00
def email_verify():
2026-05-17 03:26:01 -04:00
if session.get('access_level', 'nothing') != 'nothing':
2026-05-27 22:04:04 -04:00
return redirect('/overview')
2026-05-17 03:26:01 -04:00
2026-06-10 22:57:55 -04:00
from pages.accountcreate.action import CODE_TTL_SECS
2026-05-17 03:26:01 -04:00
2026-06-10 22:57:55 -04:00
token = session.sid
2026-06-10 14:23:47 -04:00
try:
2026-06-10 22:57:55 -04:00
con = config_utils.open_accounts_db()
client = con.execute(
'SELECT * FROM clients WHERE cookie_unique_token=?', (token,)
2026-06-10 14:23:47 -04:00
).fetchone()
con.close()
except Exception:
2026-06-10 22:57:55 -04:00
client = None
2026-06-10 14:23:47 -04:00
2026-06-10 22:57:55 -04:00
if not client or not client['email']:
2026-05-17 03:26:01 -04:00
flash('No pending account creation found. Please start over.', 'error')
2026-05-27 22:04:04 -04:00
return redirect('/accountcreate')
2026-05-17 03:26:01 -04:00
2026-06-10 22:57:55 -04:00
if int(time.time()) > client['code_sent_ts'] + CODE_TTL_SECS:
2026-06-10 14:23:47 -04:00
try:
con = config_utils.open_accounts_db()
2026-06-10 22:57:55 -04:00
con.execute(
'''UPDATE clients SET email=NULL, hashed_password=NULL,
tz_offset_seconds=NULL, verification_code=NULL, code_sent_ts=NULL
WHERE cookie_unique_token=?''',
(token,)
)
2026-06-10 14:23:47 -04:00
con.commit()
con.close()
except Exception:
pass
2026-05-17 03:26:01 -04:00
flash('Verification code has expired. Please start over.', 'error')
2026-05-27 22:04:04 -04:00
return redirect('/accountcreate')
2026-05-17 03:26:01 -04:00
submitted = request.form.get('code', '').strip()
2026-06-10 22:57:55 -04:00
if submitted != client['verification_code']:
2026-05-17 03:26:01 -04:00
flash('Incorrect verification code.', 'error')
2026-05-27 22:04:04 -04:00
return redirect(f'/{_PAGE}')
2026-05-17 03:26:01 -04:00
2026-06-10 22:57:55 -04:00
pending_email = client['email']
2026-06-10 14:23:47 -04:00
account = config_utils.get_account_by_email(pending_email)
2026-05-17 03:26:01 -04:00
if account is None:
flash('Account no longer exists. Contact your manager.', 'error')
2026-05-27 22:04:04 -04:00
return redirect('/accountcreate')
2026-05-17 03:26:01 -04:00
if account.get('hashed_password'):
flash('This account is already set up. Please log in.', 'error')
2026-05-27 22:04:04 -04:00
return redirect('/accountlogin')
2026-05-17 03:26:01 -04:00
2026-06-10 14:23:47 -04:00
now = int(time.time())
try:
con = config_utils.open_accounts_db()
con.execute(
'UPDATE accounts SET hashed_password=?, created_ts=?, created_by=? WHERE account_id=?',
2026-06-10 22:57:55 -04:00
(client['hashed_password'], now, 'self', account['account_id'])
)
con.execute(
'''UPDATE clients SET email=NULL, hashed_password=NULL,
tz_offset_seconds=NULL, verification_code=NULL, code_sent_ts=NULL
WHERE cookie_unique_token=?''',
(token,)
2026-06-10 14:23:47 -04:00
)
con.commit()
con.close()
except Exception as exc:
flash(f'Could not complete account setup: {exc}', 'error')
return redirect(f'/{_PAGE}')
2026-05-17 03:26:01 -04:00
2026-06-10 14:23:47 -04:00
session['account_id'] = account['account_id']
2026-06-10 22:57:55 -04:00
session['tz_offset_seconds'] = int(client['tz_offset_seconds'])
2026-06-10 14:23:47 -04:00
session['apply_changes_immediately'] = False
session.permanent = True
2026-05-17 03:26:01 -04:00
2026-05-27 22:04:04 -04:00
return redirect('/overview')
2026-05-17 03:26:01 -04:00
2026-05-27 22:04:04 -04:00
@bp.route('/action/accountverifyemail/email_resend')
2026-06-07 00:21:08 -04:00
@auth.require_level('nothing')
2026-05-27 22:04:04 -04:00
def email_resend():
2026-05-17 03:26:01 -04:00
if session.get('access_level', 'nothing') != 'nothing':
2026-05-27 22:04:04 -04:00
return redirect('/overview')
2026-05-17 03:26:01 -04:00
2026-06-10 22:57:55 -04:00
from pages.accountcreate.action import _send_verification_email
token = session.sid
try:
con = config_utils.open_accounts_db()
client = con.execute(
'SELECT * FROM clients WHERE cookie_unique_token=?', (token,)
).fetchone()
con.close()
except Exception:
client = None
2026-05-17 03:26:01 -04:00
2026-06-10 22:57:55 -04:00
if not client or not client['email']:
2026-05-17 03:26:01 -04:00
flash('No pending account creation found. Please start over.', 'error')
2026-05-27 22:04:04 -04:00
return redirect('/accountcreate')
2026-05-17 03:26:01 -04:00
2026-06-10 22:57:55 -04:00
code = f'{secrets.randbelow(1000000):06d}'
code_sent_ts = int(time.time())
2026-05-17 03:26:01 -04:00
try:
2026-06-10 22:57:55 -04:00
_send_verification_email(client['email'], code)
2026-05-17 03:26:01 -04:00
except Exception as exc:
flash(f'Could not resend verification email: {exc}', 'error')
2026-05-27 22:04:04 -04:00
return redirect(f'/{_PAGE}')
2026-05-17 03:26:01 -04:00
2026-06-10 14:23:47 -04:00
try:
con = config_utils.open_accounts_db()
con.execute(
2026-06-10 22:57:55 -04:00
'UPDATE clients SET verification_code=?, code_sent_ts=? WHERE cookie_unique_token=?',
(code, code_sent_ts, token)
2026-06-10 14:23:47 -04:00
)
con.commit()
con.close()
except Exception:
pass
2026-05-17 03:26:01 -04:00
flash('A new verification code has been sent.', 'success')
2026-05-27 22:04:04 -04:00
return redirect(f'/{_PAGE}')