feat(auth): écran de connexion + session signée (le Basic reste pour les scripts)

- /login professionnel, cookie HMAC 7 jours, next local seulement,
  CSRF double-submit réutilisé, /logout réel + lien Sortir.
- Middleware : session OU Basic ; navigateurs redirigés vers
  /login, API en 401 JSON ; /static et /login publics.
This commit is contained in:
Spark
2026-10-14 08:02:49 -04:00
parent 0bdde28b79
commit 319619d200
5 changed files with 290 additions and 36 deletions
+71 -4
View File
@@ -1297,11 +1297,22 @@ body.nav-closed-outils [data-group="outils"] .side-chevron { transform: rotate(-
display: flex; align-items: center; justify-content: space-between; gap: 8px;
}
.side-collapse {
display: flex; align-items: center; gap: 8px; cursor: pointer;
background: transparent; border: 1px solid var(--border); border-radius: 9px;
color: var(--text-2); padding: 6px 10px; font-size: 0.85rem; white-space: nowrap;
/* Depuis la 0.22.0 : bouton icône seule dans l'en-tête de la
barre, à droite de la recherche (même gabarit qu'elle). */
flex-shrink: 0;
width: 38px; height: 38px; border-radius: 10px; cursor: pointer;
display: inline-flex; align-items: center; justify-content: center;
background: var(--surface-2); color: var(--text-2); font-size: 1.02rem;
border: 1px solid var(--border);
transition: border-color 0.15s, color 0.15s, transform 0.15s;
}
.side-collapse:hover { color: var(--text); }
.side-collapse:hover {
color: var(--text); border-color: var(--accent, #58a6ff);
transform: translateY(-1px);
}
.side-fresh { color: var(--text-3); font-size: 0.76rem; white-space: nowrap; }
.side-logout { color: var(--text-3); font-size: 0.85rem; white-space: nowrap; }
.side-logout:hover { color: var(--text); text-decoration: none; }
.side-collapse-ico { display: inline-block; transition: transform 0.18s ease; }
body.sidebar-collapsed .side-collapse-ico { transform: rotate(180deg); }
.side-version { color: var(--text-3); font-size: 0.8rem; }
@@ -1541,3 +1552,59 @@ a.ms-title:hover { text-decoration: underline; }
border-radius: 5px; padding: 0 5px; background: var(--surface);
}
.capture-form input.repo-unknown { border-color: #f0a35e; }
/* ── Écran de connexion (0.22.0) ────────────── */
.login-body {
min-height: 100dvh; margin: 0;
display: flex; align-items: center; justify-content: center;
background:
radial-gradient(640px 420px at 18% 12%, rgba(124, 92, 252, 0.20), transparent 62%),
radial-gradient(560px 380px at 84% 88%, rgba(91, 138, 247, 0.16), transparent 60%),
var(--bg, #0a0f16);
padding: 24px 16px;
}
.login-wrap { width: 100%; max-width: 400px; }
.login-card {
background: var(--surface, #10151f);
border: 1px solid var(--border);
border-radius: 18px;
padding: 34px 32px 26px;
box-shadow: 0 24px 60px rgba(0, 0, 0, 0.5);
}
.login-brand { text-align: center; margin-bottom: 22px; }
.login-mark {
display: inline-flex; align-items: center; justify-content: center;
width: 56px; height: 56px; border-radius: 16px; font-size: 1.7rem;
background: linear-gradient(135deg, rgba(124,92,252,.35), rgba(91,138,247,.25));
border: 1px solid var(--border);
}
.login-brand h1 {
margin: 12px 0 4px; font-size: 1.55rem; font-weight: 700;
background: linear-gradient(120deg, #a78bfa, #7dd3fc);
-webkit-background-clip: text; background-clip: text;
-webkit-text-fill-color: transparent;
}
.login-sub { margin: 0; color: var(--text-3, #8b94a5); font-size: 0.9rem; }
.login-error {
margin: 0 0 14px; padding: 10px 12px; border-radius: 10px;
background: rgba(240, 120, 90, 0.12); border: 1px solid rgba(240, 120, 90, 0.45);
color: #f5a58c; font-size: 0.9rem;
}
.login-form { display: flex; flex-direction: column; gap: 14px; }
.login-form label { display: flex; flex-direction: column; gap: 6px; font-weight: 600; font-size: 0.92rem; }
.login-form input {
padding: 11px 13px; border: 1px solid var(--border); border-radius: 10px;
background: var(--bg-2, #0d1220); color: var(--text-1, #e6ebf2);
font: inherit; font-weight: 400;
}
.login-form input:focus { outline: 2px solid rgba(124, 92, 252, 0.55); outline-offset: 0; border-color: transparent; }
.login-submit {
margin-top: 4px; padding: 12px 18px; cursor: pointer;
background: linear-gradient(135deg, var(--accent, #7c5cfc), var(--accent-2, #5b8af7));
color: #fff; border: none; border-radius: 10px;
font: inherit; font-weight: 600; font-size: 1rem;
transition: filter 0.15s, transform 0.1s;
}
.login-submit:hover { filter: brightness(1.12); }
.login-submit:active { transform: scale(0.98); }
.login-foot { margin: 18px 0 0; text-align: center; color: var(--text-3, #8b94a5); font-size: 0.8rem; }