3a3b526a95
test: add comprehensive test suite (44 tests across 3 packages)
...
Store tests (21 tests):
- Session: create, validate, delete, delete-all, expiry
- Signup requests: create, duplicate, list pending, approve
(creates user with must-reset), reject, double-approve/reject
- Existing: user CRUD, auth, fave CRUD, tags, pagination
Middleware tests (9 tests):
- Real IP extraction from trusted/untrusted proxies
- Base path stripping (with prefix, empty prefix)
- Rate limiter (per-IP, exhaustion, different IPs)
- Panic recovery (returns 500)
- Security headers (CSP, X-Frame-Options, etc.)
- RequireLogin redirect
- MustResetPasswordGuard (static path passthrough)
Handler integration tests (14 tests):
- Health endpoint
- Login page rendering, successful login, wrong password
- Fave list requires auth, works when authenticated
- Private fave hidden from other users, visible to owner
- Admin panel requires admin role, works for admin
- Tag search endpoint
- Global Atom feed
- Public profile with display name
- Limited profile hides bio
Also fixes template bugs: profile.html and fave_detail.html used
$.IsOwner which fails inside {{with}} blocks ($ = root PageData,
not .Data map). Fixed with $d variable capture pattern.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 16:47:32 +02:00
1fc42bf1b2
feat: add packaging, deployment, error pages, and project docs
...
Phase 7 — Polish:
- Error page template with styled 404/403/500 pages
- Error rendering helper on Renderer
Phase 8 — Packaging & Deployment:
- Containerfile: multi-stage build, non-root user, health check,
OCI labels with build date and git revision
- Makefile: build, test, cross-compile, deb, rpm, container,
tarballs, checksums targets
- nfpm.yaml: .deb and .rpm package config
- systemd service: hardened with NoNewPrivileges, ProtectSystem,
ProtectHome, PrivateTmp, RestrictSUIDSGID
- Default environment file with commented examples
- postinstall/preremove scripts (shellcheck validated)
- compose.yaml: example Podman/Docker Compose
- Caddyfile.example: subdomain, subpath, and remote proxy configs
- CHANGELOG.md for release notes
- CLAUDE.md with architecture, conventions, and quick reference
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 16:34:32 +02:00
4e9db3f995
feat: add Atom feeds and JSON/CSV import/export
...
Phase 5 — Feeds & Import/Export:
- Atom feeds: global (/feed.xml), per-user (/u/{name}/feed.xml),
per-tag (/tags/{name}/feed.xml). Uses gorilla/feeds.
- JSON export: all user's faves with tags, pretty-printed
- CSV export: standard format with header row
- JSON import: validates and creates faves with tags
- CSV import: flexible column mapping from header row
- Import/export pages with format documentation
- Feed items include enclosure for images, author info
- Limited-visibility profiles excluded from feeds
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 16:11:44 +02:00
13aec5be6e
feat: add admin panel with user, tag, and signup management
...
Phase 4 — Admin Panel:
- Admin dashboard with user/fave/pending-request counts
- User management: create with temp password, reset password,
enable/disable accounts (prevents self-disable)
- Tag management: rename and delete tags
- Signup request management: approve (creates user with
must-reset-password) and reject pending requests
- Site settings: site name, description, signup mode
(open/requests/closed)
- All admin routes require both login and admin role
- SignupRequest model and full store (create, list pending,
approve with user creation, reject)
- SetMustResetPassword method on UserStore for admin password resets
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 16:09:30 +02:00
2cbbb20278
feat: add profiles, public views, settings, and code quality fixes
...
Phase 3 — Profiles & Public Views:
- Public profile page (/u/{username}) with OG meta tags
- User settings page (display name, bio, visibility, default privacy)
- Avatar upload with image processing
- Password change from settings (verifies current password)
- Home page shows public fave feed for logged-in users
- Must-reset-password guard redirects to /reset-password
- Profile visibility: public (full) or limited (username only)
Code quality improvements from /simplify review:
- Fix signup request persistence bug (was silently discarding data)
- Fix health check to use configured listen address, not hardcoded :8080
- Add rate limiter cleanup goroutine (was leaking memory)
- Extract shared helpers: ClearSessionCookie, IsSecureRequest, scanTags,
scanUserFrom (scanner interface), SignupRequestStore
- Replace hand-rolled joinPlaceholders with strings.Join
- Remove dead _method hidden field, redundant devMode field
- Simplify rate-limited route registration (remove double-mux)
- Log previously-swallowed errors (session delete, image delete)
- Stop leaking internal error messages to users in image upload
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 16:01:41 +02:00
fc1f7259c5
feat: implement Phase 1 (auth) and Phase 2 (faves CRUD) foundation
...
Go backend with server-rendered HTML/HTMX frontend, SQLite database,
and filesystem image storage. Self-hostable single-binary architecture.
Phase 1 — Authentication & project foundation:
- Argon2id password hashing with timing-attack prevention
- Session management with cookie-based auth and periodic cleanup
- Login, signup (open/requests/closed modes), logout, forced password reset
- CSRF double-submit cookie pattern with HTMX auto-inclusion
- Proxy-aware real IP extraction (WireGuard/Tailscale support)
- Configurable base path for subdomain and subpath deployment
- Rate limiting on auth endpoints with background cleanup
- Security headers (CSP, X-Frame-Options, Referrer-Policy)
- Structured logging with slog, graceful shutdown
- Pico CSS + HTMX vendored and embedded via go:embed
Phase 2 — Faves CRUD with tags and images:
- Full CRUD for favorites with ownership checks
- Image upload with EXIF stripping, resize to 1920px, UUID filenames
- Tag system with HTMX autocomplete (prefix search, popularity-sorted)
- Privacy controls (public/private per fave, user-configurable default)
- Tag browsing, pagination, batch tag loading (avoids N+1)
- OpenGraph meta tags on public fave detail pages
Includes code quality pass: extracted shared helpers, fixed signup
request persistence bug, plugged rate limiter memory leak, removed
dead code, and logged previously-swallowed errors.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 15:55:22 +02:00