feat: add auth and dual-stack tls management
This commit is contained in:
+115
-37
@@ -1,9 +1,9 @@
|
||||
<!doctype html>
|
||||
<html lang="zh-CN">
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>数据源控制台</title>
|
||||
<title>Duplicati Control Center</title>
|
||||
<link rel="stylesheet" href="/styles.css">
|
||||
</head>
|
||||
<body>
|
||||
@@ -11,22 +11,29 @@
|
||||
<section class="hero hero-compact">
|
||||
<div>
|
||||
<p class="eyebrow">Zero-Bandwidth Duplicati Web Client</p>
|
||||
<h1>数据源控制台</h1>
|
||||
<h1>Duplicati Control Center</h1>
|
||||
</div>
|
||||
<p class="lead">
|
||||
首页现在只负责数据源级管理。任务上传、Server DB、全局 WebDAV 默认值和源列表已经拆成菜单式子面板,不再全部挤在同一屏。
|
||||
Manage task databases, Server DB metadata, global WebDAV defaults, and site-wide HTTPS/TLS settings here.
|
||||
Browsing, enhancement, preview, and download stay in the per-source and per-file workspaces.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<div class="auth-toolbar">
|
||||
<span id="authStatus" class="auth-status">Loading login state...</span>
|
||||
<button id="logoutButton" class="ghost-button" type="button">Sign out</button>
|
||||
</div>
|
||||
|
||||
<div id="feedback" class="feedback" hidden></div>
|
||||
|
||||
<section class="workspace-shell">
|
||||
<aside class="workspace-nav" aria-label="数据源控制台菜单">
|
||||
<a class="workspace-nav-link" href="#overview" data-view-link="overview">总览</a>
|
||||
<a class="workspace-nav-link" href="#sources" data-view-link="sources">数据源列表</a>
|
||||
<a class="workspace-nav-link" href="#upload" data-view-link="upload">新增任务库</a>
|
||||
<aside class="workspace-nav" aria-label="Control Center menu">
|
||||
<a class="workspace-nav-link" href="#overview" data-view-link="overview">Overview</a>
|
||||
<a class="workspace-nav-link" href="#sources" data-view-link="sources">Sources</a>
|
||||
<a class="workspace-nav-link" href="#upload" data-view-link="upload">Upload task DB</a>
|
||||
<a class="workspace-nav-link" href="#server-db" data-view-link="server-db">Server DB</a>
|
||||
<a class="workspace-nav-link" href="#defaults" data-view-link="defaults">全局 WebDAV</a>
|
||||
<a class="workspace-nav-link" href="#defaults" data-view-link="defaults">Global WebDAV</a>
|
||||
<a class="workspace-nav-link" href="#tls" data-view-link="tls">HTTPS / TLS</a>
|
||||
</aside>
|
||||
|
||||
<div class="workspace-content">
|
||||
@@ -35,10 +42,10 @@
|
||||
<div class="panel-header">
|
||||
<div>
|
||||
<p class="section-label">Overview</p>
|
||||
<h2>控制台总览</h2>
|
||||
<h2>System summary</h2>
|
||||
</div>
|
||||
</div>
|
||||
<div id="overviewSummary" class="summary-card">正在汇总控制台状态...</div>
|
||||
<div id="overviewSummary" class="summary-card">Loading overview...</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -47,14 +54,15 @@
|
||||
<div class="panel-header">
|
||||
<div>
|
||||
<p class="section-label">Sources</p>
|
||||
<h2>数据源列表</h2>
|
||||
<h2>Uploaded task databases</h2>
|
||||
</div>
|
||||
<button id="refreshButton" class="ghost-button" type="button">刷新列表</button>
|
||||
<button id="refreshButton" class="ghost-button" type="button">Refresh</button>
|
||||
</div>
|
||||
<p class="panel-copy">
|
||||
这里显示当前所有任务库 source。点击“进入工作台”会进入该任务自己的管理页;删除只会删除该 source,不会删除 <code>Duplicati-server.sqlite</code>。
|
||||
Each uploaded Duplicati task database becomes one source. Open a source workbench to browse files,
|
||||
start enhancement, or jump into the file workspace.
|
||||
</p>
|
||||
<div id="sourceList" class="source-list empty-state">正在读取数据源列表...</div>
|
||||
<div id="sourceList" class="source-list empty-state">Loading sources...</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -63,19 +71,20 @@
|
||||
<div class="panel-header">
|
||||
<div>
|
||||
<p class="section-label">Task DB</p>
|
||||
<h2>新增任务数据源</h2>
|
||||
<h2>Add a new source</h2>
|
||||
</div>
|
||||
</div>
|
||||
<p class="panel-copy">
|
||||
上传随机名任务库,例如 <code>TMQRJYNADS.sqlite</code>。每个任务库都会保留成独立 source,不会互相覆盖。
|
||||
Upload a Duplicati task database such as <code>TMQRJYNADS.sqlite</code>. Re-uploading the same file
|
||||
reuses the existing source instead of creating a duplicate.
|
||||
</p>
|
||||
<form id="uploadForm" class="upload-form">
|
||||
<label class="file-picker">
|
||||
<span>选择任务 SQLite 文件</span>
|
||||
<span>Select task SQLite file</span>
|
||||
<input id="databaseInput" name="database" type="file" accept=".sqlite,.db,application/octet-stream">
|
||||
</label>
|
||||
<div class="form-actions">
|
||||
<button id="uploadButton" class="primary-button" type="submit">上传为新数据源</button>
|
||||
<button id="uploadButton" class="primary-button" type="submit">Upload as new source</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
@@ -86,22 +95,23 @@
|
||||
<div class="panel-header">
|
||||
<div>
|
||||
<p class="section-label">Server DB</p>
|
||||
<h2>上传服务器数据库</h2>
|
||||
<h2>Upload Duplicati-server.sqlite</h2>
|
||||
</div>
|
||||
</div>
|
||||
<p class="panel-copy">
|
||||
上传 <code>Duplicati-server.sqlite</code> 后,系统会把随机任务库名映射回友好的任务名,并尝试推导每个任务的默认 WebDAV 目标 URL。
|
||||
The server database lets the UI resolve friendly task names and infer default target URLs from
|
||||
Duplicati metadata.
|
||||
</p>
|
||||
<form id="serverDbForm" class="upload-form">
|
||||
<label class="file-picker">
|
||||
<span>选择服务器数据库</span>
|
||||
<span>Select server database</span>
|
||||
<input id="serverDbInput" name="database" type="file" accept=".sqlite,.db,application/octet-stream">
|
||||
</label>
|
||||
<div class="form-actions">
|
||||
<button id="serverDbUploadButton" class="ghost-button" type="submit">上传 Server DB</button>
|
||||
<button id="serverDbUploadButton" class="ghost-button" type="submit">Upload Server DB</button>
|
||||
</div>
|
||||
</form>
|
||||
<div id="serverDbSummary" class="summary-card">正在读取当前 Server DB 状态...</div>
|
||||
<div id="serverDbSummary" class="summary-card">Loading Server DB status...</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -110,42 +120,110 @@
|
||||
<div class="panel-header">
|
||||
<div>
|
||||
<p class="section-label">Global WebDAV</p>
|
||||
<h2>保存全局默认值</h2>
|
||||
<h2>Shared defaults</h2>
|
||||
</div>
|
||||
</div>
|
||||
<p class="panel-copy">
|
||||
WebDAV 用户名、密码和备份口令如果大多数任务都共用,可以在这里全局保存一次。单个任务的目标 URL 会优先从 <code>Duplicati-server.sqlite</code> 自动推导。
|
||||
Save credentials and a fallback base URL once when most tasks share the same WebDAV settings.
|
||||
</p>
|
||||
<form id="globalDefaultsForm" class="secret-form">
|
||||
<label>
|
||||
<span>Fallback WebDAV Base URL</span>
|
||||
<input id="globalWebdavBaseUrl" name="webdavBaseUrl" type="url" placeholder="可选,全局兜底 URL">
|
||||
<input id="globalWebdavBaseUrl" name="webdavBaseUrl" type="url" placeholder="Optional shared base URL">
|
||||
</label>
|
||||
<label>
|
||||
<span>认证方式</span>
|
||||
<span>Authentication mode</span>
|
||||
<select id="globalAuthMode" name="authMode">
|
||||
<option value="">自动 / 继承</option>
|
||||
<option value="">Auto / inherited</option>
|
||||
<option value="basic">Basic</option>
|
||||
<option value="anonymous">Anonymous</option>
|
||||
</select>
|
||||
</label>
|
||||
<label>
|
||||
<span>用户名</span>
|
||||
<input id="globalUsername" name="username" type="text" placeholder="可选,共用用户名">
|
||||
<span>Username</span>
|
||||
<input id="globalUsername" name="username" type="text" placeholder="Optional shared username">
|
||||
</label>
|
||||
<label>
|
||||
<span>密码</span>
|
||||
<input id="globalPassword" name="password" type="password" placeholder="可选,共用密码">
|
||||
<span>Password</span>
|
||||
<input id="globalPassword" name="password" type="password" placeholder="Optional shared password">
|
||||
</label>
|
||||
<label>
|
||||
<span>备份口令</span>
|
||||
<input id="globalPassphrase" name="passphrase" type="password" placeholder="共用的备份口令">
|
||||
<span>Backup passphrase</span>
|
||||
<input id="globalPassphrase" name="passphrase" type="password" placeholder="Optional shared passphrase">
|
||||
</label>
|
||||
<div class="form-actions">
|
||||
<button id="globalDefaultsSaveButton" class="ghost-button" type="submit">保存全局默认值</button>
|
||||
<button id="globalDefaultsSaveButton" class="ghost-button" type="submit">Save defaults</button>
|
||||
</div>
|
||||
</form>
|
||||
<div id="globalDefaultsSummary" class="summary-card">Loading WebDAV defaults...</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="workspace-panel" data-view-panel="tls" hidden>
|
||||
<div class="panel stack-gap">
|
||||
<div class="panel-header">
|
||||
<div>
|
||||
<p class="section-label">HTTPS / TLS</p>
|
||||
<h2>Domain and certificate settings</h2>
|
||||
</div>
|
||||
</div>
|
||||
<p class="panel-copy">
|
||||
HTTP and HTTPS stay enabled side-by-side. If no custom certificate is configured, the service keeps a
|
||||
self-signed certificate ready so HTTPS is always available.
|
||||
</p>
|
||||
<div id="tlsSummary" class="summary-card">Loading TLS configuration...</div>
|
||||
|
||||
<form id="tlsJsonForm" class="secret-form">
|
||||
<label>
|
||||
<span>Certificate mode</span>
|
||||
<select id="tlsMode" name="mode">
|
||||
<option value="self-signed">Self-signed</option>
|
||||
<option value="custom-pem">Custom PEM</option>
|
||||
</select>
|
||||
</label>
|
||||
<label>
|
||||
<span>Primary domain</span>
|
||||
<input id="tlsPrimaryDomain" name="primaryDomain" type="text" placeholder="Example: preview.example.com">
|
||||
</label>
|
||||
<label>
|
||||
<span>Additional SAN entries</span>
|
||||
<textarea id="tlsSubjectAltNames" name="subjectAltNames" rows="3" placeholder="One hostname or IP per line. Comma-separated values also work."></textarea>
|
||||
</label>
|
||||
<label>
|
||||
<span>Certificate PEM</span>
|
||||
<textarea id="tlsCertPem" name="certPem" rows="8" placeholder="-----BEGIN CERTIFICATE-----"></textarea>
|
||||
</label>
|
||||
<label>
|
||||
<span>Private key PEM</span>
|
||||
<textarea id="tlsKeyPem" name="keyPem" rows="8" placeholder="-----BEGIN PRIVATE KEY-----"></textarea>
|
||||
</label>
|
||||
<label>
|
||||
<span>Optional chain PEM</span>
|
||||
<textarea id="tlsChainPem" name="chainPem" rows="6" placeholder="Optional intermediate certificates"></textarea>
|
||||
</label>
|
||||
<div class="form-actions">
|
||||
<button id="tlsSaveButton" class="primary-button" type="submit">Save and apply</button>
|
||||
<button id="tlsDeleteCustomButton" class="ghost-button danger-button" type="button">Delete custom cert and fall back</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<form id="tlsUploadForm" class="upload-form">
|
||||
<label class="file-picker">
|
||||
<span>Upload certificate file</span>
|
||||
<input id="tlsCertificateInput" name="certificate" type="file" accept=".pem,.crt,.cer,text/plain">
|
||||
</label>
|
||||
<label class="file-picker">
|
||||
<span>Upload private key file</span>
|
||||
<input id="tlsPrivateKeyInput" name="privateKey" type="file" accept=".pem,.key,text/plain">
|
||||
</label>
|
||||
<label class="file-picker">
|
||||
<span>Upload optional chain file</span>
|
||||
<input id="tlsChainInput" name="chain" type="file" accept=".pem,.crt,.cer,text/plain">
|
||||
</label>
|
||||
<div class="form-actions">
|
||||
<button id="tlsUploadButton" class="ghost-button" type="submit">Apply uploaded certificate</button>
|
||||
</div>
|
||||
</form>
|
||||
<div id="globalDefaultsSummary" class="summary-card">正在读取全局默认值...</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user