Inital Commit
All checks were successful
Vaultwarden / Vaultwarden [arm64] (push) Successful in 59s
Vaultwarden / Vaultwarden [amd64] (push) Successful in 51s

This commit is contained in:
Cantibra
2025-10-26 21:11:06 +01:00
commit 3180255caa
89 changed files with 4156 additions and 0 deletions

View File

@@ -0,0 +1,97 @@
<!DOCTYPE html>
<html lang="en" data-bs-theme="auto">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="robots" content="noindex,nofollow" />
<link rel="icon" type="image/png" href="{{urlpath}}/vw_static/vaultwarden-favicon.png">
<title>Vaultwarden Administration</title>
<link rel="stylesheet" href="{{urlpath}}/vw_static/bootstrap.css" />
<link rel="stylesheet" href="{{urlpath}}/vw_static/admin.css" />
<script src="{{urlpath}}/vw_static/admin.js"></script>
</head>
<body>
<nav class="navbar navbar-expand-md navbar-dark bg-dark mb-4 shadow fixed-top">
<div class="container-xl">
<a class="navbar-brand" href="{{urlpath}}/admin"><img class="vaultwarden-icon" src="{{urlpath}}/vw_static/vaultwarden-icon.png" alt="V">aultwarden Administration</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarCollapse"
aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarCollapse">
<ul class="navbar-nav me-auto">
{{#if logged_in}}
<li class="nav-item">
<a class="nav-link" href="{{urlpath}}/admin">Einstellungen</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{urlpath}}/admin/users/overview">Benutzer</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{urlpath}}/admin/organizations/overview">Organisationen</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{urlpath}}/admin/diagnostics">Systemdiagnose</a>
</li>
{{/if}}
<li class="nav-item">
<a class="nav-link" href="{{urlpath}}/" target="_blank" rel="noreferrer">Tresor</a>
</li>
</ul>
<ul class="navbar-nav">
<li class="nav-item dropdown">
<button
class="btn btn-link nav-link py-0 px-0 px-md-2 dropdown-toggle d-flex align-items-center"
id="bd-theme" type="button" aria-expanded="false" data-bs-toggle="dropdown"
data-bs-display="static" aria-label="Anzeigemodus (Automatisch)">
<span class="my-1 fs-4 theme-icon-active">
<use>&#9775;</use>
</span>
<span class="d-md-none ms-2" id="bd-theme-text">
Anzeigemodus wechseln
</span>
</button>
<ul class="dropdown-menu dropdown-menu-end" aria-labelledby="bd-theme-text">
<li>
<button type="button" class="dropdown-item d-flex align-items-center"
data-bs-theme-value="light" aria-pressed="false">
<span class="me-2 fs-4 theme-icon">
<use>&#9728;</use>
</span>
Hell
</button>
</li>
<li>
<button type="button" class="dropdown-item d-flex align-items-center"
data-bs-theme-value="dark" aria-pressed="false">
<span class="me-2 fs-4 theme-icon">
<use>&#127762;</use>
</span>
Dunkel
</button>
</li>
<li>
<button type="button" class="dropdown-item d-flex align-items-center active"
data-bs-theme-value="auto" aria-pressed="true">
<span class="me-2 fs-4 theme-icon">
<use>&#9775;</use>
</span>
Systemeinstellungen
</button>
</li>
</ul>
</li>
</ul>
{{#if logged_in}}
<a style="color: #333; background-color: #fda34a; border-color: #fda34a;" class="btn btn-sm btn-secondary" href="{{urlpath}}/admin/logout">Abmelden</a>
{{/if}}
</div>
</div>
</nav>
{{> (lookup this "page_content") }}
<!-- This script needs to be at the bottom, else it will fail! -->
<script src="{{urlpath}}/vw_static/bootstrap.bundle.js"></script>
</body>
</html>

View File

@@ -0,0 +1,202 @@
<main class="container-xl">
<div id="diagnostics-block" class="my-3 p-3 rounded shadow">
<h6 class="border-bottom pb-2 mb-3">Systemdiagnose</h6>
<h3>Versionsinformationen</h3>
<div class="row">
<div class="col-md">
<dl class="row">
<dt class="col-sm-5">Server Version
<span class="badge bg-success d-none abbr-badge" id="server-success" title="Die neueste Version ist installiert.">Erfolgreich</span>
<span class="badge bg-warning text-dark d-none abbr-badge" id="server-warning" title="Eine neue Version ist verfügbar.">Warnung</span>
<span class="badge bg-info text-dark d-none abbr-badge" id="server-branch" title="Diese Version ist verzweigt.">Branched</span>
</dt>
<dd class="col-sm-7">
<span id="server-installed">{{page_data.current_release}}</span>
</dd>
<dt class="col-sm-5">Server Version
<span class="badge bg-secondary d-none abbr-badge" id="server-failed" title="Die neueste Version kann nicht bestimmt werden.">Fehler</span>
</dt>
<dd class="col-sm-7">
<span id="server-latest">{{page_data.latest_release}}<span id="server-latest-commit" class="d-none">-{{page_data.latest_commit}}</span></span>
</dd>
{{#if page_data.web_vault_enabled}}
<dt class="col-sm-5">Website Version
<span class="badge bg-success d-none abbr-badge" id="web-success" title="Die neueste Version ist installiert.">Erfolgreich</span>
<span class="badge bg-warning text-dark d-none abbr-badge" id="web-warning" title="Eine neue Version ist verfügbar.">Warnung</span>
<span class="badge bg-info text-dark d-none abbr-badge" id="web-prerelease" title="Dies ist eine Beta-Version.">Beta-Version</span>
</dt>
<dd class="col-sm-7">
<span id="web-installed">{{page_data.web_vault_version}}</span>
</dd>
{{#unless page_data.running_within_docker}}
<dt class="col-sm-5">Website Version
<span class="badge bg-secondary d-none abbr-badge" id="web-failed" title="Die neueste Version kann nicht bestimmt werden.">Fehler</span>
</dt>
<dd class="col-sm-7">
<span id="web-latest">{{page_data.latest_web_build}}</span>
</dd>
{{/unless}}
{{/if}}
{{#unless page_data.web_vault_enabled}}
<dt class="col-sm-5">Website</dt>
<dd class="col-sm-7">
<span id="web-installed">Das Web vault wurde deaktiviert.</span>
</dd>
{{/unless}}
<dt class="col-sm-5">Datenbank</dt>
<dd class="col-sm-7">
<span><b>{{page_data.db_type}}:</b> {{page_data.db_version}}</span>
</dd>
</dl>
</div>
</div>
<h3>Diagnose</h3>
<div class="row">
<div class="col-md">
<dl class="row">
<dt class="col-sm-5">Betriebssystem / Architektur</dt>
<dd class="col-sm-7">
<span class="d-block"><b>{{ page_data.host_os }} / {{ page_data.host_arch }}</b></span>
</dd>
<dt class="col-sm-5">Docker</dt>
<dd class="col-sm-7">
{{#if page_data.running_within_container}}
<span class="d-block"><b>Ja (Base: {{ page_data.container_base_image }})</b></span>
{{/if}}
{{#unless page_data.running_within_container}}
<span class="d-block"><b>Nein</b></span>
{{/unless}}
</dd>
<dt class="col-sm-5">Umgebungsvariablen</dt>
<dt class="col-sm-7">
{{#if page_data.overrides}}
<span class="d-inline"><b>Ja</b></span>
<span class="badge bg-info text-dark abbr-badge" title="Die Umgebungsvariablen wurde durch die config.json überschrieben.">Überschrieben</span>
{{/if}}
{{#unless page_data.overrides}}
<span class="d-block"><b>Nein</b></span>
{{/unless}}
</dd>
<dt class="col-sm-5">Reverse Proxy</dt>
<dd class="col-sm-7">
{{#if page_data.ip_header_exists}}
<span class="d-block" title="Ein IP-Header wurde erkannt."><b>Ja</b></span>
{{/if}}
{{#unless page_data.ip_header_exists}}
<span class="d-block" title="Es wurde kein IP-Header erkannt."><b>Nein</b></span>
{{/unless}}
</dd>
{{!-- Only show this if the IP Header Exists --}}
{{#if page_data.ip_header_exists}}
<dt class="col-sm-5">IP-Header
{{#if page_data.ip_header_match}}
<span class="badge bg-success abbr-badge" title="Die IP-Header-Konfiguration ist gültig.">Erfolgreich</span>
{{/if}}
{{#unless page_data.ip_header_match}}
<span class="badge bg-danger abbr-badge" title="Die IP-Header-Konfiguration ist ungültig.">Fehler</span>
{{/unless}}
</dt>
<dd class="col-sm-7">
{{#if page_data.ip_header_match}}
<span class="d-block"><b>Konfiguration / Server:</b> {{ page_data.ip_header_name }}</span>
{{/if}}
{{#unless page_data.ip_header_match}}
<span class="d-block"><b>Konfiguration:</b> {{ page_data.ip_header_config }}</span>
<span class="d-block"><b>Server:</b> {{ page_data.ip_header_name }}</span>
{{/unless}}
</dd>
{{/if}}
{{!-- End if IP Header Exists --}}
<dt class="col-sm-5">Internetverbindung
{{#if page_data.has_http_access}}
<span class="badge bg-success abbr-badge" title="Es konnte eine Verbindung zum Internet hergestellt werden.">Erfolgreich</span>
{{/if}}
{{#unless page_data.has_http_access}}
<span class="badge bg-danger abbr-badge" title="Es konnte keine Verbindung zum Internet hergestellt werden.">Fehler</span>
{{/unless}}
</dt>
<dd class="col-sm-7">
{{#if page_data.has_http_access}}
<span class="d-block"><b>Ja</b></span>
{{/if}}
{{#unless page_data.has_http_access}}
<span class="d-block"><b>Nein</b></span>
{{/unless}}
</dd>
<dt class="col-sm-5">Proxy</dt>
<dd class="col-sm-7">
{{#if page_data.uses_proxy}}
<span class="d-block" title="Der Traffic wird über einen Proxy geroutet."><b>Ja</b></span>
{{/if}}
{{#unless page_data.uses_proxy}}
<span class="d-block" title="Der Traffic wird direkt geroutet."><b>Nein</b></span>
{{/unless}}
</dd>
<dt class="col-sm-5">Websocket
{{#if page_data.enable_websocket}}
<span class="badge bg-success d-none abbr-badge" id="websocket-success" title="Die Websocket-Verbindung funktioniert.">Erfolgreich</span>
<span class="badge bg-danger d-none abbr-badge" id="websocket-error" title="Die Websocket-Verbindung ist fehlgeschlagen.">Fehler</span>
{{/if}}
</dt>
<dd class="col-sm-7">
{{#if page_data.enable_websocket}}
<span class="d-block" title="Websocket-Verbindungen sind aktiviert."><b>Ja</b></span>
{{/if}}
{{#unless page_data.enable_websocket}}
<span class="d-block" title="Websocket-Verbindungen sind deaktiviert."><b>Nein</b></span>
{{/unless}}
</dd>
<dt class="col-sm-5">DNS
<span class="badge bg-success d-none abbr-badge" id="dns-success" title="Die Namensauflösung zu > github.com < ist erfolgreich.">Erfolgreich</span>
<span class="badge bg-danger d-none abbr-badge" id="dns-warning" title="Die Namensauflösung zu > github.com < ist fehlgeschlagen.">Fehler</span>
</dt>
<dd class="col-sm-7">
<span id="dns-resolved"><b>{{page_data.dns_resolved}}</b></span>
</dd>
<dt class="col-sm-5">Datum & Uhrzeit (Lokal)
{{#if page_data.tz_env}}
<span class="badge bg-success abbr-badge" title="Zeitzone">{{page_data.tz_env}}</span>
{{/if}}
</dt>
<dd class="col-sm-7">
<span><b>Server:</b> {{page_data.server_time_local}}</span>
</dd>
<dt class="col-sm-5">Datum & Uhrzeit (UTC)
<span class="badge bg-success d-none abbr-badge" id="time-success" title="Die Server- und Browseruhrzeit liegen weniger als 15 Sekunden auseinander.">Erfolgreich</span>
<span class="badge bg-danger d-none abbr-badge" id="time-warning" title="Die Server- und Browseruhrzeit liegen mehr als 15 Sekunden auseinander.">Fehler</span>
<span class="badge bg-success d-none abbr-badge" id="ntp-server-success" title="Die Server- und Zeitserveruhrzeit liegen weniger als 15 Sekunden auseinander.">Erfolgreich</span>
<span class="badge bg-danger d-none abbr-badge" id="ntp-server-warning" title="Die Server- und Zeitserveruhrzeit liegen mehr als 15 Sekunden auseinander.">Fehler</span>
<span class="badge bg-success d-none abbr-badge" id="ntp-browser-success" title="Die Browser- und Zeitserveruhrzeit liegen weniger als 15 Sekunden auseinander.">Erfolgreich</span>
<span class="badge bg-danger d-none abbr-badge" id="ntp-browser-warning" title="Die Browser- und Zeitserveruhrzeit liegen mehr als 15 Sekunden auseinander.">Fehler</span>
</dt>
<dd class="col-sm-7">
<span id="ntp-time" class="d-block"><b>NTP:</b> <span id="ntp-server-string">{{page_data.ntp_time}}</span></span>
<span id="time-server" class="d-block"><b>Server:</b> <span id="time-server-string">{{page_data.server_time}}</span></span>
<span id="time-browser" class="d-block"><b>Browser:</b> <span id="time-browser-string"></span></span>
</dd>
<dt class="col-sm-5">Domain-Konfiguration
<span class="badge bg-success d-none abbr-badge" id="domain-success" title="Die Konfiguration der Domain stimmt mit der URL des Browser überein.">Erfolgreich</span>
<span class="badge bg-danger d-none abbr-badge" id="domain-warning" title="Die Konfiguration der Domain stimmt nicht mit der URL des Browser überein.">Fehler</span>
<span class="badge bg-success d-none abbr-badge" id="https-success" title="Die Verbindungen zum Server sind verschlüsselt.">Erfolgreich</span>
<span class="badge bg-danger d-none abbr-badge" id="https-warning" title="Die Verbindungen zum Server sind nicht verschlüsselt.">Fehler</span>
</dt>
<dd class="col-sm-7">
<span id="domain-server" class="d-block"><b>Server:</b> <span id="domain-server-string">{{page_data.admin_url}}</span></span>
<span id="domain-browser" class="d-block"><b>Browser:</b> <span id="domain-browser-string"></span></span>
</dd>
<dt class="col-sm-5">HTTP-Antwortvalidierung
<span class="badge bg-success d-none abbr-badge" id="http-response-success" title="Alle Header und HTTP-Anforderungsantworten sind in Ordnung.">Erfolgreich</span>
<span class="badge bg-danger d-none abbr-badge" id="http-response-warning" title="Einige Header oder HTTP-Anforderungsantworten geben ungültige Daten zurück.">Fehler</span>
</dt>
<dd class="col-sm-7">
<span id="http-response-errors" class="d-block"></span>
</dd>
</dl>
</div>
</div>
</div>
</main>
<script src="{{urlpath}}/vw_static/admin_diagnostics.js"></script>
<script type="application/json" id="diagnostics_json">{{to_json page_data}}</script>

View File

@@ -0,0 +1,23 @@
<main class="container-xl">
{{#if error}}
<div class="align-items-center p-3 mb-3 text-opacity-50 text-dark bg-danger rounded shadow">
<div>
<h6 class="mb-0 text-dark">{{error}}</h6>
</div>
</div>
{{/if}}
<div style="margin: 64px auto;" class="align-items-center p-3 mb-3 text-opacity-50 text-light bg-secondary rounded shadow">
<div>
<h6 style="margin: 16px auto !important; color: #fff !important; text-align: center !important; font-size: 1.4rem !important" class="mb-0 text-light">Authentifizierung</h6>
<form class="form-inline" method="post" action="{{urlpath}}/admin">
<input style="margin: 20px auto 10px auto;" type="password" autocomplete="password" class="form-control w-50 mr-2" name="token" placeholder="Admin-Token eingeben" autofocus="autofocus">
{{#if redirect}}
<input type="hidden" id="redirect" name="redirect" value="/{{redirect}}">
{{/if}}
<button style="display: block; margin: 20px auto 16px auto; color: #333; background-color: #fda34a; border-color: #fda34a;" type="submit" class="btn btn-primary mt-2">Anmelden</button>
</form>
</div>
</div>
</main>

View File

@@ -0,0 +1,65 @@
<main class="container-xl">
<div id="organizations-block" class="my-3 p-3 rounded shadow">
<h6 class="border-bottom pb-2 mb-3">Registrierte Organisationen</h6>
<div class="table-responsive-xl small">
<table id="orgs-table" class="table table-sm table-striped table-hover">
<thead>
<tr>
<th class="vw-org-details">Organisationen</th>
<th class="vw-users">Benutzer</th>
<th class="vw-entries">Einträge</th>
<th class="vw-attachments">Anhänge</th>
<th class="vw-misc">Sonstiges</th>
<th class="vw-actions">Aktionen</th>
</tr>
</thead>
<tbody>
{{#each page_data}}
<tr>
<td>
<svg width="48" height="48" class="float-start me-2 rounded" data-jdenticon-value="{{id}}">
<div class="float-start">
<strong>{{name}}</strong>
<span class="me-2">({{billingEmail}})</span>
<span class="d-block">
<span class="badge bg-success font-monospace">{{id}}</span>
</span>
</div>
</td>
<td>
<span class="d-block">{{user_count}}</span>
</td>
<td>
<span class="d-block">{{cipher_count}}</span>
</td>
<td>
<span class="d-block"><strong>Menge:</strong> {{attachment_count}}</span>
{{#if attachment_count}}
<span class="d-block"><strong>Größe:</strong> {{attachment_size}}</span>
{{/if}}
</td>
<td>
<span class="d-block"><strong>Sammlungen:</strong> {{collection_count}}</span>
<span class="d-block"><strong>Gruppen:</strong> {{group_count}}</span>
<span class="d-block"><strong>Berichte:</strong> {{event_count}}</span>
</td>
<td class="text-end px-1 small">
<button type="button" class="btn btn-sm btn-link p-0 border-0 float-right" vw-delete-organization data-vw-org-uuid="{{id}}" data-vw-org-name="{{name}}" data-vw-billing-email="{{billingEmail}}">Organisation löschen</button><br>
</td>
</tr>
{{/each}}
</tbody>
</table>
</div>
<div class="mt-3 clearfix">
<button style="color: #333; background-color: #fda34a; border-color: #fda34a;" type="button" class="btn btn-sm btn-primary float-end" id="reload">Aktualisieren</button>
</div>
</div>
</main>
<link rel="stylesheet" href="{{urlpath}}/vw_static/datatables.css" />
<script src="{{urlpath}}/vw_static/jquery-3.7.1.slim.js"></script>
<script src="{{urlpath}}/vw_static/datatables.js"></script>
<script src="{{urlpath}}/vw_static/admin_organizations.js"></script>
<script src="{{urlpath}}/vw_static/jdenticon-3.3.0.js"></script>

View File

@@ -0,0 +1,127 @@
<main class="container-xl">
<div id="admin_token_warning" class="alert alert-warning alert-dismissible fade show d-none">
<button type="button" class="btn-close" data-bs-target="admin_token_warning" data-bs-dismiss="alert" aria-label="Close"></button>
Sie benutzen einen unverschlüsselten 'ADMIN_TOKEN', was ein Sicherheitsrisiko darstellt.<br>
Bitte generieren Sie einen sicheren Schlüssel mit der Argon2 PHC Methode.<br>
Sie können dafür den Befehl 'vaultwarden hash' verwenden.<br>
Den 'ADMIN_TOKEN' ändern Sie entsprechend in der Vaultwaren Konfiguration (/etc/vaultwarden/vaultwarden.conf).
</div>
<div id="config-block" class="align-items-center p-3 mb-3 bg-secondary rounded shadow">
<div>
<form class="form needs-validation" id="config-form" novalidate>
{{#each page_data.config}}
{{#if groupdoc}}
<div class="card mb-3">
<button id="b_{{group}}" type="button" class="card-header text-start btn btn-link text-decoration-none" aria-expanded="false" aria-controls="g_{{group}}" data-bs-toggle="collapse" data-bs-target="#g_{{group}}">{{groupdoc}}</button>
<div id="g_{{group}}" class="card-body collapse">
{{#each elements}}
{{#if editable}}
<div class="row my-2 align-items-center is-overridden-{{overridden}} alert-row" title="[{{name}}] {{doc.description}}">
{{#case type "text" "number" "password"}}
<label for="input_{{name}}" class="col-sm-3 col-form-label">{{doc.name}}</label>
<div class="col-sm-8">
<div class="input-group">
<input class="form-control conf-{{type}}" id="input_{{name}}" type="{{type}}"
name="{{name}}" value="{{value}}" {{#if default}} placeholder="Standard: {{default}}"{{/if}}>
{{#case type "password"}}
<button class="btn btn-outline-secondary input-group-text" type="button" data-vw-pw-toggle="input_{{name}}">Anzeigen / Verbergen</button>
{{/case}}
</div>
</div>
{{/case}}
{{#case type "checkbox"}}
<div class="col-sm-3 col-form-label">{{doc.name}}</div>
<div class="col-sm-8">
<div class="form-check">
<input class="form-check-input conf-{{type}}" type="checkbox" id="input_{{name}}"
name="{{name}}" {{#if value}} checked {{/if}}>
<label class="form-check-label" for="input_{{name}}"> Standard: {{default}} </label>
</div>
</div>
{{/case}}
</div>
{{/if}}
{{/each}}
{{#case group "smtp"}}
<div class="row my-2 align-items-center pt-3 border-top" title="Verschickt eine Test-E-Mail an die angegebene E-Mail-Adresse.">
<label for="smtp-test-email" class="col-sm-3 col-form-label">SMTP-Konfigurationstest</label>
<div class="col-sm-8 input-group">
<input class="form-control" id="smtp-test-email" type="email" placeholder="E-Mail-Adresse" required spellcheck="false">
<button style="color: #333; background-color: #fda34a; border-color: #fda34a;" type="button" class="btn btn-outline-primary input-group-text" id="smtpTest">Abschicken</button>
<div class="invalid-tooltip">Bitte geben Sie eine korrekte E-Mail-Adresse an.</div>
</div>
</div>
{{/case}}
</div>
</div>
{{/if}}
{{/each}}
<div class="card mb-3">
<button id="b_readonly" type="button" class="card-header text-start btn btn-link text-decoration-none" aria-expanded="false" aria-controls="g_readonly"
data-bs-toggle="collapse" data-bs-target="#g_readonly">Read-Only Settings</button>
<div id="g_readonly" class="card-body collapse">
{{#each page_data.config}}
{{#each elements}}
{{#unless editable}}
<div class="row my-2 align-items-center alert-row" title="[{{name}}] {{doc.description}}">
{{#case type "text" "number" "password"}}
<label for="input_{{name}}" class="col-sm-3 col-form-label">{{doc.name}}</label>
<div class="col-sm-8">
<div class="input-group">
{{!--
Also set the database_url input as password here.
If we would set it to password in config.rs it will not be character masked for the support string.
And sometimes this is more useful for providing support than just 3 asterisk.
--}}
{{#if (eq name "database_url")}}
<input readonly class="form-control" id="input_{{name}}" type="password" value="{{value}}" {{#if default}} placeholder="Default: {{default}}" {{/if}}>
<button class="btn btn-outline-secondary" type="button" data-vw-pw-toggle="input_{{name}}">Anzeigen / Verbergen</button>
{{else}}
<input readonly class="form-control" id="input_{{name}}" type="{{type}}" value="{{value}}" {{#if default}} placeholder="Default: {{default}}" {{/if}} spellcheck="false">
{{#case type "password"}}
<button class="btn btn-outline-secondary" type="button" data-vw-pw-toggle="input_{{name}}">Anzeigen / Verbergen</button>
{{/case}}
{{/if}}
</div>
</div>
{{/case}}
{{#case type "checkbox"}}
<div class="col-sm-3 col-form-label">{{doc.name}}</div>
<div class="col-sm-8">
<div class="form-check align-middle">
<input disabled class="form-check-input" type="checkbox" id="input_{{name}}"
{{#if value}} checked {{/if}}>
<label class="form-check-label" for="input_{{name}}"> Standard: {{default}} </label>
</div>
</div>
{{/case}}
</div>
{{/unless}}
{{/each}}
{{/each}}
</div>
</div>
<button style="color: #333; background-color: #fda34a; border-color: #fda34a;" type="submit" class="btn btn-primary">Speichern</button>
<button style="color: #333; background-color: #fda34a; border-color: #fda34a;" type="button" class="btn btn-danger float-end" id="deleteConf">Zurücksetzen</button>
</form>
</div>
</div>
</main>
<style>
#config-block ::placeholder {
/* Most modern browsers support this now. */
color: orangered;
}
.is-overridden-true {
--bs-alert-color: #664d03;
--bs-alert-bg: #fff3cd;
--bs-alert-border-color: #ffecb5;
}
</style>
<script src="{{urlpath}}/vw_static/admin_settings.js"></script>

View File

@@ -0,0 +1,147 @@
<main class="container-xl">
<div id="users-block" class="my-3 p-3 rounded shadow">
<h6 class="border-bottom pb-2 mb-3">Registrierte Benutzer</h6>
<div class="table-responsive-xl small">
<table id="users-table" class="table table-sm table-striped table-hover">
<thead>
<tr>
<th class="vw-account-details">Benutzer</th>
<th style="padding: 0 50px 0 0 !important;" class="vw-created-at">Erstellt am</th>
<th class="vw-last-active">letzte Aktivität</th>
<th style="padding: 0 50px 0 0 !important;" class="vw-entries">Einträge</th>
<th class="vw-attachments">Anhänge</th>
<th class="vw-organizations">Organisationen</th>
<th class="vw-actions">Aktionen</th>
</tr>
</thead>
<tbody>
{{#each page_data}}
<tr>
<td>
<svg width="48" height="48" class="float-start me-2 rounded" data-jdenticon-value="{{email}}">
<div>
<strong>{{name}}</strong>
<span class="d-block">{{email}}</span>
<span class="d-block">
{{#unless user_enabled}}
<span class="badge bg-danger me-2">Deaktiviert</span>
{{/unless}}
{{#if twoFactorEnabled}}
<span class="badge bg-success me-2">2FA</span>
{{/if}}
{{#case _status 1}}
<span class="badge bg-warning text-dark me-2">Eingeladen</span>
{{/case}}
{{#if emailVerified}}
<span class="badge bg-success me-2">Verifiziert</span>
{{/if}}
</span>
</div>
</td>
<td>
<span class="d-block">{{created_at}}</span>
</td>
<td>
<span class="d-block">{{last_active}}</span>
</td>
<td>
<span class="d-block">{{cipher_count}}</span>
</td>
<td>
<span class="d-block"><strong>Menge:</strong> {{attachment_count}}</span>
{{#if attachment_count}}
<span class="d-block"><strong>Größe:</strong> {{attachment_size}}</span>
{{/if}}
</td>
<td>
<div class="overflow-auto vw-org-cell" data-vw-user-email="{{email}}" data-vw-user-uuid="{{id}}">
{{#each organizations}}
<button class="badge" data-bs-toggle="modal" data-bs-target="#userOrgTypeDialog" data-vw-org-type="{{type}}" data-vw-org-uuid="{{id}}" data-vw-org-name="{{name}}">{{name}}</button>
{{/each}}
</div>
</td>
<td class="text-end px-1 small">
<span data-vw-user-uuid="{{id}}" data-vw-user-email="{{email}}">
{{#if TwoFactorEnabled}}
<button type="button" class="btn btn-sm btn-link p-0 border-0 float-right" vw-remove2fa>2FA entfernen</button><br>
{{/if}}
<button type="button" class="btn btn-sm btn-link p-0 border-0 float-right" vw-deauth-user>Sitzungen deautorisieren</button><br>
<button type="button" class="btn btn-sm btn-link p-0 border-0 float-right" vw-delete-user>Benutzer löschen</button><br>
{{#if user_enabled}}
<button type="button" class="btn btn-sm btn-link p-0 border-0 float-right" vw-disable-user>Benutzer deaktivieren</button><br>
{{else}}
<button type="button" class="btn btn-sm btn-link p-0 border-0 float-right" vw-enable-user>Benutzer aktivieren</button><br>
{{/if}}
{{#case _Status 1}}
<button type="button" class="btn btn-sm btn-link p-0 border-0 float-right" vw-resend-user-invite>Einladung erneut senden</button><br>
{{/case}}
</span>
</td>
</tr>
{{/each}}
</tbody>
</table>
</div>
<div class="mt-3 clearfix">
<button style="color: #333; background-color: #fda34a; border-color: #fda34a;" type="button" class="btn btn-sm btn-danger" id="updateRevisions"
title="Zwingt alle Clients zur Synchronisation bei der nächsten Anmeldung.">
Synchronisieren
</button>
<button style="color: #333; background-color: #fda34a; border-color: #fda34a;" type="button" class="btn btn-sm btn-primary float-end" id="reload">Aktualisieren</button>
</div>
</div>
<div id="inviteUserFormBlock" class="align-items-center p-3 mb-3 text-white-50 bg-secondary rounded shadow">
<div>
<h6 style="margin: 16px auto !important; text-align: center !important; font-size: 1.4rem !important" class="mb-0 text-white">Registrierung</h6>
<form class="form-inline" id="inviteUserForm">
<input style="margin: 20px auto 10px auto;" type="email" class="form-control w-50" id="inviteEmail" placeholder="E-Mail-Adresse" required spellcheck="false" autofocus="autofocus">
<button style="display: block; margin: 20px auto 16px auto; color: #333; background-color: #fda34a; border-color: #fda34a;" type="submit" class="btn btn-primary">Anmelden</button>
</form>
</div>
</div>
<div id="userOrgTypeDialog" class="modal fade" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered modal-sm">
<div class="modal-content">
<div class="modal-header">
<h6 class="modal-title">
<b>Update User Type:</b><br><b>Organisation:</b> <span id="userOrgTypeDialogOrgName"></span><br><b>Benutzer:</b> <span id="userOrgTypeDialogUserEmail"></span>
</h6>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<form class="form" id="userOrgTypeForm">
<input type="hidden" name="user_uuid" id="userOrgTypeUserUuid" value="">
<input type="hidden" name="org_uuid" id="userOrgTypeOrgUuid" value="">
<div class="modal-body">
<div class="radio">
<label><input type="radio" value="2" class="form-radio-input" name="user_type" id="userOrgTypeUser">&nbsp;Benutzer</label>
</div>
<div class="radio">
<label><input type="radio" value="3" class="form-radio-input" name="user_type" id="userOrgTypeManager">&nbsp;Operator</label>
</div>
<div class="radio">
<label><input type="radio" value="1" class="form-radio-input" name="user_type" id="userOrgTypeAdmin">&nbsp;Administrator</label>
</div>
<div class="radio">
<label><input type="radio" value="0" class="form-radio-input" name="user_type" id="userOrgTypeOwner">&nbsp;Besitzer</label>
</div>
</div>
<div class="modal-footer">
<button style="color: #333; background-color: #fda34a; border-color: #fda34a;" type="button" class="btn btn-sm btn-secondary" data-bs-dismiss="modal">Abbrechen</button>
<button style="color: #333; background-color: #fda34a; border-color: #fda34a;" type="submit" class="btn btn-sm btn-primary">Rolle bearbeiten</button>
</div>
</form>
</div>
</div>
</div>
</main>
<link rel="stylesheet" href="{{urlpath}}/vw_static/datatables.css" />
<script src="{{urlpath}}/vw_static/jquery-3.7.1.slim.js"></script>
<script src="{{urlpath}}/vw_static/datatables.js"></script>
<script src="{{urlpath}}/vw_static/admin_users.js"></script>
<script src="{{urlpath}}/vw_static/jdenticon-3.3.0.js"></script>