add groups.0xchat.com
This commit is contained in:
parent
0c6725cbea
commit
49c2dc52a7
@ -193,6 +193,22 @@ func (s *State) applyModerationAction(ctx context.Context, event *nostr.Event) {
|
||||
group.ToMembersEvent,
|
||||
},
|
||||
}[event.Kind] {
|
||||
switch event.Kind {
|
||||
case nostr.KindSimpleGroupCreateGroup:
|
||||
group.LastMetadataUpdate = nostr.Now()
|
||||
group.LastAdminsUpdate = nostr.Now()
|
||||
group.LastMembersUpdate = nostr.Now()
|
||||
case nostr.KindSimpleGroupEditMetadata, nostr.KindSimpleGroupEditGroupStatus:
|
||||
group.LastMetadataUpdate = nostr.Now()
|
||||
case nostr.KindSimpleGroupAddPermission:
|
||||
group.LastMembersUpdate = nostr.Now()
|
||||
group.LastAdminsUpdate = nostr.Now()
|
||||
case nostr.KindSimpleGroupRemovePermission:
|
||||
group.LastAdminsUpdate = nostr.Now()
|
||||
case nostr.KindSimpleGroupAddUser, nostr.KindSimpleGroupRemoveUser:
|
||||
group.LastMembersUpdate = nostr.Now()
|
||||
}
|
||||
|
||||
evt := toBroadcast()
|
||||
evt.Sign(s.privateKey)
|
||||
s.Relay.BroadcastEvent(evt)
|
||||
|
40
groups.0xchat.com/extra_policies.go
Normal file
40
groups.0xchat.com/extra_policies.go
Normal file
@ -0,0 +1,40 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/fiatjaf/relay29"
|
||||
"github.com/nbd-wtf/go-nostr"
|
||||
"github.com/puzpuzpuz/xsync/v3"
|
||||
"golang.org/x/time/rate"
|
||||
)
|
||||
|
||||
var internalCallContextKey = struct{}{}
|
||||
|
||||
func blockDeletesOfOldMessages(ctx context.Context, target, deletion *nostr.Event) (acceptDeletion bool, msg string) {
|
||||
if target.CreatedAt < nostr.Now()-60*60*2 /* 2 hours */ {
|
||||
return false, "can't delete old event, contact relay admin"
|
||||
}
|
||||
|
||||
return true, ""
|
||||
}
|
||||
|
||||
// very strict rate limits
|
||||
var rateLimitBuckets = xsync.NewMapOf[*relay29.Group, *rate.Limiter]()
|
||||
|
||||
func rateLimit(ctx context.Context, event *nostr.Event) (reject bool, msg string) {
|
||||
group := state.GetGroupFromEvent(event)
|
||||
|
||||
bucket, _ := rateLimitBuckets.LoadOrCompute(group, func() *rate.Limiter {
|
||||
return rate.NewLimiter(rate.Every(time.Minute*2), 30)
|
||||
})
|
||||
|
||||
if rsv := bucket.Reserve(); rsv.Delay() != 0 {
|
||||
rsv.Cancel()
|
||||
return true, "rate-limited"
|
||||
} else {
|
||||
rsv.OK()
|
||||
return
|
||||
}
|
||||
}
|
86
groups.0xchat.com/main.go
Normal file
86
groups.0xchat.com/main.go
Normal file
@ -0,0 +1,86 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"os"
|
||||
"slices"
|
||||
|
||||
"github.com/fiatjaf/eventstore/bolt"
|
||||
"github.com/fiatjaf/khatru/policies"
|
||||
"github.com/fiatjaf/relay29"
|
||||
"github.com/kelseyhightower/envconfig"
|
||||
"github.com/nbd-wtf/go-nostr"
|
||||
"github.com/rs/zerolog"
|
||||
)
|
||||
|
||||
type Settings struct {
|
||||
Port string `envconfig:"PORT" default:"5577"`
|
||||
Domain string `envconfig:"DOMAIN" required:"true"`
|
||||
RelayName string `envconfig:"RELAY_NAME" required:"true"`
|
||||
RelayPrivkey string `envconfig:"RELAY_PRIVKEY" required:"true"`
|
||||
RelayDescription string `envconfig:"RELAY_DESCRIPTION"`
|
||||
RelayContact string `envconfig:"RELAY_CONTACT"`
|
||||
RelayIcon string `envconfig:"RELAY_ICON"`
|
||||
DatabasePath string `envconfig:"DATABASE_PATH" default:"./db"`
|
||||
|
||||
RelayPubkey string `envconfig:"-"`
|
||||
}
|
||||
|
||||
var (
|
||||
s Settings
|
||||
db = &bolt.BoltBackend{}
|
||||
log = zerolog.New(os.Stderr).Output(zerolog.ConsoleWriter{Out: os.Stdout}).With().Timestamp().Logger()
|
||||
state *relay29.State
|
||||
)
|
||||
|
||||
func main() {
|
||||
err := envconfig.Process("", &s)
|
||||
if err != nil {
|
||||
log.Fatal().Err(err).Msg("couldn't process envconfig")
|
||||
return
|
||||
}
|
||||
s.RelayPubkey, _ = nostr.GetPublicKey(s.RelayPrivkey)
|
||||
|
||||
// load db
|
||||
db.Path = s.DatabasePath
|
||||
if err := db.Init(); err != nil {
|
||||
log.Fatal().Err(err).Msg("failed to initialize database")
|
||||
return
|
||||
}
|
||||
log.Debug().Str("path", db.Path).Msg("initialized database")
|
||||
|
||||
// init relay29 stuff
|
||||
state = relay29.Init(relay29.Options{
|
||||
Domain: s.Domain,
|
||||
DB: db,
|
||||
SecretKey: s.RelayPrivkey,
|
||||
})
|
||||
|
||||
// init relay
|
||||
state.Relay.Info.Name = s.RelayName
|
||||
state.Relay.Info.Description = s.RelayDescription
|
||||
state.Relay.Info.Contact = s.RelayContact
|
||||
state.Relay.Info.Icon = s.RelayIcon
|
||||
|
||||
state.Relay.OverwriteDeletionOutcome = append(state.Relay.OverwriteDeletionOutcome,
|
||||
blockDeletesOfOldMessages,
|
||||
)
|
||||
state.Relay.RejectEvent = slices.Insert(state.Relay.RejectEvent, 0,
|
||||
policies.PreventLargeTags(64),
|
||||
policies.PreventTooManyIndexableTags(6, []int{9005}, nil),
|
||||
policies.RestrictToSpecifiedKinds(
|
||||
7, 9, 10, 11, 12,
|
||||
30023, 31922, 31923, 9802,
|
||||
9000, 9001, 9002, 9003, 9004, 9005, 9006, 9007,
|
||||
9021, 9735,
|
||||
),
|
||||
policies.PreventTimestampsInThePast(60),
|
||||
policies.PreventTimestampsInTheFuture(30),
|
||||
rateLimit,
|
||||
)
|
||||
|
||||
log.Info().Str("relay-pubkey", s.RelayPubkey).Msg("running on http://0.0.0.0:" + s.Port)
|
||||
if err := http.ListenAndServe(":"+s.Port, state.Relay); err != nil {
|
||||
log.Fatal().Err(err).Msg("failed to serve")
|
||||
}
|
||||
}
|
7
state.go
7
state.go
@ -96,7 +96,7 @@ func (s *State) NewGroup(id string) *Group {
|
||||
Group: nip29.Group{
|
||||
Address: nip29.GroupAddress{
|
||||
ID: id,
|
||||
Relay: "wss://" + s.Domain,
|
||||
Relay: "ws://" + s.Domain,
|
||||
},
|
||||
Members: map[string]*nip29.Role{},
|
||||
},
|
||||
@ -112,11 +112,12 @@ func (s *State) loadGroups(ctx context.Context) {
|
||||
|
||||
group := s.NewGroup(id)
|
||||
f := nostr.Filter{
|
||||
Limit: 5000, Kinds: nip29.ModerationEventKinds, Tags: nostr.TagMap{"h": []string{id}},
|
||||
Kinds: nip29.ModerationEventKinds,
|
||||
Tags: nostr.TagMap{"h": []string{id}},
|
||||
}
|
||||
ch, _ := s.DB.QueryEvents(ctx, f)
|
||||
|
||||
events := make([]*nostr.Event, 0, 5000)
|
||||
events := make([]*nostr.Event, 0)
|
||||
for event := range ch {
|
||||
events = append(events, event)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user