13 Commits

Author SHA1 Message Date
Dave Kempe be3bea8b30 Connections audit log
New SQLite table addressbook_audit_log records destructive and
mutating actions against the connections tree: create_folder,
update_folder, delete_folder, create_entry, update_entry,
delete_entry. Each row captures user_email, action, scope,
folder_path, optional entry_name, client IP, a small JSON details
blob, and created_at.

Details is deliberately headline-only: counts for delete_folder
(subfolders_deleted, entries_deleted), allowed_groups_count +
inherit_from_parent for folder writes, session type for entry
writes. Entry field values (password, private_key, hostname) and
full request bodies are never written. Audit rows live in SQLite,
not Vault, so logging content would leak Vault-only secrets onto
disk.

The six handlers in api.rs gain ConnectInfo + HeaderMap +
TrustedProxies + Db extractors so client IP can be resolved
through the existing auth::client_ip helper (respecting trusted
proxies) and the audit row can be written post-success.

New admin-only endpoint GET /api/admin/addressbook-audit mirrors
the existing token audit shape (limit + email filter, capped at
1000). admin.html gains a "Connections Audit Log" section below
the token audit, auto-loaded on page show.

cleanup_old_audit_log now also sweeps the new table on the same
retention window as token_audit_log.
2026-04-21 17:45:38 +10:00
Dave Kempe 0d69e8fed4 Rename Address Book → Connections; allowed_groups picker; session privacy (#102)
Three pieces of v1.6.0 work that happened together and are easier to
review as one save point.

Rename: Address Book → Connections
- static/addressbook.html renamed to static/connections.html
- Nav links, page titles, empty states, onboarding, and prose updated
  across all 8 static pages (connections, admin, docs, index,
  recordings, reports, sessions, tokens).
- README, CLAUDE.md, and every file under docs/ updated.
- src/main.rs: connections.html added to the branded-page map and
  route list; /addressbook.html returns a 308 permanent redirect so
  existing bookmarks keep working.
- Backend API paths, Rust types, and Vault storage paths are
  deliberately unchanged — internal only.

Folder allowed_groups picker
- New SQLite table `seen_groups` tracks OIDC groups observed in any
  user login; OIDC callback upserts after extracting groups.
- `GET /api/auth/known-groups` (admin-only) returns the union of
  group_role_mappings and seen_groups.
- `GET /api/addressbook/folders/{scope}/{folder}/config` adds the
  missing endpoint the frontend was already calling — existing
  allowed_groups now prefill the edit-folder modal.
- Folder modal swaps the free-text comma-separated input for a chip
  picker with a themed combobox dropdown: autocomplete over known
  groups, keyboard nav, "+ add custom" row for unlisted groups.

Active session visibility (GitHub #102)
- `GET /api/sessions` scopes to the caller's own sessions by default;
  `?all=true` lets admins opt in (used by the Sessions page).
- `GET /api/sessions/{id}` and the thumbnail GET/PUT endpoints are
  now owner-or-admin, returning 404 for other callers so session
  existence isn't leaked.
- Connections' Active Sessions strip is now always owner-scoped —
  admins still manage everyone via the Sessions page.
2026-04-18 21:56:20 +10:00
Dave Kempe 88b754a11c Address book: subfolder tree UI + shared design system
Frontend for #101 — subfolder support (backend landed in c2a3822) — plus
a site-wide visual overhaul extracted into a single shared stylesheet.

Address book
- Folder sidebar renders as a tree with lazy-loaded children via the
  /api/addressbook/folders/{scope}/{path}/subfolders endpoint.
- Scope badge is now an icon with hover tooltip: ⊕ shared, ▣ instance.
- New "+ subfolder" button creates a nested folder under the selection.
- Move-entry dropdown includes any loaded subfolders.
- Batch folder API now returns path + has_children so the tree can
  render chevrons without a second request per folder.

Design system (rustguac.css)
- Extracted ~700 lines of near-duplicate CSS from each page into a
  shared stylesheet linked by every page.
- 18px body, strict 38/44/54px control heights, uppercase letter-spaced
  section labels, zebra table rows, active-nav underline bar.
- Uniform button ladder: primary (red) / accent (connect, teal) /
  ghost (+ buttons) / small (edit/delete chrome).
- Generic status colors, type badges, pagination, token-reveal,
  summary cards, hop cards, and flow diagram now live in one place.

Per-page updates
- addressbook, admin, docs, index, recordings, reports, sessions,
  tokens: style blocks reduced to page-specific layouts only.
- reports/recordings/sessions: bare <strong> page titles promoted
  to <h2> for proper heading hierarchy.
- Stripped inline padding/font-size attributes that were overriding
  the shared ladder.
2026-04-18 21:56:20 +10:00
Dave Kempe 77c7c535f4 Docs cleanup, default theme to aurora, Vault install guidance
- Switch default theme from dark to aurora across server config,
  all 9 static HTML pages, example config, and docs
- Fix theme docs: list all 8 presets (was 6, missing jaguar/aurora),
  add missing type_vdi_bg/type_vdi_fg fields
- Add Vault/address book setup as recommended post-install step in
  installation docs — the address book is the primary user-facing
  feature and requires Vault
- Renumber subsequent install steps
2026-04-16 16:54:25 +10:00
Dave Kempe fb0f965bb2 Fix nav: Logout + Settings float right together on all pages
Logout link moved inside the float-right user-menu-wrapper so both
Logout and Settings appear on the far right of the nav bar. Fixed
addressbook.html Settings font size to match other pages (1.3em).
2026-04-05 10:20:10 +10:00
Dave Kempe c48be9ed3f Move Logout button out of Settings dropdown on all pages
Logout is now a standalone nav link next to Settings (Logout Settings
order, right-aligned). Applied consistently across all 7 HTML pages.
Removed Logout from the settings dropdown menu.
2026-04-05 10:01:35 +10:00
Dave Kempe b2892e404f v0.9.2: Dependency updates
- sha2 0.11.0-rc.5 → 0.11.0 (stable release)
- rusqlite 0.38.0 → 0.39.0 (bundled SQLite 3.51.3)
- clap 4.5.60 → 4.6.0
- toml 1.0.4 → 1.1.0
- libc 0.2.182 → 0.2.183
- pulldown-cmark 0.13.1 → 0.13.3
- tracing-subscriber 0.3.22 → 0.3.23
- uuid 1.22.0 → 1.23.0
2026-03-28 12:27:42 +11:00
Dave Kempe 7acbb302fa v0.8.5: Reports, session history, enriched recordings
Session history:
- New session_history SQLite table tracks all sessions with user,
  entry, folder, hostname, duration, and recording file
- Automatic cleanup via session_history_retention_days config (default 90)
- 8 new unit tests for session history DB functions

Reports page (poweruser+ only):
- Summary cards: total sessions, hours, unique users, active now
- Sortable/filterable session history table with pagination
- Top Connections and Top Users leaderboards
- CSV export for session history with filters

Enriched recordings:
- Recording .meta sidecars now include user, folder, entry name, session type
- Recordings API returns enriched metadata from .meta files
- Recordings page shows User, Entry, Folder columns

Other:
- Reports nav link on all pages, hidden for operator/viewer roles
- Reports documentation in docs/reports.md
- Onboarding wizard for new users (role-scoped, dismissable)
- Settings menu label visibility improvement
- Fixed stale credential variable test (hyphen support)
2026-03-22 20:36:26 +11:00
Dave Kempe 6bafc79d60 v0.8.0: Credential variables, bug fixes
Credential variables — address book entries reference $domain_username /
$domain_password instead of storing static credentials. Users fill in their
own values via My Credentials (gear menu), stored per-user in Vault KV.
All variables set → silent launch; missing → prompted. Hyphens allowed in
variable names. Docs section added.

Bug fixes:
- Rate limiting disabled by default; opt-in via rate_limit = true (#62)
- Docker: copy FreeRDP guac-common-svc plugins to runtime image (#64)
- Docker/install: add chromium-sandbox package for non-root web sessions (#61)
- Logo: skip redundant JS src= when server-side branding already set (#65)
- Sessions page: hide Open/Share buttons for non-active sessions (#63)
- Drive: expose drive_configured in /api/auth/status, warn in UI when
  [drive] not configured
- install.sh: verify FreeRDP plugin installation

UI polish:
- Nav bar: border separator + spacing between header and nav on all pages
- Address book: password show/hide toggle on all password fields
- Drive diagnostic logging (session.rs, websocket.rs, client.html)

Closes #61, #62, #63, #64, #65
2026-03-13 13:47:11 +11:00
Dave Kempe 2bf34440e6 v0.5.1: RDP resize fix, new themes, Docker config persistence
- Fix RDP display resize for FreeRDP 3.x (patch 004: config.h struct layout)
- Add aurora theme (midnight blue with ambient glow gradients)
- Add jaguar theme (racing green & gold with subtle gradients)
- Add bg_pattern support for CSS gradient backgrounds in themes
- Fix Docker config.toml persistence across rebuilds (#38)
- Add Docker Compose volume mount documentation
- Increase API rate limit to 5/s burst 30 (fix spurious 429s)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 17:08:14 +11:00
Dave Kempe ea72c52a31 v0.5.0: Theme system, ARM64 builds, Docker fixes, dependency updates
Theme system:
- 6 built-in presets (dark, light, high-contrast, terminal, nord, corporate)
- Admin configures preset + per-color overrides in [theme] config section
- Client-side theme switching via localStorage (flash-free)
- All static pages updated with 28 CSS custom properties

Proxy telemetry:
- Track which side terminated connection (guacd/browser/cancelled)
- Timing-based log levels (guacd close <5s = warning)
- Clamp session dimensions to safe ranges (width 640-8192, height 480-8192, DPI 16-384)

Docker fixes (#37):
- Fix port mismatch: Dockerfile now uses 8089 consistently
- Auto-generate admin API key on first run
- Add API key setup docs and recordings volume to compose example

ARM64 support:
- Multi-platform Docker builds (linux/amd64 + linux/arm64)
- Native ARM64 .deb and tarball builds via ubuntu-24.04-arm runner

Dependency updates:
- rustls 0.23.37, chrono 0.4.44, clap 4.5.60, toml 1.0.3
- futures-util 0.3.32, uuid 1.21.0, pulldown-cmark 0.13.1
- actions/upload-artifact v7, actions/download-artifact v8

Also: FreeRDP 3.x NULL deref patch (003), .gitignore for .playwright-mcp/

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 15:05:41 +11:00
Dave Kempe a94b743d6c Add user API tokens with role-based access and audit logging
User API tokens allow OIDC users to authenticate via bearer token for
automation and scripting. Powerusers and admins can create their own
tokens; admins can create tokens for operators. Tokens use SHA-256
hashing, optional max_role caps, optional expiry, and full audit
logging of create/revoke operations with client IPs.

- DB schema: user_api_tokens and token_audit_log tables
- Auth middleware: validates user tokens as fallback after admin keys
- API: 7 new endpoints (self-service + admin token management)
- UI: tokens.html (self-service) + admin.html token/audit sections
- Nav: Tokens link added to all pages (visible for operator+)
- Docs: API reference, security model, roles/access control updated
- Background cleanup: expired tokens + 90-day audit log retention

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 15:02:54 +11:00
Dave Kempe 67101e27ce Initial public release
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 14:38:53 +11:00