Clone this repository
For self-hosted knots, clone URLs may differ based on your setup.
Download tar.gz
Implement a complete community suggestions feature allowing users to propose
ideas and vote on them. This is off-protocol (not stored on PDS/firehose)
and uses PostgreSQL directly for storage.
Changes:
- Add CRUD endpoints for community suggestions (create, get, list)
- Add voting with toggle semantics and atomic vote count updates
- Add admin-only status management (open/under_review/approved/declined)
- Add rate limiting: 3 suggestions/day per user, 10 req/min create, 30 req/min vote
- Add PostgreSQL migration (030) with community_suggestions and suggestion_votes tables
- Add repository with row-level locking for consistent vote counting
- Extract shared xrpc.WriteError() helper, refactor adminreport to use it
- Add Caddy proxy port (8080) to mobile port forwarding script
- Add comprehensive E2E integration tests
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
XRPC method names in atProto follow camelCase convention. The getProfile
endpoint was incorrectly using all-lowercase "getprofile".
Changes:
- Rename route from social.coves.actor.getprofile to social.coves.actor.getProfile
- Update startup log message, handler comment, and docs
- Update all E2E and integration test URLs and error messages
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Close the network-use loophole so forks running as hosted services
must share their modifications.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Narrow the Caddy /api/* catch-all to only proxy /api/me to the Go
backend, since SvelteKit now owns /api/auth/* and /api/proxy/*. Update
the dev script to auto-detect the coves-frontend directory (falling
back to kelp) and switch from npm to pnpm.
Changes:
- Replace broad /api/* proxy rule with specific /api/me route
- Add coves-frontend directory auto-detection in web-dev-run.sh
- Switch frontend dev server from npm to pnpm
- Normalize Caddyfile.dev indentation to tabs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Refactors the mobile-only OAuth redirect URI system into a configurable
allowlist that supports both mobile apps (custom schemes + Universal Links)
and web clients (HTTPS redirects). Adds Caddy-based reverse proxy for web
frontend development, enabling same-origin cookie sharing between Vite
frontend and Coves backend.
Changes:
- Refactor isAllowedMobileRedirectURI() into OAuthHandler.isAllowedRedirectURI()
with BuildAllowedRedirectURIs() builder for the configurable allowlist
- Add smart redirect: HTTPS clients get direct HTTP redirect, custom scheme
clients get the intermediate redirect page
- Add Caddyfile.dev reverse proxy config (Vite :5173 + Coves :8081 on :8080)
- Add scripts/web-dev-run.sh for combined backend+frontend dev startup
- Add Makefile targets: run-web, web-proxy, web-proxy-bg, web-proxy-stop
- Auto-run db-migrate before server start in make run and make run-web
- Update OAuth client comments to clarify ATProto loopback client_id spec
- Add PAR request debug logging in dev auth resolver
- Update all security tests to use OAuthHandler instance methods
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Implement one-directional user blocking following the atProto write-forward
pattern. Blocks are written to the blocker's PDS repo and indexed via the
Jetstream firehose consumer into a new user_blocks table.
Changes:
- Add social.coves.actor.block lexicon and DB migration (029)
- Add userblocks domain package (service, repository, interfaces, errors)
- Add XRPC endpoints: blockUser, unblockUser, getBlockedUsers
- Extend Jetstream consumer to index block create/delete events
- Filter blocked users' posts from timeline, discover, and community feeds
- Filter blocked users' comments from comment threads
- Hydrate viewer.blocking on profile responses for authenticated viewers
- Refactor test helpers: DRY PDS client factories, atomic counters
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add a new /api/me endpoint that returns the authenticated user's own
profile with stats. This provides a convenient way for the frontend to
fetch the current user's profile without needing to know their DID.
Changes:
- Add MeHandler with HandleMe serving GET /api/me
- Register route with RequireAuth middleware
- Generalize handleServiceError with operation parameter for reuse
- Add 6 unit tests covering success, nil stats, auth, errors, timeout
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Update the build image to Go 1.25 and add the missing environment
variables for the OAuth confidential client feature added in c65da94.
Changes:
- Bump Go version from 1.24-alpine to 1.25-alpine in Dockerfile
- Add OAUTH_CLIENT_PRIVATE_KEY and OAUTH_CLIENT_KEY_ID env vars to
docker-compose.prod.yml with empty defaults for backward compatibility
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implements OAuth confidential client authentication to enable 1-year session
lifetimes (vs 14 days for public clients). Auth servers enforce shorter limits
for public clients, so this upgrade is necessary for improved UX.
Changes:
- Add OAUTH_CLIENT_PRIVATE_KEY and OAUTH_CLIENT_KEY_ID env configuration
- Add /oauth-client-keys.json JWKS endpoint for public key discovery
- Expand OAuth scopes to include all Coves record types and blob uploads
- Add LogoURI and PolicyURI to client metadata for auth screen branding
- Add cmd/tools/generate-oauth-key utility for P-256 key generation
- Update session TTL defaults to 1 year / 18 months for confidential clients
- Add scope validation with warnings in callback handler
- Fix WebSocket timeout handling in integration tests to prevent panics
- Increase unique name entropy in tests to reduce collision probability
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Update bluesky-social/indigo dependency to the latest version and adapt
to its API changes. Also simplify OAuth configuration by removing the
deprecated transition:generic scope.
Changes:
- Update Go version from 1.24.0 to 1.25
- Update indigo to v0.0.0-20260202181658-ea3d39eec464
- Fix DID parsing calls to use value type instead of pointer (indigo API change)
- Remove transition:generic from OAuth scopes (now using atproto only)
- Fix test isolation in CleanupExpiredSessions test
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>