diff --git a/app/templates/admin/create_user.html b/app/templates/admin/create_user.html index 4bcfc74..45f0b95 100644 --- a/app/templates/admin/create_user.html +++ b/app/templates/admin/create_user.html @@ -2,6 +2,29 @@ {% block title %}Create User{% endblock %} {% block page_title %}User Management{% endblock %} +{% block head %} + +{% endblock %} + {% block content %}
@@ -127,6 +150,26 @@
+ + +
@@ -160,18 +203,52 @@ function togglePw(fieldId, iconId) { } } -// ── Password strength indicator ─────────────────────────────────────────────── +// ── Password strength + rule checklist ──────────────────────────────────────── +// Mirrors server-side validate_password() rules in validation_service.py. +// Any change to the server rules must be reflected here too. +const PW_RULES = { + len : pw => pw.length >= 8, + upper : pw => /[A-Z]/.test(pw), + digit : pw => /\d/.test(pw), + special: pw => /[!@#$%^&*()\-_=+\[\]{};:'",.<>?/\\|`~]/.test(pw), +}; + +function setPwRule(id, met) { + const el = document.getElementById('pw-rule-' + id); + if (!el) return; + el.className = 'pw-rule ' + (met ? 'met' : 'unmet'); + el.querySelector('.ri').innerHTML = met + ? '' + : ''; +} + document.getElementById('pw-field').addEventListener('input', function () { const val = this.value; - let score = 0; - if (val.length >= 8) score++; - if (val.length >= 12) score++; - if (/[A-Z]/.test(val) && /[a-z]/.test(val))score++; - if (/[0-9]/.test(val)) score++; - if (/[^A-Za-z0-9]/.test(val)) score++; const bar = document.getElementById('pw-strength-bar'); const label = document.getElementById('pw-strength-label'); + const rules = document.getElementById('pw-rules-box'); + + if (val.length === 0) { + bar.style.width = '0%'; + label.textContent = ''; + rules.style.display = 'none'; + return; + } + + rules.style.display = 'grid'; + setPwRule('len', PW_RULES.len(val)); + setPwRule('upper', PW_RULES.upper(val)); + setPwRule('digit', PW_RULES.digit(val)); + setPwRule('special', PW_RULES.special(val)); + + let score = 0; + if (PW_RULES.len(val)) score++; + if (PW_RULES.upper(val)) score++; + if (PW_RULES.digit(val)) score++; + if (PW_RULES.special(val)) score++; + if (val.length >= 16) score++; // bonus for extra length + const levels = [ { pct: '20%', bg: '#dc2626', text: 'Very weak' }, { pct: '40%', bg: '#d97706', text: 'Weak' }, @@ -179,11 +256,6 @@ document.getElementById('pw-field').addEventListener('input', function () { { pct: '80%', bg: '#16a34a', text: 'Strong' }, { pct: '100%', bg: '#059669', text: 'Very strong' }, ]; - if (val.length === 0) { - bar.style.width = '0%'; - label.textContent = ''; - return; - } const lvl = levels[Math.min(score - 1, 4)] || levels[0]; bar.style.width = lvl.pct; bar.style.background = lvl.bg; diff --git a/app/templates/admin/edit_user.html b/app/templates/admin/edit_user.html index 7529d83..cac89ad 100644 --- a/app/templates/admin/edit_user.html +++ b/app/templates/admin/edit_user.html @@ -2,6 +2,29 @@ {% block title %}Edit User{% endblock %} {% block page_title %}Edit User{% endblock %} +{% block head %} + +{% endblock %} + {% block content %}
@@ -50,6 +73,33 @@
+
+ +
+
+
+
+ + + +
@@ -64,6 +114,67 @@ {% block scripts %}