ci: fix pipeline, update readme and anonymize ZT references
This commit is contained in:
+249
@@ -0,0 +1,249 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover">
|
||||
<title>Hydr'Hacked — Installation</title>
|
||||
|
||||
<link rel="manifest" href="/manifest.json">
|
||||
<meta name="theme-color" content="#1a1a1a">
|
||||
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
||||
<meta name="apple-mobile-web-app-title" content="Hydr'Hacked">
|
||||
<link rel="apple-touch-icon" href="/images/icone-192.png">
|
||||
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="/style.css">
|
||||
<script src="/lucide.min.js"></script>
|
||||
<script src="/app.auth.js"></script>
|
||||
<style>
|
||||
.setup-container {
|
||||
min-height: 100vh;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 2rem;
|
||||
background: var(--bg-main);
|
||||
}
|
||||
.setup-box {
|
||||
background: var(--bg-card);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 16px;
|
||||
padding: 2.5rem;
|
||||
width: 100%;
|
||||
max-width: 420px;
|
||||
box-shadow: 0 8px 32px rgba(0,0,0,0.4);
|
||||
}
|
||||
.setup-logo {
|
||||
text-align: center;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
.setup-logo img {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
.setup-logo h1 {
|
||||
font-size: 1.8rem;
|
||||
font-weight: 700;
|
||||
color: white;
|
||||
margin: 0;
|
||||
}
|
||||
.setup-logo p {
|
||||
color: var(--text-sec);
|
||||
font-size: 0.9rem;
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
.setup-badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
background: rgba(229, 9, 20, 0.15);
|
||||
color: var(--primary);
|
||||
font-size: 0.75rem;
|
||||
font-weight: 600;
|
||||
padding: 4px 12px;
|
||||
border-radius: 20px;
|
||||
margin-bottom: 1.5rem;
|
||||
border: 1px solid rgba(229, 9, 20, 0.3);
|
||||
}
|
||||
.setup-form { display: flex; flex-direction: column; gap: 1rem; }
|
||||
.setup-form label {
|
||||
display: block;
|
||||
font-size: 0.8rem;
|
||||
font-weight: 600;
|
||||
color: var(--text-sec);
|
||||
margin-bottom: 6px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
.setup-form input {
|
||||
width: 100%;
|
||||
padding: 12px 16px;
|
||||
background: var(--bg-main);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 10px;
|
||||
color: white;
|
||||
font-size: 1rem;
|
||||
transition: border-color 0.2s, box-shadow 0.2s;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.setup-form input:focus {
|
||||
outline: none;
|
||||
border-color: var(--primary);
|
||||
box-shadow: 0 0 0 3px rgba(229, 9, 20, 0.15);
|
||||
}
|
||||
.setup-form button[type="submit"] {
|
||||
width: 100%;
|
||||
padding: 14px;
|
||||
background: var(--primary);
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 10px;
|
||||
font-size: 1rem;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
transition: background 0.2s, transform 0.1s;
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
.setup-form button[type="submit"]:hover { background: #c40812; }
|
||||
.setup-form button[type="submit"]:active { transform: scale(0.98); }
|
||||
.setup-form button[type="submit"]:disabled {
|
||||
background: #4b5563;
|
||||
color: #9ca3af;
|
||||
cursor: not-allowed;
|
||||
transform: none;
|
||||
}
|
||||
|
||||
.setup-error {
|
||||
background: rgba(239, 68, 68, 0.1);
|
||||
border: 1px solid rgba(239, 68, 68, 0.3);
|
||||
color: #ef4444;
|
||||
padding: 10px 14px;
|
||||
border-radius: 8px;
|
||||
font-size: 0.85rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="setup-container">
|
||||
<div class="setup-box">
|
||||
<div class="setup-logo">
|
||||
<img src="/images/logo_transparent.png" alt="Logo">
|
||||
<h1>Hydr'Hacked</h1>
|
||||
<p>Configuration initiale</p>
|
||||
</div>
|
||||
|
||||
<div style="text-align: center;">
|
||||
<span class="setup-badge">
|
||||
<i data-lucide="shield" style="width: 14px; height: 14px;"></i>
|
||||
Création du compte administrateur
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<% if (error) { %>
|
||||
<div class="setup-error" style="margin-bottom: 1rem;">
|
||||
<%= error %>
|
||||
</div>
|
||||
<% } %>
|
||||
|
||||
<div id="setup-client-error" class="setup-error" style="margin-bottom: 1rem; display: none;"></div>
|
||||
|
||||
<form class="setup-form" id="setup-form" action="/setup" method="POST">
|
||||
<div>
|
||||
<label for="setup-username">Nom d'utilisateur</label>
|
||||
<input type="text" id="setup-username" name="username" placeholder="admin" required
|
||||
minlength="3" maxlength="32" pattern="[a-zA-Z0-9_.\-]+" autofocus autocomplete="username">
|
||||
</div>
|
||||
|
||||
<div class="password-requirements" style="text-align: left;">
|
||||
<strong>Exigences du mot de passe :</strong>
|
||||
<ul style="margin-top: 8px;">
|
||||
<li id="req-length" class="invalid" style="display: flex; align-items: center; gap: 6px; font-size: 0.8rem;"><span class="icon-holder"><i data-lucide="x" style="width:14px;height:14px;"></i></span> Au moins 8 caractères</li>
|
||||
<li id="req-upper" class="invalid" style="display: flex; align-items: center; gap: 6px; font-size: 0.8rem;"><span class="icon-holder"><i data-lucide="x" style="width:14px;height:14px;"></i></span> Au moins une majuscule (A-Z)</li>
|
||||
<li id="req-number" class="invalid" style="display: flex; align-items: center; gap: 6px; font-size: 0.8rem;"><span class="icon-holder"><i data-lucide="x" style="width:14px;height:14px;"></i></span> Au moins un chiffre (0-9)</li>
|
||||
<li id="req-special" class="invalid" style="display: flex; align-items: center; gap: 6px; font-size: 0.8rem;"><span class="icon-holder"><i data-lucide="x" style="width:14px;height:14px;"></i></span> Au moins un caractère spécial</li>
|
||||
<li id="req-match" class="invalid" style="display: flex; align-items: center; gap: 6px; font-size: 0.8rem;"><span class="icon-holder"><i data-lucide="x" style="width:14px;height:14px;"></i></span> Mots de passe identiques</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="setup-password">Mot de passe</label>
|
||||
<div class="password-container">
|
||||
<input type="password" id="setup-password" name="password" placeholder="Faut sécuriser le compte !"
|
||||
required minlength="8" maxlength="128" autocomplete="new-password">
|
||||
<button type="button" class="toggle-password" tabindex="-1">
|
||||
<i data-lucide="eye" class="eye-icon"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<label for="setup-confirm">Confirmer le mot de passe</label>
|
||||
<div class="password-container">
|
||||
<input type="password" id="setup-confirm" name="confirmPassword" placeholder="Retapez le mot de passe"
|
||||
required minlength="8" maxlength="128" autocomplete="new-password">
|
||||
<button type="button" class="toggle-password" tabindex="-1">
|
||||
<i data-lucide="eye" class="eye-icon"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" id="setup-submit-btn" disabled>Créer le compte administrateur</button>
|
||||
<div style="text-align: center; margin-top: 3rem; margin-bottom: 1rem;">
|
||||
<p style="font-size: 0.85rem; color: var(--text-sec); display: inline-flex; align-items: center; gap: 6px; background: var(--bg-card); padding: 6px 12px; border-radius: 20px; border: 1px solid var(--border);">
|
||||
<i data-lucide="info" style="width: 14px; height: 14px;"></i>
|
||||
Hydr'Hacked v1.4.8
|
||||
</p>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
if (typeof lucide !== 'undefined') lucide.createIcons();
|
||||
|
||||
// Initialize password visibility toggles using the shared library
|
||||
if (window.AuthHelpers) {
|
||||
AuthHelpers.initPasswordToggles();
|
||||
}
|
||||
|
||||
const passwordInput = document.getElementById('setup-password');
|
||||
const confirmInput = document.getElementById('setup-confirm');
|
||||
const submitBtn = document.getElementById('setup-submit-btn');
|
||||
|
||||
const validateSetupInputs = () => {
|
||||
if (!window.AuthHelpers) return;
|
||||
const val = passwordInput.value;
|
||||
const confirmVal = confirmInput.value;
|
||||
|
||||
// Use the shared library validation logic
|
||||
const statuses = AuthHelpers.validateComplexity(val, confirmVal);
|
||||
|
||||
// Use the shared library UI updater
|
||||
AuthHelpers.updateRequirementsUI(document.getElementById('setup-form'), statuses);
|
||||
|
||||
submitBtn.disabled = !statuses.allValid;
|
||||
};
|
||||
|
||||
passwordInput.addEventListener('input', validateSetupInputs);
|
||||
confirmInput.addEventListener('input', validateSetupInputs);
|
||||
|
||||
document.getElementById('setup-form').addEventListener('submit', function(e) {
|
||||
const password = passwordInput.value;
|
||||
const confirm = confirmInput.value;
|
||||
const errorDiv = document.getElementById('setup-client-error');
|
||||
|
||||
errorDiv.style.display = 'none';
|
||||
|
||||
if (password !== confirm) {
|
||||
e.preventDefault();
|
||||
errorDiv.textContent = 'Les mots de passe ne correspondent pas.';
|
||||
errorDiv.style.display = 'block';
|
||||
return;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user