Skip to content

Commit

Permalink
Merge pull request #49 from fedecarboni7/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
fedecarboni7 authored Aug 20, 2024
2 parents 9d29ff4 + 24dd9b9 commit b931012
Show file tree
Hide file tree
Showing 6 changed files with 123 additions and 38 deletions.
12 changes: 11 additions & 1 deletion app/routes/player_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ async def get_form(

@router.post("/submit", response_class=HTMLResponse)
async def submit_form(request: Request, db: Session = Depends(get_db), current_user: User = Depends(get_current_user)):
if not current_user:
request.session.clear()
return RedirectResponse("/login", status_code=302)

start_time_1 = time.time()
current_user_id = current_user.id
form_data = await request.form()
Expand Down Expand Up @@ -181,6 +185,9 @@ async def submit_form(request: Request, db: Session = Depends(get_db), current_u

@router.get("/reset")
async def reset_session(db: Session = Depends(get_db), current_user: User = Depends(get_current_user)):
if not current_user:
return {"error": "No hay un usuario autenticado"}

current_user_id = current_user.id

def delete_players():
Expand Down Expand Up @@ -232,7 +239,10 @@ def update_and_commit():


@router.delete("/player/{player_id}")
def delete_player(player_id: int, db: Session = Depends(get_db)):
def delete_player(player_id: int, db: Session = Depends(get_db), current_user: User = Depends(get_current_user)):
if not current_user:
return HTMLResponse("No hay un usuario autenticado", status_code=401)

try:
player = execute_with_retries(query_player, db, player_id)
except OperationalError:
Expand Down
15 changes: 4 additions & 11 deletions app/utils/validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
def validate_username(username: str):
if len(username) < 3 or len(username) > 30:
raise ValueError("El nombre de usuario debe tener entre 3 y 30 caracteres.")
if not re.match(r'^[\w.]+$', username):
if not re.match(r'^[\w.@]+$', username):
raise ValueError("El nombre de usuario solo puede contener letras, números, guiones bajos y puntos.")

def validate_password(password: str):
Expand All @@ -16,13 +16,6 @@ def validate_password(password: str):
raise ValueError("La contraseña debe contener al menos una letra minúscula.")
if not re.search(r"[0-9]", password):
raise ValueError("La contraseña debe contener al menos un número.")
if not re.search(r"[!@#$%^&*(),.?\":{}|<>]", password):
raise ValueError("La contraseña debe contener al menos un carácter especial.")
if re.search(r"(.)\1\1\1", password):
raise ValueError("La contraseña no debe contener más de tres caracteres repetidos consecutivos.")
if re.search(r"(012|123|234|345|456|567|678|789|890|qwerty|asdf)", password.lower()):
raise ValueError("La contraseña no debe contener secuencias de números o teclas comunes.")

common_passwords = ["123456", "password", "12345678", "qwerty", "abc123"]
if password.lower() in common_passwords:
raise ValueError("La contraseña es demasiado común. Por favor, elija una diferente.")
if len(password) < 12 and not re.search(r"[!@#$%^&*(),.?\":{}|<>]", password):
raise ValueError("La contraseña de menos de 12 caracteres debe contener al menos un carácter especial.")

69 changes: 47 additions & 22 deletions static/js/script-v1.1.js → static/js/script-v1.0.3.js
Original file line number Diff line number Diff line change
Expand Up @@ -240,21 +240,43 @@ function renumerarJugadores() {
}

// Mostrar u ocultar detalles de un jugador
function toggleDetails(button) {
const details = button.parentNode.nextElementSibling;
const icon = button.querySelector('.toggle-icon');

if (details.style.maxHeight === "0px") {
details.style.maxHeight = details.scrollHeight + "px";
details.style.paddingBottom = "5px";
icon.classList.add('rotate');
function rotateIcon(detailsContainer, icon) {
//wait for the animation to finish before removing the class
detailsContainer.addEventListener('transitionend', function() {
if (detailsContainer.style.maxHeight === "0px") {
if (icon) {
icon.classList.remove('rotate');
} else {
icon = detailsContainer.previousElementSibling.querySelector('.toggle-icon');
icon.classList.remove('rotate');
}
} else {
if (icon) {
icon.classList.add('rotate');
} else {
icon = detailsContainer.previousElementSibling.querySelector('.toggle-icon');
icon.classList.add('rotate');
}
}
});
}

function toggleDetails(element) {
const detailsContainer = element.parentNode.nextElementSibling;
const icon = element.querySelector('.toggle-icon');

if (detailsContainer.style.maxHeight === "0px") {
detailsContainer.style.maxHeight = detailsContainer.scrollHeight + "px";
detailsContainer.style.paddingBottom = "5px";
} else {
details.style.maxHeight = "0px";
details.style.paddingBottom = "0px";
icon.classList.remove('rotate');
detailsContainer.style.maxHeight = "0px";
detailsContainer.style.paddingBottom = "0px";
}

rotateIcon(detailsContainer, icon);
}


// Puntuar habilidades de los jugadores con estrellas
document.addEventListener('DOMContentLoaded', function() {
const starRatings = document.querySelectorAll('.star-rating');
Expand Down Expand Up @@ -481,14 +503,15 @@ function compartirEquipos(button) {
}
textoCompartir += '\n'; // Agrega una línea en blanco entre equipos
}
if (navigator.share) {
navigator.share({
title: 'Resultados de los Equipos - Opción ' + (parseInt(indice)),
text: textoCompartir
})
.then(() => console.log('Resultados compartidos exitosamente.'))
.catch((error) => console.error('Error al compartir:', error));
} else {
textoCompartir += 'Generado con: https://armar-equipos.up.railway.app'; // Agrega el enlace al sitio web
const shareData = {
title: 'Resultados de los Equipos - Opción ' + (parseInt(indice)),
text: textoCompartir
};
try {
navigator.share(shareData)
} catch (err) {
console.log(`Error: ${err}`);
// Opción alternativa para navegadores que no soportan Web Share API
alert('Tu navegador no soporta la función de compartir. Por favor, copia el texto manualmente.');
navigator.clipboard.writeText(textoCompartir)
Expand All @@ -504,13 +527,15 @@ function compartirEquipos(button) {
// Mostrar u ocultar detalles de los equipos
function toggleStats(button) {
const container = button.parentNode.nextElementSibling;
if (container.style.display === "none") {
const textSpan = button.querySelector('span');

if (container.style.display === "none" || container.style.display === "") {
container.style.display = "flex";
button.textContent = "Ocultar detalles";
textSpan.textContent = "Ocultar detalles";
createRadarChart(container);
} else {
container.style.display = "none";
button.textContent = "Mostrar detalles";
textSpan.textContent = "Mostrar detalles";
}
}

Expand Down
13 changes: 9 additions & 4 deletions templates/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<link rel="manifest" href="../static/favicon-v1.0/site.webmanifest">
<link rel="stylesheet" type="text/css" href="/static/css/styles-v1.0.0.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.6.0/css/all.min.css">
<script src="static/js/script-v1.1.js"></script>
<script src="/static/js/script-v1.0.3.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
</head>
<body>
Expand All @@ -29,7 +29,7 @@ <h1>Armar Equipos</h1>
<div class="player-header">
<input type="checkbox" name="selectedPlayers" value="{{ player.id }}">
<label>Jugador {{ loop.index }}:</label>
<input type="text" name="names" value="{{ player.name }}" required readonly>
<input type="text" name="names" value="{{ player.name }}" onclick="toggleDetails(this)" required readonly>
<button class="toggle-details" type="button" onclick="toggleDetails(this)">
<i class="fa-solid fa-angle-down toggle-icon"></i>
</button>
Expand Down Expand Up @@ -182,8 +182,13 @@ <h2>Equipo 2</h2>

<div class="stats-container">
<div class="button-container">
<button type="button" onclick="toggleStats(this)">Mostrar detalles</button>
<button type="button" id="shareButton{{ i // 2 + 1 }}" onclick="compartirEquipos(this)">Compartir equipos</button>
<button type="button" onclick="toggleStats(this)">
<i class="fas fa-chart-bar" style="padding-right: 5px;"></i>
<span>Mostrar detalles</span>
</button>
<button type="button" id="shareButton{{ i // 2 + 1 }}" onclick="compartirEquipos(this)">
<i class="fas fa-share" style="padding-right: 5px;"></i> Enviar equipos
</button>
</div>
<div class="content-container" style="display: none;">
<div class="table-container">
Expand Down
1 change: 1 addition & 0 deletions templates/login.html
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ <h1 class="text-2xl font-bold text-center">Iniciar sesión</h1>
class="grow"
placeholder="Contraseña"
name="password"
autocomplete="current-password"
required />
</label>
<br />
Expand Down
51 changes: 51 additions & 0 deletions templates/signup.html
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,16 @@ <h1 class="text-2xl font-bold text-center">Crear cuenta</h1>
class="grow"
placeholder="Contraseña"
name="password"
autocomplete="new-password"
required />
</label>
<ul class="text-sm list-disc pl-5 mt-2" id="password-requirements">
<li id="length-requirement" class="text-gray-600">Al menos 8 caracteres</li>
<li id="uppercase-requirement" class="text-gray-600">Una letra mayúscula</li>
<li id="lowercase-requirement" class="text-gray-600">Una letra minúscula</li>
<li id="number-requirement" class="text-gray-600">Un número</li>
<li id="special-char-requirement" class="text-gray-600 hidden">Un carácter especial (si tiene menos de 12 caracteres)</li>
</ul>
<br />
<button type="submit" class="btn btn-primary w-full">Crear</button>
</form>
Expand All @@ -74,4 +82,47 @@ <h1 class="text-2xl font-bold text-center">Crear cuenta</h1>
</div>
</div>
</body>
<script>
const passwordInput = document.querySelector('input[name="password"]');
const submitButton = document.querySelector('button[type="submit"]');
const lengthReq = document.getElementById('length-requirement');
const uppercaseReq = document.getElementById('uppercase-requirement');
const lowercaseReq = document.getElementById('lowercase-requirement');
const numberReq = document.getElementById('number-requirement');
const specialCharReq = document.getElementById('special-char-requirement');

passwordInput.addEventListener('input', function () {
const password = passwordInput.value;
const minLength = password.length >= 8;
const hasUppercase = /[A-Z]/.test(password);
const hasLowercase = /[a-z]/.test(password);
const hasNumber = /\d/.test(password);
const hasSpecialChar = /[!@#$%^&*(),.?":{}|<>]/.test(password);

lengthReq.classList.toggle('text-green-600', minLength);
lengthReq.classList.toggle('text-gray-600', !minLength);

uppercaseReq.classList.toggle('text-green-600', hasUppercase);
uppercaseReq.classList.toggle('text-gray-600', !hasUppercase);

lowercaseReq.classList.toggle('text-green-600', hasLowercase);
lowercaseReq.classList.toggle('text-gray-600', !hasLowercase);

numberReq.classList.toggle('text-green-600', hasNumber);
numberReq.classList.toggle('text-gray-600', !hasNumber);

const specialCharRequired = password.length < 12;
specialCharReq.classList.toggle('hidden', !specialCharRequired);
specialCharReq.classList.toggle('text-green-600', hasSpecialChar && specialCharRequired);
specialCharReq.classList.toggle('text-gray-600', !(hasSpecialChar && specialCharRequired));

let valid = minLength && hasUppercase && hasLowercase && hasNumber;

if (specialCharRequired) {
valid = valid && hasSpecialChar;
}

submitButton.disabled = !valid;
});
</script>
</html>

0 comments on commit b931012

Please sign in to comment.