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

83 lines
2.6 KiB
Python
Raw 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 bcrypt
2026-06-07 00:21:08 -04:00
import auth
import config_utils
2026-05-27 20:56:30 -04:00
import sanitize
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-06-10 14:23:47 -04:00
def _tz_to_offset_seconds(tz_str):
2026-05-17 03:26:01 -04:00
try:
2026-06-10 14:23:47 -04:00
from zoneinfo import ZoneInfo
from datetime import datetime
return int(datetime.now(ZoneInfo(tz_str)).utcoffset().total_seconds())
2026-05-17 03:26:01 -04:00
except Exception:
2026-06-10 14:23:47 -04:00
import settings as _s
return _s.get_host_utc_offset()
2026-05-17 03:26:01 -04:00
2026-05-27 22:04:04 -04:00
@bp.route('/action/preferences/accountdetails_save', methods=['POST'])
2026-06-07 00:21:08 -04:00
@auth.require_level('viewer')
2026-05-27 22:04:04 -04:00
def accountdetails_save():
2026-05-27 20:56:30 -04:00
tz = sanitize.timezone(request.form.get('timezone', '').strip())
if not tz:
flash('Timezone is required.', 'error')
2026-05-27 22:04:04 -04:00
return redirect(f'/{_PAGE}')
2026-05-27 20:56:30 -04:00
2026-06-10 14:23:47 -04:00
tz_offset = _tz_to_offset_seconds(tz)
session['tz_offset_seconds'] = tz_offset
2026-05-27 20:56:30 -04:00
flash('Preferences saved.', 'success')
2026-05-27 22:04:04 -04:00
return redirect(f'/{_PAGE}')
2026-05-27 20:56:30 -04:00
2026-05-27 22:04:04 -04:00
@bp.route('/action/preferences/changepassword_save', methods=['POST'])
2026-06-07 00:21:08 -04:00
@auth.require_level('viewer')
2026-05-27 22:04:04 -04:00
def changepassword_save():
2026-05-17 03:26:01 -04:00
current_password = request.form.get('current_password', '')
new_password = request.form.get('new_password', '')
confirm_password = request.form.get('confirm_password', '')
if not current_password or not new_password or not confirm_password:
flash('All fields are required.', 'error')
2026-05-27 22:04:04 -04:00
return redirect(f'/{_PAGE}')
2026-05-17 03:26:01 -04:00
if new_password != confirm_password:
flash('New passwords do not match.', 'error')
2026-05-27 22:04:04 -04:00
return redirect(f'/{_PAGE}')
2026-05-17 03:26:01 -04:00
if len(new_password) < 8:
flash('New password must be at least 8 characters.', '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
account = config_utils.get_account_by_id(session.get('account_id', ''))
2026-05-17 03:26:01 -04:00
if account is None:
flash('Account not found. Please log in again.', '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
if not bcrypt.checkpw(current_password.encode('utf-8'), account['hashed_password'].encode('utf-8')):
2026-05-17 03:26:01 -04:00
flash('Current password is incorrect.', '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
hashed = bcrypt.hashpw(new_password.encode('utf-8'), bcrypt.gensalt()).decode('utf-8')
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(
'UPDATE accounts SET hashed_password=? WHERE account_id=?',
(hashed, account['account_id'])
)
con.commit()
con.close()
except Exception as exc:
flash(f'Could not update password: {exc}', 'error')
return redirect(f'/{_PAGE}')
2026-05-17 03:26:01 -04:00
flash('Password changed successfully.', 'success')
2026-05-27 22:04:04 -04:00
return redirect(f'/{_PAGE}')