v0.1.4
This commit is contained in:
1 parent
19dfc51360
commit
b6e8ddb9c7
31 files changed
+1080
-32
No files matched your search
+40
-5
@@ -203,6 +203,7 @@
|
||||
['users', T('Skrzynki', 'Mailboxes')],
|
||||
['backends', T('Backendy', 'Backends')],
|
||||
['activesync', 'ActiveSync'],
|
||||
['autodiscover', 'Autodiscover'],
|
||||
['policies', T('Polityki', 'Policies')],
|
||||
['security', T('Bezpieczeństwo', 'Security')],
|
||||
['logs', T('Logi i audyt', 'Logs & audit')],
|
||||
@@ -645,7 +646,7 @@
|
||||
['carddav.include_regex', 'Include regex', 'text'], ['carddav.exclude_regex', 'Exclude regex', 'text'], ['carddav.timeout_secs', 'Timeout (s)', 'number'],
|
||||
], testBlock('carddav')), { bind: bindTests });
|
||||
|
||||
PAGES.activesync = (v) => settingsPage(v, 'PROTOCOL', 'ActiveSync', T('Logowanie, protokół, synchronizacja, push i Autodiscover.', 'Login, protocol, synchronisation, push and Autodiscover.'), (s) =>
|
||||
PAGES.activesync = (v) => settingsPage(v, 'PROTOCOL', 'ActiveSync', T('Logowanie, protokół, synchronizacja i push.', 'Login, protocol, synchronisation and push.'), (s) =>
|
||||
section(s, T('Ogólne', 'General'), '', [
|
||||
['general.server_name', T('Nazwa serwera', 'Server name'), 'text'], ['general.default_timezone', T('Domyślna strefa czasowa', 'Default time zone'), 'tz'],
|
||||
['general.login_format', T('Format loginu', 'Login format'), 'select', { options: [['as_given', T('jak podany przez urządzenie', 'as given by device')], ['local_part', T('tylko część lokalna (bez @domena)', 'local part only')], ['full_email', T('pełny e-mail (dopisz domenę)', 'full e-mail (append domain)')]], help: T('Odpowiednik USE_FULLEMAIL_FOR_LOGIN. Prefiks DOMENA\\ jest zawsze usuwany.', 'Equivalent of USE_FULLEMAIL_FOR_LOGIN. DOMAIN\\ prefixes are always stripped.') }],
|
||||
@@ -668,10 +669,6 @@
|
||||
['ping.lifetime_min', T('Min. heartbeat (s)', 'Min heartbeat (s)'), 'number'], ['ping.lifetime_max', T('Maks. heartbeat (s)', 'Max heartbeat (s)'), 'number'],
|
||||
['ping.max_folders', T('Maks. folderów', 'Max folders'), 'number'],
|
||||
]) +
|
||||
section(s, 'Autodiscover', T('Automatyczna konfiguracja kont na telefonach (/autodiscover/autodiscover.xml).', 'Automatic account configuration (/autodiscover/autodiscover.xml).'), [
|
||||
['autodiscover.enabled', T('Włączony', 'Enabled'), 'bool'], ['autodiscover.require_auth', T('Wymagaj poprawnego hasła', 'Require valid password'), 'bool'],
|
||||
['autodiscover.server_url', T('Publiczny URL ActiveSync', 'Public ActiveSync URL'), 'text', { wide: true, ph: 'https://mail.example.com/Microsoft-Server-ActiveSync', help: T('Puste = wyznaczony z nagłówka Host.', 'Empty = derived from the Host header.') }],
|
||||
]) +
|
||||
section(s, T('Logowanie i retencja', 'Logging & retention'), '', [
|
||||
['logging.log_wbxml', T('Loguj zdekodowany WBXML (debug, zawiera treść poczty!)', 'Log decoded WBXML (debug, contains mail data!)'), 'bool'],
|
||||
['logging.debug_users', T('Użytkownicy z logowaniem debug', 'Debug users'), 'list'],
|
||||
@@ -700,6 +697,44 @@
|
||||
['reqencsmimemessages', T('Wymagaj szyfrowania S/MIME', 'Require encrypted S/MIME'), 'bool'], ['allowsmimesoftcerts', T('Certyfikaty programowe S/MIME', 'S/MIME soft certs'), 'bool'],
|
||||
];
|
||||
|
||||
// Autodiscover: settings, served domains and DNS / endpoint diagnostics
|
||||
const LEVEL_LABEL = { ok: 'OK', warn: T('UWAGA', 'WARN'), fail: T('BŁĄD', 'FAIL'), info: 'INFO' };
|
||||
const LEVEL_CLASS = { ok: 'ok', warn: 'warn', fail: 'bad', info: 'info' };
|
||||
|
||||
function diagHtml(r) {
|
||||
const rows = r.checks.map((c) => `<tr><td><span class="pill ${LEVEL_CLASS[c.level] || 'muted'}">${esc(LEVEL_LABEL[c.level] || c.level)}</span></td><td class="wrap mono-cell">${esc(c.title)}</td><td class="wrap">${esc(c.detail)}</td></tr>`).join('');
|
||||
const verdictFail = r.checks[0] && r.checks[0].level === 'fail';
|
||||
const advice = verdictFail ? `<h3 class="sub-h">${T('Zalecane rekordy DNS (wystarczy jeden z nich)', 'Recommended DNS records (one of them is enough)')}</h3><pre class="code">${esc(r.dns_records.join('\n'))}</pre>
|
||||
<h3 class="sub-h">${T('Przykład nginx dla autodiscover.' + r.domain, 'nginx example for autodiscover.' + r.domain)}</h3><pre class="code">${esc(r.nginx)}</pre>` : '';
|
||||
return `<h3 class="sub-h">@${esc(r.domain)}</h3><table><thead><tr><th>${T('Wynik', 'Result')}</th><th>${T('Sprawdzenie', 'Check')}</th><th>${T('Szczegóły', 'Details')}</th></tr></thead><tbody>${rows}</tbody></table>${advice}`;
|
||||
}
|
||||
|
||||
PAGES.autodiscover = (v) => settingsPage(v, 'PROTOCOL', 'Autodiscover',
|
||||
T('Automatyczna konfiguracja kont na telefonach: domeny, wymagane rekordy DNS i diagnostyka endpointów.', 'Automatic account setup on phones: served domains, required DNS records and endpoint diagnostics.'),
|
||||
(s) => section(s, T('Ustawienia', 'Settings'), T('Telefon szuka Autodiscover pod domeną adresu e-mail (np. user@example.com → https://example.com/autodiscover/…, https://autodiscover.example.com/autodiscover/… lub rekord SRV), a nie pod nazwą serwera.', 'Phones look for Autodiscover on the domain of the e-mail address (e.g. user@example.com → https://example.com/autodiscover/…, https://autodiscover.example.com/autodiscover/… or an SRV record), not on the server name.'), [
|
||||
['autodiscover.enabled', T('Włączony', 'Enabled'), 'bool'], ['autodiscover.require_auth', T('Wymagaj poprawnego hasła', 'Require valid password'), 'bool'],
|
||||
['autodiscover.server_url', T('Publiczny URL ActiveSync', 'Public ActiveSync URL'), 'text', { wide: true, ph: 'https://mail.example.com/Microsoft-Server-ActiveSync', help: T('Adres przekazywany telefonom. Puste = z nagłówka Host żądania (zwykle autodiscover.<domena>, co bywa błędne).', 'Address handed to phones. Empty = from the Host header of the request (usually autodiscover.<domain>, which is often wrong).') }],
|
||||
['autodiscover.domains', T('Domeny e-mail', 'E-mail domains'), 'list', { ph: 'example.com\nexample.org https://mail.example.org/Microsoft-Server-ActiveSync', help: T('Jedna domena na linię, opcjonalnie z własnym adresem ActiveSync po spacji (domyślnie: Publiczny URL powyżej). Gdy lista nie jest pusta, żądania dla innych domen są odrzucane (pusta = wszystkie domeny). Zapisz zmiany przed uruchomieniem diagnostyki.', 'One domain per line, optionally followed by its own ActiveSync URL after a space (default: the Public URL above). When the list is not empty, requests for other domains are refused (empty = all domains). Save before running diagnostics.') }],
|
||||
], `<div class="diag-bar"><button class="outline" id="diag-all">${T('Uruchom diagnostykę wszystkich domen', 'Run diagnostics for all domains')}</button><span class="fine" id="diag-hint"></span></div><div id="diag-out"></div>`),
|
||||
{ bind: (form) => {
|
||||
const doms = (S.settings.autodiscover.domains || []).filter(Boolean).map((e) => e.trim().split(/[\s=]+/)[0].toLowerCase().replace(/\.$/, ''));
|
||||
const out = $('#diag-out', form);
|
||||
$('#diag-hint', form).textContent = doms.length ? doms.map((d) => '@' + d).join(' ') : T('Dodaj domeny i zapisz, aby uruchomić diagnostykę.', 'Add domains and save to run diagnostics.');
|
||||
$('#diag-all', form).disabled = !doms.length;
|
||||
$('#diag-all', form).addEventListener('click', async (e) => {
|
||||
const b = e.target;
|
||||
b.disabled = true; out.innerHTML = '';
|
||||
for (const d of doms) {
|
||||
const holder = document.createElement('div');
|
||||
holder.innerHTML = `<div class="result">${T('Sprawdzam', 'Checking')} ${esc(d)}…</div>`;
|
||||
out.appendChild(holder);
|
||||
try { holder.innerHTML = diagHtml(await api('POST', '/api/autodiscover/check', { domain: d })); }
|
||||
catch (err) { holder.innerHTML = `<div class="result bad">${esc(d)}: ${esc(err.message)}</div>`; }
|
||||
}
|
||||
b.disabled = false;
|
||||
});
|
||||
} });
|
||||
|
||||
PAGES.policies = async (v) => {
|
||||
let sel = 0;
|
||||
await settingsPage(v, 'PROVISIONING', T('Polityki urządzeń', 'Device policies'), T('Polityki bezpieczeństwa przekazywane urządzeniom (odpowiednik policies.ini). Zmiana polityki wymusza ponowny provisioning urządzeń.', 'Security policies pushed to devices (policies.ini equivalent). Changing a policy forces devices to re-provision.'), (s) => {
|
||||
|
||||
Reference in new issue
Block a user