package nostr import ( "context" "fmt" "git.devvul.com/asara/gologger" "git.devvul.com/asara/well-goknown/config" "github.com/fiatjaf/eventstore/postgresql" "github.com/fiatjaf/khatru" "github.com/fiatjaf/khatru/policies" "github.com/jmoiron/sqlx" "github.com/nbd-wtf/go-nostr" ) var ( DB *sqlx.DB RelayDb postgresql.PostgresBackend relay *khatru.Relay ) type nostrUser struct { Pubkey string `db:"pubkey"` Relays *string `db:"relays,omitempty"` } type nostrWellKnown struct { Names map[string]string `json:"names"` Relays map[string][]string `json:"relays,omitempty"` NIP46 map[string][]string `json:"nip46,omitempty"` } func NewRelay(version string) *khatru.Relay { // relay configuration relay = khatru.NewRelay() relay.Info.Name = config.GetConfig().RelayName relay.Info.PubKey = config.GetConfig().RelayPubkey relay.Info.Description = config.GetConfig().RelayDescription relay.Info.Icon = config.GetConfig().RelayIcon relay.Info.Contact = config.GetConfig().RelayContact relay.Info.Version = version relay.Info.Software = "https://git.devvul.com/asara/well-goknown" // contact lists relay.Info.SupportedNIPs = []int{ 1, // basic protocol 2, // contact lists 4, // encrypted DMs 11, // relay info 42, // auth 70, // protected events } relay.OnConnect = append(relay.OnConnect, func(ctx context.Context) { khatru.RequestAuth(ctx) }) // storage relay.StoreEvent = append(relay.StoreEvent, RelayDb.SaveEvent) relay.QueryEvents = append(relay.QueryEvents, RelayDb.QueryEvents) relay.CountEvents = append(relay.CountEvents, RelayDb.CountEvents) relay.DeleteEvent = append(relay.DeleteEvent, RelayDb.DeleteEvent) // apply policies relay.RejectEvent = append( relay.RejectEvent, RejectUnregisteredNpubs, policies.ValidateKind, ) relay.RejectFilter = append( relay.RejectFilter, policies.RejectKind04Snoopers, ) return relay } func RejectUnregisteredNpubs(ctx context.Context, event *nostr.Event) (reject bool, msg string) { l := gologger.Get(config.GetConfig().LogLevel).With().Str("context", "nostr-reject-unregistered").Logger() // always allow auth messages if event.Kind == 22242 { return false, "" } authenticatedUser := khatru.GetAuthed(ctx) if authenticatedUser == "" { l.Debug().Msgf("pubkey not authed: %s", event.PubKey) return true, fmt.Sprintf("auth-required: interacting with this relay requires authentication") } // reject nip-04 messages to users who aren't registered if event.Kind == 4 { receiver := event.Tags.GetFirst([]string{"p"}).Value() var rid int err := DB.QueryRow("SELECT id FROM users WHERE pubkey=$1", receiver).Scan(&rid) if err != nil { rid = -1 } var sid int err = DB.QueryRow("SELECT id FROM users WHERE pubkey=$1", authenticatedUser).Scan(&sid) if err != nil { sid = -1 } if rid != -1 && sid != -1 { l.Debug().Msgf("pubkeys %s or %s not found to be registered", receiver, event.PubKey) return true, fmt.Sprintf("restricted: nobody in this nip04 message is registered to the relay") } return false, "" } // check if user is registered var uid int err := DB.QueryRow("SELECT id FROM users WHERE pubkey=$1", authenticatedUser).Scan(&uid) if err != nil { l.Debug().Msgf("kind: %v, pubkey: %s, error: %s", event.Kind, event.PubKey, err.Error()) return true, fmt.Sprintf("restricted: pubkey %s is not registered to any users", authenticatedUser) } return false, "" }