Version initiale — carte des établissements scolaires

Carte Leaflet (annuaire Éducation nationale) + API PHP/MySQL :
fiche établissement (effectifs, IPS, population INSEE, DPE ADEME),
GED documents/photos, commentaires par groupe, gestion utilisateurs
et politique de mots de passe. Imports opendata (effectifs, IPS,
population, DPE, IRIS).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-03 21:35:41 +02:00
commit 5633969d98
40 changed files with 7242 additions and 0 deletions
+61
View File
@@ -0,0 +1,61 @@
/* Politique de mot de passe — validation + jauge côté client.
* Miroir de password_policy_check() (api/db.php) : ≥ 8 caractères et au moins
* 3 types parmi minuscule / majuscule / chiffre / caractère spécial.
* Expose window.PWPolicy = { check, attach }.
*/
(function () {
'use strict';
const MIN_LEN = 8;
const MIN_CLASSES = 3;
function classes(pwd) {
return {
lower: /[a-z]/.test(pwd),
upper: /[A-Z]/.test(pwd),
digit: /[0-9]/.test(pwd),
special: /[^A-Za-z0-9]/.test(pwd),
};
}
function check(pwd) {
pwd = pwd || '';
const c = classes(pwd);
const nbClasses = (c.lower ? 1 : 0) + (c.upper ? 1 : 0) + (c.digit ? 1 : 0) + (c.special ? 1 : 0);
const lenOk = pwd.length >= MIN_LEN;
const classesOk = nbClasses >= MIN_CLASSES;
const unmet = [];
if (!lenOk) unmet.push(`au moins ${MIN_LEN} caractères`);
if (!classesOk) unmet.push(`au moins ${MIN_CLASSES} types (minuscule, majuscule, chiffre, spécial)`);
// Score 0..4 pour la jauge.
let score = 0;
if (lenOk) score++;
if (pwd.length >= 12) score++;
score += Math.max(0, nbClasses - 1);
score = Math.min(4, score);
return { ok: lenOk && classesOk, unmet, score, lenOk, classesOk, nbClasses };
}
const LABELS = ['Très faible', 'Faible', 'Moyen', 'Bon', 'Fort'];
function attach(input, meter) {
if (!input || !meter) return;
const render = () => {
const r = check(input.value);
if (!input.value) { meter.innerHTML = ''; return; }
const pct = (r.score / 4) * 100;
const lvl = r.ok ? Math.max(2, r.score) : Math.min(1, r.score);
meter.innerHTML =
`<div class="pw-bar"><span class="pw-bar-fill lvl-${lvl}" style="width:${pct}%"></span></div>
<div class="pw-label">${r.ok ? '✓ ' : ''}${LABELS[r.score]}</div>
<ul class="pw-crit">
<li class="${r.lenOk ? 'ok' : 'ko'}">≥ ${MIN_LEN} caractères</li>
<li class="${r.classesOk ? 'ok' : 'ko'}">≥ ${MIN_CLASSES} types parmi minuscule / majuscule / chiffre / spécial</li>
</ul>`;
};
input.addEventListener('input', render);
render();
}
window.PWPolicy = { check, attach };
})();