securisation d'acces à la page
This commit is contained in:
parent
17d89c024d
commit
773cc71613
3 changed files with 286 additions and 96 deletions
|
|
@ -702,8 +702,13 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
const cv = new URLSearchParams(window.location.search).get('cv');
|
const cv = new URLSearchParams(window.location.search).get('cv');
|
||||||
if (cv) document.getElementById('backBtn').href = `index.html?cv=${cv}`;
|
const validCodes = ['f3b9c7a8d5e4b2d1c0a9b8d7', 'e2d1c0b9a8f7e6d5c4b3a2f1', 'a1b2c3d4e5f6a7b8c9d0e1f2'];
|
||||||
|
if (!cv || !validCodes.includes(cv)) {
|
||||||
|
window.location.href = 'index.html';
|
||||||
|
} else {
|
||||||
|
document.getElementById('backBtn').href = `index.html?cv=${cv}`;
|
||||||
if (typeof umami !== 'undefined') umami.track('ecosystem-view');
|
if (typeof umami !== 'undefined') umami.track('ecosystem-view');
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
184
index.html
184
index.html
|
|
@ -3485,8 +3485,187 @@
|
||||||
|
|
||||||
// Sélection du fichier JSON selon le paramètre ?cv=
|
// Sélection du fichier JSON selon le paramètre ?cv=
|
||||||
const cvParam = new URLSearchParams(window.location.search).get('cv');
|
const cvParam = new URLSearchParams(window.location.search).get('cv');
|
||||||
const cvAllowed = ['ux', 'dsi'];
|
|
||||||
const cvFile = cvAllowed.includes(cvParam) ? `cv-data-${cvParam}.json` : 'cv-data.json';
|
// Mapping des codes de 24 caractères vers les fichiers de CV correspondants
|
||||||
|
const cvMap = {
|
||||||
|
'f3b9c7a8d5e4b2d1c0a9b8d7': 'cv-data.json', // Version Générale (Directeur Conseil Service)
|
||||||
|
'e2d1c0b9a8f7e6d5c4b3a2f1': 'cv-data-ux.json', // Version UX & Digital Manager
|
||||||
|
'a1b2c3d4e5f6a7b8c9d0e1f2': 'cv-data-dsi.json' // Version Directeur SI & Transformation
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!cvParam || !cvMap[cvParam]) {
|
||||||
|
// Masquer l'écran de chargement
|
||||||
|
const ld = document.getElementById('loading');
|
||||||
|
if (ld) ld.remove();
|
||||||
|
|
||||||
|
// Masquer les contrôles globaux non pertinents pour l'écran de verrouillage
|
||||||
|
const burger = document.getElementById('burgerBtn');
|
||||||
|
if (burger) burger.style.display = 'none';
|
||||||
|
const readProgress = document.getElementById('read-progress');
|
||||||
|
if (readProgress) readProgress.style.display = 'none';
|
||||||
|
|
||||||
|
// Injecter le CSS pour la page privée
|
||||||
|
const style = document.createElement('style');
|
||||||
|
style.textContent = `
|
||||||
|
.private-container {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
min-height: 100vh;
|
||||||
|
background: #02050a;
|
||||||
|
color: #f4f7fb;
|
||||||
|
font-family: 'Inter', system-ui, -apple-system, sans-serif;
|
||||||
|
padding: 20px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
position: fixed;
|
||||||
|
inset: 0;
|
||||||
|
z-index: 9999;
|
||||||
|
}
|
||||||
|
.private-card {
|
||||||
|
background: rgba(7, 18, 29, 0.75);
|
||||||
|
backdrop-filter: blur(16px);
|
||||||
|
-webkit-backdrop-filter: blur(16px);
|
||||||
|
border: 1px solid rgba(0, 215, 255, 0.2);
|
||||||
|
border-radius: 16px;
|
||||||
|
padding: 40px 30px;
|
||||||
|
max-width: 440px;
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
box-shadow: 0 0 40px rgba(0, 215, 255, 0.08);
|
||||||
|
}
|
||||||
|
.lock-icon {
|
||||||
|
color: #00d8ff;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
animation: pulse-glow 3s infinite ease-in-out;
|
||||||
|
display: inline-flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
@keyframes pulse-glow {
|
||||||
|
0%, 100% {
|
||||||
|
transform: scale(1);
|
||||||
|
filter: drop-shadow(0 0 8px rgba(0, 216, 255, 0.4));
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
transform: scale(1.05);
|
||||||
|
filter: drop-shadow(0 0 20px rgba(0, 216, 255, 0.8));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.private-card h1 {
|
||||||
|
font-family: 'Orbitron', 'Arial Black', sans-serif;
|
||||||
|
font-size: 22px;
|
||||||
|
letter-spacing: 0.15em;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
color: #00d8ff;
|
||||||
|
text-shadow: 0 0 10px rgba(0, 216, 255, 0.3);
|
||||||
|
}
|
||||||
|
.private-card p {
|
||||||
|
color: #9aa8b8;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 1.6;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
.input-group {
|
||||||
|
position: relative;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
.private-card input {
|
||||||
|
width: 100%;
|
||||||
|
padding: 14px 16px;
|
||||||
|
background: rgba(2, 5, 10, 0.8);
|
||||||
|
border: 1px solid rgba(0, 215, 255, 0.15);
|
||||||
|
border-radius: 8px;
|
||||||
|
color: #fff;
|
||||||
|
font-family: 'Share Tech Mono', 'Courier New', monospace;
|
||||||
|
font-size: 15px;
|
||||||
|
letter-spacing: 0.05em;
|
||||||
|
text-align: center;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
.private-card input:focus {
|
||||||
|
outline: none;
|
||||||
|
border-color: #00d8ff;
|
||||||
|
box-shadow: 0 0 15px rgba(0, 216, 255, 0.25);
|
||||||
|
}
|
||||||
|
.private-card button {
|
||||||
|
width: 100%;
|
||||||
|
padding: 14px;
|
||||||
|
background: linear-gradient(135deg, #00d8ff 0%, #228cff 100%);
|
||||||
|
border: none;
|
||||||
|
border-radius: 8px;
|
||||||
|
color: #02050a;
|
||||||
|
font-family: 'Orbitron', sans-serif;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 700;
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
.private-card button:hover {
|
||||||
|
transform: translateY(-2px);
|
||||||
|
box-shadow: 0 5px 20px rgba(0, 216, 255, 0.4);
|
||||||
|
}
|
||||||
|
.private-card button:active {
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
.error-message {
|
||||||
|
color: #ff3c74;
|
||||||
|
font-size: 12px;
|
||||||
|
margin-top: 15px;
|
||||||
|
font-family: 'Share Tech Mono', monospace;
|
||||||
|
min-height: 18px;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
document.head.appendChild(style);
|
||||||
|
|
||||||
|
// Injecter le HTML de la page privée dans #app
|
||||||
|
const app = document.getElementById('app');
|
||||||
|
app.innerHTML = `
|
||||||
|
<div class="private-container">
|
||||||
|
<div class="private-card">
|
||||||
|
<div class="lock-icon">
|
||||||
|
<svg width="64" height="64" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||||
|
<rect x="3" y="11" width="18" height="11" rx="2" ry="2"></rect>
|
||||||
|
<path d="M7 11V7a5 5 0 0 1 10 0v4"></path>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<h1>PAGE PRIVÉE</h1>
|
||||||
|
<p>Ce curriculum vitæ est confidentiel. Veuillez saisir votre code d'accès de 24 caractères pour y accéder.</p>
|
||||||
|
<form id="accessForm">
|
||||||
|
<div class="input-group">
|
||||||
|
<input type="text" id="accessCode" placeholder="Code d'accès (24 caractères)" maxlength="24" autocomplete="off" required>
|
||||||
|
</div>
|
||||||
|
<button type="submit">VALIDER</button>
|
||||||
|
</form>
|
||||||
|
<div id="errorMessage" class="error-message"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
// Se focaliser sur le champ de saisie
|
||||||
|
const accessCodeInput = document.getElementById('accessCode');
|
||||||
|
if (accessCodeInput) accessCodeInput.focus();
|
||||||
|
|
||||||
|
// Écouter la soumission du formulaire
|
||||||
|
document.getElementById('accessForm').addEventListener('submit', (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
const code = accessCodeInput.value.trim();
|
||||||
|
if (cvMap[code]) {
|
||||||
|
// Rediriger avec le bon paramètre d'URL
|
||||||
|
window.location.search = `?cv=${code}`;
|
||||||
|
} else {
|
||||||
|
// Afficher le message d'erreur
|
||||||
|
const errEl = document.getElementById('errorMessage');
|
||||||
|
if (errEl) {
|
||||||
|
errEl.textContent = '❌ Code d\'accès invalide';
|
||||||
|
accessCodeInput.style.borderColor = '#ff3c74';
|
||||||
|
accessCodeInput.style.boxShadow = '0 0 15px rgba(255, 60, 116, 0.25)';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
const cvFile = cvMap[cvParam];
|
||||||
|
|
||||||
fetch(cvFile)
|
fetch(cvFile)
|
||||||
.then(r => {
|
.then(r => {
|
||||||
|
|
@ -3586,6 +3765,7 @@
|
||||||
</span>
|
</span>
|
||||||
</div>`;
|
</div>`;
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// ══════════════════════════════════════════════
|
// ══════════════════════════════════════════════
|
||||||
// TÉLÉCHARGEMENT PDF
|
// TÉLÉCHARGEMENT PDF
|
||||||
|
|
|
||||||
|
|
@ -980,7 +980,12 @@
|
||||||
</main>
|
</main>
|
||||||
<script>
|
<script>
|
||||||
const cv = new URLSearchParams(window.location.search).get('cv');
|
const cv = new URLSearchParams(window.location.search).get('cv');
|
||||||
if (cv) document.getElementById('backBtn').href = `index.html?cv=${cv}`;
|
const validCodes = ['f3b9c7a8d5e4b2d1c0a9b8d7', 'e2d1c0b9a8f7e6d5c4b3a2f1', 'a1b2c3d4e5f6a7b8c9d0e1f2'];
|
||||||
|
if (!cv || !validCodes.includes(cv)) {
|
||||||
|
window.location.href = 'index.html';
|
||||||
|
} else {
|
||||||
|
document.getElementById('backBtn').href = `index.html?cv=${cv}`;
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue