Configure Feed
Select the types of activity you want to include in your feed.
Configure Feed
Select the types of activity you want to include in your feed.
Clone this repository
For self-hosted knots, clone URLs may differ based on your setup.
Download tar.gz
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>
Fix schema URL conflict between resource.Default() and our semconv.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Axiom uses OTLP/HTTP, not gRPC. The gRPC exporter was failing with
HTTP 464 errors.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Pass OpenTelemetry environment variables to appview container.
Disabled by default for self-hosters.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add pluggable observability infrastructure that supports any OTLP-compatible
backend (Jaeger, Axiom, Grafana, Honeycomb). Disabled by default with zero
overhead when not enabled.
Changes:
- Add internal/observability package with config, provider, and middleware
- Integrate tracing into main.go with graceful shutdown
- Add Jaeger service to docker-compose with 'observability' profile
- Add `make dev-up-otel` for local tracing with Jaeger UI
- Document OTEL_* environment variables in example files
- Add OpenTelemetry SDK dependencies (otel, otlptracegrpc, otelhttp)
Usage:
make dev-up-otel # Start dev stack with Jaeger
OTEL_ENABLED=true OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317 make run
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>