fix(auth/users): corregir edicion de contraseñas de usuarios, cambio de contraseña y evitar pantalla en blanco

This commit is contained in:
2026-09-23 15:38:48 -03:00
parent b540015b7e
commit 6ecaef9b9d
8 changed files with 428 additions and 21 deletions
+32
View File
@@ -444,6 +444,38 @@ def get_document_types():
'document_types': DOCUMENT_TYPES
}), 200
@api_admin_bp.route('/users/<int:id>/password', methods=['POST', 'PUT'])
@jwt_required
def reset_user_password(id):
"""
Permite a los administradores restablecer la contraseña de acceso de cualquier usuario.
"""
if not g.jwt_user.is_admin():
return jsonify({
'error': 'Forbidden',
'message': 'Solo los administradores institucionales pueden restablecer contraseñas.'
}), 403
user = User.query.get_or_404(id)
data = request.get_json(silent=True) or request.form.to_dict() or {}
new_password = (data.get('password') or data.get('new_password') or '').strip()
if not new_password or len(new_password) < 6:
return jsonify({
'error': 'BadRequest',
'message': 'La nueva contraseña debe contener al menos 6 caracteres.'
}), 400
user.set_password(new_password)
db.session.commit()
return jsonify({
'status': 'success',
'message': f'Contraseña restablecida exitosamente para {user.name}.',
'user_id': user.id
}), 200
@api_admin_bp.route('/users/<int:id>/toggle', methods=['POST'])
@jwt_required
def toggle_user(id):
+49
View File
@@ -340,6 +340,54 @@ def logout():
return resp
@api_auth_bp.route('/change_password', methods=['POST'])
@api_auth_bp.route('/change-password', methods=['POST'])
@jwt_required
def change_password():
"""
Permite al usuario autenticado cambiar su propia contraseña institucional.
Valida la contraseña actual y la confirmación de la nueva clave.
"""
data = request.get_json(silent=True) or request.form.to_dict() or {}
current_password = data.get('current_password', '').strip()
new_password = data.get('new_password', '').strip()
confirm_password = data.get('confirm_password', '').strip()
if not current_password or not new_password:
return jsonify({
'error': 'BadRequest',
'message': 'Debe ingresar la contraseña actual y la nueva contraseña.'
}), 400
if new_password != confirm_password:
return jsonify({
'error': 'BadRequest',
'message': 'La nueva contraseña y su confirmación no coinciden.'
}), 400
if len(new_password) < 6:
return jsonify({
'error': 'BadRequest',
'message': 'La nueva contraseña debe tener al menos 6 caracteres.'
}), 400
user = g.jwt_user
if not user.check_password(current_password):
return jsonify({
'error': 'Unauthorized',
'message': 'La contraseña actual ingresada es incorrecta.'
}), 401
user.set_password(new_password)
db.session.commit()
logger.info(f"[Auth] Password successfully updated for user {user.email}")
return jsonify({
'status': 'success',
'message': 'Contraseña actualizada correctamente.'
}), 200
@api_auth_bp.route('/me', methods=['GET'])
@jwt_required
def get_current_user():
@@ -348,3 +396,4 @@ def get_current_user():
"""
profile = user_service.get_profile_data(g.jwt_user)
return jsonify(profile), 200