Add curation ACL mode and complete graph query implementation (v0.47.0)
Some checks failed
Go / build-and-release (push) Has been cancelled
Some checks failed
Go / build-and-release (push) Has been cancelled
Curation Mode: - Three-tier publisher classification: Trusted, Blacklisted, Unclassified - Per-pubkey rate limiting (default 50/day) for unclassified users - IP flood protection (default 500/day) with automatic banning - Event kind allow-listing via categories, ranges, and custom kinds - Query filtering hides blacklisted pubkey events (admin/owner exempt) - Web UI for managing trusted/blacklisted pubkeys and configuration - NIP-86 API endpoints for all curation management operations Graph Query Extension: - Complete reference aggregation for Badger and Neo4j backends - E-tag graph backfill migration (v8) runs automatically on startup - Configuration options: ORLY_GRAPH_QUERIES_ENABLED, MAX_DEPTH, etc. - NIP-11 advertisement of graph query capabilities Files modified: - app/handle-nip86-curating.go: NIP-86 curation API handlers (new) - app/web/src/CurationView.svelte: Curation management UI (new) - app/web/src/kindCategories.js: Kind category definitions (new) - pkg/acl/curating.go: Curating ACL implementation (new) - pkg/database/curating-acl.go: Database layer for curation (new) - pkg/neo4j/graph-refs.go: Neo4j ref collection (new) - pkg/database/migrations.go: E-tag graph backfill migration - pkg/protocol/graph/executor.go: Reference aggregation support - app/handle-event.go: Curation config event processing - app/handle-req.go: Blacklist filtering for queries - docs/GRAPH_QUERIES_REMAINING_PLAN.md: Updated completion status 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -53,7 +53,7 @@ type C struct {
|
||||
IPBlacklist []string `env:"ORLY_IP_BLACKLIST" usage:"comma-separated list of IP addresses to block; matches on prefixes to allow subnets, e.g. 192.168 = 192.168.0.0/16"`
|
||||
Admins []string `env:"ORLY_ADMINS" usage:"comma-separated list of admin npubs"`
|
||||
Owners []string `env:"ORLY_OWNERS" usage:"comma-separated list of owner npubs, who have full control of the relay for wipe and restart and other functions"`
|
||||
ACLMode string `env:"ORLY_ACL_MODE" usage:"ACL mode: follows, managed (nip-86), none" default:"none"`
|
||||
ACLMode string `env:"ORLY_ACL_MODE" usage:"ACL mode: follows, managed (nip-86), curating, none" default:"none"`
|
||||
AuthRequired bool `env:"ORLY_AUTH_REQUIRED" usage:"require authentication for all requests (works with managed ACL)" default:"false"`
|
||||
AuthToWrite bool `env:"ORLY_AUTH_TO_WRITE" usage:"require authentication only for write operations (EVENT), allow REQ/COUNT without auth" default:"false"`
|
||||
BootstrapRelays []string `env:"ORLY_BOOTSTRAP_RELAYS" usage:"comma-separated list of bootstrap relay URLs for initial sync"`
|
||||
@@ -167,6 +167,12 @@ type C struct {
|
||||
// Cluster replication configuration
|
||||
ClusterPropagatePrivilegedEvents bool `env:"ORLY_CLUSTER_PROPAGATE_PRIVILEGED_EVENTS" default:"true" usage:"propagate privileged events (DMs, gift wraps, etc.) to relay peers for replication"`
|
||||
|
||||
// Graph query configuration (NIP-XX)
|
||||
GraphQueriesEnabled bool `env:"ORLY_GRAPH_QUERIES_ENABLED" default:"true" usage:"enable graph traversal queries (_graph filter extension)"`
|
||||
GraphMaxDepth int `env:"ORLY_GRAPH_MAX_DEPTH" default:"16" usage:"maximum depth for graph traversal queries (1-16)"`
|
||||
GraphMaxResults int `env:"ORLY_GRAPH_MAX_RESULTS" default:"10000" usage:"maximum pubkeys/events returned per graph query"`
|
||||
GraphRateLimitRPM int `env:"ORLY_GRAPH_RATE_LIMIT_RPM" default:"60" usage:"graph queries per minute per connection (0=unlimited)"`
|
||||
|
||||
// Archive relay configuration (query augmentation from authoritative archives)
|
||||
ArchiveEnabled bool `env:"ORLY_ARCHIVE_ENABLED" default:"false" usage:"enable archive relay query augmentation (fetch from archives, cache locally)"`
|
||||
ArchiveRelays []string `env:"ORLY_ARCHIVE_RELAYS" default:"wss://archive.orly.dev/" usage:"comma-separated list of archive relay URLs for query augmentation"`
|
||||
@@ -332,6 +338,25 @@ func VersionRequested() (requested bool) {
|
||||
return
|
||||
}
|
||||
|
||||
// CuratingModeRequested checks if the first command line argument is "curatingmode"
|
||||
// and returns the owner npub/hex pubkey if provided.
|
||||
//
|
||||
// Return Values
|
||||
// - requested: true if the 'curatingmode' subcommand was provided
|
||||
// - ownerKey: the npub or hex pubkey provided as the second argument (empty if not provided)
|
||||
func CuratingModeRequested() (requested bool, ownerKey string) {
|
||||
if len(os.Args) > 1 {
|
||||
switch strings.ToLower(os.Args[1]) {
|
||||
case "curatingmode":
|
||||
requested = true
|
||||
if len(os.Args) > 2 {
|
||||
ownerKey = os.Args[2]
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// KV is a key/value pair.
|
||||
type KV struct{ Key, Value string }
|
||||
|
||||
@@ -660,3 +685,25 @@ func (cfg *C) GetTorConfigValues() (
|
||||
cfg.TorBinary,
|
||||
cfg.TorSOCKS
|
||||
}
|
||||
|
||||
// GetGraphConfigValues returns the graph query configuration values.
|
||||
// This avoids circular imports with pkg/protocol/graph while allowing main.go
|
||||
// to construct the graph executor configuration.
|
||||
func (cfg *C) GetGraphConfigValues() (
|
||||
enabled bool,
|
||||
maxDepth int,
|
||||
maxResults int,
|
||||
rateLimitRPM int,
|
||||
) {
|
||||
maxDepth = cfg.GraphMaxDepth
|
||||
if maxDepth < 1 {
|
||||
maxDepth = 1
|
||||
}
|
||||
if maxDepth > 16 {
|
||||
maxDepth = 16
|
||||
}
|
||||
return cfg.GraphQueriesEnabled,
|
||||
maxDepth,
|
||||
cfg.GraphMaxResults,
|
||||
cfg.GraphRateLimitRPM
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user