diff --git a/app/routes/auth.py b/app/routes/auth.py index 8ae6d2a..611aa01 100644 --- a/app/routes/auth.py +++ b/app/routes/auth.py @@ -67,7 +67,7 @@ def profile(): if form.validate_on_submit(): current_user.full_name = form.full_name.data.strip() or None - current_user.email = form.email.data + current_user.email = form.email.data.strip().lower() if form.new_password.data: current_user.set_password(form.new_password.data) @@ -156,7 +156,7 @@ def create_user(): user = User( username=form.username.data, full_name=form.full_name.data.strip() or None, - email=form.email.data, + email=form.email.data.strip().lower(), role=role ) user.set_password(form.password.data) @@ -190,7 +190,7 @@ def edit_user(user_id): if form.validate_on_submit(): user.username = form.username.data user.full_name = form.full_name.data.strip() or None - user.email = form.email.data + user.email = form.email.data.strip().lower() if not director_editing: user.role = form.role.data @@ -479,12 +479,22 @@ def forgot_password(): form = ForgotPasswordForm() if form.validate_on_submit(): - user = User.query.filter_by(email=form.email.data.strip().lower()).first() + # Case-insensitive lookup: emails are stored with inconsistent casing + # across create/edit/import paths, so a plain lowercased == match can + # silently miss a mixed-case stored address and send nothing. + email_input = form.email.data.strip().lower() + user = User.query.filter( + db.func.lower(User.email) == email_input + ).first() if user and user.active: token = user.generate_set_password_token(expires_hours=1) db.session.commit() _send_password_reset_email(user, token, base_url=request.host_url) - logger.info('AUTH | forgot_password | user=%s | email=%s', user.username, user.email) + logger.info('AUTH | forgot_password | reset link dispatched | user=%s | email=%s', + user.username, user.email) + else: + # No leak to the user (generic message below), but log for diagnosis. + logger.info('AUTH | forgot_password | no active account for email=%s', email_input) # Always show the same message — never reveal whether the email exists flash( 'If an account with that email address exists, a password reset link ' diff --git a/app/routes/customers.py b/app/routes/customers.py index a27a803..1ede8d8 100644 --- a/app/routes/customers.py +++ b/app/routes/customers.py @@ -328,7 +328,7 @@ def edit(customer_id): if form.validate_on_submit(): customer.username = form.username.data customer.full_name = form.full_name.data.strip() or None - customer.email = form.email.data + customer.email = form.email.data.strip().lower() if form.password.data: customer.set_password(form.password.data) db.session.commit()