Merge pull request 'Sécurité : purge désactivée par défaut, rôle lecture seule, en-têtes et limites TCP' (#16) from feat/securite into main
This commit was merged in pull request #16.
This commit is contained in:
commit
2f84bc8deb
13 files changed
+543
-50
No files matched your search
+30
-2
@@ -132,6 +132,10 @@ const I18N = {
|
||||
purgeForbidden: 'Purging is disabled on this server (ALLOW_PURGE=false).',
|
||||
err_purge_unavailable: 'VictoriaLogs refuses deletions: start it with -delete.enable (see docker-compose.yml)',
|
||||
err_purge_forbidden: 'Purging is disabled on this server (ALLOW_PURGE=false)',
|
||||
err_read_only: 'Read-only account: changes are reserved to administrators',
|
||||
err_cross_site: 'Request refused: it comes from another site',
|
||||
authOff: 'No authentication: anyone who can reach this page can read the logs and change the settings. Set AUTH_USER / AUTH_PASS or AUTH_MODE=oidc.',
|
||||
readOnlyNote: 'Read-only account: these settings can only be changed by an administrator.',
|
||||
err_purge_confirm: 'Type PURGE to confirm',
|
||||
liveZoomed: 'Live view is not available on a zoomed range',
|
||||
connZoom: 'live paused (zoom)',
|
||||
@@ -284,6 +288,10 @@ const I18N = {
|
||||
purgeForbidden: 'La purge est désactivée sur ce serveur (ALLOW_PURGE=false).',
|
||||
err_purge_unavailable: 'VictoriaLogs refuse les suppressions : lancez-le avec -delete.enable (voir docker-compose.yml)',
|
||||
err_purge_forbidden: 'La purge est désactivée sur ce serveur (ALLOW_PURGE=false)',
|
||||
err_read_only: 'Compte en lecture seule : les modifications sont réservées aux administrateurs',
|
||||
err_cross_site: 'Requête refusée : elle vient d\'un autre site',
|
||||
authOff: 'Aucune authentification : toute personne qui atteint cette page peut lire les logs et changer les réglages. Définissez AUTH_USER / AUTH_PASS ou AUTH_MODE=oidc.',
|
||||
readOnlyNote: 'Compte en lecture seule : seul un administrateur peut modifier ces réglages.',
|
||||
err_purge_confirm: 'Tapez PURGE pour confirmer',
|
||||
liveZoomed: 'Le direct n\'est pas disponible sur une plage zoomée',
|
||||
connZoom: 'direct en pause (zoom)',
|
||||
@@ -2215,14 +2223,34 @@ $('#settingsDlg').addEventListener('click', (ev) => { if (ev.target === ev.curre
|
||||
applyLogFont(store.get('logFont', 'system'));
|
||||
applyLogSize(store.get('logSize', 'medium'));
|
||||
applyLogDensity(store.get('logDensity', 'normal'));
|
||||
$('#authWarnClose').addEventListener('click', () => {
|
||||
$('#authWarn').hidden = true;
|
||||
store.set('authWarnHidden', '1');
|
||||
});
|
||||
|
||||
applyLang();
|
||||
$('#range').value = store.get('range', '1h');
|
||||
if (!$('#range').value) $('#range').value = '1h';
|
||||
$('#severity').value = store.get('severity', '');
|
||||
|
||||
// With a login (local or OIDC), show who is logged in and the log out button.
|
||||
// Without a login, warn that the UI is open to everyone. With a login (local or OIDC),
|
||||
// show who is logged in and the log out button, and lock the admin settings of a
|
||||
// read-only account.
|
||||
fetch('/auth/me').then((res) => (res.ok ? res.json() : null)).then((me) => {
|
||||
if (!me || !me.user) return;
|
||||
if (!me) return;
|
||||
if (me.mode === 'none' && store.get('authWarnHidden') !== '1') $('#authWarn').hidden = false;
|
||||
if (me.role === 'viewer') {
|
||||
document.body.classList.add('read-only');
|
||||
for (const p of document.querySelectorAll('[data-panel="filters"], [data-panel="sources"], [data-panel="data"]')) {
|
||||
for (const s of p.querySelectorAll('.set-section')) s.inert = true;
|
||||
const note = document.createElement('p');
|
||||
note.className = 'ro-note';
|
||||
note.dataset.i18n = 'readOnlyNote';
|
||||
note.textContent = t('readOnlyNote');
|
||||
p.prepend(note);
|
||||
}
|
||||
}
|
||||
if (!me.user) return;
|
||||
const btn = $('#logoutBtn');
|
||||
btn.hidden = false;
|
||||
btn.dataset.user = me.user;
|
||||
|
||||
@@ -97,6 +97,12 @@
|
||||
|
||||
<section id="histo" class="histo" data-i18n-aria="histoAria" hidden></section>
|
||||
|
||||
<div id="authWarn" class="auth-warn" role="status" hidden>
|
||||
<span data-i18n="authOff"></span>
|
||||
<button id="authWarnClose" class="icon-btn" type="button" data-i18n-aria="close">
|
||||
<svg viewBox="0 0 24 24"><path d="M6 6l12 12M18 6 6 18"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
<div id="error" class="error-banner" hidden></div>
|
||||
<button id="newPill" class="pill" type="button" hidden></button>
|
||||
|
||||
|
||||
+17
-1
@@ -433,6 +433,22 @@ mark.hit { background: var(--hit); color: inherit; border-radius: 3px; padding:
|
||||
font-family: var(--mono); font-size: 12.5px; white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.auth-warn {
|
||||
display: flex; align-items: center; gap: 10px;
|
||||
margin: 6px 20px 0; padding: 6px 8px 6px 14px;
|
||||
border: 1px solid color-mix(in srgb, var(--sev-warning) 45%, transparent);
|
||||
background: color-mix(in srgb, var(--sev-warning) 12%, transparent);
|
||||
color: var(--text); border-radius: var(--radius); font-size: 12.5px;
|
||||
}
|
||||
.auth-warn[hidden] { display: none; }
|
||||
.auth-warn span { flex: 1; }
|
||||
.auth-warn .icon-btn { width: 26px; height: 26px; flex: none; }
|
||||
.ro-note {
|
||||
margin: 0 0 12px; padding: 8px 12px; border-radius: var(--radius); font-size: 12.5px;
|
||||
background: color-mix(in srgb, var(--accent) 10%, transparent); color: var(--text);
|
||||
}
|
||||
.read-only .set-panel .set-section[inert] { opacity: .55; }
|
||||
|
||||
.pill {
|
||||
position: fixed; top: 70px; left: 50%; transform: translateX(-50%); z-index: 30;
|
||||
border: 0; border-radius: 999px; padding: 7px 16px;
|
||||
@@ -663,7 +679,7 @@ input.switch:focus-visible { outline: 2px solid var(--accent); outline-offset: 2
|
||||
#count { flex: 1 1 50%; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
||||
.histo { padding: 0 16px 6px; }
|
||||
.h-leg { display: none; }
|
||||
.list, .error-banner, .table { margin-left: 16px; margin-right: 16px; }
|
||||
.list, .error-banner, .auth-warn, .table { margin-left: 16px; margin-right: 16px; }
|
||||
/* Phones: no columns, two lines per log (layout below); the widths do not apply */
|
||||
.table { display: block; }
|
||||
.table .list { display: block; margin: 0; }
|
||||
|
||||
Reference in new issue
Block a user