Compare commits
3 Commits
v0.11.103.1
...
v0.11.105
| Author | SHA1 | Date | |
|---|---|---|---|
| 7846342412 | |||
| 2d0e9989ed | |||
| 92f3430892 |
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "site-gateway",
|
||||
"version": "0.11.102",
|
||||
"version": "0.11.105",
|
||||
"private": true,
|
||||
"description": "Site Gateway: simple self-hosted website publishing, reverse proxying, and automatic HTTPS.",
|
||||
"type": "module",
|
||||
|
||||
+1
-1
@@ -413,7 +413,7 @@ function render() {
|
||||
return;
|
||||
}
|
||||
if (!management) {
|
||||
const headings = { certificates:["Certificates","Expiration, issuer, and certificate-detection status for automatic HTTPS."], logs:["Access Logs & Gateway Events","Recent requests, upstream responses, and gateway health events served through Caddy."], performance:["Performance","Live and historical request throughput across your gateway."], administration:["Administration","Users, gateway defaults, backups, security, and updates."], streaming:["Streaming hosts","Forward raw TCP/UDP traffic on a specific port straight to another host and port."], redirects:["Redirect hosts","Send domains to a new destination with clear, predictable rules."], access:["Access Lists","Create reusable network and login protection for your hosts."], documentation:["Documentation","Plain-language guidance and real-world Site Gateway examples."], account:["My Account","Manage your profile, password, and two-factor authentication."] };
|
||||
const headings = { certificates:["Certificates","Expiration, issuer, and certificate-detection status for automatic HTTPS."], logs:["Access Logs & Gateway Events","Recent requests, upstream responses, and gateway health events served through Caddy."], performance:["Performance","Live and historical request throughput across your gateway."], administration:["Administration","Users, gateway defaults, backups, and updates."], streaming:["Streaming hosts","Forward raw TCP/UDP traffic on a specific port straight to another host and port."], redirects:["Redirect hosts","Send domains to a new destination with clear, predictable rules."], access:["Access Lists","Create reusable network and login protection for your hosts."], documentation:["Documentation","Plain-language guidance and real-world Site Gateway examples."], account:["My Account","Manage your profile, password, and two-factor authentication."] };
|
||||
const heading = headings[state.view] || ["Site Gateway",""]; $("#page-title").textContent = heading[0]; $("#page-subtitle").textContent = heading[1];
|
||||
$("#open-create").textContent = state.view === "administration" ? "+ Create user" : state.view === "streaming" ? "+ New streaming host" : state.view === "redirects" ? "+ New redirect host" : state.view === "access" ? "+ New Access List" : $("#open-create").textContent;
|
||||
if (state.view === "streaming") $("#stream-empty").classList.toggle("hidden", !state.loaded || state.streams.length > 0);
|
||||
|
||||
@@ -275,7 +275,7 @@ document.addEventListener("click", event => { if (event.target.closest(".create-
|
||||
function decorateAccessToggles() { document.querySelectorAll("#access-list [data-access-id]").forEach(card => { const item = state.accessLists.find(value => value.id === card.dataset.accessId); const footer = card.querySelector(".card-footer"); if (!footer || !item) return; card.querySelectorAll(".menu [data-access-action=toggle]").forEach(button => button.remove()); if (footer.querySelector("[data-access-action=toggle]")) return; let actions = footer.querySelector(".card-actions"); if (!actions) { actions = document.createElement("div"); actions.className = "card-actions"; footer.append(actions); } const toggle = document.createElement("button"); toggle.className = "toggle " + (item.enabled !== false ? "on" : ""); toggle.dataset.accessAction = "toggle"; toggle.setAttribute("aria-label", (item.enabled !== false ? "Disable" : "Enable") + " Access List"); toggle.innerHTML = "<span></span>"; actions.append(toggle); }); }
|
||||
function decorateGroupCards() { document.querySelectorAll('[data-admin-panel="groups"] .group-card').forEach(card => { const group = state.groups.find(value => value.id === card.querySelector("[data-group-action]")?.dataset.groupId); if (!group) return; const icon = card.querySelector(".site-icon"); if (icon && icon.textContent.trim() === "GR") icon.innerHTML = featureIcon(group, "GR"); const menu = card.querySelector(".menu"); if (menu && !menu.querySelector("[data-group-action=icon]")) { const button = document.createElement("button"); button.dataset.groupAction = "icon"; button.dataset.groupId = group.id; button.textContent = "Change icon"; menu.prepend(button); } }); }
|
||||
document.addEventListener("click", event => { const button = event.target.closest("[data-group-action=icon]"); if (!button) return; event.preventDefault(); event.stopImmediatePropagation(); openIconPicker("groups", button.dataset.groupId); }, true);
|
||||
function normalizeAdminTabOrder() { const tabs = document.querySelector(".admin-tabs"); if (!tabs) return; const order = ["users","groups","defaults","audit","backups","security","retention","danger"]; order.forEach((name, index) => { const button = tabs.querySelector(`[data-admin-tab="${name}"]`); if (button) { if (name === "retention") button.textContent = "Logs & Retention"; tabs.append(button); } }); }
|
||||
function normalizeAdminTabOrder() { const tabs = document.querySelector(".admin-tabs"); if (!tabs) return; const order = ["users","groups","defaults","audit","backups","retention","danger"]; order.forEach((name, index) => { const button = tabs.querySelector(`[data-admin-tab="${name}"]`); if (button) { if (name === "retention") button.textContent = "Logs & Retention"; tabs.append(button); } }); }
|
||||
document.addEventListener("click", event => { if (event.target.closest(".admin-tabs")) setTimeout(normalizeAdminTabOrder, 0); });
|
||||
|
||||
// --- Backup encryption password field: placeholder/visibility polish -------------
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<title>Site Gateway</title>
|
||||
<meta name="description" content="Host sites, proxy services, and manage HTTPS from one simple dashboard.">
|
||||
<link rel="icon" type="image/png" href="/site-gateway-icon-approved.png">
|
||||
<link rel="stylesheet" href="/styles.css?v=0.11.100">
|
||||
<link rel="stylesheet" href="/styles.css?v=0.11.104">
|
||||
</head>
|
||||
|
||||
<!-- ================================================================
|
||||
@@ -164,7 +164,7 @@
|
||||
<div><strong id="cert-healthy">0</strong><span>Healthy</span></div><div><strong id="cert-30">0</strong><span>Within 30 days</span></div><div><strong id="cert-7">0</strong><span>Within 7 days</span></div><div><strong id="cert-warning">0</strong><span>Needs attention</span></div><div><strong id="cert-pending">0</strong><span>Not detected</span></div>
|
||||
</div>
|
||||
<div class="diagnostic-section-heading"><p class="eyebrow">Certificate inventory</p><h2>Certificates</h2><p class="muted">Managed and uploaded certificates assigned to configured domains.</p></div><div id="certificate-list" class="data-list diagnostic-list"><p class="quiet-state">Loading certificates…</p></div>
|
||||
<section class="dashboard-panel readiness-panel"><div class="panel-heading"><div><p class="eyebrow">Guided diagnostics</p><h2>Domain readiness</h2><p class="muted">DNS, listener, TLS, and upstream checks for every configured domain.</p></div></div><div id="readiness-list" class="dashboard-list diagnostic-list"><p class="quiet-state">Checking configured domains…</p></div></section>
|
||||
<section class="dashboard-panel readiness-panel"><div class="panel-heading"><div><p class="eyebrow">Guided diagnostics</p><h2>Domain readiness</h2><p class="muted">DNS, listener, TLS, and upstream checks for every configured domain.</p></div></div><div id="readiness-list" class="dashboard-list diagnostic-list"><p class="quiet-state">Checking configured domains…</p></div></section><section class="dashboard-panel"><div class="panel-heading"><div><p class="eyebrow">Certificate health</p><h2>Renewal thresholds</h2><p class="muted">Control when a certificate is flagged as renewing soon, critical, or stale on this page and the dashboard.</p></div></div><form id="health-settings-form" class="settings-form"><label>Renewing-soon warning<input name="warningDays" type="number" min="8" max="120" value="30"><small>Days remaining before a certificate is highlighted.</small></label><label>Critical warning<input name="criticalDays" type="number" min="1" max="119" value="7"><small>Must be lower than the renewing-soon threshold.</small></label><label>Stale health data<input name="staleMinutes" type="number" min="2" max="1440" value="10"><small>Minutes before a displayed check is considered old.</small></label><div class="dialog-actions"><button class="button primary">Save health settings</button></div></form></section>
|
||||
</section>
|
||||
|
||||
<!-- Logs view: access log table + gateway event/activity log -->
|
||||
@@ -197,9 +197,9 @@
|
||||
</section>
|
||||
|
||||
<!-- Administration: tabbed panels (Users / Groups / Audit log / Logs & Retention /
|
||||
Gateway defaults / Backup & restore / Security & updates / Danger Zone) -->
|
||||
Gateway defaults / Backup & restore / Danger Zone) -->
|
||||
<section id="users-view" class="feature-view hidden">
|
||||
<div class="admin-tabs"><button class="tab-active" data-admin-tab="users">Users</button><button data-admin-tab="groups">Groups</button><button data-admin-tab="defaults">Gateway defaults</button><button data-admin-tab="audit">Audit log</button><button data-admin-tab="backups">Backup & restore</button><button data-admin-tab="security">Security & updates</button><button data-admin-tab="retention">Logs & Retention</button><button data-admin-tab="danger" class="danger-tab">Danger Zone</button></div>
|
||||
<div class="admin-tabs"><button class="tab-active" data-admin-tab="users">Users</button><button data-admin-tab="groups">Groups</button><button data-admin-tab="defaults">Gateway defaults</button><button data-admin-tab="audit">Audit log</button><button data-admin-tab="backups">Backup & restore</button><button data-admin-tab="retention">Logs & Retention</button><button data-admin-tab="danger" class="danger-tab">Danger Zone</button></div>
|
||||
<!-- Users tab -->
|
||||
<section data-admin-panel="users">
|
||||
<div id="user-summary" class="summary user-summary" aria-label="User summary"></div>
|
||||
@@ -227,9 +227,7 @@
|
||||
</div>
|
||||
</section>
|
||||
<!-- Backup & restore tab -->
|
||||
<section data-admin-panel="backups" class="hidden settings-panel"><div class="panel-heading"><div><h2>Backup & restore</h2><p class="muted">Create a copy, restore a previous version, or schedule automatic backups.</p></div><div class="row-actions"><button id="import-backup" class="button secondary">Import backup</button><button id="create-backup" class="button primary">Create backup</button></div></div><input id="backup-upload" type="file" accept=".sgbackup,application/zip" hidden><form id="backup-settings-form" class="settings-form backup-settings"><div class="form-section form-section-wide"><p class="eyebrow">Scheduled backups</p><div class="form-grid"><label class="check-control"><input name="enabled" type="checkbox"><span>Enable scheduled backups</span></label><label>Backup type<select name="type"><option value="complete">Complete (Recommended) — configuration + hosted files</option><option value="configuration">Configuration only</option></select><small id="backup-type-help">Configuration only includes settings and metadata, not uploaded Hosted Site files.</small></label><p id="backup-config-only-warning" class="callout hidden" style="grid-column:1/-1"><strong>Heads up</strong><span>Scheduled backups are set to Configuration only — they will not include your Hosted Site files, icons, or certificates. Switch to Complete if you want scheduled backups to protect those too.</span></p><label>Schedule<select name="frequency"><option value="daily">Daily</option><option value="weekly">Weekly</option><option value="monthly">Monthly</option></select></label><label>Hour<select name="hour"></select></label><label>Keep<input name="retention" type="number" min="1" max="100" value="7"></label><label class="check-control"><input name="includeLogs" type="checkbox"><span>Include logs</span></label></div></div><div class="form-section form-section-wide"><p class="eyebrow">Encryption</p><div class="form-grid encryption-grid"><label class="backup-password-field"><span class="field-label">Backup encryption password <span class="optional">Optional</span></span><input name="backupPassword" type="password" autocomplete="new-password"><small>Used for manually created backups and required when restoring an encrypted archive. It is not stored by Site Gateway.</small></label><label class="check-control encryption-toggle"><input name="encrypt" type="checkbox"><span>Encrypt scheduled backups<small>Uses the container’s <code>BACKUP_PASSWORD</code> value. Enable only after configuring that value.</small></span></label></div></div><div class="dialog-actions"><button class="button secondary">Save schedule</button></div></form><div class="callout"><strong>Storage guidance</strong><span id="backup-path">Backups are stored in /data/backups. Mount /backups separately to protect against appdata disk failure.</span><span id="backup-summary" class="backup-summary"></span></div><div id="backup-list" class="data-list"></div></section>
|
||||
<!-- Security & updates tab -->
|
||||
<section data-admin-panel="security" class="hidden settings-panel"><h2>Security, health & updates</h2><section class="dashboard-panel"><div class="panel-heading"><div><p class="eyebrow">Reliability</p><h2>Configuration safety & updates</h2></div></div><dl class="system-grid"><div class="system-tile"><dt>Configuration safety</dt><dd>Validates generated Caddy configuration before every reload and retains the active configuration when validation fails.</dd></div><div class="system-tile"><dt>Container updates</dt><dd>Installed by pulling a new pinned image. Create a backup before changing versions.</dd></div></dl></section><section class="dashboard-panel"><div class="panel-heading"><div><p class="eyebrow">Troubleshooting & support</p><h2>Gateway diagnostics</h2><p class="muted">Run checks and download a redacted report when you need to investigate a gateway issue.</p></div><button id="download-support" class="button secondary admin-only">Download support report</button></div><p class="muted feature-note">The report includes version, configuration health, certificate readiness, upstream checks, and recent events. Passwords, private keys, session secrets, cookies, and certificate contents are excluded.</p></section><form id="health-settings-form" class="settings-form"><label>Renewing-soon warning<input name="warningDays" type="number" min="8" max="120" value="30"><small>Days remaining before a certificate is highlighted.</small></label><label>Critical warning<input name="criticalDays" type="number" min="1" max="119" value="7"><small>Must be lower than the renewing-soon threshold.</small></label><label>Stale health data<input name="staleMinutes" type="number" min="2" max="1440" value="10"><small>Minutes before a displayed check is considered old.</small></label><div class="dialog-actions"><button class="button primary">Save health settings</button></div></form></section>
|
||||
<section data-admin-panel="backups" class="hidden settings-panel"><div class="panel-heading"><div><h2>Backup & restore</h2><p class="muted">Create a copy, restore a previous version, or schedule automatic backups.</p></div><div class="row-actions"><button id="import-backup" class="button secondary">Import backup</button><button id="create-backup" class="button primary">Create backup</button></div></div><input id="backup-upload" type="file" accept=".sgbackup,application/zip" hidden><form id="backup-settings-form" class="settings-form backup-settings"><div class="form-section form-section-wide"><p class="eyebrow">Scheduled backups</p><div class="form-grid"><label class="check-control"><input name="enabled" type="checkbox"><span>Enable scheduled backups</span></label><label>Backup type<select name="type"><option value="complete">Complete (Recommended) — configuration + hosted files</option><option value="configuration">Configuration only</option></select><small id="backup-type-help">Configuration only includes settings and metadata, not uploaded Hosted Site files.</small></label><p id="backup-config-only-warning" class="callout hidden" style="grid-column:1/-1"><strong>Heads up</strong><span>Scheduled backups are set to Configuration only — they will not include your Hosted Site files, icons, or certificates. Switch to Complete if you want scheduled backups to protect those too.</span></p><label>Schedule<select name="frequency"><option value="daily">Daily</option><option value="weekly">Weekly</option><option value="monthly">Monthly</option></select></label><label>Hour<select name="hour"></select></label><label>Keep<input name="retention" type="number" min="1" max="100" value="7"></label><label class="check-control"><input name="includeLogs" type="checkbox"><span>Include logs</span></label></div></div><div class="form-section form-section-wide"><p class="eyebrow">Encryption</p><div class="form-grid encryption-grid"><label class="backup-password-field"><span class="field-label">Backup encryption password <span class="optional">Optional</span></span><input name="backupPassword" type="password" autocomplete="new-password"><small>Used for manually created backups and required when restoring an encrypted archive. It is not stored by Site Gateway.</small></label><label class="check-control encryption-toggle"><input name="encrypt" type="checkbox"><span>Encrypt scheduled backups<small>Uses the container’s <code>BACKUP_PASSWORD</code> value. Enable only after configuring that value.</small></span></label></div></div><div class="dialog-actions"><button class="button secondary">Save schedule</button></div></form><div class="callout"><strong>Storage guidance</strong><span id="backup-path">Backups are stored in /data/backups. Mount /backups separately to protect against appdata disk failure.</span><span id="backup-summary" class="backup-summary"></span></div><div id="backup-list" class="data-list"></div></section><section class="dashboard-panel"><div class="panel-heading"><div><p class="eyebrow">Troubleshooting & support</p><h2>Gateway diagnostics</h2><p class="muted">Run checks and download a redacted report when you need to investigate a gateway issue.</p></div><button id="download-support" class="button secondary admin-only">Download support report</button></div><p class="muted feature-note">The report includes version, configuration health, certificate readiness, upstream checks, and recent events. Passwords, private keys, session secrets, cookies, and certificate contents are excluded.</p></section>
|
||||
<!-- Danger Zone tab -->
|
||||
<section data-admin-panel="danger" class="hidden settings-panel danger-zone"><h2>Danger Zone</h2><p class="muted">These actions can permanently remove Site Gateway data. Review each warning carefully before continuing.</p><div class="danger-card"><p class="eyebrow">Restore defaults</p><h3>Reset gateway preferences</h3><p>Restore default site behavior, backup scheduling, certificate thresholds, and interface preferences. Your users, routes, certificates, logs, and backups remain intact.</p><button id="restore-defaults" class="button secondary">Restore default settings</button></div><div class="danger-card destructive"><p class="eyebrow">Permanent action</p><h3>Factory reset</h3><p>Deletes all Site Gateway data under <code>/data</code>, including users, routes, certificates, logs, backups, and settings. Docker-mounted files outside <code>/data</code> are not affected. The container restarts at first-install setup.</p><form id="factory-reset-form" class="danger-form"><label>Administrator username<input name="username" autocomplete="username" required></label><label>Administrator password<input name="password" type="password" autocomplete="current-password" required></label><label>Type <strong>FACTORY RESET</strong> to confirm<input name="confirmation" required autocomplete="off"></label><p id="factory-reset-error" class="error"></p><div class="danger-actions"><button class="button secondary" type="button" id="factory-reset-cancel">Cancel</button><button class="button danger" type="submit">Erase all data and reset</button></div></form></div></section>
|
||||
</section>
|
||||
@@ -432,6 +430,6 @@
|
||||
<div id="toast" class="toast" role="status"></div>
|
||||
<div id="update-banner" class="update-banner hidden" role="status"><span>A new version of Site Gateway is available.</span><div class="update-banner-actions"><button id="update-banner-refresh" class="button primary">Refresh</button><button id="update-banner-dismiss" class="text-button">Dismiss</button></div></div>
|
||||
<!-- App scripts: core (app.js) then extended views/admin (features.js) -->
|
||||
<script src="/app.js?v=0.11.102" defer></script><script src="/features.js?v=0.11.100" defer></script>
|
||||
<script src="/app.js?v=0.11.105" defer></script><script src="/features.js?v=0.11.105" defer></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user