Arreglado VotePoints, y Implementado el Cambio de Correo

This commit is contained in:
adevopg
2024-11-18 09:07:52 +01:00
parent 8ec3ed14cd
commit c3c424277b
20 changed files with 525 additions and 202 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+10 -2
View File
@@ -3,7 +3,7 @@ from django.contrib import admin
from django import forms
from .models import (
Noticia, ClienteCategoria, SistemaOperativo, ServerSelection,
RecruitAFriend, DownloadClientPage, ContentCreator, RecruitReward, GuildRenameSettings
RecruitAFriend, DownloadClientPage, ContentCreator, RecruitReward, GuildRenameSettings, VoteSite
)
from django.db import connections
import logging
@@ -139,7 +139,15 @@ class GuildRenameSettingsAdmin(admin.ModelAdmin):
(None, {
'fields': ('cost',)
}),
)
)
@admin.register(VoteSite)
class VoteSiteAdmin(admin.ModelAdmin):
list_display = ('name', 'points', 'url', 'image_url')
search_fields = ('name',)
list_editable = ('points',)
list_display_links = ('name',)
# Registro de modelos en el admin
+40 -3
View File
@@ -106,11 +106,13 @@ class ClaimedReward(models.Model):
class AccountActivation(models.Model):
username = models.CharField(max_length=17)
email = models.EmailField()
old_email = models.EmailField(null=True, blank=True)
password = models.CharField(max_length=64) # Hash de la contraseña
salt = models.BinaryField(max_length=32)
verifier = models.BinaryField(max_length=32)
recruiter_id = models.IntegerField(null=True, blank=True)
hash = models.CharField(max_length=32, unique=True)
old_email_hash = models.CharField(max_length=32, null=True, blank=True)
created_at = models.DateTimeField(default=timezone.now)
def is_expired(self):
@@ -118,14 +120,14 @@ class AccountActivation(models.Model):
class SecurityToken(models.Model):
user_id = models.IntegerField() # Referencia al ID del usuario en `acore_auth`
user = models.ForeignKey(User, on_delete=models.CASCADE)
token = models.CharField(max_length=6)
created_at = models.DateTimeField(auto_now_add=True)
expires_at = models.DateTimeField()
ip_address = models.GenericIPAddressField()
def __str__(self):
return f"Token for user_id {self.user_id}"
return f"Token for {self.user.username}"
class GuildRenameSettings(models.Model):
@@ -136,5 +138,40 @@ class GuildRenameSettings(models.Model):
class Meta:
verbose_name = "Configuración de Renombrar Hermandad"
verbose_name_plural = "Configuraciones de Renombrar Hermandad"
verbose_name_plural = "Configuraciones de Renombrar Hermandad"
class VoteSite(models.Model):
name = models.CharField(max_length=100, unique=True)
url = models.URLField(max_length=200, help_text="URL del sitio de votación")
image_url = models.URLField(max_length=300, help_text="URL completa de la imagen")
points = models.IntegerField(default=1, help_text="Puntos otorgados por votar")
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.name
class VoteLog(models.Model):
account_id = models.IntegerField()
vote_site = models.ForeignKey('VoteSite', on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True)
last_vote_time = models.DateTimeField(null=True, blank=True)
processed = models.BooleanField(default=False)
processed_at = models.DateTimeField(null=True, blank=True)
def __str__(self):
return f"Voto para {self.vote_site.name} por cuenta {self.account_id}"
class HomeApiPoints(models.Model):
accountID = models.IntegerField(unique=True)
vp = models.IntegerField(default=0)
dp = models.IntegerField(default=0)
class Meta:
db_table = 'home_api_points'
def __str__(self):
return f"Cuenta {self.accountID} - PV: {self.vp}, DP: {self.dp}"
@@ -1,70 +1,42 @@
if (window.history.replaceState) {
window.history.replaceState(null, null, window.location.href);
};
$(function(){
$(".toggle-password").click(function() {
$(this).toggleClass("fa-eye fa-eye-slash");
var type = $(this).hasClass("fa-eye-slash") ? "text" : "password";
$("#password").attr("type", type);
});
});
$(function(){
$(".toggle-token").click(function() {
$(this).toggleClass("fa-eye fa-eye-slash");
var type = $(this).hasClass("fa-eye-slash") ? "text" : "password";
$("#security-token").attr("type", type);
});
});
$(function(){
$('#conf-new-email').on("cut copy paste",function(e) {
e.preventDefault();
});
});
$(function(){
$('.change-email-button').on('click', function(e) {
e.preventDefault();
e.stopPropagation();
$(document).ready(function() {
$('#nw-change-email-form').on('submit', function(e) {
e.preventDefault(); // Evitar el envío por defecto del formulario
$("#change-email-response").empty();
var button = $(this);
var buttonoriginal = button.html();
var bValue = button.data('id');
var data = {changeemail: bValue};
data = $("#uw-change-email-form").serialize() + '&' + $.param(data);
var form = $(this);
var button = $('.change-email-button');
var originalText = button.html();
changeButton(button, 'Cambiando correo');
button.html("Cambiando correo...");
button.prop("disabled", true);
$.ajax({
type: 'POST',
url: '',
data: data,
url: form.attr('action'),
data: form.serialize(), // Serializar los datos correctamente
dataType: 'json',
success: function(data) {
$("#change-email-response").append(data.message).hide().slideDown();
success: function(response) {
$("#change-email-response").html(response.message).hide().slideDown();
if (data.success === true) {
if (response.success) {
button.html("Correo cambiado");
button.css("color","#d79602");
}
else {
} else {
setTimeout(function() {
$("#change-email-response").slideUp( function() {
$("#change-email-response").empty();
restoreButton(button, buttonoriginal);
$("#change-email-response").slideUp(function() {
$("#change-email-response").empty();
button.html(originalText);
button.prop("disabled", false);
});
}, 5000);
}
},
error: function() {
setTimeout(function() {
alert("Algo ha salido mal. Por favor intente más tarde");
window.location.reload();
}, 2000);
error: function(xhr, status, error) {
console.error("Error:", error);
console.error("Detalles:", xhr.responseText);
$("#change-email-response").html('<span class="red-form-response">Algo ha salido mal. Inténtelo de nuevo.</span>');
button.html(originalText);
button.prop("disabled", false);
}
});
});
});
});
@@ -0,0 +1,75 @@
$(document).ready(function() {
$('.vote-button').each(function() {
var button = $(this);
var remainingTime = button.data('remaining-time');
if (remainingTime) {
startCooldownTimer(button, remainingTime);
}
});
$('.vote-button').on('click', function(e) {
e.preventDefault();
$("#voteResponse").empty();
var button = $(this);
var voteUrl = button.data('url').trim();
var data = { vote: voteUrl };
button.html("Votando...");
button.prop("disabled", true);
var otherWindow = window.open(voteUrl, "_blank");
otherWindow.opener = null;
$.ajax({
type: 'POST',
url: '',
data: data,
dataType: 'json',
success: function(response) {
$("#voteResponse").html(response.message).hide().slideDown();
if (response.success) {
button.html("Votado");
button.prop("disabled", true);
} else {
button.html("Votar");
button.prop("disabled", false);
}
// Ocultar el mensaje después de 5 segundos
setTimeout(function() {
$("#voteResponse").slideUp(function() {
$("#voteResponse").empty();
});
}, 5000);
},
error: function() {
$("#voteResponse").html('<span class="red-form-response">Algo ha salido mal. Por favor, inténtalo más tarde.</span>');
// Ocultar el mensaje después de 5 segundos en caso de error
setTimeout(function() {
$("#voteResponse").slideUp(function() {
$("#voteResponse").empty();
});
}, 5000);
}
});
});
});
function startCooldownTimer(button, remainingTime) {
var interval = setInterval(function() {
if (remainingTime <= 0) {
clearInterval(interval);
button.html("Votar");
button.prop("disabled", false);
} else {
var hours = Math.floor(remainingTime / 3600);
var minutes = Math.floor((remainingTime % 3600) / 60);
button.html(`Espera ${hours}h ${minutes}m`);
remainingTime--;
}
}, 1000);
}
@@ -0,0 +1,28 @@
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>Activación del Nuevo Correo</title>
</head>
<body>
<table style="width: 100%; max-width: 600px; margin: 0 auto; border: 1px solid #dddddd; padding: 20px;">
<tr>
<td style="text-align: center;">
<h2>Activación de Nuevo Correo</h2>
</td>
</tr>
<tr>
<td>
<p>Hola {{ username }},</p>
<p>Tu solicitud para cambiar el correo electrónico en <strong>{{ NOMBRE_SERVIDOR }}</strong> ha sido recibida.</p>
<p>Por favor, haz clic en el siguiente enlace para confirmar tu nuevo correo:</p>
<p style="text-align: center;">
<a href="{{ activation_link }}" style="display: inline-block; padding: 10px 20px; background-color: #28a745; color: white; text-decoration: none; border-radius: 5px;">Activar nuevo correo</a>
</p>
<p>Si no realizaste esta solicitud, por favor contacta con soporte.</p>
<p>Atentamente,<br>El equipo de {{ NOMBRE_SERVIDOR }}</p>
</td>
</tr>
</table>
</body>
</html>
@@ -0,0 +1,28 @@
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>Confirmación de Cambio de Correo</title>
</head>
<body>
<table style="width: 100%; max-width: 600px; margin: 0 auto; border: 1px solid #dddddd; padding: 20px;">
<tr>
<td style="text-align: center;">
<h2>Confirmación de Cambio de Correo</h2>
</td>
</tr>
<tr>
<td>
<p>Hola {{ username }},</p>
<p>Has solicitado cambiar tu correo electrónico registrado en <strong>{{ NOMBRE_SERVIDOR }}</strong>.</p>
<p>Para confirmar este cambio, haz clic en el siguiente enlace:</p>
<p style="text-align: center;">
<a href="{{ confirm_link }}" style="display: inline-block; padding: 10px 20px; background-color: #007bff; color: white; text-decoration: none; border-radius: 5px;">Confirmar cambio</a>
</p>
<p>Si no solicitaste este cambio, por favor ignora este correo.</p>
<p>Atentamente,<br>El equipo de {{ NOMBRE_SERVIDOR }}</p>
</td>
</tr>
</table>
</body>
</html>
@@ -0,0 +1,27 @@
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>Notificación de Cambio de Correo</title>
</head>
<body>
<table style="width: 100%; max-width: 600px; margin: 0 auto; border: 1px solid #dddddd; padding: 20px;">
<tr>
<td style="text-align: center;">
<h2>Cambio de Correo Exitoso</h2>
</td>
</tr>
<tr>
<td>
<p>Hola {{ username }},</p>
<p>Te notificamos que tu correo electrónico en <strong>{{ NOMBRE_SERVIDOR }}</strong> ha sido cambiado exitosamente al siguiente correo:</p>
<p style="text-align: center;">
<strong>{{ new_email }}</strong>
</p>
<p>Si no realizaste este cambio, por favor contacta inmediatamente con soporte.</p>
<p>Atentamente,<br>El equipo de {{ NOMBRE_SERVIDOR }}</p>
</td>
</tr>
</table>
</body>
</html>
+36 -4
View File
@@ -14,10 +14,42 @@
<div class="centered">
<br>
<br>
<span class="red-form-response">El cambio de correo ya no es una herramienta disponible por autogestión.</span>
<hr>
<div class="alert-message" id="change-email-response"></div>
<br>
<form id="nw-change-email-form" method="POST" accept-charset="utf-8">
{% csrf_token %}
<table class="middle-center-table">
<tr>
<td><input type="password" maxlength="16" name="cur-password" id="cur-password" placeholder="Contraseña actual" required></td>
</tr>
<tr>
<td><input type="email" name="cur-email" id="cur-email" placeholder="Correo actual" required></td>
</tr>
<tr>
<td><input type="email" name="new-email" id="new-email" placeholder="Nuevo correo" required></td>
</tr>
<tr>
<td><input type="email" name="conf-new-email" id="conf-new-email" placeholder="Confirmar nuevo correo" required></td>
</tr>
<tr>
<td>
<input type="text" maxlength="6" name="security-token" id="security-token" placeholder="Token de seguridad" required>
<span class="far fa-eye toggle-token"></span>
</td>
</tr>
<tr>
<td>
<button type="submit" class="change-email-button">Cambiar Correo</button>
</td>
</tr>
</table>
<hr>
<div class="alert-message" id="change-email-response"></div>
</form>
</hr>
<br>
</div>
</div>
</div>
+1
View File
@@ -51,6 +51,7 @@
<script src="{{ URL_PRINCIPAL }}/static/nw-themes/nw-ryu/nw-js-handlers/security_token_response.js"></script>
<script src="{{ URL_PRINCIPAL }}/static/nw-themes/nw-ryu/nw-js-handlers/change_password_response.js"></script>
<script src="{{ URL_PRINCIPAL }}/static/nw-themes/nw-ryu/nw-js-handlers/rename_guild_response.js"></script>
<script src="{{ URL_PRINCIPAL }}/static/nw-themes/nw-ryu/nw-js-handlers/vote_points_response.js"></script>
<script>var aowow_tooltips = { "colorlinks": true, "iconizelinks": true, "renamelinks": true }</script>
<script src="{{ URL_PRINCIPAL }}/static/nw-themes/nw-ryu/nw-js/nw-scripts.js"></script>
+11 -3
View File
@@ -20,9 +20,17 @@
<legend>Estado de la cuenta</legend>
<div class="separate">
<img src="{{ URL_PRINCIPAL }}/static/nw-themes/nw-ryu/nw-images/nw-ranks/1_Newbie.svg" class="nw-rank" alt="Nivel 1" title="Nivel 1">
<p>PD: <span>0</span></p>
<p>PV: <span>0</span></p>
<p>Token de Seguridad: <span>Sin solicitar</span></p>
<p>PD: <span>{{ dp }}</span></p>
<p>PV: <span>{{ vp }}</span></p>
<p>Token de Seguridad:
<span>
{% if token_status == "Solicitado" %}
{{ token_status }} - {{ token_date }}
{% else %}
{{ token_status }}
{% endif %}
</span>
</p>
{% if account_status.is_banned %}
<p>Cuenta baneada: <span></span></p>
+26 -116
View File
@@ -52,122 +52,32 @@
<button class="refresh-button" onclick="doRefresh();"><img class="refresh-icon" src="{{ URL_PRINCIPAL }}/static/nw-themes/nw-ryu/nw-images/nw-icons/refresh.webp" title="Refrescar" alt="Refrescar"></button>
<p><span>Nota:</span> Gtop100 puede demorar unos minutos en acreditar el voto.</p>
<br>
<div class="inline-div">
<table>
<tbody><tr>
<td><img class="img-med-icon" src="{{ URL_PRINCIPAL }}/static/nw-themes/nw-ryu/nw-images/nw-vote-sites/gtop100.jpg" title="Gtop100" alt="Gtop100"></td>
</tr>
<tr>
<td>Gtop100</td>
</tr>
<tr>
<td><hr></td>
</tr>
<tr>
<td class="lefted">PV: <span>1</span></td>
</tr>
<tr>
<td class="lefted"></td>
</tr>
<tr>
<td><hr></td>
</tr>
<tr>
<td>
<form action="" method="POST" id="uw-vote-form" accept-charset="utf-8">
<button type="submit" name="vote" class="vote-button" value="https://gtop100.com/topsites/World-of-Warcraft/sitedetails/{{ NOMBRE_SERVIDOR }}-94649?vote=1&amp;pingUsername=91402">Votar</button>
</form>
</td>
</tr><tr>
</tr></tbody></table>
</div>
<div class="inline-div">
<table>
<tbody><tr>
<td><img class="img-med-icon" src="{{ URL_PRINCIPAL }}/static/nw-themes/nw-ryu/nw-images/nw-vote-sites/topg.webp" title="TopG" alt="TopG"></td>
</tr>
<tr>
<td>TopG</td>
</tr>
<tr>
<td><hr></td>
</tr>
<tr>
<td class="lefted">PV: <span>1</span></td>
</tr>
<tr>
<td class="lefted"></td>
</tr>
<tr>
<td><hr></td>
</tr>
<tr>
<td>
<form action="" method="POST" id="uw-vote-form" accept-charset="utf-8">
<button type="submit" name="vote" class="vote-button" value="https://topg.org/wow-private-servers/in-496618-91402">Votar</button>
</form>
</td>
</tr><tr>
</tr></tbody></table>
</div>
<div class="inline-div">
<table>
<tbody><tr>
<td><img class="img-med-icon" src="{{ URL_PRINCIPAL }}/static/nw-themes/nw-ryu/nw-images/nw-vote-sites/top100arena.jpg" title="Top100arena" alt="Top100arena"></td>
</tr>
<tr>
<td>Top100arena</td>
</tr>
<tr>
<td><hr></td>
</tr>
<tr>
<td class="lefted">PV: <span>1</span></td>
</tr>
<tr>
<td class="lefted"></td>
</tr>
<tr>
<td><hr></td>
</tr>
<tr>
<td>
<form action="" method="POST" id="uw-vote-form" accept-charset="utf-8">
<button type="submit" name="vote" class="vote-button" value="http://www.top100arena.com/in.asp?id=94147&amp;incentive=91402">Votar</button>
</form>
</td>
</tr><tr>
</tr></tbody></table>
</div>
<div class="inline-div">
<table>
<tbody><tr>
<td><img class="img-med-icon" src="{{ URL_PRINCIPAL }}/static/nw-themes/nw-ryu/nw-images/nw-vote-sites/arenatop100.webp" title="Arena-Top100" alt="Arena-Top100"></td>
</tr>
<tr>
<td>Arena-Top100</td>
</tr>
<tr>
<td><hr></td>
</tr>
<tr>
<td class="lefted">PV: <span>1</span></td>
</tr>
<tr>
<td class="lefted"></td>
</tr>
<tr>
<td><hr></td>
</tr>
<tr>
<td>
<form action="" method="POST" id="uw-vote-form" accept-charset="utf-8">
<button type="submit" name="vote" class="vote-button" value="https://www.arena-top100.com/index.php?a=in&amp;u={{ NOMBRE_SERVIDOR }}&amp;id=91402">Votar</button>
</form>
</td>
</tr><tr>
</tr></tbody></table>
</div>
<div id="vote-panel">
<div id="vote-panel">
{% for site in vote_sites %}
<div class="inline-div">
<table>
<tr>
<td><img class="img-med-icon" src="{{ site.image_url }}" title="{{ site.name }}" alt="{{ site.name }}"></td>
</tr>
<tr>
<td>{{ site.name }}</td>
</tr>
<tr>
<td>PV: <span>{{ site.points }}</span></td>
</tr>
<tr>
<td>
<form method="POST" class="nw-vote-form" accept-charset="utf-8">
{% csrf_token %}
<button type="button" class="vote-button" data-url="{{ site.url }}" data-remaining-time="{{ site.remaining_time }}">Votar</button>
</form>
</td>
</tr>
</table>
</div>
{% endfor %}
<hr>
<div class="alert-message" id="voteResponse"></div>
<br>
+3 -1
View File
@@ -23,7 +23,9 @@ urlpatterns = [
path('not-found/', views.not_found, name='not-found'),
path('change-password/', views.change_password_view, name='change_password'),
path('security-token/', views.security_token_view, name='security_token'),
path('change-email/', views.change_email_view, name='change_email'),
path('change-email/', views.change_email_view, name='change-email'),
path('confirm-old-email/', views.confirm_old_email_view, name='confirm-old-email'),
path('confirm-new-email/', views.confirm_new_email_view, name='confirm-new-email'),
path('promo-code/', views.promo_code_view, name='promo_code'),
path('transfer-d-points/', views.transfer_d_points_view, name='transfer_d_points'),
path('rename-guild/', views.rename_guild_view, name='rename-guild'),
+214 -19
View File
@@ -5,12 +5,12 @@ import binascii
import os
import re
from django.shortcuts import render, redirect
from django.http import JsonResponse
from django.http import HttpResponse, JsonResponse
from django.db import connections
from django.contrib import messages
from django.contrib.auth import logout
from django import forms
from .models import Noticia, ClienteCategoria, ServerSelection, RecruitAFriend, DownloadClientPage, ContentCreator, RecruitReward, ClaimedReward, AccountActivation, SecurityToken, GuildRenameSettings
from .models import Noticia, ClienteCategoria, ServerSelection, RecruitAFriend, DownloadClientPage, ContentCreator, RecruitReward, ClaimedReward, AccountActivation, SecurityToken, GuildRenameSettings, VoteSite, VoteLog, HomeApiPoints
from django.views.decorators.csrf import csrf_exempt
import logging
from datetime import datetime, timedelta
@@ -22,7 +22,6 @@ from django.utils.crypto import get_random_string
from django.conf import settings
import secrets
# Configuración del logger
logger = logging.getLogger(__name__)
@@ -340,7 +339,7 @@ def register_view(request):
)
# Enviar correo de activación
activation_link = f"http://localhost:8009/es/activate-account?act={activation_hash}"
activation_link = f"{settings.URL_PRINCIPAL}/es/activate-account?act={activation_hash}"
context = {
'username': username,
'password': password,
@@ -610,6 +609,21 @@ def my_account(request):
# Obtener el estado de la cuenta
account_status = get_account_status(account_id)
# Obtener los puntos (DP y VP) del usuario desde la tabla `home_api_points`
user_points = HomeApiPoints.objects.filter(accountID=account_id).first()
dp = user_points.dp if user_points else 0
vp = user_points.vp if user_points else 0
# Obtener el estado del token de seguridad
security_token = SecurityToken.objects.filter(user_id=account_id).first()
if security_token:
token_status = "Solicitado"
token_date = security_token.created_at.strftime('%H:%M:%S %d-%m-%Y')
else:
token_status = "Sin solicitar"
token_date = None
return render(request, 'my-account/my-account.html', {
'is_logged_in': is_logged_in,
@@ -620,10 +634,15 @@ def my_account(request):
'last_ip': account_data[4],
'last_attempt_ip': account_data[5],
'joindate': formatear_fecha(account_data[6]),
},
'account_status': account_status,
'characters': characters,
'has_characters': has_characters,
'dp': dp,
'vp': vp,
'token_status': token_status,
'token_date': token_date
})
@@ -951,15 +970,146 @@ def send_security_token_email(email, username, token, ip_address):
context=context
)
def change_email_view(request):
"""
Vista para la página de 'Cambiar Correo'.
Simplemente renderiza un template con información relevante.
"""
username = request.session.get('username')
if not username:
return redirect('login')
# Obtener el usuario desde la base de datos de `acore_auth`
with connections['acore_auth'].cursor() as cursor:
cursor.execute("""
SELECT id, email, reg_mail
FROM account
WHERE username = %s
""", [username])
account_data = cursor.fetchone()
if not account_data:
return redirect('login')
user_id, current_email, reg_email = account_data
security_token = SecurityToken.objects.filter(user_id=user_id).first()
if request.method == 'POST':
print("Datos recibidos:", request.POST)
current_password = request.POST.get('cur-password', '').strip()
current_email_input = request.POST.get('cur-email', '').strip()
new_email = request.POST.get('new-email', '').strip()
conf_new_email = request.POST.get('conf-new-email', '').strip()
token = request.POST.get('security-token', '').strip()
# Validar los campos
if not all([current_password, current_email_input, new_email, conf_new_email, token]):
return JsonResponse({'success': False, 'message': 'Por favor, complete todos los campos.'})
if current_email_input != current_email:
return JsonResponse({'success': False, 'message': 'El correo actual no es correcto.'})
if new_email != conf_new_email:
return JsonResponse({'success': False, 'message': 'Los correos no coinciden.'})
if not re.match(r'^[a-zA-Z0-9._%+-]+@gmail\.com$', new_email):
return JsonResponse({'success': False, 'message': 'El nuevo correo no es válido.'})
if not security_token or security_token.token != token:
return JsonResponse({'success': False, 'message': 'Token de seguridad incorrecto.'})
if not authenticate(username, current_password):
return JsonResponse({'success': False, 'message': 'Contraseña incorrecta.'})
# Generar hashes
old_email_hash = secrets.token_urlsafe(16)
new_email_hash = secrets.token_urlsafe(16)
# Guardar en `AccountActivation`
AccountActivation.objects.create(
username=username,
email=new_email,
old_email=current_email,
password='',
salt=b'',
verifier=b'',
recruiter_id=user_id,
hash=new_email_hash,
old_email_hash=old_email_hash
)
# Enviar confirmación al correo actual
confirm_old_email_link = f"{settings.URL_PRINCIPAL}/es/confirm-old-email?hash={old_email_hash}"
context_old_email = {
'username': username,
'confirm_link': confirm_old_email_link,
'NOMBRE_SERVIDOR': settings.NOMBRE_SERVIDOR
}
enviar_correo(
subject=f'Confirme el cambio de correo para {username}',
to_email=current_email,
template='emails/confirm_old_email.html',
context=context_old_email
)
return JsonResponse({'success': True, 'message': 'Se ha enviado un correo de confirmación al correo actual.'})
return render(request, 'account/change_email.html')
def confirm_old_email_view(request):
hash = request.GET.get('hash')
activation = AccountActivation.objects.filter(old_email_hash=hash).first()
if not activation:
return HttpResponse('Enlace no válido o expirado.', status=400)
# Enviar correo al nuevo correo para confirmar el cambio
activation_link = f"{settings.URL_PRINCIPAL}/es/confirm-new-email?hash={activation.hash}"
context_new_email = {
'username': activation.username,
'activation_link': activation_link,
'NOMBRE_SERVIDOR': settings.NOMBRE_SERVIDOR
}
enviar_correo(
subject=f'Confirme su nuevo correo para {activation.username}',
to_email=activation.email,
template='emails/confirm_new_email.html',
context=context_new_email
)
return HttpResponse('Correo confirmado. Se ha enviado un enlace al nuevo correo.')
def confirm_new_email_view(request):
hash = request.GET.get('hash')
activation = AccountActivation.objects.filter(hash=hash).first()
if not activation:
return HttpResponse('Enlace no válido o expirado.', status=400)
# Actualizar el correo en la base de datos
with connections['acore_auth'].cursor() as cursor:
cursor.execute("""
UPDATE account
SET email = %s, reg_mail = %s
WHERE username = %s
""", [activation.email, activation.email, activation.username])
# Enviar notificación al correo anterior
context_old_email = {
'username': activation.username,
'new_email': activation.email,
'NOMBRE_SERVIDOR': settings.NOMBRE_SERVIDOR
}
enviar_correo(
subject=f'Su correo ha sido cambiado en {settings.NOMBRE_SERVIDOR}',
to_email=activation.old_email,
template='emails/old_email_notification.html',
context=context_old_email
)
return HttpResponse('El cambio de correo ha sido confirmado y completado con éxito.')
def promo_code_view(request):
return render(request, 'account/promo_code.html')
@@ -967,9 +1117,6 @@ def transfer_d_points_view(request):
# Renderizar la plantilla para la transferencia de puntos
return render(request, 'account/transfer_d_points.html')
from .models import GuildRenameSettings
def rename_guild_view(request):
# Verificar si el usuario está autenticado mediante la sesión
username = request.session.get('username')
@@ -1037,12 +1184,60 @@ def rename_guild_view(request):
'rename_cost': rename_cost
})
def vote_points_view(request):
"""
Vista para la página de puntos de votación.
"""
return render(request, 'account/vote_points.html')
# Verificar si el usuario tiene un `username` en la sesión
username = request.session.get('username')
if not username:
return redirect('login')
# Obtener el `account_id` basado en el `username`
with connections['acore_auth'].cursor() as cursor:
cursor.execute("SELECT id FROM account WHERE username = %s", [username])
account_data = cursor.fetchone()
if not account_data:
return JsonResponse({'success': False, 'message': 'Cuenta no encontrada.'})
account_id = account_data[0]
if request.method == 'POST':
vote_url = request.POST.get('vote').strip()
site = VoteSite.objects.filter(url=vote_url).first()
if not site:
return JsonResponse({'success': False, 'message': 'Sitio de votación no encontrado.'})
# Verificar si ya ha votado en las últimas 12 horas y 30 minutos
last_vote = VoteLog.objects.filter(account_id=account_id, vote_site=site).order_by('-created_at').first()
now = timezone.now()
if last_vote:
time_diff = now - last_vote.created_at
cooldown_period = timedelta(hours=12, minutes=30)
if time_diff < cooldown_period:
remaining_time = cooldown_period - time_diff
hours, remainder = divmod(remaining_time.seconds, 3600)
minutes, _ = divmod(remainder, 60)
return JsonResponse({
'success': False,
'message': f'<span class="red-form-response">Tienes que esperar {hours} horas y {minutes} minutos antes de volver a votar.</span>'
})
# Acreditar puntos al usuario y registrar el voto
user_points = HomeApiPoints.objects.filter(accountID=account_id).first()
if user_points:
user_points.vp += site.points
user_points.save()
else:
HomeApiPoints.objects.create(accountID=account_id, vp=site.points, dp=0)
# Registrar el voto
VoteLog.objects.create(account_id=account_id, vote_site=site, last_vote_time=now)
return JsonResponse({'success': True, 'message': f'Has votado en {site.name}. Se han acreditado {site.points} PV.'})
vote_sites = VoteSite.objects.all()
return render(request, 'account/vote_points.html', {'vote_sites': vote_sites})
def d_points_view(request):
"""
Binary file not shown.
+1 -1
View File
@@ -43,7 +43,7 @@ INSTALLED_APPS = [
# Configuración para AC SOAP
AC_SOAP_URL = "http://127.0.0.1:2079"
AC_SOAP_USER = "AC_SOAP"
AC_SOAP_USER = " "
AC_SOAP_PASSWORD = "Ladyamy89"
AC_SOAP_URN = "urn:AC"