mirror of
https://github.com/github-tijlxyz/khatru-pyramid.git
synced 2025-04-19 18:31:18 +00:00
rewrite things to use htmlgo (wip).
This commit is contained in:
parent
6fbde5f302
commit
32c484178f
3
go.mod
3
go.mod
@ -8,6 +8,7 @@ require (
|
||||
github.com/kelseyhightower/envconfig v1.4.0
|
||||
github.com/nbd-wtf/go-nostr v0.20.0
|
||||
github.com/rs/zerolog v1.31.0
|
||||
github.com/theplant/htmlgo v1.0.3
|
||||
)
|
||||
|
||||
require (
|
||||
@ -52,3 +53,5 @@ require (
|
||||
golang.org/x/sys v0.12.0 // indirect
|
||||
google.golang.org/protobuf v1.23.0 // indirect
|
||||
)
|
||||
|
||||
replace github.com/fiatjaf/khatru => /home/fiatjaf/comp/khatru
|
||||
|
5
go.sum
5
go.sum
@ -53,8 +53,6 @@ github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4
|
||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/fasthttp/websocket v1.5.3 h1:TPpQuLwJYfd4LJPXvHDYPMFWbLjsT91n3GpWtCQtdek=
|
||||
github.com/fasthttp/websocket v1.5.3/go.mod h1:46gg/UBmTU1kUaTcwQXpUxtRwG2PvIZYeA8oL6vF3Fs=
|
||||
github.com/fiatjaf/khatru v0.0.0-20231003113207-bbe186494e68 h1:oBx0uzT+KILepoPAPsjAghqAPSo9uV4pR1myr1rQQGA=
|
||||
github.com/fiatjaf/khatru v0.0.0-20231003113207-bbe186494e68/go.mod h1:8shKDuVtrdLfsuHV4FBC3qYTTXnyfOLAgKqUt4u+Okk=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU=
|
||||
@ -141,6 +139,9 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
|
||||
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc=
|
||||
github.com/theplant/htmlgo v1.0.3 h1:G7/YSf8OrOIRHVQ13avd78T/GV1kDl/jMwpQURrXB0o=
|
||||
github.com/theplant/htmlgo v1.0.3/go.mod h1:pCKSFJsoVNkyW+yN2i1Mst+8130NSQzIU7L2IbnuyKg=
|
||||
github.com/theplant/testingutils v0.0.0-20190603093022-26d8b4d95c61 h1:757/ruZNgTsOf5EkQBo0i3Bx/P2wgF5ljVkODeUX/uA=
|
||||
github.com/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM=
|
||||
github.com/tidwall/gjson v1.14.4/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
||||
|
269
handler.go
269
handler.go
@ -3,12 +3,10 @@ package main
|
||||
import (
|
||||
"context"
|
||||
"embed"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/nbd-wtf/go-nostr"
|
||||
"github.com/theplant/htmlgo"
|
||||
)
|
||||
|
||||
// embed ui files
|
||||
@ -17,177 +15,126 @@ import (
|
||||
var dist embed.FS
|
||||
|
||||
func inviteTreeHandler(w http.ResponseWriter, r *http.Request) {
|
||||
formattedInviteData := buildHTMLTree(whitelist, "")
|
||||
|
||||
data := map[string]interface{}{
|
||||
"Relayname": s.RelayName,
|
||||
"Relaydescription": s.RelayDescription,
|
||||
"Pagetitle": "Invite Hierarchy",
|
||||
"Pagecontent": `
|
||||
<input type="text" id="inviteuser-input" placeholder="npub1..." /><button class="inviteuser">Invite!</button>
|
||||
` + formattedInviteData,
|
||||
}
|
||||
|
||||
tmpl, err := template.ParseFS(dist, "ui/dist/index.html")
|
||||
if err != nil {
|
||||
http.Error(w, "Error parsing template: "+err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
err = tmpl.Execute(w, data)
|
||||
if err != nil {
|
||||
http.Error(w, "Error executing template: "+err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
content := inviteTreePageHTML(r.Context(), InviteTreePageParams{})
|
||||
htmlgo.Fprint(w, baseHTML(content), r.Context())
|
||||
}
|
||||
|
||||
func reportsViewerHandler(w http.ResponseWriter, r *http.Request) {
|
||||
var formattedReportsData template.HTML = ""
|
||||
// var formattedReportsData template.HTML = ""
|
||||
|
||||
events, _ := db.QueryEvents(context.Background(), nostr.Filter{
|
||||
Kinds: []int{1984},
|
||||
Limit: 52,
|
||||
})
|
||||
// events, _ := db.QueryEvents(context.Background(), nostr.Filter{
|
||||
// Kinds: []int{1984},
|
||||
// Limit: 52,
|
||||
// })
|
||||
|
||||
type Report struct {
|
||||
ID string
|
||||
ByUser string
|
||||
AboutUser string
|
||||
AboutEvent string
|
||||
Type string
|
||||
Content string
|
||||
}
|
||||
// type Report struct {
|
||||
// ID string
|
||||
// ByUser string
|
||||
// AboutUser string
|
||||
// AboutEvent string
|
||||
// Type string
|
||||
// Content string
|
||||
// }
|
||||
|
||||
for ev := range events {
|
||||
pTag := ev.Tags.GetFirst([]string{"p"})
|
||||
// for ev := range events {
|
||||
// pTag := ev.Tags.GetFirst([]string{"p"})
|
||||
|
||||
eTag := ev.Tags.GetFirst([]string{"e"})
|
||||
if pTag != nil {
|
||||
typeReport := eTag.Relay()[6:]
|
||||
if typeReport == "" {
|
||||
typeReport = pTag.Relay()[6:]
|
||||
}
|
||||
report := Report{
|
||||
ID: ev.ID,
|
||||
ByUser: ev.PubKey,
|
||||
AboutUser: pTag.Value(),
|
||||
AboutEvent: eTag.Value(),
|
||||
Type: typeReport,
|
||||
Content: ev.Content,
|
||||
}
|
||||
// get AboutEvent content, note1 ect
|
||||
formattedReportsData += template.HTML(fmt.Sprintf(`
|
||||
<div>
|
||||
<p><b>Report %v</b></p>
|
||||
<p>By User: <a class="user" href="nostr:%v">%v</a></p>
|
||||
<p>About User: <a class="user" href="nostr:%v">%v</a></p>`,
|
||||
report.ID,
|
||||
getUserInfo(context.Background(), report.ByUser).Npub,
|
||||
getUserInfo(context.Background(), report.ByUser).Name,
|
||||
getUserInfo(context.Background(), report.AboutUser).Npub,
|
||||
getUserInfo(context.Background(), report.AboutUser).Name,
|
||||
))
|
||||
if report.AboutEvent != "" {
|
||||
// fetch event data
|
||||
aboutEvents, _ := db.QueryEvents(context.TODO(), nostr.Filter{
|
||||
IDs: []string{report.AboutEvent},
|
||||
})
|
||||
for aboutEvent := range aboutEvents {
|
||||
formattedReportsData += template.HTML(fmt.Sprintf(`
|
||||
<p>
|
||||
About Event: <ul>
|
||||
<p>Kind: %v</p>
|
||||
<p>Tags: %v</p>
|
||||
<p>Content: %v</p>
|
||||
</ul>
|
||||
</p>`,
|
||||
template.HTMLEscaper(aboutEvent.Kind),
|
||||
template.HTMLEscaper(aboutEvent.Tags),
|
||||
template.HTMLEscaper(aboutEvent.Content),
|
||||
))
|
||||
}
|
||||
}
|
||||
formattedReportsData += template.HTML(fmt.Sprintf(`
|
||||
<p>Type: %v</p>`,
|
||||
report.Type,
|
||||
))
|
||||
if report.Content != "" {
|
||||
formattedReportsData += template.HTML(fmt.Sprintf(`
|
||||
<p>Content: %v</p>
|
||||
<div>
|
||||
<button data-actionarg='[["e", "%v"],["p", "%v"]]' class="removefromrelay">Ban Reported User and Remove Report</button>
|
||||
<button data-actionarg='[["e", "%v"]]' class="removefromrelay">Remove This Report</button>
|
||||
<button data-actionarg='[["p", "%v"]]' class="removefromrelay">Ban User who wrote report</button>
|
||||
</div>
|
||||
</div>
|
||||
<hr />`,
|
||||
template.HTMLEscaper(report.Content),
|
||||
template.HTMLEscaper(report.ID),
|
||||
template.HTMLEscaper(report.AboutUser),
|
||||
template.HTMLEscaper(report.ID),
|
||||
template.HTMLEscaper(report.ByUser),
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
// eTag := ev.Tags.GetFirst([]string{"e"})
|
||||
// if pTag != nil {
|
||||
// typeReport := eTag.Relay()[6:]
|
||||
// if typeReport == "" {
|
||||
// typeReport = pTag.Relay()[6:]
|
||||
// }
|
||||
// report := Report{
|
||||
// ID: ev.ID,
|
||||
// ByUser: ev.PubKey,
|
||||
// AboutUser: pTag.Value(),
|
||||
// AboutEvent: eTag.Value(),
|
||||
// Type: typeReport,
|
||||
// Content: ev.Content,
|
||||
// }
|
||||
// // get AboutEvent content, note1 ect
|
||||
// formattedReportsData += template.HTML(fmt.Sprintf(`
|
||||
// <div>
|
||||
// <p><b>Report %v</b></p>
|
||||
// <p>By User: <a class="user" href="nostr:%v">%v</a></p>
|
||||
// <p>About User: <a class="user" href="nostr:%v">%v</a></p>`,
|
||||
// report.ID,
|
||||
// getUserInfo(context.Background(), report.ByUser).Npub,
|
||||
// getUserInfo(context.Background(), report.ByUser).Name,
|
||||
// getUserInfo(context.Background(), report.AboutUser).Npub,
|
||||
// getUserInfo(context.Background(), report.AboutUser).Name,
|
||||
// ))
|
||||
// if report.AboutEvent != "" {
|
||||
// // fetch event data
|
||||
// aboutEvents, _ := db.QueryEvents(context.TODO(), nostr.Filter{
|
||||
// IDs: []string{report.AboutEvent},
|
||||
// })
|
||||
// for aboutEvent := range aboutEvents {
|
||||
// formattedReportsData += template.HTML(fmt.Sprintf(`
|
||||
// <p>
|
||||
// About Event: <ul>
|
||||
// <p>Kind: %v</p>
|
||||
// <p>Tags: %v</p>
|
||||
// <p>Content: %v</p>
|
||||
// </ul>
|
||||
// </p>`,
|
||||
// template.HTMLEscaper(aboutEvent.Kind),
|
||||
// template.HTMLEscaper(aboutEvent.Tags),
|
||||
// template.HTMLEscaper(aboutEvent.Content),
|
||||
// ))
|
||||
// }
|
||||
// }
|
||||
// formattedReportsData += template.HTML(fmt.Sprintf(`
|
||||
// <p>Type: %v</p>`,
|
||||
// report.Type,
|
||||
// ))
|
||||
// if report.Content != "" {
|
||||
// formattedReportsData += template.HTML(fmt.Sprintf(`
|
||||
// <p>Content: %v</p>
|
||||
// <div>
|
||||
// <button data-actionarg='[["e", "%v"],["p", "%v"]]' class="removefromrelay">Ban Reported User and Remove Report</button>
|
||||
// <button data-actionarg='[["e", "%v"]]' class="removefromrelay">Remove This Report</button>
|
||||
// <button data-actionarg='[["p", "%v"]]' class="removefromrelay">Ban User who wrote report</button>
|
||||
// </div>
|
||||
// </div>
|
||||
// <hr />`,
|
||||
// template.HTMLEscaper(report.Content),
|
||||
// template.HTMLEscaper(report.ID),
|
||||
// template.HTMLEscaper(report.AboutUser),
|
||||
// template.HTMLEscaper(report.ID),
|
||||
// template.HTMLEscaper(report.ByUser),
|
||||
// ))
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
data := map[string]interface{}{
|
||||
"Relayname": s.RelayName,
|
||||
"Relaydescription": s.RelayDescription,
|
||||
"Pagetitle": "Reports Viewer",
|
||||
"Pagecontent": formattedReportsData,
|
||||
}
|
||||
// data := map[string]interface{}{
|
||||
// "Relayname": s.RelayName,
|
||||
// "Relaydescription": s.RelayDescription,
|
||||
// "Pagetitle": "Reports Viewer",
|
||||
// "Pagecontent": formattedReportsData,
|
||||
// }
|
||||
|
||||
tmpl, err := template.ParseFS(dist, "ui/dist/index.html")
|
||||
if err != nil {
|
||||
http.Error(w, "Error parsing template: "+err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
// tmpl, err := template.ParseFS(dist, "ui/dist/index.html")
|
||||
// if err != nil {
|
||||
// http.Error(w, "Error parsing template: "+err.Error(), http.StatusInternalServerError)
|
||||
// return
|
||||
// }
|
||||
|
||||
// Execute the template with the provided data and write it to the response
|
||||
err = tmpl.Execute(w, data)
|
||||
if err != nil {
|
||||
http.Error(w, "Error executing template: "+err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
// // Execute the template with the provided data and write it to the response
|
||||
// err = tmpl.Execute(w, data)
|
||||
// if err != nil {
|
||||
// http.Error(w, "Error executing template: "+err.Error(), http.StatusInternalServerError)
|
||||
// return
|
||||
// }
|
||||
}
|
||||
|
||||
func homePageHandler(w http.ResponseWriter, r *http.Request) {
|
||||
relayOwnerInfo := getUserInfo(context.Background(), s.RelayPubkey)
|
||||
|
||||
data := map[string]interface{}{
|
||||
"Relayname": s.RelayName,
|
||||
"Relaydescription": s.RelayDescription,
|
||||
"Pagetitle": "Info",
|
||||
"Pagecontent": template.HTML(fmt.Sprintf(`
|
||||
<div>Relay Name: %v</div>
|
||||
<div>Relay Description: %v</div>
|
||||
<div>Relay Owner: <a class="user" href="nostr:%v">%v</a></div>
|
||||
<div>Relay Alternative Contact: %v</div>
|
||||
<br />
|
||||
<div><sub>This relay uses <a target="_blank" rel="noopener noreferrer" href="https://github.com/github-tijlxyz/khatru-invite">Khatru Invite</a>, which is build with <a target="_blank" rel="noopener noreferrer" href="https://github.com/fiatjaf/khatru">Khatru</a></sub></div>
|
||||
`, s.RelayName, s.RelayDescription, relayOwnerInfo.Npub, relayOwnerInfo.Name, s.RelayContact)),
|
||||
}
|
||||
|
||||
tmpl, err := template.ParseFS(dist, "ui/dist/index.html")
|
||||
if err != nil {
|
||||
http.Error(w, "Error parsing template: "+err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
err = tmpl.Execute(w, data)
|
||||
if err != nil {
|
||||
http.Error(w, "Error executing template: "+err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func redirectHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if strings.HasPrefix(r.URL.Path, "/assets") {
|
||||
staticHandler("ui/dist", w, r)
|
||||
} else if r.URL.Path == "/" {
|
||||
homePageHandler(w, r)
|
||||
}
|
||||
content := homePageHTML(r.Context(), HomePageParams{
|
||||
RelayOwnerInfo: getUserInfo(context.Background(), s.RelayPubkey),
|
||||
})
|
||||
htmlgo.Fprint(w, baseHTML(content), r.Context())
|
||||
}
|
||||
|
||||
func staticHandler(prefix string, w http.ResponseWriter, r *http.Request) {
|
||||
|
9
main.go
9
main.go
@ -16,6 +16,7 @@ import (
|
||||
)
|
||||
|
||||
type Settings struct {
|
||||
Port string `envconfig:"PORT" default:"3334"`
|
||||
RelayName string `envconfig:"RELAY_NAME" required:"true"`
|
||||
RelayPubkey string `envconfig:"RELAY_PUBKEY" required:"true"`
|
||||
RelayDescription string `envconfig:"RELAY_DESCRIPTION"`
|
||||
@ -83,10 +84,12 @@ func main() {
|
||||
// ui
|
||||
relay.Router().HandleFunc("/reports", reportsViewerHandler)
|
||||
relay.Router().HandleFunc("/users", inviteTreeHandler)
|
||||
relay.Router().HandleFunc("/", redirectHandler)
|
||||
relay.Router().HandleFunc("/", homePageHandler)
|
||||
|
||||
log.Info().Msg("running on http://127.0.0.1:3334")
|
||||
http.ListenAndServe(":3334", relay)
|
||||
log.Info().Msg("running on http://0.0.0.0:" + s.Port)
|
||||
if err := http.ListenAndServe(":"+s.Port, relay); err != nil {
|
||||
log.Fatal().Err(err).Msg("failed to serve")
|
||||
}
|
||||
}
|
||||
|
||||
// save whitelist on shutdown
|
||||
|
92
pages.go
Normal file
92
pages.go
Normal file
@ -0,0 +1,92 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
. "github.com/theplant/htmlgo"
|
||||
)
|
||||
|
||||
func baseHTML(inside HTMLComponent) HTMLComponent {
|
||||
navItemClass := "text-gray-300 hover:bg-gray-700 hover:text-white rounded-md px-3 py-2 font-medium"
|
||||
|
||||
return HTML(
|
||||
Head(
|
||||
Meta().Charset("utf-8"),
|
||||
Meta().Name("viewport").Content("width=device-width, initial-scale=1"),
|
||||
Title(s.RelayName),
|
||||
Script("").Src("https://cdn.tailwindcss.com"),
|
||||
),
|
||||
Body(
|
||||
Div(
|
||||
H1(s.RelayName).Class("font-bold text-2xl"),
|
||||
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),
|
||||
).Class("flex flex-1 items-center justify-center"),
|
||||
Div(inside).Class("m-4"),
|
||||
).Class("bg-gray-800 mx-4 my-6 text-white"),
|
||||
)
|
||||
}
|
||||
|
||||
type HomePageParams struct {
|
||||
RelayOwnerInfo SimpleUserInfo
|
||||
}
|
||||
|
||||
func homePageHTML(ctx context.Context, params HomePageParams) HTMLComponent {
|
||||
contact := Div()
|
||||
if s.RelayContact != "" {
|
||||
contact = Div().Text("alternative contact: " + s.RelayContact)
|
||||
}
|
||||
|
||||
description := Div()
|
||||
if s.RelayDescription != "" {
|
||||
description = Div().Text("description: " + s.RelayDescription)
|
||||
}
|
||||
|
||||
return Div(
|
||||
Div().Text("name: "+s.RelayName),
|
||||
description,
|
||||
contact,
|
||||
Div(
|
||||
Text("relay master: "),
|
||||
A().Text(params.RelayOwnerInfo.Name).Href("nostr:"+params.RelayOwnerInfo.Npub),
|
||||
),
|
||||
Br(),
|
||||
Div(
|
||||
Text("this relay uses"),
|
||||
A().Target("_blank").Href("https://github.com/github-tijlxyz/khatru-invite").Text("Khatru Invite"),
|
||||
Text(" which is built with "),
|
||||
A().Target("_blank").Href("https://github.com/fiatjaf/khatru").Text("Khatru"),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
type InviteTreePageParams struct{}
|
||||
|
||||
func inviteTreePageHTML(ctx context.Context, params InviteTreePageParams) HTMLComponent {
|
||||
return Div(
|
||||
Input("").Type("text").Placeholder("npub1..."),
|
||||
Button("invite"),
|
||||
buildInviteTree(ctx, ""),
|
||||
)
|
||||
}
|
||||
|
||||
func buildInviteTree(ctx context.Context, invitedBy string) HTMLComponent {
|
||||
tree := Ul()
|
||||
for _, entry := range whitelist {
|
||||
if entry.InvitedBy == invitedBy {
|
||||
user := getUserInfo(ctx, entry.PublicKey)
|
||||
tree = tree.Children(
|
||||
Li(
|
||||
A().Href("nostr:"+user.Npub).Text(user.Name),
|
||||
A().Text("remove"),
|
||||
buildInviteTree(ctx, entry.PublicKey),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
return tree
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="description" content="{{.Relaydescription}}">
|
||||
<script src="./src/main.ts" type="module"></script>
|
||||
<title>{{.Relayname}} | {{.Pagetitle}}</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div>
|
||||
<h1>{{.Relayname}}</h1>
|
||||
<p>{{.Relaydescription}}</p>
|
||||
</div>
|
||||
<hr />
|
||||
<div>
|
||||
<span>
|
||||
<a href="/">information</a> -
|
||||
<a href="/users">invite tree</a> -
|
||||
<a href="/reports">admin reports viewer</a>
|
||||
</span>
|
||||
</div>
|
||||
<hr />
|
||||
<br />
|
||||
<div>
|
||||
{{.Pagecontent}}
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
28
utils.go
28
utils.go
@ -3,37 +3,17 @@ package main
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"html/template"
|
||||
|
||||
"github.com/nbd-wtf/go-nostr"
|
||||
)
|
||||
|
||||
func buildHTMLTree(entries []WhitelistEntry, invitedBy string) template.HTML {
|
||||
html := "<ul>"
|
||||
|
||||
for _, entry := range entries {
|
||||
if entry.InvitedBy == invitedBy {
|
||||
user := getUserInfo(context.TODO(), entry.PublicKey)
|
||||
html += fmt.Sprintf(`
|
||||
<li>
|
||||
<a class="user" href="nostr:%s">%s</a>
|
||||
<a data-actionarg='[["p", "%v"]]' class="rembtn removefromrelay">x</a>
|
||||
%s
|
||||
</li>`, template.HTMLEscapeString(user.Npub),
|
||||
template.HTMLEscapeString(user.Name),
|
||||
entry.PublicKey,
|
||||
buildHTMLTree(entries, entry.PublicKey))
|
||||
}
|
||||
func isPublicKeyInWhitelist(pubkey string) bool {
|
||||
if pubkey == s.RelayPubkey {
|
||||
return true
|
||||
}
|
||||
|
||||
html += "</ul>"
|
||||
return template.HTML(html)
|
||||
}
|
||||
|
||||
func isPkInWhitelist(targetPk string) bool {
|
||||
for i := 0; i < len(whitelist); i++ {
|
||||
if whitelist[i].PublicKey == targetPk {
|
||||
if whitelist[i].PublicKey == pubkey {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ var whitelist []WhitelistEntry
|
||||
|
||||
func whitelistRejecter(ctx context.Context, evt *nostr.Event) (reject bool, msg string) {
|
||||
// check if user in whitelist
|
||||
if !isPkInWhitelist(evt.PubKey) {
|
||||
if !isPublicKeyInWhitelist(evt.PubKey) {
|
||||
return true, "You are not invited to this relay"
|
||||
}
|
||||
|
||||
@ -28,10 +28,8 @@ func whitelistRejecter(ctx context.Context, evt *nostr.Event) (reject bool, msg
|
||||
if evt.Kind == 20201 {
|
||||
pTags := evt.Tags.GetAll([]string{"p"})
|
||||
for _, tag := range pTags {
|
||||
if !isPkInWhitelist(tag.Value()) {
|
||||
if nostr.IsValidPublicKeyHex(tag.Value()) {
|
||||
whitelist = append(whitelist, WhitelistEntry{PublicKey: tag.Value(), InvitedBy: evt.PubKey})
|
||||
}
|
||||
if nostr.IsValidPublicKeyHex(tag.Value()) && !isPublicKeyInWhitelist(tag.Value()) {
|
||||
whitelist = append(whitelist, WhitelistEntry{PublicKey: tag.Value(), InvitedBy: evt.PubKey})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user