server : API (état, dry-run, apply avec empreinte et confirmation SDN, journal, paramètres), page de connexion
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015a8P6WMRPeqdpd5VCh6jAy
This commit is contained in:
1 parent
3aae9ce925
commit
010034b988
7 files changed
+1014
No files matched your search
@@ -0,0 +1,67 @@
|
||||
// Login page: language, theme, local form and/or OIDC button (from /auth/config).
|
||||
(function () {
|
||||
var I18N = {
|
||||
fr: { intro: 'Synchronisation de configuration Proxmox VE', user: 'Utilisateur', pass: 'Mot de passe',
|
||||
submit: 'Se connecter', sso: 'Se connecter avec le SSO', or: 'ou',
|
||||
error: 'Utilisateur ou mot de passe incorrect.', theme: 'Thème clair / sombre',
|
||||
demo: 'Mode démo : comptes {a}, {o} et {l}, mot de passe {p}.' },
|
||||
en: { intro: 'Proxmox VE configuration synchronization', user: 'User', pass: 'Password',
|
||||
submit: 'Sign in', sso: 'Sign in with SSO', or: 'or',
|
||||
error: 'Wrong user or password.', theme: 'Light / dark theme',
|
||||
demo: 'Demo mode: accounts {a}, {o} and {l}, password {p}.' },
|
||||
};
|
||||
function get(k) { try { return localStorage.getItem('confsync.' + k); } catch (e) { return null; } }
|
||||
function set(k, v) { try { localStorage.setItem('confsync.' + k, v); } catch (e) {} }
|
||||
var lang = get('lang');
|
||||
if (!I18N[lang]) lang = /^en\b/i.test(navigator.language || '') ? 'en' : 'fr';
|
||||
var cfg = { local: true, oidc: false, demo: false };
|
||||
|
||||
function el(id) { return document.getElementById(id); }
|
||||
function code(s) { var c = document.createElement('code'); c.textContent = s; return c; }
|
||||
function applyLang() {
|
||||
var d = I18N[lang];
|
||||
document.documentElement.lang = lang;
|
||||
document.querySelectorAll('[data-i18n]').forEach(function (e) { e.textContent = d[e.dataset.i18n]; });
|
||||
document.querySelectorAll('[data-i18n-title]').forEach(function (e) { e.title = d[e.dataset.i18nTitle]; });
|
||||
document.querySelectorAll('[data-i18n-aria]').forEach(function (e) { e.setAttribute('aria-label', d[e.dataset.i18nAria]); });
|
||||
document.querySelectorAll('#langSwitch [data-lang]').forEach(function (b) { b.setAttribute('aria-checked', String(b.dataset.lang === lang)); });
|
||||
var h = el('demoHint');
|
||||
h.textContent = '';
|
||||
if (cfg.demo) {
|
||||
// "{a}" placeholders become <code> elements, never HTML from a string
|
||||
d.demo.split(/(\{[aolp]\})/).forEach(function (part) {
|
||||
var v = { '{a}': 'admin', '{o}': 'operateur', '{l}': 'lecteur', '{p}': 'confsync-demo' }[part];
|
||||
h.appendChild(v ? code(v) : document.createTextNode(part));
|
||||
});
|
||||
}
|
||||
}
|
||||
document.querySelectorAll('#langSwitch [data-lang]').forEach(function (b) {
|
||||
b.addEventListener('click', function () { lang = b.dataset.lang; set('lang', lang); applyLang(); });
|
||||
});
|
||||
el('themeBtn').addEventListener('click', function () {
|
||||
var root = document.documentElement;
|
||||
var dark = root.dataset.theme ? root.dataset.theme === 'dark' : matchMedia('(prefers-color-scheme: dark)').matches;
|
||||
root.dataset.theme = dark ? 'light' : 'dark';
|
||||
set('theme', root.dataset.theme);
|
||||
});
|
||||
|
||||
var q = new URLSearchParams(location.search);
|
||||
var ret = q.get('r') || '/';
|
||||
el('ret').value = ret;
|
||||
el('err').hidden = q.get('e') !== '1';
|
||||
el('ssoBtn').href = 'auth/oidc?r=' + encodeURIComponent(ret);
|
||||
|
||||
function show() {
|
||||
el('localForm').hidden = !cfg.local;
|
||||
el('ssoBtn').hidden = !cfg.oidc;
|
||||
el('sep').hidden = !(cfg.local && cfg.oidc);
|
||||
el('submitBtn').className = cfg.oidc ? 'btn' : 'btn primary';
|
||||
el('demoHint').hidden = !cfg.demo;
|
||||
applyLang();
|
||||
}
|
||||
show();
|
||||
fetch('auth/config', { headers: { Accept: 'application/json' } })
|
||||
.then(function (r) { return r.json(); })
|
||||
.then(function (c) { cfg = c; show(); })
|
||||
.catch(function () {});
|
||||
})();
|
||||
Reference in new issue
Block a user