from pathlib import Path from flask import Blueprint, request, session, redirect, flash import bcrypt import auth import config_utils import sanitize _PAGE = Path(__file__).parent.name bp = Blueprint(_PAGE, __name__) def _tz_to_offset_seconds(tz_str): try: from zoneinfo import ZoneInfo from datetime import datetime return int(datetime.now(ZoneInfo(tz_str)).utcoffset().total_seconds()) except Exception: import settings as _s return _s.get_host_utc_offset() @bp.route('/action/preferences/accountdetails_save', methods=['POST']) @auth.require_level('viewer') def accountdetails_save(): tz = sanitize.timezone(request.form.get('timezone', '').strip()) if not tz: flash('Timezone is required.', 'error') return redirect(f'/{_PAGE}') tz_offset = _tz_to_offset_seconds(tz) session['timezone'] = tz session['tz_offset_seconds'] = tz_offset flash('Preferences saved.', 'success') return redirect(f'/{_PAGE}') @bp.route('/action/preferences/changepassword_save', methods=['POST']) @auth.require_level('viewer') def changepassword_save(): 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') return redirect(f'/{_PAGE}') if new_password != confirm_password: flash('New passwords do not match.', 'error') return redirect(f'/{_PAGE}') if len(new_password) < 8: flash('New password must be at least 8 characters.', 'error') return redirect(f'/{_PAGE}') account = config_utils.get_account_by_id(session.get('account_id', '')) if account is None: flash('Account not found. Please log in again.', 'error') return redirect('/accountlogin') if not bcrypt.checkpw(current_password.encode('utf-8'), account['hashed_password'].encode('utf-8')): flash('Current password is incorrect.', 'error') return redirect(f'/{_PAGE}') hashed = bcrypt.hashpw(new_password.encode('utf-8'), bcrypt.gensalt()).decode('utf-8') 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}') flash('Password changed successfully.', 'success') return redirect(f'/{_PAGE}')