Add web UI: login, dashboard, and share management (templ + Tailwind + htmx)
New internal/web package mounted at /ui/, separate from DAV Basic Auth: - Cookie-based sessions (opaque random tokens in a new web_sessions SQLite table, internal/db/sessions.go), checked against the same cfg.Users/bcrypt credentials as DAV Basic Auth. - Dashboard listing the logged-in user's own calendars/address books, who they're shared with, and what's shared with them. - Share/unshare directly from the dashboard, updated in place via htmx partial swaps (POST to create/update, DELETE to revoke). Always verifies the resource actually belongs to the logged-in user before granting a share. - Templates written in templ (internal/web/templates/*.templ, generated *_templ.go committed), styled with Tailwind CSS v4 (web/input.css, compiled to web/static/app.css), with htmx vendored as a static file for the dynamic bits. Both are embedded into the binary at build time (web/staticassets.go) so the compiled server has no Node.js/web/ runtime dependency. - Wired into cmd/server/main.go at /ui/ alongside the existing /cal/, /card/, /files/ routes; welcome page links to it. - Tests: internal/web/server_test.go covers login success/failure, the login-required redirect, dashboard rendering, share/unshare including the htmx-v2-sends-DELETE-params-as-query-string quirk, and rejecting shares of resources the user doesn't own. - Docs: README (new 'Web UI' section, updated sharing section, project layout, dependencies) and copilot-instructions updated accordingly. Makefile: new templ-generate/web-deps/web-css targets. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -14,6 +14,8 @@ A self-hosted **CalDAV**, **CardDAV**, and **WebDAV** server written in Go.
|
||||
- Per-user isolated collections
|
||||
- **Calendar/address book sharing** — grant other users read or write
|
||||
access to your calendars/address books
|
||||
- **Web UI** — a small dashboard (login, manage shares) at `/ui/`, built
|
||||
with templ + Tailwind + htmx
|
||||
- Auto-discovery via `/.well-known/caldav` and `/.well-known/carddav`
|
||||
- Optional **TLS** (or use a reverse proxy)
|
||||
- Structured logging (text or JSON)
|
||||
@@ -146,8 +148,8 @@ grantee's own home-set alongside their own calendars — no separate account
|
||||
or extra client configuration needed.
|
||||
|
||||
Sharing grants are stored in a small SQLite database at
|
||||
`<data_dir>/nidus.db` (not in `config.yaml`) and managed with the
|
||||
`nidusctl` CLI (there's no web UI yet):
|
||||
`<data_dir>/nidus.db` (not in `config.yaml`) and can be managed either via
|
||||
the `nidusctl` CLI or the web UI's dashboard (see below):
|
||||
|
||||
```bash
|
||||
# Give bob write access to alice's "work" calendar
|
||||
@@ -173,6 +175,35 @@ Read-only shares reject any write (PUT/DELETE) with `403 Forbidden`.
|
||||
|
||||
---
|
||||
|
||||
## Web UI
|
||||
|
||||
A small server-rendered dashboard is served at `/ui/` (separate from the
|
||||
DAV endpoints, which stay on HTTP Basic Auth):
|
||||
|
||||
- **Login** (`/ui/login`) — cookie-based session, stored server-side in
|
||||
`nidus.db` (`web_sessions` table), independent of DAV Basic Auth.
|
||||
- **Dashboard** (`/ui/`) — lists your own calendars/address books, who
|
||||
they're shared with, and any resources other users have shared with you.
|
||||
- **Share management** — add/remove shares directly from the dashboard
|
||||
(same effect as `nidusctl`); updates happen in place via
|
||||
[htmx](https://htmx.org/) without a full page reload.
|
||||
- **Logout** (`/ui/logout`).
|
||||
|
||||
Implementation: [templ](https://templ.guide/) for type-safe Go HTML
|
||||
templates, [Tailwind CSS v4](https://tailwindcss.com/) for styling, and
|
||||
htmx for the sprinkles of dynamic behavior (form submission via
|
||||
POST/DELETE, partial page swaps) — no separate JS build/framework needed.
|
||||
The compiled CSS and the htmx bundle are embedded into the Go binary
|
||||
(`web/staticassets.go`), so no Node.js is required at runtime, only when
|
||||
you change styles or templates during development:
|
||||
|
||||
```bash
|
||||
make web-deps # once, installs the Tailwind CLI (needs Node.js/npm)
|
||||
make web-css # regenerate templ code + rebuild web/static/app.css
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## TLS / Reverse proxy
|
||||
|
||||
### Self-signed certificate (development)
|
||||
@@ -242,15 +273,19 @@ users:
|
||||
caldav-server/
|
||||
├── cmd/server/ # main entrypoint
|
||||
├── internal/
|
||||
│ ├── auth/ # HTTP Basic Auth middleware
|
||||
│ ├── auth/ # HTTP Basic Auth middleware (DAV endpoints)
|
||||
│ ├── caldav/ # CalDAV backend
|
||||
│ ├── carddav/ # CardDAV backend
|
||||
│ ├── config/ # YAML config loader
|
||||
│ ├── db/ # SQLite store (calendar/address book shares)
|
||||
│ ├── db/ # SQLite store (shares, web UI sessions)
|
||||
│ ├── store/ # filesystem storage layer
|
||||
│ ├── web/ # web UI (cookie sessions, dashboard, share mgmt)
|
||||
│ │ └── templates/ # templ templates (+ generated *_templ.go)
|
||||
│ └── webdav/ # WebDAV file handler
|
||||
├── tools/hashpwd/ # bcrypt password hasher CLI
|
||||
├── tools/nidusctl/ # sharing-grant admin CLI
|
||||
├── web/ # front-end assets: Tailwind input/config, static/
|
||||
│ └── static/ # compiled app.css + htmx.min.js (embedded into the binary)
|
||||
├── config.example.yaml # sample configuration (copy to config.yaml)
|
||||
├── Dockerfile
|
||||
├── docker-compose.yaml
|
||||
@@ -279,4 +314,12 @@ go test ./... -race
|
||||
| `golang.org/x/crypto` | bcrypt |
|
||||
| `golang.org/x/net` | `golang.org/x/net/webdav` |
|
||||
| `gopkg.in/yaml.v3` | YAML config parsing |
|
||||
| `modernc.org/sqlite` | Pure-Go SQLite driver (calendar/address book shares) |
|
||||
| `modernc.org/sqlite` | Pure-Go SQLite driver (shares, web UI sessions) |
|
||||
| `github.com/a-h/templ` | Type-safe Go HTML templates (web UI) |
|
||||
|
||||
Front-end (dev-only, not required at runtime — see [Web UI](#web-ui)):
|
||||
|
||||
| Tool | Purpose |
|
||||
|------|---------|
|
||||
| Tailwind CSS v4 (`web/package.json`) | Utility-first CSS, compiled to `web/static/app.css` |
|
||||
| [htmx](https://htmx.org/) (`web/static/htmx.min.js`, vendored) | Partial page updates without a JS framework |
|
||||
|
||||
Reference in New Issue
Block a user