122 lines
3.4 KiB
Go
122 lines
3.4 KiB
Go
|
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, ""
|
||
|
}
|