mirror of
https://github.com/github-tijlxyz/khatru-pyramid.git
synced 2025-06-03 15:52:04 +00:00
making everything almost work again.
This commit is contained in:
parent
32c484178f
commit
86509c59b5
20
handler.go
20
handler.go
@ -19,6 +19,26 @@ func inviteTreeHandler(w http.ResponseWriter, r *http.Request) {
|
||||
htmlgo.Fprint(w, baseHTML(content), r.Context())
|
||||
}
|
||||
|
||||
func addToWhitelistHandler(w http.ResponseWriter, r *http.Request) {
|
||||
pubkey := r.PostFormValue("pubkey")
|
||||
if err := addToWhitelist(r.Context(), pubkey, s.RelayPubkey); err != nil {
|
||||
http.Error(w, "failed to add to whitelist: "+err.Error(), 500)
|
||||
return
|
||||
}
|
||||
content := buildInviteTree(r.Context(), s.RelayPubkey)
|
||||
htmlgo.Fprint(w, content, r.Context())
|
||||
}
|
||||
|
||||
func removeFromWhitelistHandler(w http.ResponseWriter, r *http.Request) {
|
||||
pubkey := r.PostFormValue("pubkey")
|
||||
if err := removeFromWhitelist(r.Context(), pubkey); err != nil {
|
||||
http.Error(w, "failed to remove from whitelist: "+err.Error(), 500)
|
||||
return
|
||||
}
|
||||
content := buildInviteTree(r.Context(), s.RelayPubkey)
|
||||
htmlgo.Fprint(w, content, r.Context())
|
||||
}
|
||||
|
||||
func reportsViewerHandler(w http.ResponseWriter, r *http.Request) {
|
||||
// var formattedReportsData template.HTML = ""
|
||||
|
||||
|
37
main.go
37
main.go
@ -3,14 +3,9 @@ package main
|
||||
import (
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"sync"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/fiatjaf/khatru"
|
||||
"github.com/fiatjaf/khatru/plugins/storage/badgern"
|
||||
"github.com/joho/godotenv"
|
||||
"github.com/kelseyhightower/envconfig"
|
||||
"github.com/rs/zerolog"
|
||||
)
|
||||
@ -36,25 +31,6 @@ func main() {
|
||||
return
|
||||
}
|
||||
|
||||
// save whitelist on shutdown
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
handleSignals()
|
||||
}()
|
||||
|
||||
// backup whitelist every hour
|
||||
go func() {
|
||||
for {
|
||||
time.Sleep(time.Hour)
|
||||
saveWhitelist()
|
||||
}
|
||||
}()
|
||||
|
||||
// init env config
|
||||
godotenv.Load(".env")
|
||||
|
||||
// init relay
|
||||
relay := khatru.NewRelay()
|
||||
|
||||
@ -78,11 +54,11 @@ func main() {
|
||||
relay.QueryEvents = append(relay.QueryEvents, db.QueryEvents)
|
||||
relay.CountEvents = append(relay.CountEvents, db.CountEvents)
|
||||
relay.DeleteEvent = append(relay.DeleteEvent, db.DeleteEvent)
|
||||
|
||||
relay.RejectEvent = append(relay.RejectEvent, whitelistRejecter)
|
||||
|
||||
// ui
|
||||
relay.Router().HandleFunc("/reports", reportsViewerHandler)
|
||||
relay.Router().HandleFunc("/add-to-whitelist", addToWhitelistHandler)
|
||||
relay.Router().HandleFunc("/remove-from-whitelist", removeFromWhitelistHandler)
|
||||
relay.Router().HandleFunc("/users", inviteTreeHandler)
|
||||
relay.Router().HandleFunc("/", homePageHandler)
|
||||
|
||||
@ -91,12 +67,3 @@ func main() {
|
||||
log.Fatal().Err(err).Msg("failed to serve")
|
||||
}
|
||||
}
|
||||
|
||||
// save whitelist on shutdown
|
||||
func handleSignals() {
|
||||
sigCh := make(chan os.Signal, 1)
|
||||
signal.Notify(sigCh, os.Interrupt, syscall.SIGTERM)
|
||||
<-sigCh
|
||||
saveWhitelist()
|
||||
os.Exit(0)
|
||||
}
|
||||
|
40
pages.go
40
pages.go
@ -6,8 +6,10 @@ import (
|
||||
. "github.com/theplant/htmlgo"
|
||||
)
|
||||
|
||||
const buttonClass = "rounded-md bg-white p-2 text-sm font-semibold text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 hover:bg-gray-50"
|
||||
|
||||
func baseHTML(inside HTMLComponent) HTMLComponent {
|
||||
navItemClass := "text-gray-300 hover:bg-gray-700 hover:text-white rounded-md px-3 py-2 font-medium"
|
||||
navItemClass := "text-gray-600 hover:bg-gray-200 rounded-md px-3 py-2 font-medium"
|
||||
|
||||
return HTML(
|
||||
Head(
|
||||
@ -15,6 +17,8 @@ func baseHTML(inside HTMLComponent) HTMLComponent {
|
||||
Meta().Name("viewport").Content("width=device-width, initial-scale=1"),
|
||||
Title(s.RelayName),
|
||||
Script("").Src("https://cdn.tailwindcss.com"),
|
||||
Script("").Src("https://unpkg.com/htmx.org@1.9.6"),
|
||||
Script("").Src("https://unpkg.com/hyperscript.org@0.9.12"),
|
||||
),
|
||||
Body(
|
||||
Div(
|
||||
@ -22,12 +26,12 @@ func baseHTML(inside HTMLComponent) HTMLComponent {
|
||||
P().Text(s.RelayDescription).Class("text-lg"),
|
||||
).Class("mx-auto my-6 text-center"),
|
||||
Nav(
|
||||
A().Text("information").Href("/").Class(navItemClass),
|
||||
A().Text("invite tree").Href("/users").Class(navItemClass),
|
||||
A().Text("reports").Href("/reports").Class(navItemClass),
|
||||
A().Text("information").Href("/").Class(navItemClass).Attr("hx-boost", "true", "hx-target", "main", "hx-select", "main"),
|
||||
A().Text("invite tree").Href("/users").Class(navItemClass).Attr("hx-boost", "true", "hx-target", "main", "hx-select", "main"),
|
||||
A().Text("reports").Href("/reports").Class(navItemClass).Attr("hx-boost", "true", "hx-target", "main", "hx-select", "main"),
|
||||
).Class("flex flex-1 items-center justify-center"),
|
||||
Div(inside).Class("m-4"),
|
||||
).Class("bg-gray-800 mx-4 my-6 text-white"),
|
||||
Main(inside).Class("m-4"),
|
||||
).Class("mx-4 my-6"),
|
||||
)
|
||||
}
|
||||
|
||||
@ -67,26 +71,28 @@ func homePageHTML(ctx context.Context, params HomePageParams) HTMLComponent {
|
||||
type InviteTreePageParams struct{}
|
||||
|
||||
func inviteTreePageHTML(ctx context.Context, params InviteTreePageParams) HTMLComponent {
|
||||
return Div(
|
||||
Input("").Type("text").Placeholder("npub1..."),
|
||||
Button("invite"),
|
||||
buildInviteTree(ctx, ""),
|
||||
)
|
||||
return Form(
|
||||
Input("pubkey").Type("text").Placeholder("npub1...").Class("w-96 rounded-md border-0 p-2 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600"),
|
||||
Button("invite").Class(buttonClass),
|
||||
Div(
|
||||
buildInviteTree(ctx, s.RelayPubkey),
|
||||
).Id("tree").Class("mt-3"),
|
||||
).Attr("hx-post", "/add-to-whitelist", "hx-trigger", "submit", "hx-target", "#tree")
|
||||
}
|
||||
|
||||
func buildInviteTree(ctx context.Context, invitedBy string) HTMLComponent {
|
||||
tree := Ul()
|
||||
children := make([]HTMLComponent, 0, len(whitelist))
|
||||
for _, entry := range whitelist {
|
||||
if entry.InvitedBy == invitedBy {
|
||||
user := getUserInfo(ctx, entry.PublicKey)
|
||||
tree = tree.Children(
|
||||
children = append(children,
|
||||
Li(
|
||||
A().Href("nostr:"+user.Npub).Text(user.Name),
|
||||
A().Text("remove"),
|
||||
A().Href("nostr:"+user.Npub).Text(user.Name).Class("font-mono"),
|
||||
Button("remove").Class(buttonClass).Attr("hx-post", "/remove-from-whitelist", "hx-trigger", "click", "hx-target", "#tree"),
|
||||
buildInviteTree(ctx, entry.PublicKey),
|
||||
),
|
||||
).Class("ml-3"),
|
||||
)
|
||||
}
|
||||
}
|
||||
return tree
|
||||
return Ul(children...)
|
||||
}
|
||||
|
26
whitelist.go
26
whitelist.go
@ -6,11 +6,12 @@ import (
|
||||
"os"
|
||||
|
||||
"github.com/nbd-wtf/go-nostr"
|
||||
"golang.org/x/exp/slices"
|
||||
)
|
||||
|
||||
type WhitelistEntry struct {
|
||||
PublicKey string `json:"pk"`
|
||||
InvitedBy string `json:"invited_by"`
|
||||
PublicKey string `json:"pk"`
|
||||
}
|
||||
|
||||
var whitelist []WhitelistEntry
|
||||
@ -26,12 +27,6 @@ func whitelistRejecter(ctx context.Context, evt *nostr.Event) (reject bool, msg
|
||||
invited/whitelisted user invites new user
|
||||
*/
|
||||
if evt.Kind == 20201 {
|
||||
pTags := evt.Tags.GetAll([]string{"p"})
|
||||
for _, tag := range pTags {
|
||||
if nostr.IsValidPublicKeyHex(tag.Value()) && !isPublicKeyInWhitelist(tag.Value()) {
|
||||
whitelist = append(whitelist, WhitelistEntry{PublicKey: tag.Value(), InvitedBy: evt.PubKey})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -76,6 +71,23 @@ func whitelistRejecter(ctx context.Context, evt *nostr.Event) (reject bool, msg
|
||||
return false, ""
|
||||
}
|
||||
|
||||
func addToWhitelist(ctx context.Context, pubkey string, invitedBy string) error {
|
||||
if nostr.IsValidPublicKeyHex(pubkey) && !isPublicKeyInWhitelist(pubkey) {
|
||||
whitelist = append(whitelist, WhitelistEntry{PublicKey: pubkey, InvitedBy: invitedBy})
|
||||
}
|
||||
return saveWhitelist()
|
||||
}
|
||||
|
||||
func removeFromWhitelist(ctx context.Context, pubkey string) error {
|
||||
idx := slices.IndexFunc(whitelist, func(we WhitelistEntry) bool { return we.PublicKey == pubkey })
|
||||
if idx == -1 {
|
||||
return nil
|
||||
}
|
||||
|
||||
whitelist = append(whitelist[0:idx], whitelist[idx+1:]...)
|
||||
return saveWhitelist()
|
||||
}
|
||||
|
||||
func loadWhitelist() error {
|
||||
if _, err := os.Stat("whitelist.json"); os.IsNotExist(err) {
|
||||
whitelist = []WhitelistEntry{}
|
||||
|
Loading…
x
Reference in New Issue
Block a user