131 lines
3.0 KiB
Go
131 lines
3.0 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"io"
|
|
"log"
|
|
"os"
|
|
"path/filepath"
|
|
"time"
|
|
|
|
"github.com/fiatjaf/eventstore/strfry"
|
|
"github.com/fiatjaf/relay29"
|
|
"github.com/nbd-wtf/go-nostr"
|
|
)
|
|
|
|
var (
|
|
state *relay29.State
|
|
ctx = context.Background()
|
|
|
|
strfrydb strfry.StrfryBackend
|
|
)
|
|
|
|
func main() {
|
|
incoming := json.NewDecoder(os.Stdin)
|
|
outgoing := json.NewEncoder(os.Stdout)
|
|
|
|
curr, _ := os.Getwd()
|
|
path := filepath.Join(curr, "strfry29.json")
|
|
confb, err := os.ReadFile(path)
|
|
if err != nil {
|
|
log.Fatalf("couldn't open config file at %s: %s", path, err)
|
|
return
|
|
}
|
|
|
|
var conf struct {
|
|
Domain string `json:"domain"`
|
|
RelaySecretKey string `json:"relay_secret_key"`
|
|
StrfryConfig string `json:"strfry_config_path"`
|
|
StrfryExecutable string `json:"strfry_executable_path"`
|
|
}
|
|
if err := json.Unmarshal(confb, &conf); err != nil {
|
|
log.Fatalf("invalid json config at %s: %s", path, err)
|
|
return
|
|
}
|
|
|
|
strfrydb = strfry.StrfryBackend{
|
|
ConfigPath: conf.StrfryConfig,
|
|
ExecutablePath: conf.StrfryExecutable,
|
|
}
|
|
strfrydb.Init()
|
|
defer strfrydb.Close()
|
|
|
|
state = relay29.New(relay29.Options{
|
|
Domain: conf.Domain,
|
|
DB: &strfrydb,
|
|
SecretKey: conf.RelaySecretKey,
|
|
})
|
|
|
|
state.AllowPrivateGroups = false
|
|
state.GetAuthed = func(ctx context.Context) string { return "" }
|
|
state.Relay = protoRelay{}
|
|
|
|
// rebuild metadata events (replaceable) for all groups and make them available
|
|
filter := nostr.Filter{Kinds: []int{nostr.KindSimpleGroupMetadata, nostr.KindSimpleGroupAdmins, nostr.KindSimpleGroupMembers}}
|
|
if err := republishMetadataEvents(filter); err != nil {
|
|
log.Fatalf("failed to republish metadata events on startup: %s", err)
|
|
return
|
|
}
|
|
|
|
for {
|
|
var msg StrfryMessage
|
|
|
|
err := incoming.Decode(&msg)
|
|
if err == io.EOF {
|
|
return
|
|
}
|
|
if err != nil {
|
|
log.Print("[strfry29] failed to decode request. killing: " + err.Error())
|
|
return
|
|
}
|
|
|
|
// message, _ := json.Marshal(msg)
|
|
// log.Print("[strfry29] got event: ", string(message))
|
|
|
|
if reject, rejectMsg := accept(msg.Event); reject {
|
|
outgoing.Encode(StrfryResponse{
|
|
ID: msg.Event.ID,
|
|
Action: "reject",
|
|
Msg: rejectMsg,
|
|
})
|
|
} else {
|
|
outgoing.Encode(StrfryResponse{
|
|
ID: msg.Event.ID,
|
|
Action: "accept",
|
|
})
|
|
|
|
go func() {
|
|
time.Sleep(time.Millisecond * 200)
|
|
|
|
state.ApplyModerationAction(ctx, msg.Event)
|
|
state.ReactToJoinRequest(ctx, msg.Event)
|
|
state.ReactToLeaveRequest(ctx, msg.Event)
|
|
}()
|
|
}
|
|
}
|
|
}
|
|
|
|
type StrfryMessage struct {
|
|
Type string `json:"type"`
|
|
Event *nostr.Event `json:"event"`
|
|
SourceType string `json:"sourceType"`
|
|
}
|
|
|
|
type StrfryResponse struct {
|
|
ID string `json:"id"`
|
|
Action string `json:"action"`
|
|
Msg string `json:"msg"`
|
|
}
|
|
|
|
type protoRelay struct{}
|
|
|
|
func (p protoRelay) AddEvent(ctx context.Context, evt *nostr.Event) (skipBroadcast bool, writeError error) {
|
|
err := strfrydb.SaveEvent(ctx, evt)
|
|
return false, err
|
|
}
|
|
|
|
func (p protoRelay) BroadcastEvent(evt *nostr.Event) {
|
|
strfrydb.SaveEvent(ctx, evt)
|
|
}
|