import { apiGet, apiPost, apiPut, isAuthRedirectError } from '../api.js'; import { guard } from '../core/auth-guard.js'; import { esc, formatDeSyncDateTime } from '../core/utils.js'; const loadingEl = document.getElementById('page-loading'); const mainEl = document.getElementById('page-main'); const errEl = document.getElementById('page-error'); function showError(msg) { loadingEl.hidden = true; mainEl.hidden = true; errEl.hidden = false; errEl.textContent = msg; } function renderSyncLog(entries) { const tbody = document.getElementById('sync-log-body'); if (!entries.length) { tbody.innerHTML = 'Noch keine Einträge.'; return; } tbody.innerHTML = entries .map( (e) => ` ${esc(formatDeSyncDateTime(e.finishedAt))} ${e.triggerType === 'automatic' ? 'Automatisch' : 'Manuell'} ${e.status === 'success' ? 'Erfolg' : 'Fehler'} ${esc(String(e.usersSynced ?? 0))} ${e.errorMessage ? esc(e.errorMessage) : '—'} `, ) .join(''); } function applyIntegrationForm(data) { const ldap = data.ldap || {}; document.getElementById('ldap_syncEnabled').checked = Boolean(ldap.syncEnabled); document.getElementById('ldap_serverUrl').value = ldap.serverUrl ?? ''; document.getElementById('ldap_searchBase').value = ldap.searchBase ?? ''; document.getElementById('ldap_bindDn').value = ldap.bindDn ?? ''; document.getElementById('ldap_bindPassword').value = ''; document.getElementById('ldap_userSearchFilter').value = ldap.userSearchFilter || ldap.userFilter || ''; document.getElementById('ldap_usernameAttribute').value = ldap.usernameAttribute ?? ''; document.getElementById('ldap_firstNameAttribute').value = ldap.firstNameAttribute ?? ''; document.getElementById('ldap_lastNameAttribute').value = ldap.lastNameAttribute ?? ''; document.getElementById('ldap_syncIntervalMinutes').value = String( ldap.syncIntervalMinutes ?? 0, ); const tv = data.teamviewer || {}; document.getElementById('tv_bearerToken').value = tv.bearerToken || tv.apiToken || ''; document.getElementById('tv_notes').value = tv.notes ?? tv.apiNotes ?? ''; } async function run() { const data = await apiGet('/settings/integrations'); let syncStatus = { lastSyncAt: null, entries: [] }; try { syncStatus = await apiGet('/ldap/sync-status'); } catch { /* ältere Server */ } applyIntegrationForm(data); document.getElementById('ldap-last-sync').textContent = `Letzte Synchronisation: ${formatDeSyncDateTime(syncStatus.lastSyncAt)}`; renderSyncLog(Array.isArray(syncStatus.entries) ? syncStatus.entries : []); const ldapBody = document.getElementById('ldap-section-body'); const ldapToggle = document.getElementById('ldap-toggle'); const chev = ldapToggle.querySelector('.ldap-chevron'); function setLdapOpen(open) { ldapBody.hidden = !open; ldapToggle.setAttribute('aria-expanded', String(open)); chev.textContent = open ? '▲' : '▼'; } ldapToggle.onclick = () => setLdapOpen(ldapBody.hidden); document.getElementById('btn-ldap-sync-now').onclick = async () => { const btn = document.getElementById('btn-ldap-sync-now'); btn.disabled = true; try { const r = await apiPost('/ldap/sync', {}); if (r.errors && r.errors.length) { alert(r.errors.join('\n')); } else if (r.ok === false && r.error) { alert(r.error); } location.reload(); } catch (err) { alert(err.message || String(err)); } finally { btn.disabled = false; } }; document.getElementById('form-opt').onsubmit = async (e) => { e.preventDefault(); const fd = new FormData(e.target); await apiPut('/settings/integrations', { ldap: { serverUrl: fd.get('ldap_serverUrl'), bindDn: fd.get('ldap_bindDn'), bindPassword: fd.get('ldap_bindPassword'), searchBase: fd.get('ldap_searchBase'), userSearchFilter: fd.get('ldap_userSearchFilter'), usernameAttribute: fd.get('ldap_usernameAttribute'), firstNameAttribute: fd.get('ldap_firstNameAttribute'), lastNameAttribute: fd.get('ldap_lastNameAttribute'), syncIntervalMinutes: fd.get('ldap_syncIntervalMinutes'), syncEnabled: fd.get('ldap_syncEnabled') === 'on', }, teamviewer: { bearerToken: fd.get('tv_bearerToken'), notes: fd.get('tv_notes'), }, }); location.reload(); }; } async function init() { const st = await guard({ needsAdmin: true, activeNav: 'options' }); if (!st) return; loadingEl.hidden = true; mainEl.hidden = false; try { await run(); } catch (e) { if (isAuthRedirectError(e)) return; showError(e.message || 'Fehler'); } } init();