linuxrouter/docker/routlin-dash/app/pages/accountlogin/action.py
2026-06-12 11:16:31 -04:00

74 lines
3 KiB
Python

from pathlib import Path
from flask import Blueprint, request, session, redirect, flash
import bcrypt
import auth
import config_utils
import sanitize
import settings
_PAGE = Path(__file__).parent.name
bp = Blueprint(_PAGE, __name__)
@bp.route('/action/accountlogin/form_login', methods=['POST'])
@auth.require_level('nothing')
def form_login():
if session.get('access_level', 'nothing') != 'nothing':
return redirect('/overview')
email = sanitize.email(request.form.get('email', ''))
password = request.form.get('password', '')
if not email or not password:
flash('Email address and password are required.', 'error')
return redirect(f'/{_PAGE}')
account = config_utils.get_account_by_email(email)
if account is None:
flash('Email address not recognised.', 'error')
return redirect(f'/{_PAGE}')
if not account.get('hashed_password'):
# Either brand-new account or email change approved - check for a pending verification row
try:
con = config_utils.open_accounts_db()
client = con.execute(
'SELECT * FROM clients WHERE email=? AND verification_code IS NOT NULL', (email,)
).fetchone()
if client and client['cookie_unique_token'] != session.sid:
con.execute(
'''INSERT INTO clients (cookie_unique_token, email, hashed_password, verification_code, code_sent_ts)
VALUES (?,?,?,?,?)
ON CONFLICT(cookie_unique_token) DO UPDATE SET
email=excluded.email,
hashed_password=excluded.hashed_password,
verification_code=excluded.verification_code,
code_sent_ts=excluded.code_sent_ts''',
(session.sid, client['email'], client['hashed_password'],
client['verification_code'], client['code_sent_ts'])
)
con.execute('DELETE FROM clients WHERE cookie_unique_token=?',
(client['cookie_unique_token'],))
con.commit()
con.close()
except Exception:
client = None
if client:
flash('Please check your inbox and enter your verification code.', 'info')
return redirect('/accountverifyemail')
flash('Account setup is not complete. Please use Create Account to set your password first.', 'error')
return redirect(f'/{_PAGE}')
if not bcrypt.checkpw(password.encode('utf-8'), account['hashed_password'].encode('utf-8')):
flash('Invalid email address or password.', 'error')
return redirect(f'/{_PAGE}')
session.clear()
session['account_id'] = account['account_id']
session['tz_offset_seconds'] = settings.get_host_utc_offset()
session['apply_changes_immediately'] = False
session.permanent = True
return redirect('/overview')