93 Commits
Author SHA1 Message Date
tbenandClaude Opus 5.5 0d8daab3d0 Apply client changes to the running tunnel without a restart
Saving a client or rule restarted the whole host tunnel (wg-quick down/up)
and re-ran the firewall manager setup, which was slow and briefly dropped
every client on the host.

Client and rule changes now sync peers with `wg syncconf` and re-run the
PostUp script, skipping the firewalld/ufw step. Host creation and edits
still do a full restart.

PostUp now loads the per-host chains with `iptables-restore --noflush`, so
re-running it on a live tunnel swaps the rules atomically instead of
leaving the chains empty between flush and re-add.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-11-03 08:30:41 +01:00
tbenandClaude Opus 5.5 77ced6cc52 Add editing of client access rules
Saved rules and client form drafts can now be edited through the rule
modal. On the Rules tab, saving re-runs client setup so the firewall
matches, and both add and edit ask for confirmation.

Comma-separated destinations were rejected because drafts were validated
before being split; validate each one after splitting instead. When
editing, the first destination updates the rule and the rest are added
as new rules.

Pin the id in the client_rules PUT handler so a request body can't
change it.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-11-01 14:27:10 +01:00
tbenandClaude Opus 5.5 577f3828c8 Remove the MCP tool guidelines from AGENTS.md
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-11-01 14:27:10 +01:00
tben 2a74c1e3e6 Fix copy buttons on non-secure (plain http) deployments
`navigator.clipboard` only exists in secure contexts, so every copy button
threw on plain-http LAN/IP deployments and falsely reported failure.

Add copyTextToClipboard(), which uses the Clipboard API on secure origins
and falls back to a hidden textarea + `execCommand("copy")` otherwise
(restoring focus/selection and always cleaning the element up). CopyButton
now reports success only when the text actually reached the clipboard.

installClipboardFallback() polyfills a working `navigator.clipboard` on
insecure pages so twui's CodeBlock/CopySlug/Input copy icons work too,
without editing twui sources. It is installed once from AppProviders.
2026-10-21 15:22:16 +01:00
tben d9f5367270 Restore the installer functions dropped by the Caddy commit
ed4a6f3 rewrote the middle of install-wg-ui.sh and deleted seven function
definitions while leaving every call site in place. The runtime only
stopped at the first one, so `update wg-ui` died with:

  install-wg-ui.sh: line 202: clone_or_update: command not found

Fixing that line alone would have moved the failure to
install_dependencies three lines down, and with install_systemd_unit /
install_openrc_unit gone the script could never have written a service
unit again. Restore all seven from 0f94004, keeping the Caddy work that
landed in the same commit:

- clone_or_update, install_dependencies, ensure_env_file,
  setup_wireguard, install_wg_quick_helper: byte-identical to 0f94004.
- install_systemd_unit / install_openrc_unit: identical, except wg-ui now
  starts after docker, since Caddy ingress reloads go through docker exec.

Add install-wg-ui.test.ts so this class of bug cannot come back silently:
it asserts the script parses, that every invoked function has a
definition (indented calls included, which is how clone_or_update hid),
and that the update flow runs in order. Checked against the pre-fix
script, the definition test fails with exactly the seven missing names.
2026-10-21 14:41:59 +01:00
tben cbd5451ab7 Run the Caddy TLS ingress as a Docker container
Caddy previously ran as a host binary in /opt/caddy with a wgui-caddy
systemd/OpenRC unit. Only Caddy is containerized; the app still runs on the
host as root because it shells out to wg, ip and iptables.

- Add caddy-container-commands.ts as the single source of truth for the
  run/exec/validate/inspect argument arrays. Every value stays a separate
  argv element, the image is pinned to caddy:2.11.4-alpine, and the
  entrypoint is set explicitly because some mirrors publish the image with
  a null Entrypoint (which made Docker exec "run" as a binary).
- Rewrite install-caddy.sh: require_docker with distro-specific hints,
  pull + recreate the container, assert it is running and echo the daemon
  error instead of discarding it, normalize the admin socket path in
  existing Caddyfiles, and clean up a legacy native install only after the
  container is up so the ingress port is never unbound. Add
  --purge-legacy / --purge for hosts that want to drop the old install
  without installing the container.
- Move the admin socket to /var/lib/wgui/caddy/admin.sock so it lives
  inside the mounted Caddy dir and reloads work over docker exec.
- Validate candidate configs in a throwaway container, mounting the TLS
  dir read-only as well: provisioning the tls app loads every certificate
  referenced by a tls directive, so without that mount a route with a
  certificate failed validation and its Caddyfile was never committed.
- Report docker-based installed/version/service_active, skip
  validate/reload with a warning when the image is absent, and update the
  system setup tool check to look for docker.
- Issue certificates with a docker exec reload command and chown files to
  root:root, since the container reads them through a read-only mount.
- Update the Setup UI copy and docs (README, AGENTS.md).

Also drops the unused EmptyContent import and a stray debug log in the
client route form, and stops passing the unsupported cancel_href prop to
ClientRouteForm from the route add/edit pages.
2026-10-21 14:34:16 +01:00
tben 2cc876b062 Update routes 2026-10-21 13:34:25 +01:00
tben 42feb73264 Update Reverse proxy and TLS configuration on Caddy 2026-10-21 13:01:33 +01:00
tben ed4a6f3ec8 Add TLS feature with Caddy 2026-10-21 09:13:59 +01:00
tbenandClaude Opus 5.5 1462067e72 Register Prism's common languages in twui CodeBlock
- Load refractor's ~36 common languages plus docker, nginx, toml,
  powershell, jsx and tsx (was 6)
- Expand TWUIPrismLanguages to 54 names/aliases for autocomplete;
  `language` now also accepts any registered refractor name
- RemoteCodeBlock re-exports the list instead of keeping a stale copy

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-16 06:46:19 +01:00
tbenandClaude Opus 5.5 548a934008 Add syntax highlighting and light/dark themes to twui CodeBlock
- Highlight string children with refractor (Prism) when `language` is
  set, rendered as React token spans; add ini/bash/json/yaml/ts support
- Add `theme` prop (auto | light | dark); auto follows the `.dark` class.
  Palettes are `--twui-code-*` CSS variables (GitHub Light/Dark, all
  tokens WCAG AA) so custom themes need no component changes
- Fix layout: real padding, singleBlock copy button no longer covers
  the code, clipped rounded corners, wrapperProps.style honoured,
  long tokens wrap
- MDX helpers take `codeTheme` and no longer force a black background
- Highlight WireGuard config blocks as ini

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-16 06:44:43 +01:00
tbenandClaude Opus 5.5 cad1d32ae4 Redesign the frontend UI on twui
Rebuild every page on a shared set of twui-based primitives with a dense
ops-console look, WireGuard red accent and light/dark/system theming.

- Add design tokens (WireGuard red accent, zinc neutrals, theme-flipping
  semantic colours) and a no-flash theme cookie + toggle
- Add shared components: page header, panel, sub-nav, data table with
  mobile card list, stat tile, status dot, key-value list, copy button,
  inline alert, empty state, form section/actions, confirm dialog and
  toast providers
- New admin shell (sidebar, sticky header, mobile drawer) and a centered
  shell for auth and 404; strip the public template pages
- Unify adding clients at /admin/clients/add with a host picker; tabbed
  client detail (Overview / Rules / Config & QR) with config copy/download
- Re-run client setup after rule changes on the detail page so the
  firewall matches the DB
- Split Setup into status/maintenance/firewall and Settings into
  profile/password subpages
- Replace window.confirm/alert and page reloads with in-app dialogs,
  toasts and in-place list updates
- Fix nested rule form submitting the client form, prefilled signup
  passwords, hidden submit buttons, fields not updating after "next
  free" lookups, and TinyMCE white-on-white in dark mode

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-16 06:29:21 +01:00
tben e50b0405b0 Fix security issues 2026-10-15 21:10:36 +01:00
tbenandClaude Opus 5.5 fe4b1b02d1 Remove unused dependencies and dead code, refresh AGENTS.md
- Drop unused email module and media text extraction path
- Remove 12 unused dependencies
- Remove unused imports in server.ts
- Add typecheck and test scripts
- Rewrite AGENTS.md to describe this project

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-15 21:09:27 +01:00
tbenandClaude Opus 5.5 617400c19f Enforce client ownership in clients CRUD put/post
Non-super-admin PUT updated the client whose id equalled the user's id;
it now updates the requested client only if the user owns it. POST no
longer lets non-super-admins overwrite existing clients by id.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-15 21:09:27 +01:00
tbenandClaude Opus 5.5 cd707465f4 Harden admin API routes and shell usage
- Require admin auth on interface-local-ip, network-interfaces,
  next-listen-port and public-ip (interface-local-ip and public-ip
  allowed unauthenticated command injection as root)
- Validate interface names and call ip/curl via execFileSync
- Write host/client WireGuard configs with fs instead of shell
  heredocs, validating IPs, AllowedIPs, endpoint and listen port
- Replace rm -rf/cat/mkdir/chmod/test shell calls with fs APIs
- Refuse private media requested through the public media route

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-15 21:09:27 +01:00
tbenandClaude Opus 5.5 178f98104c Fix type-check after bun-sqlite 1.2.0 upgrade
Import types from @moduletrace/bun-sqlite/types now that the package
has an exports map, and guard optional ctx.props in signup server fn.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-15 21:09:27 +01:00
tben 0f940048d4 Update bunext and bun-sqlite versions 2026-10-15 20:44:16 +01:00
tben b6f7eb0c75 Allow wildcard rule access host public IP ports 2026-10-07 11:28:41 +01:00
tben c42f0440ac Iptables generator funciton bugfix followup: allow host network ports 2026-09-28 21:24:44 +01:00
tben 19486bbfa0 Iptables generator funciton bugfix 2026-09-28 20:31:17 +01:00
tben 8492ae1a2a Revert to previous version 2026-09-28 18:54:01 +01:00
tben 73a3384d98 Fix DNS resolution issues 2026-09-28 18:34:09 +01:00
tben 9b6136c648 Remove comments 2026-09-28 12:37:24 +01:00
tben 464b814dd1 Bugfix: host form public ip interface param 2026-09-27 16:19:40 +01:00
tben 3d0ef98385 Iptables restrictions bugfix: #3: Restrict inter-host access 2026-09-27 16:07:55 +01:00
tben 5560567143 Iptables restrictions bugfix: #2: Restrict inter-host access 2026-09-27 15:57:36 +01:00
tben 65b321f73b Iptables restrictions bugfix: #1 2026-09-27 15:40:05 +01:00
tben dbae73a746 Add firewall rules logic for all hosts 2026-09-27 14:25:27 +01:00
tben bbf29a5c1a Update README.md. Add link to site URL 2026-09-27 07:10:28 +01:00
tben 8ed5fd1845 Update clients fetch function 2026-09-27 06:59:16 +01:00
tben c23c8f73cd Update AGENTS.md file 2026-09-27 06:09:11 +01:00
tben 400831246f Fix iptables internet forwarding bug. Update UI errors. 2026-09-27 06:08:07 +01:00
tben dc8700feaa Iptables hardening and dev server bind fix 2026-09-22 13:59:56 +01:00
tben 782727bc44 Iptables bugfix: add space between -i flag and interface name 2026-09-22 13:35:53 +01:00
tben 4adec1700e Extract shared ClientsTable component and useClientRulesMap hook 2026-09-22 13:35:02 +01:00
tben c4b057ba7a Add input title and label to setup repo input 2026-09-21 15:13:31 +01:00
tben 803ba0adef Iptables bugfix: allow dns queries over wireguard tunnel 2026-09-21 15:08:54 +01:00
tben b0536765ce Update database schema. Client rules are randomly deleted because of the foreign key. Remove all foreign keys from db schema 2026-09-21 14:14:54 +01:00
tben d52c584c8f Update README.md. Update curl installation URL 2026-09-21 07:13:31 +01:00
tben 501b99cbc8 Update README.md. Remove deploy and docker. Add zip and unzip to dependencies 2026-09-21 04:30:51 +01:00
tben a681354eab Update host update form for main host (host 0) 2026-09-20 20:48:47 +01:00
tben b2706ce878 Add client DNS config when client allows all IPs 2026-09-20 20:24:01 +01:00
tben db9b66b984 Bugfix. Remove main duplicate 2026-09-20 20:04:18 +01:00
tben 4f49d3f3f5 Remove crypto and replace with npm uuid package 2026-09-20 19:52:39 +01:00
tben 6f09d0a2f3 Update installation script. Setup BunSQLite, configure firewall 2026-09-20 19:41:55 +01:00
tben 8535a52830 Add server request debug logs 2026-09-20 19:23:27 +01:00
tben 79433168df Update server start log 2026-09-20 19:19:15 +01:00
tben a4c7130c0e Remove install script from server.ts 2026-09-20 19:18:15 +01:00
tben 11fd924c50 Add observability log to server.ts 2026-09-20 19:15:56 +01:00