diff --git a/home/__pycache__/views.cpython-313.pyc b/home/__pycache__/views.cpython-313.pyc index 346eb7b..411d7a1 100644 Binary files a/home/__pycache__/views.cpython-313.pyc and b/home/__pycache__/views.cpython-313.pyc differ diff --git a/home/static/nw-themes/nw-ryu/nw-js-handlers/change_password_response.js b/home/static/nw-themes/nw-ryu/nw-js-handlers/change_password_response.js new file mode 100644 index 0000000..5202b71 --- /dev/null +++ b/home/static/nw-themes/nw-ryu/nw-js-handlers/change_password_response.js @@ -0,0 +1,43 @@ +$(function(){ + $('.change-password-button').on('click', function(e) { + e.preventDefault(); + e.stopPropagation(); + $("#change-password-response").empty(); + + var button = $(this); + var originalText = button.html(); + var data = $("#nw-change-password-form").serialize(); + + changeButton(button, 'Cambiando contraseña'); + + $.ajax({ + type: 'POST', + url: '', + data: data, + dataType: 'json', + success: function(response) { + $("#change-password-response").html(response.message).hide().slideDown(); + + if (response.success) { + button.html("Contraseña cambiada").css("color", "#d79602"); + if (response.redirect) { + setTimeout(function() { + window.location.href = '/es/log-in'; + }, 3000); + } + } else { + setTimeout(function() { + $("#change-password-response").slideUp(function() { + $("#change-password-response").empty(); + restoreButton(button, originalText); + }); + }, 5000); + } + }, + error: function() { + alert("Algo ha salido mal. Por favor, intenta más tarde."); + window.location.reload(); + } + }); + }); +}); diff --git a/home/templates/partials/change_password.html b/home/templates/partials/change_password.html index 0e0a1d3..f11cad0 100644 --- a/home/templates/partials/change_password.html +++ b/home/templates/partials/change_password.html @@ -13,7 +13,7 @@


-
+
diff --git a/home/templates/partials/head.html b/home/templates/partials/head.html index 0f29e79..0ea9692 100644 --- a/home/templates/partials/head.html +++ b/home/templates/partials/head.html @@ -49,6 +49,7 @@ + diff --git a/home/views.py b/home/views.py index 32658a8..1151566 100644 --- a/home/views.py +++ b/home/views.py @@ -600,7 +600,7 @@ def my_account(request): account_data = cursor.fetchone() if not account_data: - return redirect('login') + return redirect('index') account_id = account_data[0] @@ -780,11 +780,78 @@ def get_account_characters(account_id): def change_password_view(request): + # Verificar si el usuario está autenticado mediante la sesión + username = request.session.get('username') + if not username: + return redirect('login') + + # Obtener el usuario desde la base de datos de `acore_auth` + user_data = get_user_from_acore(username) + if not user_data: + return redirect('login') + + user_id = user_data['id'] + email = user_data['email'] + + if request.method == 'POST': + current_password = request.POST.get('cur-password').strip() + new_password = request.POST.get('new-password').strip() + conf_new_password = request.POST.get('conf-new-password').strip() + security_token = request.POST.get('security-token').strip() + + # Validar campos vacíos + if not current_password or not new_password or not conf_new_password or not security_token: + return JsonResponse({'success': False, 'message': 'Por favor, complete todos los campos.'}) + + # Validar que la nueva contraseña coincida con su confirmación + if new_password != conf_new_password: + return JsonResponse({'success': False, 'message': 'Las contraseñas no coinciden.'}) + + # Validar longitud de la nueva contraseña + if len(new_password) > 16: + return JsonResponse({'success': False, 'message': 'La contraseña nueva no debe exceder los 16 caracteres.'}) + + # Verificar si el token de seguridad ha sido generado + existing_token = SecurityToken.objects.filter(user_id=user_id).first() + if not existing_token: + return JsonResponse({'success': False, 'message': 'No tienes un token de seguridad generado. Por favor, genera uno antes de cambiar tu contraseña.'}) + + # Verificar si el token proporcionado es correcto + if existing_token.token != security_token: + return JsonResponse({'success': False, 'message': 'El token ingresado es incorrecto.'}) + + # Verificar la contraseña actual usando la función `authenticate` + if not authenticate(username, current_password): + return JsonResponse({'success': False, 'message': 'La contraseña actual es incorrecta.'}) + + # Generar salt y verifier para la nueva contraseña + new_salt = binascii.hexlify(os.urandom(32)).decode('utf-8').upper() + new_verifier = calculate_srp6_verifier(username, new_password, new_salt) + + # Convertir `salt` y `verifier` a bytes antes de guardarlos en la base de datos + new_salt_bytes = binascii.unhexlify(new_salt) + new_verifier_bytes = binascii.unhexlify(new_verifier) + + # Actualizar la contraseña en la base de datos + with connections['acore_auth'].cursor() as cursor: + cursor.execute(""" + UPDATE account SET salt = %s, verifier = %s WHERE username = %s + """, [new_salt_bytes, new_verifier_bytes, username]) + + # Cerrar la sesión por seguridad + if 'username' in request.session: + del request.session['username'] + + # Redirigir al usuario a la página de inicio de sesión + return JsonResponse({ + 'success': True, + 'message': 'Contraseña cambiada exitosamente. Has sido desconectado por seguridad.', + 'redirect': True + }) + return render(request, 'account/change_password.html') - - def get_user_from_acore(username): """ Obtiene la información del usuario desde la base de datos `acore_auth`. @@ -800,12 +867,12 @@ def security_token_view(request): # Verificar si el usuario está autenticado mediante la sesión username = request.session.get('username') if not username: - return redirect('login') + return redirect('index') # Obtener el usuario desde la base de datos de `acore_auth` user_data = get_user_from_acore(username) if not user_data: - return redirect('login') + return redirect('index') user_id = user_data['id'] email = user_data['email'] @@ -946,7 +1013,7 @@ def help_view(request): # Verificar si el usuario está logueado if 'username' not in request.session: # Si no está logueado, redirigir al inicio de sesión - return redirect('login') + return redirect('index') # Si está logueado, renderizar la página de ayuda return render(request, 'community/help.html') @@ -1045,7 +1112,7 @@ def get_achievement_name(achievement_id): def novawow_players_view(request): # Verificar si el usuario está logueado if 'username' not in request.session: - return redirect('/login') + return redirect('index') # Obtener las 5 hermandades con más miembros with connections['acore_characters'].cursor() as cursor: