🔐 RESTORE: Admin password reset functionality

 Added admin password reset capability with:
   - Generate secure temporary passwords (12 chars with symbols)
   - Create password reset links with 15-min expiry
   - Beautiful modal UI with copy-to-clipboard functionality
   - Toggle password visibility for security
   - Reset buttons in both users list and user detail pages
   - Proper error handling and loading states
   - Responsive design for mobile/desktop

FEATURES:
- Admins can reset any user's password instantly
- Users get both temporary password and reset link options
- Secure password generation with proper entropy
- Audit logging of all password reset actions
- Professional UI with Bootstrap modals and tooltips

SAFE: Only affects admin functionality, calculator unchanged
This commit is contained in:
Gan, Jimmy
2025-07-11 13:36:05 +08:00
parent fefe9b10c0
commit ea5b4e5f18
3 changed files with 414 additions and 3 deletions
+46
View File
@@ -478,6 +478,52 @@ def reset_cost_factors():
flash('An error occurred while resetting cost factors.', 'error')
return redirect(url_for('admin.cost_factors'))
@bp.route('/user/<int:user_id>/reset-password', methods=['POST'])
@login_required
@limiter.limit("10 per minute")
def admin_reset_password(user_id):
"""Admin function to reset a user's password"""
try:
user = User.query.get_or_404(user_id)
# Generate a temporary password
import secrets
import string
# Generate a secure temporary password (12 characters with mix of letters, numbers, symbols)
temp_password = ''.join(secrets.choice(string.ascii_letters + string.digits + '!@#$%^&*') for _ in range(12))
# Set the new password
user.set_password(temp_password)
# Generate a reset token for the user (optional - they can use this to set their own password)
reset_token = user.generate_reset_token()
db.session.commit()
# Log the password reset
current_app.logger.info(f'Admin {current_user.email} reset password for user {user.email}')
# Create reset URL
reset_url = url_for('auth.reset_password', token=reset_token, _external=True)
return jsonify({
'status': 'success',
'message': 'Password reset successfully',
'temporary_password': temp_password,
'reset_url': reset_url,
'username': user.username,
'email': user.email
})
except Exception as e:
db.session.rollback()
current_app.logger.error(f'Admin password reset error: {str(e)}')
return jsonify({
'status': 'error',
'message': 'An error occurred while resetting the password'
}), 500
@bp.route('/debug-endpoints')
def debug_endpoints():
from flask import current_app