Port upstream security fixes and features from ngoduykhanh/wireguard-ui
- Escape HTML in client list and wake-on-LAN names to prevent XSS - Log successful/failed login attempts with remote address - Fix leading-comma bug in AllowedIPs template when only extra allowed IPs are set - Add PreUp script support for server interfaces (alongside existing PostUp/PreDown/PostDown) - Fix endpoint parsing to support IPv6 addresses (upstream PR #223) Cherry-picked from upstream PRs #656, #653, #680, #673, #223. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
5a7709bc6e
commit
fc0d192e59
@@ -1593,3 +1593,529 @@ Keine Commits in dieser Session.
|
||||
- templates/servers.html | 4 ++--
|
||||
|
||||
---
|
||||
## 2026-07-12 16:27 – 16:27 (0m)
|
||||
**Beschreibung:** Claude Code Session
|
||||
**Projekt:** wireguard-ui-multi
|
||||
|
||||
### Commits
|
||||
- 58db683 Remove legacy default-server page, unify on multi-server registry
|
||||
|
||||
### Geänderte Dateien
|
||||
- DEVLOG.md | 140 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
- handler/routes.go | 108 ++++++++++++++++++----------------------------------
|
||||
- main.go | 7 ++--
|
||||
- router/router.go | 6 ---
|
||||
- store/jsondb/jsondb.go | 57 +++++-----------------------
|
||||
- store/store.go | 3 --
|
||||
- templates/base.html | 10 -----
|
||||
- templates/server.html | 255 --------------------------------------------------------------------------------------------------------------------------
|
||||
- templates/servers.html | 177 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
- util/util.go | 4 +-
|
||||
|
||||
---
|
||||
## 2026-07-12 16:28 – 16:29 (0m)
|
||||
**Beschreibung:** Claude Code Session
|
||||
**Projekt:** wireguard-ui-multi
|
||||
|
||||
### Commits
|
||||
Keine Commits in dieser Session.
|
||||
|
||||
### Geänderte Dateien
|
||||
- DEVLOG.md | 140 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
- handler/routes.go | 108 ++++++++++++++++++----------------------------------
|
||||
- main.go | 7 ++--
|
||||
- router/router.go | 6 ---
|
||||
- store/jsondb/jsondb.go | 57 +++++-----------------------
|
||||
- store/store.go | 3 --
|
||||
- templates/base.html | 10 -----
|
||||
- templates/server.html | 255 --------------------------------------------------------------------------------------------------------------------------
|
||||
- templates/servers.html | 177 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
- util/util.go | 4 +-
|
||||
|
||||
---
|
||||
## 2026-07-12 16:31 – 16:31 (0m)
|
||||
**Beschreibung:** Claude Code Session
|
||||
**Projekt:** wireguard-ui-multi
|
||||
|
||||
### Commits
|
||||
Keine Commits in dieser Session.
|
||||
|
||||
### Geänderte Dateien
|
||||
- DEVLOG.md | 140 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
- handler/routes.go | 108 ++++++++++++++++++----------------------------------
|
||||
- main.go | 7 ++--
|
||||
- router/router.go | 6 ---
|
||||
- store/jsondb/jsondb.go | 57 +++++-----------------------
|
||||
- store/store.go | 3 --
|
||||
- templates/base.html | 10 -----
|
||||
- templates/server.html | 255 --------------------------------------------------------------------------------------------------------------------------
|
||||
- templates/servers.html | 177 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
- util/util.go | 4 +-
|
||||
|
||||
---
|
||||
## 2026-07-12 16:31 – 16:32 (0m)
|
||||
**Beschreibung:** Claude Code Session
|
||||
**Projekt:** wireguard-ui-multi
|
||||
|
||||
### Commits
|
||||
- 9c90e3f Rewrite About page for the fork, drop upstream GitHub API calls
|
||||
|
||||
### Geänderte Dateien
|
||||
- templates/about.html | 104 +++++++-------------------------------------------------------------------------------------------------
|
||||
|
||||
---
|
||||
## 2026-07-12 16:32 – 16:33 (0m)
|
||||
**Beschreibung:** Claude Code Session
|
||||
**Projekt:** wireguard-ui-multi
|
||||
|
||||
### Commits
|
||||
Keine Commits in dieser Session.
|
||||
|
||||
### Geänderte Dateien
|
||||
- templates/about.html | 104 +++++++-------------------------------------------------------------------------------------------------
|
||||
|
||||
---
|
||||
## 2026-07-12 16:34 – 16:35 (1m)
|
||||
**Beschreibung:** Claude Code Session
|
||||
**Projekt:** wireguard-ui-multi
|
||||
|
||||
### Commits
|
||||
Keine Commits in dieser Session.
|
||||
|
||||
### Geänderte Dateien
|
||||
- templates/about.html | 104 +++++++-------------------------------------------------------------------------------------------------
|
||||
|
||||
---
|
||||
## 2026-07-12 16:36 – 16:38 (2m)
|
||||
**Beschreibung:** Claude Code Session
|
||||
**Projekt:** wireguard-ui-multi
|
||||
|
||||
### Commits
|
||||
- 0000643 Add missing server delete: handler, route, and UI button
|
||||
|
||||
### Geänderte Dateien
|
||||
- handler/routes.go | 13 +++++++++++++
|
||||
- main.go | 1 +
|
||||
- templates/servers.html | 31 +++++++++++++++++++++++++++++++
|
||||
|
||||
---
|
||||
## 2026-07-12 16:39 – 16:39 (0m)
|
||||
**Beschreibung:** Claude Code Session
|
||||
**Projekt:** wireguard-ui-multi
|
||||
|
||||
### Commits
|
||||
Keine Commits in dieser Session.
|
||||
|
||||
### Geänderte Dateien
|
||||
- handler/routes.go | 13 +++++++++++++
|
||||
- main.go | 1 +
|
||||
- templates/servers.html | 31 +++++++++++++++++++++++++++++++
|
||||
|
||||
---
|
||||
## 2026-07-12 16:41 – 16:51 (9m)
|
||||
**Beschreibung:** Claude Code Session
|
||||
**Projekt:** wireguard-ui-multi
|
||||
|
||||
### Commits
|
||||
Keine Commits in dieser Session.
|
||||
|
||||
### Geänderte Dateien
|
||||
- handler/routes.go | 13 +++++++++++++
|
||||
- main.go | 1 +
|
||||
- templates/servers.html | 31 +++++++++++++++++++++++++++++++
|
||||
|
||||
---
|
||||
## 2026-07-12 16:52 – 16:52 (0m)
|
||||
**Beschreibung:** Claude Code Session
|
||||
**Projekt:** wireguard-ui-multi
|
||||
|
||||
### Commits
|
||||
- 28eb08d Add nftables firewall ruleset preview per server (review-only)
|
||||
|
||||
### Geänderte Dateien
|
||||
- firewall/nftables.go | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
- handler/routes.go | 18 ++++++++++++++++++
|
||||
- main.go | 1 +
|
||||
- model/setting.go | 7 ++++++-
|
||||
- templates/servers.html | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
|
||||
|
||||
---
|
||||
## 2026-07-12 16:57 – 17:31 (33m)
|
||||
**Beschreibung:** Claude Code Session
|
||||
**Projekt:** wireguard-ui-multi
|
||||
|
||||
### Commits
|
||||
- 1d08090 Add live firewall rule management per server (nftables)
|
||||
|
||||
### Geänderte Dateien
|
||||
- firewall/apply.go | 44 ++++++++++++++++++++++++++++++
|
||||
- firewall/nftables.go | 76 +++++++++++++++++++++++++++++++++++++++-------------
|
||||
- handler/routes.go | 155 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
|
||||
- main.go | 5 ++++
|
||||
- model/firewall.go | 21 +++++++++++++++
|
||||
- store/jsondb/jsondb.go | 59 +++++++++++++++++++++++++++++++++++++++++
|
||||
- store/store.go | 4 +++
|
||||
- templates/servers.html | 178 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------
|
||||
|
||||
---
|
||||
## 2026-07-12 17:33 – 17:35 (2m)
|
||||
**Beschreibung:** Claude Code Session
|
||||
**Projekt:** wireguard-ui-multi
|
||||
|
||||
### Commits
|
||||
- bdcf1ec Add read-only OS package update status (apt) on the About page
|
||||
|
||||
### Geänderte Dateien
|
||||
- handler/routes.go | 9 +++++++++
|
||||
- main.go | 1 +
|
||||
- system/updates.go | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
- templates/about.html | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
---
|
||||
## 2026-07-12 17:36 – 17:36 (0m)
|
||||
**Beschreibung:** Claude Code Session
|
||||
**Projekt:** wireguard-ui-multi
|
||||
|
||||
### Commits
|
||||
Keine Commits in dieser Session.
|
||||
|
||||
### Geänderte Dateien
|
||||
- handler/routes.go | 9 +++++++++
|
||||
- main.go | 1 +
|
||||
- system/updates.go | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
- templates/about.html | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
---
|
||||
## 2026-07-12 17:36 – 17:36 (0m)
|
||||
**Beschreibung:** Claude Code Session
|
||||
**Projekt:** wireguard-ui-multi
|
||||
|
||||
### Commits
|
||||
Keine Commits in dieser Session.
|
||||
|
||||
### Geänderte Dateien
|
||||
- handler/routes.go | 9 +++++++++
|
||||
- main.go | 1 +
|
||||
- system/updates.go | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
- templates/about.html | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
---
|
||||
## 2026-07-12 17:40 – 17:45 (5m)
|
||||
**Beschreibung:** Claude Code Session
|
||||
**Projekt:** wireguard-ui-multi
|
||||
|
||||
### Commits
|
||||
- eb1913d Add central host-wide firewall allow/block lists
|
||||
|
||||
### Geänderte Dateien
|
||||
- firewall/apply.go | 28 ++++++++++++------
|
||||
- firewall/global.go | 63 ++++++++++++++++++++++++++++++++++++++++
|
||||
- handler/routes.go | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
- main.go | 6 ++++
|
||||
- model/iplist.go | 15 ++++++++++
|
||||
- router/router.go | 6 ++++
|
||||
- store/jsondb/jsondb.go | 30 +++++++++++++++++++
|
||||
- store/store.go | 3 ++
|
||||
- templates/base.html | 8 +++++
|
||||
- templates/firewall_lists.html | 184 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
---
|
||||
## 2026-07-12 17:47 – 17:48 (0m)
|
||||
**Beschreibung:** Claude Code Session
|
||||
**Projekt:** wireguard-ui-multi
|
||||
|
||||
### Commits
|
||||
Keine Commits in dieser Session.
|
||||
|
||||
### Geänderte Dateien
|
||||
- firewall/apply.go | 28 ++++++++++++------
|
||||
- firewall/global.go | 63 ++++++++++++++++++++++++++++++++++++++++
|
||||
- handler/routes.go | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
- main.go | 6 ++++
|
||||
- model/iplist.go | 15 ++++++++++
|
||||
- router/router.go | 6 ++++
|
||||
- store/jsondb/jsondb.go | 30 +++++++++++++++++++
|
||||
- store/store.go | 3 ++
|
||||
- templates/base.html | 8 +++++
|
||||
- templates/firewall_lists.html | 184 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
---
|
||||
## 2026-07-12 17:49 – 17:51 (1m)
|
||||
**Beschreibung:** Claude Code Session
|
||||
**Projekt:** wireguard-ui-multi
|
||||
|
||||
### Commits
|
||||
- 77ba2b4 Add bulk import for global firewall allow/block lists
|
||||
|
||||
### Geänderte Dateien
|
||||
- handler/routes.go | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
- main.go | 1 +
|
||||
- templates/firewall_lists.html | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
---
|
||||
## 2026-07-12 17:52 – 17:55 (3m)
|
||||
**Beschreibung:** Claude Code Session
|
||||
**Projekt:** wireguard-ui-multi
|
||||
|
||||
### Commits
|
||||
- 0f92317 Fix "no such file or directory" on first use of new collections
|
||||
|
||||
### Geänderte Dateien
|
||||
- store/jsondb/jsondb.go | 17 ++++++++++++++---
|
||||
|
||||
---
|
||||
## 2026-07-12 19:58 – 19:59 (0m)
|
||||
**Beschreibung:** Claude Code Session
|
||||
**Projekt:** wireguard-ui-multi
|
||||
|
||||
### Commits
|
||||
Keine Commits in dieser Session.
|
||||
|
||||
### Geänderte Dateien
|
||||
- store/jsondb/jsondb.go | 17 ++++++++++++++---
|
||||
|
||||
---
|
||||
## 2026-07-12 20:01 – 20:02 (0m)
|
||||
**Beschreibung:** Claude Code Session
|
||||
**Projekt:** wireguard-ui-multi
|
||||
|
||||
### Commits
|
||||
- a9649f6 Add .gitignore for private/ - local-only files never pushed to gitea
|
||||
|
||||
### Geänderte Dateien
|
||||
- .gitignore | 4 ++++
|
||||
|
||||
---
|
||||
## 2026-07-12 20:03 – 20:13 (9m)
|
||||
**Beschreibung:** Claude Code Session
|
||||
**Projekt:** wireguard-ui-multi
|
||||
|
||||
### Commits
|
||||
Keine Commits in dieser Session.
|
||||
|
||||
### Geänderte Dateien
|
||||
- .gitignore | 4 ++++
|
||||
|
||||
---
|
||||
## 2026-07-12 20:14 – 20:15 (0m)
|
||||
**Beschreibung:** Claude Code Session
|
||||
**Projekt:** wireguard-ui-multi
|
||||
|
||||
### Commits
|
||||
Keine Commits in dieser Session.
|
||||
|
||||
### Geänderte Dateien
|
||||
- .gitignore | 4 ++++
|
||||
|
||||
---
|
||||
## 2026-07-12 20:16 – 20:16 (0m)
|
||||
**Beschreibung:** Claude Code Session
|
||||
**Projekt:** wireguard-ui-multi
|
||||
|
||||
### Commits
|
||||
Keine Commits in dieser Session.
|
||||
|
||||
### Geänderte Dateien
|
||||
- .gitignore | 4 ++++
|
||||
|
||||
---
|
||||
## 2026-07-12 20:18 – 20:34 (15m)
|
||||
**Beschreibung:** Claude Code Session
|
||||
**Projekt:** wireguard-ui-multi
|
||||
|
||||
### Commits
|
||||
Keine Commits in dieser Session.
|
||||
|
||||
### Geänderte Dateien
|
||||
- .gitignore | 4 ++++
|
||||
|
||||
---
|
||||
## 2026-07-12 20:36 – 20:38 (2m)
|
||||
**Beschreibung:** Claude Code Session
|
||||
**Projekt:** wireguard-ui-multi
|
||||
|
||||
### Commits
|
||||
Keine Commits in dieser Session.
|
||||
|
||||
### Geänderte Dateien
|
||||
- .gitignore | 4 ++++
|
||||
|
||||
---
|
||||
## 2026-07-12 20:38 – 20:44 (5m)
|
||||
**Beschreibung:** Claude Code Session
|
||||
**Projekt:** wireguard-ui-multi
|
||||
|
||||
### Commits
|
||||
- 00d084a Fix nftables auto-merge syntax and block private/reserved ranges
|
||||
|
||||
### Geänderte Dateien
|
||||
- firewall/global.go | 4 ++--
|
||||
- handler/routes.go | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
---
|
||||
## 2026-07-12 20:45 – 20:45 (0m)
|
||||
**Beschreibung:** Claude Code Session
|
||||
**Projekt:** wireguard-ui-multi
|
||||
|
||||
### Commits
|
||||
Keine Commits in dieser Session.
|
||||
|
||||
### Geänderte Dateien
|
||||
- firewall/global.go | 4 ++--
|
||||
- handler/routes.go | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
---
|
||||
## 2026-07-12 20:48 – 20:52 (3m)
|
||||
**Beschreibung:** Claude Code Session
|
||||
**Projekt:** wireguard-ui-multi
|
||||
|
||||
### Commits
|
||||
- 5a7709b Add enable/disable toggle for the global firewall allow/block lists
|
||||
|
||||
### Geänderte Dateien
|
||||
- firewall/apply.go | 20 ++++++++++++++++++++
|
||||
- handler/routes.go | 32 ++++++++++++++++++++++++++++++++
|
||||
- main.go | 2 ++
|
||||
- templates/firewall_lists.html | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
---
|
||||
## 2026-07-12 23:00 – 23:00 (0m)
|
||||
**Beschreibung:** Claude Code Session
|
||||
**Projekt:** wireguard-ui-multi
|
||||
|
||||
### Commits
|
||||
Keine Commits in dieser Session.
|
||||
|
||||
### Geänderte Dateien
|
||||
- firewall/apply.go | 20 ++++++++++++++++++++
|
||||
- handler/routes.go | 32 ++++++++++++++++++++++++++++++++
|
||||
- main.go | 2 ++
|
||||
- templates/firewall_lists.html | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
---
|
||||
## 2026-07-12 23:00 – 23:01 (1m)
|
||||
**Beschreibung:** Claude Code Session
|
||||
**Projekt:** wireguard-ui-multi
|
||||
|
||||
### Commits
|
||||
Keine Commits in dieser Session.
|
||||
|
||||
### Geänderte Dateien
|
||||
- firewall/apply.go | 20 ++++++++++++++++++++
|
||||
- handler/routes.go | 32 ++++++++++++++++++++++++++++++++
|
||||
- main.go | 2 ++
|
||||
- templates/firewall_lists.html | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
---
|
||||
## 2026-07-12 23:02 – 23:02 (0m)
|
||||
**Beschreibung:** Claude Code Session
|
||||
**Projekt:** wireguard-ui-multi
|
||||
|
||||
### Commits
|
||||
Keine Commits in dieser Session.
|
||||
|
||||
### Geänderte Dateien
|
||||
- firewall/apply.go | 20 ++++++++++++++++++++
|
||||
- handler/routes.go | 32 ++++++++++++++++++++++++++++++++
|
||||
- main.go | 2 ++
|
||||
- templates/firewall_lists.html | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
---
|
||||
## 2026-07-12 23:03 – 23:04 (1m)
|
||||
**Beschreibung:** Claude Code Session
|
||||
**Projekt:** wireguard-ui-multi
|
||||
|
||||
### Commits
|
||||
Keine Commits in dieser Session.
|
||||
|
||||
### Geänderte Dateien
|
||||
- firewall/apply.go | 20 ++++++++++++++++++++
|
||||
- handler/routes.go | 32 ++++++++++++++++++++++++++++++++
|
||||
- main.go | 2 ++
|
||||
- templates/firewall_lists.html | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
---
|
||||
## 2026-07-12 23:05 – 23:06 (0m)
|
||||
**Beschreibung:** Claude Code Session
|
||||
**Projekt:** wireguard-ui-multi
|
||||
|
||||
### Commits
|
||||
Keine Commits in dieser Session.
|
||||
|
||||
### Geänderte Dateien
|
||||
- firewall/apply.go | 20 ++++++++++++++++++++
|
||||
- handler/routes.go | 32 ++++++++++++++++++++++++++++++++
|
||||
- main.go | 2 ++
|
||||
- templates/firewall_lists.html | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
---
|
||||
## 2026-07-12 23:14 – 23:14 (0m)
|
||||
**Beschreibung:** Claude Code Session
|
||||
**Projekt:** wireguard-ui-multi
|
||||
|
||||
### Commits
|
||||
Keine Commits in dieser Session.
|
||||
|
||||
### Geänderte Dateien
|
||||
- firewall/apply.go | 20 +++++++++++++
|
||||
- handler/routes.go | 32 +++++++++++++++++++++
|
||||
- main.go | 2 ++
|
||||
- templates/firewall_lists.html | 65 +++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
---
|
||||
## 2026-07-12 23:15 – 23:15 (0m)
|
||||
**Beschreibung:** Claude Code Session
|
||||
**Projekt:** wireguard-ui-multi
|
||||
|
||||
### Commits
|
||||
Keine Commits in dieser Session.
|
||||
|
||||
### Geänderte Dateien
|
||||
- firewall/apply.go | 20 +++++++++++++
|
||||
- handler/routes.go | 32 +++++++++++++++++++++
|
||||
- main.go | 2 ++
|
||||
- templates/firewall_lists.html | 65 +++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
---
|
||||
## 2026-07-12 23:17 – 23:21 (4m)
|
||||
**Beschreibung:** Claude Code Session
|
||||
**Projekt:** wireguard-ui-multi
|
||||
|
||||
### Commits
|
||||
Keine Commits in dieser Session.
|
||||
|
||||
### Geänderte Dateien
|
||||
- firewall/apply.go | 20 ++++++++++++++++++++
|
||||
- handler/routes.go | 32 ++++++++++++++++++++++++++++++++
|
||||
- main.go | 2 ++
|
||||
- templates/firewall_lists.html | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
---
|
||||
## 2026-07-12 23:22 – 23:22 (0m)
|
||||
**Beschreibung:** Claude Code Session
|
||||
**Projekt:** wireguard-ui-multi
|
||||
|
||||
### Commits
|
||||
Keine Commits in dieser Session.
|
||||
|
||||
### Geänderte Dateien
|
||||
- firewall/apply.go | 20 ++++++++++++++++++++
|
||||
- handler/routes.go | 32 ++++++++++++++++++++++++++++++++
|
||||
- main.go | 2 ++
|
||||
- templates/firewall_lists.html | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
---
|
||||
## 2026-07-12 23:24 – 23:26 (1m)
|
||||
**Beschreibung:** Claude Code Session
|
||||
**Projekt:** wireguard-ui-multi
|
||||
|
||||
### Commits
|
||||
Keine Commits in dieser Session.
|
||||
|
||||
### Geänderte Dateien
|
||||
- firewall/apply.go | 20 ++++++++++++++++++++
|
||||
- handler/routes.go | 32 ++++++++++++++++++++++++++++++++
|
||||
- main.go | 2 ++
|
||||
- templates/firewall_lists.html | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
---
|
||||
|
||||
+23
-15
@@ -1,3 +1,11 @@
|
||||
/*
|
||||
Hack using jQuery's text() method and a temporary element to escape html()
|
||||
utilizing jQuery.
|
||||
*/
|
||||
function escapeHtml(unsafe) {
|
||||
return $('<div/>').text(unsafe).html();
|
||||
}
|
||||
|
||||
function renderClientList(data) {
|
||||
$.each(data, function(index, obj) {
|
||||
// render telegram button
|
||||
@@ -6,13 +14,13 @@ function renderClientList(data) {
|
||||
telegramButton = `<div class="btn-group">
|
||||
<button type="button" class="btn btn-outline-primary btn-sm" data-toggle="modal"
|
||||
data-target="#modal_telegram_client" data-clientid="${obj.Client.id}"
|
||||
data-clientname="${obj.Client.name}">Telegram</button>
|
||||
data-clientname="${escapeHtml(obj.Client.name)}">Telegram</button>
|
||||
</div>`
|
||||
}
|
||||
|
||||
let telegramHtml = "";
|
||||
if (obj.Client.telegram_userid && obj.Client.telegram_userid.length > 0) {
|
||||
telegramHtml = `<span class="info-box-text" style="display: none"><i class="fas fa-tguserid"></i>${obj.Client.telegram_userid}</span>`
|
||||
telegramHtml = `<span class="info-box-text" style="display: none"><i class="fas fa-tguserid"></i>${escapeHtml(obj.Client.telegram_userid)}</span>`
|
||||
}
|
||||
|
||||
// render client status css tag style
|
||||
@@ -24,13 +32,13 @@ function renderClientList(data) {
|
||||
// render client allocated ip addresses
|
||||
let allocatedIpsHtml = "";
|
||||
$.each(obj.Client.allocated_ips, function(index, obj) {
|
||||
allocatedIpsHtml += `<small class="badge badge-secondary">${obj}</small> `;
|
||||
allocatedIpsHtml += `<small class="badge badge-secondary">${escapeHtml(obj)}</small> `;
|
||||
})
|
||||
|
||||
// render client allowed ip addresses
|
||||
let allowedIpsHtml = "";
|
||||
$.each(obj.Client.allowed_ips, function(index, obj) {
|
||||
allowedIpsHtml += `<small class="badge badge-secondary">${obj}</small> `;
|
||||
allowedIpsHtml += `<small class="badge badge-secondary">${escapeHtml(obj)}</small> `;
|
||||
})
|
||||
|
||||
let subnetRangesString = "";
|
||||
@@ -40,7 +48,7 @@ function renderClientList(data) {
|
||||
|
||||
let additionalNotesHtml = "";
|
||||
if (obj.Client.additional_notes && obj.Client.additional_notes.length > 0) {
|
||||
additionalNotesHtml = `<span class="info-box-text" style="display: none"><i class="fas fa-additional_notes"></i>${obj.Client.additional_notes.toUpperCase()}</span>`
|
||||
additionalNotesHtml = `<span class="info-box-text" style="display: none"><i class="fas fa-additional_notes"></i>${escapeHtml(obj.Client.additional_notes.toUpperCase())}</span>`
|
||||
}
|
||||
|
||||
// render client html content
|
||||
@@ -56,12 +64,12 @@ function renderClientList(data) {
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-outline-primary btn-sm" data-toggle="modal"
|
||||
data-target="#modal_qr_client" data-clientid="${obj.Client.id}"
|
||||
data-clientname="${obj.Client.name}" ${obj.QRCode != "" ? '' : ' disabled'}>QR code</button>
|
||||
data-clientname="${escapeHtml(obj.Client.name)}" ${obj.QRCode != "" ? '' : ' disabled'}>QR code</button>
|
||||
</div>
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-outline-primary btn-sm" data-toggle="modal"
|
||||
data-target="#modal_email_client" data-clientid="${obj.Client.id}"
|
||||
data-clientname="${obj.Client.name}">Email</button>
|
||||
data-clientname="${escapeHtml(obj.Client.name)}">Email</button>
|
||||
</div>
|
||||
${telegramButton}
|
||||
<div class="btn-group">
|
||||
@@ -72,22 +80,22 @@ function renderClientList(data) {
|
||||
<div class="dropdown-menu" role="menu">
|
||||
<a class="dropdown-item" href="#" data-toggle="modal"
|
||||
data-target="#modal_edit_client" data-clientid="${obj.Client.id}"
|
||||
data-clientname="${obj.Client.name}">Edit</a>
|
||||
data-clientname="${escapeHtml(obj.Client.name)}">Edit</a>
|
||||
<a class="dropdown-item" href="#" data-toggle="modal"
|
||||
data-target="#modal_pause_client" data-clientid="${obj.Client.id}"
|
||||
data-clientname="${obj.Client.name}">Disable</a>
|
||||
data-clientname="${escapeHtml(obj.Client.name)}">Disable</a>
|
||||
<a class="dropdown-item" href="#" data-toggle="modal"
|
||||
data-target="#modal_remove_client" data-clientid="${obj.Client.id}"
|
||||
data-clientname="${obj.Client.name}">Delete</a>
|
||||
data-clientname="${escapeHtml(obj.Client.name)}">Delete</a>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<span class="info-box-text"><i class="fas fa-user"></i> ${obj.Client.name}</span>
|
||||
<span class="info-box-text" style="display: none"><i class="fas fa-key"></i> ${obj.Client.public_key}</span>
|
||||
<span class="info-box-text" style="display: none"><i class="fas fa-subnetrange"></i>${subnetRangesString}</span>
|
||||
<span class="info-box-text"><i class="fas fa-user"></i> ${escapeHtml(obj.Client.name)}</span>
|
||||
<span class="info-box-text" style="display: none"><i class="fas fa-key"></i> ${escapeHtml(obj.Client.public_key)}</span>
|
||||
<span class="info-box-text" style="display: none"><i class="fas fa-subnetrange"></i>${escapeHtml(subnetRangesString)}</span>
|
||||
${telegramHtml}
|
||||
${additionalNotesHtml}
|
||||
<span class="info-box-text"><i class="fas fa-envelope"></i> ${obj.Client.email}</span>
|
||||
<span class="info-box-text"><i class="fas fa-envelope"></i> ${escapeHtml(obj.Client.email)}</span>
|
||||
<span class="info-box-text"><i class="fas fa-clock"></i>
|
||||
${prettyDateTime(obj.Client.created_at)}</span>
|
||||
<span class="info-box-text"><i class="fas fa-history"></i>
|
||||
@@ -95,7 +103,7 @@ function renderClientList(data) {
|
||||
<span class="info-box-text"><i class="fas fa-server" style="${obj.Client.use_server_dns ? "opacity: 1.0" : "opacity: 0.5"}"></i>
|
||||
${obj.Client.use_server_dns ? 'DNS enabled' : 'DNS disabled'}</span>
|
||||
<span class="info-box-text"><i class="fas fa-file"></i>
|
||||
${obj.Client.additional_notes}</span>
|
||||
${escapeHtml(obj.Client.additional_notes)}</span>
|
||||
<span class="info-box-text"><strong>IP Allocation</strong></span>`
|
||||
+ allocatedIpsHtml
|
||||
+ `<span class="info-box-text"><strong>Allowed IPs</strong></span>`
|
||||
|
||||
@@ -22,6 +22,8 @@ require (
|
||||
gopkg.in/go-playground/validator.v9 v9.31.0
|
||||
)
|
||||
|
||||
require github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2
|
||||
|
||||
require (
|
||||
github.com/go-playground/locales v0.14.1 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
github.com/NicoNex/echotron/v3 v3.27.0 h1:iq4BLPO+Dz1JHjh2HPk0D0NldAZSYcAjaOicgYEhUzw=
|
||||
github.com/NicoNex/echotron/v3 v3.27.0/go.mod h1:LpP5IyHw0y+DZUZMBgXEDAF9O8feXrQu7w7nlJzzoZI=
|
||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so=
|
||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
|
||||
github.com/coreos/bbolt v1.3.1-coreos.6.0.20180223184059-4f5275f4ebbf/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
|
||||
+3
-1
@@ -106,7 +106,7 @@ func Login(db store.IStore) echo.HandlerFunc {
|
||||
|
||||
dbuser, err := db.GetUserByName(username)
|
||||
if err != nil {
|
||||
log.Infof("Cannot query user %s from DB", username)
|
||||
log.Warnf("Invalid credentials. Cannot query user %s from DB (%s)", username, c.Request().RemoteAddr)
|
||||
return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "Invalid credentials"})
|
||||
}
|
||||
|
||||
@@ -161,9 +161,11 @@ func Login(db store.IStore) echo.HandlerFunc {
|
||||
cookie.SameSite = http.SameSiteLaxMode
|
||||
c.SetCookie(cookie)
|
||||
|
||||
log.Infof("Logged in successfully user %s (%s)", username, c.Request().RemoteAddr)
|
||||
return c.JSON(http.StatusOK, jsonHTTPResponse{true, "Logged in successfully"})
|
||||
}
|
||||
|
||||
log.Warnf("Invalid credentials user %s (%s)", username, c.Request().RemoteAddr)
|
||||
return c.JSON(http.StatusUnauthorized, jsonHTTPResponse{false, "Invalid credentials"})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ import (
|
||||
|
||||
var (
|
||||
// command-line banner information
|
||||
appVersion = "development"
|
||||
appVersion = strings.TrimSpace(embeddedVersion)
|
||||
gitCommit = "N/A"
|
||||
gitRef = "N/A"
|
||||
buildTime = fmt.Sprintf(time.Now().UTC().Format("01-02-2006 15:04:05"))
|
||||
@@ -74,6 +74,11 @@ var embeddedTemplates embed.FS
|
||||
//go:embed assets/*
|
||||
var embeddedAssets embed.FS
|
||||
|
||||
// embed the VERSION file
|
||||
//
|
||||
//go:embed VERSION
|
||||
var embeddedVersion string
|
||||
|
||||
func init() {
|
||||
// command-line flags and env variables
|
||||
flag.BoolVar(&flagDisableLogin, "disable-login", util.LookupEnvOrBool("DISABLE_LOGIN", flagDisableLogin), "Disable authentication on the app. This is potentially dangerous.")
|
||||
|
||||
@@ -25,6 +25,7 @@ type ServerInterface struct {
|
||||
Addresses []string `json:"addresses"`
|
||||
ListenPort int `json:"listen_port,string"` // ,string to get listen_port string input as int
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
PreUp string `json:"pre_up"`
|
||||
PostUp string `json:"post_up"`
|
||||
PreDown string `json:"pre_down"`
|
||||
PostDown string `json:"post_down"`
|
||||
|
||||
@@ -2,6 +2,7 @@ package router
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"html"
|
||||
"io"
|
||||
"io/fs"
|
||||
"reflect"
|
||||
@@ -124,6 +125,7 @@ func New(tmplDir fs.FS, extraData map[string]interface{}, secret [64]byte) *echo
|
||||
// create template list
|
||||
funcs := template.FuncMap{
|
||||
"StringsJoin": strings.Join,
|
||||
"attrescaper": html.EscapeString,
|
||||
}
|
||||
templates := make(map[string]*template.Template)
|
||||
templates["login.html"] = template.Must(template.New("login").Funcs(funcs).Parse(tmplLoginString))
|
||||
|
||||
@@ -70,7 +70,9 @@ func (o *JsonDB) Init() error {
|
||||
serverInterface := new(model.ServerInterface)
|
||||
serverInterface.Addresses = util.LookupEnvOrStrings(util.ServerAddressesEnvVar, []string{util.DefaultServerAddress})
|
||||
serverInterface.ListenPort = util.LookupEnvOrInt(util.ServerListenPortEnvVar, util.DefaultServerPort)
|
||||
serverInterface.PreUp = util.LookupEnvOrString(util.ServerPreUpScriptEnvVar, "")
|
||||
serverInterface.PostUp = util.LookupEnvOrString(util.ServerPostUpScriptEnvVar, "")
|
||||
serverInterface.PreDown = util.LookupEnvOrString(util.ServerPreDownScriptEnvVar, "")
|
||||
serverInterface.PostDown = util.LookupEnvOrString(util.ServerPostDownScriptEnvVar, "")
|
||||
serverInterface.UpdatedAt = time.Now().UTC()
|
||||
o.conn.Write("server", "interfaces", serverInterface)
|
||||
|
||||
@@ -143,6 +143,10 @@ All Servers
|
||||
<input type="text" class="form-control" id="_iface_listen_port" name="_iface_listen_port"
|
||||
placeholder="e.g. 51822">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="_iface_pre_up" class="control-label">Pre Up Script</label>
|
||||
<input type="text" class="form-control" id="_iface_pre_up" placeholder="Pre Up Script">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="_iface_post_up" class="control-label">Post Up Script</label>
|
||||
<input type="text" class="form-control" id="_iface_post_up" placeholder="Post Up Script">
|
||||
@@ -439,6 +443,7 @@ All Servers
|
||||
modal.find("#_iface_server_id").val(serverId);
|
||||
modal.find("#_iface_addresses").val((obj.Interface && obj.Interface.addresses) ? obj.Interface.addresses.join(", ") : "");
|
||||
modal.find("#_iface_listen_port").val(obj.Interface ? obj.Interface.listen_port : "");
|
||||
modal.find("#_iface_pre_up").val(obj.Interface ? obj.Interface.pre_up : "");
|
||||
modal.find("#_iface_post_up").val(obj.Interface ? obj.Interface.post_up : "");
|
||||
modal.find("#_iface_pre_down").val(obj.Interface ? obj.Interface.pre_down : "");
|
||||
modal.find("#_iface_post_down").val(obj.Interface ? obj.Interface.post_down : "");
|
||||
@@ -455,6 +460,7 @@ All Servers
|
||||
const data = {
|
||||
"addresses": addresses,
|
||||
"listen_port": $("#_iface_listen_port").val(),
|
||||
"pre_up": $("#_iface_pre_up").val(),
|
||||
"post_up": $("#_iface_post_up").val(),
|
||||
"pre_down": $("#_iface_pre_down").val(),
|
||||
"post_down": $("#_iface_post_down").val()
|
||||
|
||||
@@ -90,7 +90,7 @@
|
||||
<button type="button"
|
||||
class="btn btn-outline-primary btn-sm btn_modify_wake_on_lan_host"
|
||||
data-toggle="modal" data-target="#modal_wake_on_lan_host"
|
||||
data-name="{{ .Name }}" data-mac-address="{{ .MacAddress }}">Edit
|
||||
data-name="{{ .Name | attrescaper }}" data-mac-address="{{ .MacAddress }}">Edit
|
||||
</button>
|
||||
<button type="button" class="btn btn-outline-danger btn-sm" data-toggle="modal"
|
||||
data-target="#modal_remove_wake_on_lan_host"
|
||||
@@ -98,7 +98,7 @@
|
||||
</button>
|
||||
</div>
|
||||
<hr>
|
||||
<span class="info-box-text"><i class="fas fa-address-card"></i> <span class="name">{{ .Name }}</span></span>
|
||||
<span class="info-box-text"><i class="fas fa-address-card"></i> <span class="name">{{ .Name | attrescaper }}</span></span>
|
||||
<span class="info-box-text"><i class="fas fa-ethernet"></i> <span class="mac-address">{{ .MacAddress }}</span></span>
|
||||
<span class="info-box-text"><i class="fas fa-clock"></i>
|
||||
<span class="latest-used">
|
||||
|
||||
+9
-1
@@ -8,6 +8,7 @@ Address = {{$first :=true}}{{range .serverConfig.Interface.Addresses }}{{if $fir
|
||||
ListenPort = {{ .serverConfig.Interface.ListenPort }}
|
||||
PrivateKey = {{ .serverConfig.KeyPair.PrivateKey }}
|
||||
{{if .globalSettings.MTU}}MTU = {{ .globalSettings.MTU }}{{end}}
|
||||
PreUp = {{ .serverConfig.Interface.PreUp }}
|
||||
PostUp = {{ .serverConfig.Interface.PostUp }}
|
||||
PreDown = {{ .serverConfig.Interface.PreDown }}
|
||||
PostDown = {{ .serverConfig.Interface.PostDown }}
|
||||
@@ -27,7 +28,14 @@ Table = {{ .globalSettings.Table }}
|
||||
[Peer]
|
||||
PublicKey = {{ .Client.PublicKey }}
|
||||
{{if .Client.PresharedKey}}PresharedKey = {{ .Client.PresharedKey }}{{end}}
|
||||
AllowedIPs = {{$first :=true}}{{range .Client.AllocatedIPs }}{{if $first}}{{$first = false}}{{else}},{{end}}{{.}}{{end}}{{range .Client.ExtraAllowedIPs }},{{.}}{{end}}
|
||||
AllowedIPs = {{ $first := true }}
|
||||
{{- range .Client.AllocatedIPs -}}
|
||||
{{- if not $first}}, {{ end -}}{{ . -}}{{ $first = false -}}
|
||||
{{- end -}}
|
||||
{{- range .Client.ExtraAllowedIPs -}}
|
||||
{{- if not $first}}, {{ end -}}{{ . -}}{{ $first = false -}}
|
||||
{{- end }}
|
||||
{{"\n"}}
|
||||
{{if $.globalSettings.PersistentKeepalive}}PersistentKeepalive = {{ $.globalSettings.PersistentKeepalive }}{{end}}
|
||||
{{if .Client.Endpoint}}Endpoint = {{ .Client.Endpoint }}{{end}}
|
||||
{{end}}{{end}}
|
||||
|
||||
@@ -62,7 +62,9 @@ const (
|
||||
LogLevel = "WGUI_LOG_LEVEL"
|
||||
ServerAddressesEnvVar = "WGUI_SERVER_INTERFACE_ADDRESSES"
|
||||
ServerListenPortEnvVar = "WGUI_SERVER_LISTEN_PORT"
|
||||
ServerPreUpScriptEnvVar = "WGUI_SERVER_PRE_UP_SCRIPT"
|
||||
ServerPostUpScriptEnvVar = "WGUI_SERVER_POST_UP_SCRIPT"
|
||||
ServerPreDownScriptEnvVar = "WGUI_SERVER_PRE_DOWN_SCRIPT"
|
||||
ServerPostDownScriptEnvVar = "WGUI_SERVER_POST_DOWN_SCRIPT"
|
||||
DefaultClientAllowedIpsEnvVar = "WGUI_DEFAULT_CLIENT_ALLOWED_IPS"
|
||||
DefaultClientExtraAllowedIpsEnvVar = "WGUI_DEFAULT_CLIENT_EXTRA_ALLOWED_IPS"
|
||||
|
||||
+52
-9
@@ -21,6 +21,7 @@ import (
|
||||
"text/template"
|
||||
"time"
|
||||
|
||||
"github.com/asaskevich/govalidator"
|
||||
"github.com/ngoduykhanh/wireguard-ui/store"
|
||||
"github.com/ngoduykhanh/wireguard-ui/telegram"
|
||||
"github.com/skip2/go-qrcode"
|
||||
@@ -61,17 +62,10 @@ func BuildClientConfig(client model.Client, server model.Server, setting model.G
|
||||
|
||||
peerAllowedIPs := fmt.Sprintf("AllowedIPs = %s\n", strings.Join(client.AllowedIPs, ","))
|
||||
|
||||
desiredHost := setting.EndpointAddress
|
||||
desiredPort := server.Interface.ListenPort
|
||||
if strings.Contains(desiredHost, ":") {
|
||||
split := strings.Split(desiredHost, ":")
|
||||
desiredHost = split[0]
|
||||
if n, err := strconv.Atoi(split[1]); err == nil {
|
||||
desiredPort = n
|
||||
} else {
|
||||
desiredHost, desiredPort, err := ParseEndpoint(setting.EndpointAddress, server.Interface.ListenPort)
|
||||
if err != nil {
|
||||
log.Error("Endpoint appears to be incorrectly formatted: ", err)
|
||||
}
|
||||
}
|
||||
peerEndpoint := fmt.Sprintf("Endpoint = %s:%d\n", desiredHost, desiredPort)
|
||||
|
||||
peerPersistentKeepalive := ""
|
||||
@@ -900,3 +894,52 @@ func GetCookiePath() string {
|
||||
}
|
||||
return cookiePath
|
||||
}
|
||||
|
||||
func RemoveIPv6Brackets(host string) string {
|
||||
ipv6 := host
|
||||
if matchBrackets, _ := regexp.MatchString(`^\[.*\]$`, ipv6); matchBrackets {
|
||||
ipv6 = strings.Replace(ipv6, "[", "", -1)
|
||||
ipv6 = strings.Replace(ipv6, "]", "", -1)
|
||||
|
||||
// only remove brackets if valid ipv6 address
|
||||
if govalidator.IsIPv6(ipv6) {
|
||||
return ipv6
|
||||
}
|
||||
}
|
||||
return host
|
||||
}
|
||||
|
||||
func AddIPv6Brackets(host string) string {
|
||||
ipv6 := host
|
||||
|
||||
// only add brackets if valid ipv6 address
|
||||
if govalidator.IsIPv6(ipv6) {
|
||||
ipv6 = "[" + ipv6 + "]"
|
||||
return ipv6
|
||||
}
|
||||
return host
|
||||
}
|
||||
|
||||
func ParseEndpoint(host string, defaultPort int) (string, int, error) {
|
||||
port := defaultPort
|
||||
|
||||
// remove brackets from standalone IPv6 address
|
||||
host = RemoveIPv6Brackets(host)
|
||||
|
||||
if govalidator.IsIPv4(host) || govalidator.IsIPv6(host) || govalidator.IsDNSName(host) {
|
||||
return AddIPv6Brackets(host), port, nil
|
||||
}
|
||||
|
||||
// check if specific port contained
|
||||
host, strPort, err := net.SplitHostPort(host)
|
||||
if err != nil {
|
||||
return "", -1, errors.New("invalid Host")
|
||||
}
|
||||
|
||||
port, err = strconv.Atoi(strPort)
|
||||
if err != nil || port > 65535 || port < 0 {
|
||||
return "", -1, errors.New("invalid Port")
|
||||
}
|
||||
|
||||
return AddIPv6Brackets(host), port, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user