Address code review findings across API, web and deployment
release gate / check (push) Failing after 6m43s
release gate / check (push) Failing after 6m43s
High severity: - wire TRUSTED_PROXY through Compose/deploy/docs and warn at web startup - bucket public rate limits on effective client IP, add per-bookmark budget, and forward the signed browser identity from the share page - disable first-run bootstrap in server deployments and document seeding - serialize last-admin demotion in one advisory-locked transaction Medium/low: - cap and batch share recipient inserts - add a shared outbound budget for preview/CardDAV/IMAP/signal work - pin CardDAV dials to 443 and bound IMAP logout - fix rightward kanban column drags and normalize cards on column delete - classify backend outages in auth guards, add request timeouts and an error boundary, remove the dead login route, surface throttling - enforce pinned/unpinned page reorder grouping server-side - avoid preview work for stale bookmark versions; drop duplicate dialog fetch - sequence-guard collection/tag/calendar/quick-find loads - validate property config and fix MULTI_SELECT/DATE filter inputs - document index maintenance; apply same-origin check to sign-out - trim signup names, unique shared dates and kanban keys (migration 010), reset reference cache on identity changes, hide OIDC issuer, return 413 for oversized direct bodies, escape Markdown link destinations - remove dead template files and duplicate test helper Verified with go build/vet, full PostgreSQL race suite, db convergence, tsc, both ESLint configs and a Next production build.
This commit is contained in:
+46
@@ -308,6 +308,52 @@ HTTPS reverse proxy to the web app on port 3000, set `NEXTAUTH_URL` to your
|
||||
public HTTPS URL, and set `COOKIE_SECURE=1`. The database remains internal to
|
||||
Docker.
|
||||
|
||||
### Rate-limit identity behind a proxy
|
||||
|
||||
Set `TRUSTED_PROXY=1` in `.env` when (and only when) the proxy in front of the
|
||||
web container **overwrites** `X-Real-IP` with the browser's address — the
|
||||
bundled nginx template does, and `scripts/server-deploy.sh` writes the flag
|
||||
for server deployments. The Next server then signs that address and forwards
|
||||
it to Go, so each browser gets its own login/signup/public-endpoint bucket.
|
||||
Without it every client shares the web container's bucket (20 logins/minute
|
||||
for the whole instance).
|
||||
|
||||
Do **not** set `TRUSTED_PROXY=1` while port 3000 is reachable directly:
|
||||
clients could then choose their own rate-limit identity. The web process logs
|
||||
a startup warning when `NEXTAUTH_URL` is HTTPS but the flag is missing.
|
||||
|
||||
### First-run administrator on an exposed server
|
||||
|
||||
The default empty `ADMIN_EMAILS` plus bootstrap lets the first signup become
|
||||
administrator. That is fine locally, but on a public host it is a race with
|
||||
whoever registers first after DNS goes live. For exposed deployments:
|
||||
|
||||
1. Put `ALLOW_BOOTSTRAP_SIGNUP=0` in `.env` (server-deploy.sh writes it).
|
||||
2. List the operator in `ADMIN_EMAILS=you@example.com` and restart the app.
|
||||
3. Provision the account with `SEED_EMAIL=you@example.com SEED_PASSWORD='...' make seed`.
|
||||
|
||||
`SIGNUP_ENABLED=0` additionally closes self-service registration. Public
|
||||
signup can never grant `ADMIN` after bootstrap is disabled; recovery is
|
||||
operator-driven.
|
||||
|
||||
### Large-install index maintenance
|
||||
|
||||
Migration `007` builds GIN trigram indexes on `Page(title)` and
|
||||
`Page(content)`. The migration runner wraps each file in one transaction, so
|
||||
`CREATE INDEX CONCURRENTLY` is unavailable and the build holds locks that
|
||||
block writes for its duration. Fresh and small installations are fine; on a
|
||||
large existing `Page` table, schedule a maintenance window, or pre-build the
|
||||
indexes yourself before deploying (the migration uses `IF NOT EXISTS` and
|
||||
becomes a no-op):
|
||||
|
||||
```sql
|
||||
CREATE EXTENSION IF NOT EXISTS pg_trgm;
|
||||
CREATE INDEX CONCURRENTLY IF NOT EXISTS "Page_title_trgm_idx" ON "Page" USING gin (title gin_trgm_ops);
|
||||
CREATE INDEX CONCURRENTLY IF NOT EXISTS "Page_content_trgm_idx" ON "Page" USING gin (content gin_trgm_ops);
|
||||
```
|
||||
|
||||
Run those through `make db-shell` (they cannot run inside a transaction).
|
||||
|
||||
### Bundled deployment script
|
||||
|
||||
The repository ships a target-agnostic deployment for exactly this setup —
|
||||
|
||||
Reference in New Issue
Block a user