OpenNIT-Vault-Extension/extension/options.html
2026-07-01 18:26:57 +02:00

304 lines
No EOL
12 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>OpenNIT Vault &ndash; Einstellungen</title>
<style>
/* ── Reset & Base ──────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }
body {
font-family: "Source Sans Pro", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
font-size: 14px;
color: #212529;
background: #f4f6f9;
margin: 0; padding: 0;
min-height: 100vh;
}
/* ── Main navbar (AdminLTE style) ─────────────────────────────────────── */
.main-header {
background: #343a40;
border-bottom: 3px solid #007bff;
padding: 0 1.25rem;
height: 56px;
display: flex;
align-items: center;
gap: 1rem;
position: sticky;
top: 0;
z-index: 100;
box-shadow: 0 2px 6px rgba(0,0,0,.25);
}
.brand-logo {
width: 36px; height: 36px;
border-radius: 6px;
background: none;
display: flex; align-items: center; justify-content: center;
overflow: hidden; flex-shrink: 0;
}
.brand-logo img { width: 26px; height: 26px; object-fit: contain; }
.brand-text {
color: #fff;
font-size: 1rem;
font-weight: 700;
letter-spacing: .01em;
white-space: nowrap;
}
.brand-sep { color: rgba(255,255,255,.35); margin: 0 2px; font-weight: 300; }
.brand-sub { color: #adb5bd; font-weight: 400; font-size: .95rem; }
.header-user {
margin-left: auto;
display: flex;
align-items: center;
gap: .5rem;
color: #dee2e6;
font-size: .82rem;
}
.user-badge {
background: rgba(255,255,255,.1);
border: 1px solid rgba(255,255,255,.15);
border-radius: 20px;
padding: 3px 10px 3px 6px;
display: flex;
align-items: center;
gap: 5px;
font-size: .78rem;
}
.user-dot { width: 7px; height: 7px; background: #28a745; border-radius: 50%; }
/* ── Content wrapper ──────────────────────────────────────────────────── */
.content-wrapper { max-width: 680px; margin: 0 auto; padding: 1.5rem 1.25rem; }
/* ── Card (AdminLTE .card) ───────────────────────────────────────────── */
.card {
background: #fff;
border: none;
border-radius: .35rem;
box-shadow: 0 1px 3px rgba(0,0,0,.08), 0 1px 2px rgba(0,0,0,.06);
margin-bottom: 1.25rem;
}
.card-header {
background: #f8f9fa;
border-bottom: 1px solid #dee2e6;
padding: .75rem 1.25rem;
border-radius: .35rem .35rem 0 0;
display: flex;
align-items: center;
gap: .5rem;
}
.card-header h3 {
margin: 0;
font-size: .9rem;
font-weight: 600;
color: #343a40;
line-height: 1;
}
.card-header .card-tools { margin-left: auto; }
.card-body { padding: 1.25rem; }
/* ── Form controls ───────────────────────────────────────────────────── */
.form-group { margin-bottom: 1rem; }
.form-group:last-child { margin-bottom: 0; }
label.control-label {
display: block;
font-size: .78rem;
font-weight: 700;
color: #6c757d;
text-transform: uppercase;
letter-spacing: .04em;
margin-bottom: .35rem;
}
.form-control {
display: block;
width: 100%;
padding: .45rem .75rem;
font-size: .9rem;
color: #495057;
background: #fff;
border: 1px solid #ced4da;
border-radius: .25rem;
transition: border-color .15s, box-shadow .15s;
}
.form-control:focus {
outline: none;
border-color: #80bdff;
box-shadow: 0 0 0 .2rem rgba(0,123,255,.25);
}
.form-text { font-size: .78rem; color: #6c757d; margin-top: .25rem; line-height: 1.5; }
/* ── Buttons ─────────────────────────────────────────────────────────── */
.btn {
display: inline-flex;
align-items: center;
gap: .35rem;
padding: .4rem .85rem;
font-size: .875rem;
font-weight: 600;
border: 1px solid transparent;
border-radius: .25rem;
cursor: pointer;
transition: background .15s, border-color .15s, color .15s;
text-decoration: none;
}
.btn-primary { background: #007bff; border-color: #007bff; color: #fff; }
.btn-primary:hover { background: #0069d9; border-color: #0062cc; }
.btn-default { background: #fff; border-color: #ced4da; color: #212529; }
.btn-default:hover { background: #f8f9fa; border-color: #adb5bd; }
.btn-sm { padding: .28rem .65rem; font-size: .8rem; }
.btn-group { display: flex; gap: .5rem; flex-wrap: wrap; align-items: center; margin-top: .75rem; }
/* ── Alerts ──────────────────────────────────────────────────────────── */
.alert { padding: .65rem 1rem; border-radius: .25rem; font-size: .85rem; margin-top: .75rem; border: 1px solid transparent; }
.alert-success { background: #d4edda; color: #155724; border-color: #c3e6cb; }
.alert-danger { background: #f8d7da; color: #721c24; border-color: #f5c6cb; }
.alert-info { background: #d1ecf1; color: #0c5460; border-color: #bee5eb; }
.save-ok { color: #28a745; font-size: .82rem; font-weight: 600; display: inline-flex; align-items: center; gap: 4px; }
/* ── Spinner ─────────────────────────────────────────────────────────── */
.fa-spin-sm {
display: inline-block;
width: 12px; height: 12px;
border: 2px solid #dee2e6;
border-top-color: #007bff;
border-radius: 50%;
animation: sp .7s linear infinite;
vertical-align: middle;
}
@keyframes sp { to { transform: rotate(360deg); } }
/* ── Steps list ──────────────────────────────────────────────────────── */
.steps-list { list-style: none; margin: 0; padding: 0; }
.steps-list li {
display: flex;
gap: .875rem;
align-items: flex-start;
padding: .5rem 0;
border-bottom: 1px solid #f1f3f5;
font-size: .875rem;
color: #495057;
line-height: 1.55;
}
.steps-list li:last-child { border-bottom: none; padding-bottom: 0; }
.step-badge {
min-width: 22px; height: 22px;
background: #007bff;
color: #fff;
border-radius: 50%;
display: flex; align-items: center; justify-content: center;
font-size: .7rem;
font-weight: 700;
flex-shrink: 0;
margin-top: .15rem;
}
</style>
</head>
<body>
<!-- Main Header -->
<nav class="main-header">
<div class="brand-logo"><img src="icon128.png" alt=""></div>
<span class="brand-text" id="optTitle">OpenNIT Vault</span>
<div class="header-user" id="headerStatus" style="display:none;">
<span class="user-badge">
<span class="user-dot"></span>
<span id="headerUser"></span>
</span>
</div>
</nav>
<div class="content-wrapper">
<!-- Connection card -->
<div class="card">
<div class="card-header">
<h3>Server-Verbindung</h3>
</div>
<div class="card-body">
<div class="form-group">
<label class="control-label" for="serverUrl">Server-URL</label>
<input type="url" class="form-control" id="serverUrl"
placeholder="https://ihre-opennit.firma.de"
value="">
<span class="form-text">Adresse Ihrer OpenNIT-Instanz &ndash; ohne abschlie&szlig;enden Slash.</span>
</div>
<!-- SSO-Anmeldung (empfohlen) -->
<div class="btn-group">
<button class="btn btn-primary" id="btnSso">
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="margin-right:2px;"><path d="M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4"/><polyline points="10 17 15 12 10 7"/><line x1="15" y1="12" x2="3" y2="12"/></svg>
Mit OpenNIT anmelden
</button>
<button class="btn btn-default" id="btnLogout" style="display:none;">Abmelden</button>
<span id="ssoMsg"></span>
</div>
<span class="form-text">Empfohlen: Anmeldung wie an OpenNIT (lokal + 2FA / Microsoft 365 / Keycloak). Der Zugang wird automatisch erneuert.</span>
<div id="statusMsg"></div>
<!-- Erweitert: manueller Token -->
<details style="margin-top:1rem;">
<summary style="cursor:pointer;font-size:.82rem;color:#6c757d;font-weight:600;">Erweitert: manueller Token</summary>
<div style="margin-top:.75rem;">
<div class="form-group">
<label class="control-label" for="apiToken">API-Token</label>
<input type="password" class="form-control" id="apiToken"
placeholder="Token aus dem Vault einf&uuml;gen&hellip;">
<span class="form-text">Alternative ohne SSO (z. B. Kiosk/Headless): Vault &rarr; &bdquo;Extension&ldquo; &rarr; Token generieren.</span>
</div>
<div class="btn-group">
<button class="btn btn-default btn-sm" id="btnSave">Token speichern</button>
<button class="btn btn-default btn-sm" id="btnTest">Verbindung testen</button>
<span id="savedMsg"></span>
</div>
</div>
</details>
</div>
</div>
<!-- Security card -->
<div class="card">
<div class="card-header">
<h3>Sicherheit</h3>
</div>
<div class="card-body">
<div class="form-group">
<label class="control-label" for="lockDuration">PIN-Sperre: erneut fragen</label>
<select class="form-control" id="lockDuration">
<option value="5">Nach 5 Minuten</option>
<option value="15">Nach 15 Minuten</option>
<option value="60">Nach 1 Stunde</option>
<option value="session">Bis der Browser geschlossen wird</option>
</select>
<span class="form-text">Ist im Web-Tresor ein <strong>Tresor-PIN</strong> aktiv, verlangt die Erweiterung diesen PIN <strong>serverseitig erzwungen</strong>, damit ein gestohlener Token allein nichts nützt. Diese Einstellung legt nur fest, <em>wie lange</em> eine Entsperrung gilt. Ohne gesetzten Tresor-PIN entfällt die Sperre.</span>
</div>
<div class="form-group">
<label class="control-label"><input type="checkbox" id="clipClear" checked> Zwischenablage nach 30&nbsp;Sekunden leeren</label>
<span class="form-text">Kopierte Passwörter und 2FA-Codes werden nach kurzer Zeit automatisch aus der Zwischenablage entfernt.</span>
</div>
<div class="btn-group">
<button class="btn btn-primary btn-sm" id="btnSaveSec">Speichern</button>
<span id="savedSecMsg"></span>
</div>
</div>
</div>
<!-- Setup card -->
<div class="card">
<div class="card-header">
<h3>Einrichtungsschritte</h3>
</div>
<div class="card-body">
<ul class="steps-list">
<li><span class="step-badge">1</span><span>Öffnen Sie den <strong>Passwort-Vault</strong> in Ihrer OpenNIT-Anwendung.</span></li>
<li><span class="step-badge">2</span><span>Klicken Sie auf <strong>&bdquo;Extension&ldquo;</strong> in der Toolbar und generieren Sie einen API-Token.</span></li>
<li><span class="step-badge">3</span><span>Fügen Sie den Token oben in das Token-Feld ein und klicken Sie auf <strong>Speichern</strong>.</span></li>
<li><span class="step-badge">4</span><span>Fokussieren Sie ein Login-Feld auf einer Website &ndash; Vault-Vorschl&auml;ge erscheinen automatisch.</span></li>
</ul>
</div>
</div>
</div><!-- /.content-wrapper -->
<script src="options.js"></script>
</body>
</html>