mirror of
https://github.com/github-tijlxyz/khatru-pyramid.git
synced 2025-06-06 18:31:02 +00:00
basic reports page (just displaying, untested).
This commit is contained in:
parent
3846365c8e
commit
8885d99cac
@ -32,13 +32,13 @@ func userRowComponent(ctx context.Context, profile sdk.ProfileMetadata, loggedUs
|
|||||||
}
|
}
|
||||||
|
|
||||||
return Li(
|
return Li(
|
||||||
userNameComponent(ctx, profile),
|
userNameComponent(profile),
|
||||||
button,
|
button,
|
||||||
inviteTreeComponent(ctx, profile.PubKey, loggedUser),
|
inviteTreeComponent(ctx, profile.PubKey, loggedUser),
|
||||||
).Class("ml-6")
|
).Class("ml-6")
|
||||||
}
|
}
|
||||||
|
|
||||||
func userNameComponent(ctx context.Context, profile sdk.ProfileMetadata) HTMLComponent {
|
func userNameComponent(profile sdk.ProfileMetadata) HTMLComponent {
|
||||||
return A().Href("nostr:" + profile.Npub()).Children(
|
return A().Href("nostr:" + profile.Npub()).Children(
|
||||||
Span(profile.ShortName()).Attr(
|
Span(profile.ShortName()).Attr(
|
||||||
"npub", profile.Npub(),
|
"npub", profile.Npub(),
|
||||||
|
121
handler.go
121
handler.go
@ -3,6 +3,7 @@ package main
|
|||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/nbd-wtf/go-nostr"
|
||||||
"github.com/nbd-wtf/go-nostr/nip19"
|
"github.com/nbd-wtf/go-nostr/nip19"
|
||||||
"github.com/theplant/htmlgo"
|
"github.com/theplant/htmlgo"
|
||||||
)
|
)
|
||||||
@ -43,114 +44,20 @@ func removeFromWhitelistHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func reportsViewerHandler(w http.ResponseWriter, r *http.Request) {
|
func reportsViewerHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
// var formattedReportsData template.HTML = ""
|
events, err := db.QueryEvents(r.Context(), nostr.Filter{
|
||||||
|
Kinds: []int{1984},
|
||||||
|
Limit: 52,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, "failed to query reports: "+err.Error(), 500)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// events, _ := db.QueryEvents(context.Background(), nostr.Filter{
|
content := reportsPageHTML(r.Context(), ReportsPageParams{
|
||||||
// Kinds: []int{1984},
|
reports: events,
|
||||||
// Limit: 52,
|
loggedUser: getLoggedUser(r),
|
||||||
// })
|
})
|
||||||
|
htmlgo.Fprint(w, content, r.Context())
|
||||||
// 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"})
|
|
||||||
|
|
||||||
// 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,
|
|
||||||
// }
|
|
||||||
|
|
||||||
// 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
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func homePageHandler(w http.ResponseWriter, r *http.Request) {
|
func homePageHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
6
main.go
6
main.go
@ -56,7 +56,11 @@ func main() {
|
|||||||
relay.QueryEvents = append(relay.QueryEvents, db.QueryEvents)
|
relay.QueryEvents = append(relay.QueryEvents, db.QueryEvents)
|
||||||
relay.CountEvents = append(relay.CountEvents, db.CountEvents)
|
relay.CountEvents = append(relay.CountEvents, db.CountEvents)
|
||||||
relay.DeleteEvent = append(relay.DeleteEvent, db.DeleteEvent)
|
relay.DeleteEvent = append(relay.DeleteEvent, db.DeleteEvent)
|
||||||
relay.RejectEvent = append(relay.RejectEvent, rejectEventsFromUsersNotInWhitelist)
|
relay.RejectEvent = append(relay.RejectEvent,
|
||||||
|
rejectEventsFromUsersNotInWhitelist,
|
||||||
|
restrictToKinds,
|
||||||
|
validateAndFilterReports,
|
||||||
|
)
|
||||||
|
|
||||||
// load users registry
|
// load users registry
|
||||||
if err := loadWhitelist(); err != nil {
|
if err := loadWhitelist(); err != nil {
|
||||||
|
71
pages.go
71
pages.go
@ -3,6 +3,7 @@ package main
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
"github.com/nbd-wtf/go-nostr"
|
||||||
sdk "github.com/nbd-wtf/nostr-sdk"
|
sdk "github.com/nbd-wtf/nostr-sdk"
|
||||||
. "github.com/theplant/htmlgo"
|
. "github.com/theplant/htmlgo"
|
||||||
)
|
)
|
||||||
@ -62,7 +63,7 @@ func homePageHTML(ctx context.Context, params HomePageParams) HTMLComponent {
|
|||||||
contact,
|
contact,
|
||||||
Div(
|
Div(
|
||||||
Text("relay master: "),
|
Text("relay master: "),
|
||||||
userNameComponent(ctx, params.relayOwnerInfo),
|
userNameComponent(params.relayOwnerInfo),
|
||||||
),
|
),
|
||||||
Br(),
|
Br(),
|
||||||
Div(
|
Div(
|
||||||
@ -102,3 +103,71 @@ func inviteTreePageHTML(ctx context.Context, params InviteTreePageParams) HTMLCo
|
|||||||
).Id("tree").Class("mt-3"),
|
).Id("tree").Class("mt-3"),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ReportsPageParams struct {
|
||||||
|
reports chan *nostr.Event
|
||||||
|
loggedUser string
|
||||||
|
}
|
||||||
|
|
||||||
|
func reportsPageHTML(ctx context.Context, params ReportsPageParams) HTMLComponent {
|
||||||
|
items := make([]HTMLComponent, 0, 52)
|
||||||
|
for report := range params.reports {
|
||||||
|
var primaryType string
|
||||||
|
var secondaryType string
|
||||||
|
var relatedContent HTMLComponent
|
||||||
|
|
||||||
|
if e := report.Tags.GetFirst([]string{"e", ""}); e != nil {
|
||||||
|
// event report
|
||||||
|
res, _ := sys.StoreRelay().QuerySync(ctx, nostr.Filter{IDs: []string{(*e)[1]}})
|
||||||
|
if len(res) == 0 {
|
||||||
|
sys.Store.DeleteEvent(ctx, report)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(*e) >= 3 {
|
||||||
|
primaryType = (*e)[2]
|
||||||
|
}
|
||||||
|
|
||||||
|
relatedEvent := res[0]
|
||||||
|
relatedContent = Div(
|
||||||
|
Text("event reported: "),
|
||||||
|
Div().Text(relatedEvent.String()).Class("text-mono"),
|
||||||
|
)
|
||||||
|
} else if p := report.Tags.GetFirst([]string{"p", ""}); p != nil {
|
||||||
|
// pubkey report
|
||||||
|
if !isPublicKeyInWhitelist((*p)[1]) {
|
||||||
|
sys.Store.DeleteEvent(ctx, report)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(*p) >= 3 {
|
||||||
|
primaryType = (*p)[2]
|
||||||
|
}
|
||||||
|
|
||||||
|
relatedProfile := fetchAndStoreProfile(ctx, (*p)[1])
|
||||||
|
relatedContent = Div(
|
||||||
|
Text("profile reported: "),
|
||||||
|
userNameComponent(relatedProfile),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
reporter := sys.FetchProfileMetadata(ctx, report.PubKey)
|
||||||
|
report := Div(
|
||||||
|
Div(Span(primaryType).Class("font-semibold"), Text(" report")).Class("font-lg"),
|
||||||
|
Div().Text(secondaryType),
|
||||||
|
Div(Text("by "), userNameComponent(reporter)),
|
||||||
|
Div().Text(report.Content).Class("p-3"),
|
||||||
|
relatedContent,
|
||||||
|
)
|
||||||
|
|
||||||
|
items = append(items, report)
|
||||||
|
}
|
||||||
|
return baseHTML(
|
||||||
|
Div(
|
||||||
|
H1("reports received").Class("text-xl p-4"),
|
||||||
|
Div(items...),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
29
relay.go
29
relay.go
@ -3,6 +3,7 @@ package main
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
"github.com/fiatjaf/khatru/plugins"
|
||||||
"github.com/nbd-wtf/go-nostr"
|
"github.com/nbd-wtf/go-nostr"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -10,5 +11,33 @@ func rejectEventsFromUsersNotInWhitelist(ctx context.Context, event *nostr.Event
|
|||||||
if isPublicKeyInWhitelist(event.PubKey) {
|
if isPublicKeyInWhitelist(event.PubKey) {
|
||||||
return false, ""
|
return false, ""
|
||||||
}
|
}
|
||||||
|
if event.Kind == 1985 {
|
||||||
|
// we accept reports from anyone (will filter them for relevance in the next function)
|
||||||
|
return false, ""
|
||||||
|
}
|
||||||
return true, "not authorized"
|
return true, "not authorized"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var restrictToKinds = plugins.RestrictToSpecifiedKinds(
|
||||||
|
0, 1, 3, 5, 6, 8, 16, 1063, 1985, 9735, 10000, 10001, 10002, 30008, 30009, 30311, 31922, 31923, 31924, 31925)
|
||||||
|
|
||||||
|
func validateAndFilterReports(ctx context.Context, event *nostr.Event) (reject bool, msg string) {
|
||||||
|
if event.Kind == 1985 {
|
||||||
|
if e := event.Tags.GetFirst([]string{"e", ""}); e != nil {
|
||||||
|
// event report: check if the target event is here
|
||||||
|
res, _ := sys.StoreRelay().QuerySync(ctx, nostr.Filter{IDs: []string{(*e)[1]}})
|
||||||
|
if len(res) == 0 {
|
||||||
|
return true, "we don't know anything about the target event"
|
||||||
|
}
|
||||||
|
} else if p := event.Tags.GetFirst([]string{"p", ""}); p != nil {
|
||||||
|
// pubkey report
|
||||||
|
if !isPublicKeyInWhitelist((*p)[1]) {
|
||||||
|
return true, "target pubkey is not a user of this relay"
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return true, "invalid report"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false, ""
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user