mirror of
https://github.com/github-tijlxyz/khatru-pyramid.git
synced 2025-06-06 18:31:02 +00:00
Compare commits
5 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
5e9a09b3c5 | ||
![]() |
66e0c849fc | ||
![]() |
34ab0272c7 | ||
![]() |
c4a241a99f | ||
![]() |
cbc84a2004 |
8
go.mod
8
go.mod
@ -4,8 +4,8 @@ go 1.24.1
|
||||
|
||||
require (
|
||||
github.com/a-h/templ v0.3.857
|
||||
github.com/fiatjaf/eventstore v0.16.4
|
||||
github.com/fiatjaf/khatru v0.17.7
|
||||
github.com/fiatjaf/eventstore v0.16.7
|
||||
github.com/fiatjaf/khatru v0.18.0
|
||||
github.com/kelseyhightower/envconfig v1.4.0
|
||||
github.com/nbd-wtf/go-nostr v0.51.10
|
||||
github.com/rs/zerolog v1.33.0
|
||||
@ -44,7 +44,7 @@ require (
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/puzpuzpuz/xsync/v3 v3.5.1 // indirect
|
||||
github.com/rs/cors v1.11.1 // indirect
|
||||
github.com/savsgio/gotils v0.0.0-20240704082632-aef3928b8a38 // indirect
|
||||
github.com/savsgio/gotils v0.0.0-20250408102913-196191ec6287 // indirect
|
||||
github.com/tidwall/gjson v1.18.0 // indirect
|
||||
github.com/tidwall/match v1.1.1 // indirect
|
||||
github.com/tidwall/pretty v1.2.1 // indirect
|
||||
@ -53,6 +53,6 @@ require (
|
||||
github.com/valyala/fasthttp v1.60.0 // indirect
|
||||
golang.org/x/arch v0.16.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 // indirect
|
||||
golang.org/x/net v0.38.0 // indirect
|
||||
golang.org/x/net v0.39.0 // indirect
|
||||
golang.org/x/sys v0.32.0 // indirect
|
||||
)
|
||||
|
16
go.sum
16
go.sum
@ -72,10 +72,10 @@ github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+m
|
||||
github.com/dvyukov/go-fuzz v0.0.0-20200318091601-be3528f3a813/go.mod h1:11Gm+ccJnvAhCNLlf5+cS9KjtbaD5I5zaZpFMsTHWTw=
|
||||
github.com/fasthttp/websocket v1.5.12 h1:e4RGPpWW2HTbL3zV0Y/t7g0ub294LkiuXXUuTOUInlE=
|
||||
github.com/fasthttp/websocket v1.5.12/go.mod h1:I+liyL7/4moHojiOgUOIKEWm9EIxHqxZChS+aMFltyg=
|
||||
github.com/fiatjaf/eventstore v0.16.4 h1:pENYeuhawxMxlJk8HpRy3pb2oap0fwbphzUgsy7QPws=
|
||||
github.com/fiatjaf/eventstore v0.16.4/go.mod h1:0gU8fzYO/bG+NQAVlHtJWOlt3JKKFefh5Xjj2d1dLIs=
|
||||
github.com/fiatjaf/khatru v0.17.7 h1:1NB2qe/KPF2hIrlzrZOXHj4xIQsulJw1mVlFXYzmhkk=
|
||||
github.com/fiatjaf/khatru v0.17.7/go.mod h1:4KW6mom+7ajwrhj5IvLJTBKj6peV8bdZjU6XoDVrX2Q=
|
||||
github.com/fiatjaf/eventstore v0.16.7 h1:QSDuOVkPdXKUQvITD/vz3qLwXhKgaVjPdZx1dQJEOpY=
|
||||
github.com/fiatjaf/eventstore v0.16.7/go.mod h1:cm7rn3an71pYrf5CFWhdHTeozvVh0urLun4ziWdvA+Y=
|
||||
github.com/fiatjaf/khatru v0.18.0 h1:EXLz53jlasRtim9lljnUGQ53bEzIn4aTdEYaRavINZQ=
|
||||
github.com/fiatjaf/khatru v0.18.0/go.mod h1:4KW6mom+7ajwrhj5IvLJTBKj6peV8bdZjU6XoDVrX2Q=
|
||||
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/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
@ -146,8 +146,8 @@ github.com/rs/cors v1.11.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU
|
||||
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||
github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8=
|
||||
github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
|
||||
github.com/savsgio/gotils v0.0.0-20240704082632-aef3928b8a38 h1:D0vL7YNisV2yqE55+q0lFuGse6U8lxlg7fYTctlT5Gc=
|
||||
github.com/savsgio/gotils v0.0.0-20240704082632-aef3928b8a38/go.mod h1:sM7Mt7uEoCeFSCBM+qBrqvEo+/9vdmj19wzp3yzUhmg=
|
||||
github.com/savsgio/gotils v0.0.0-20250408102913-196191ec6287 h1:qIQ0tWF9vxGtkJa24bR+2i53WBCz1nW/Pc47oVYauC4=
|
||||
github.com/savsgio/gotils v0.0.0-20250408102913-196191ec6287/go.mod h1:sM7Mt7uEoCeFSCBM+qBrqvEo+/9vdmj19wzp3yzUhmg=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
@ -187,8 +187,8 @@ golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73r
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8=
|
||||
golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
|
||||
golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY=
|
||||
golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610=
|
||||
golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
|
28
handler.go
28
handler.go
@ -91,31 +91,3 @@ func reportsViewerHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
reportsPage(events, getLoggedUser(r)).Render(r.Context(), w)
|
||||
}
|
||||
|
||||
func joubleHandler(w http.ResponseWriter, r *http.Request) {
|
||||
fmt.Fprintf(w, `
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>pyramid</title>
|
||||
<script>
|
||||
window.relayGroups = [{
|
||||
groupName: 'pyramid',
|
||||
relayUrls: [location.href.replace('http', 'ws').replace('/browse', '')],
|
||||
isActive: true,
|
||||
}]
|
||||
window.hideRelaySettings = true
|
||||
</script>
|
||||
<script type="module" crossorigin src="https://cdn.jsdelivr.net/npm/jouble@0.0.6/dist/index.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="https://cdn.jsdelivr.net/npm/jouble@0.0.6/dist/index.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script src="https://cdn.jsdelivr.net/npm/window.nostr.js@0.4.7/dist/window.nostr.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
`)
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ templ layout(loggedUser string) {
|
||||
</div>
|
||||
<nav class="flex flex-1 items-center justify-center">
|
||||
<a href="/" class="text-gray-600 hover:bg-gray-200 rounded-md px-3 py-2 font-medium" hx-boost="true" hx-target="main" hx-select="main">invite tree</a>
|
||||
<a href="/browse" class="text-gray-600 hover:bg-gray-200 rounded-md px-3 py-2 font-medium">browse</a>
|
||||
<a target="_blank" class="text-gray-600 hover:bg-gray-200 rounded-md px-3 py-2 font-medium" _="on load set my href to `https://jumble.social/?r=${location.hostname}`">browse</a>
|
||||
<a href="/reports" class="text-gray-600 hover:bg-gray-200 rounded-md px-3 py-2 font-medium" hx-boost="true" hx-target="main" hx-select="main">reports</a>
|
||||
if loggedUser == s.RelayPubkey {
|
||||
<a href="/cleanup" class="text-gray-600 hover:bg-gray-200 rounded-md px-3 py-2 font-medium">clear stuff</a>
|
||||
|
14
main.go
14
main.go
@ -9,6 +9,7 @@ import (
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/fiatjaf/eventstore/lmdb"
|
||||
"github.com/fiatjaf/khatru"
|
||||
@ -43,6 +44,8 @@ var (
|
||||
switch kind {
|
||||
case 7:
|
||||
return true, true
|
||||
case 1111:
|
||||
return true, false
|
||||
default:
|
||||
return false, false
|
||||
}
|
||||
@ -63,6 +66,8 @@ func main() {
|
||||
return
|
||||
}
|
||||
|
||||
relay.ServiceURL = "wss://" + s.Domain
|
||||
|
||||
// enable negentropy
|
||||
relay.Negentropy = true
|
||||
|
||||
@ -86,7 +91,13 @@ func main() {
|
||||
}
|
||||
relay.Info.Software = "https://github.com/github-tijlxyz/khatru-pyramid"
|
||||
|
||||
policies.ApplySaneDefaults(relay)
|
||||
relay.RejectFilter = append(relay.RejectFilter,
|
||||
policies.NoComplexFilters,
|
||||
policies.FilterIPRateLimiter(20, time.Minute, 100),
|
||||
)
|
||||
relay.RejectConnection = append(relay.RejectConnection,
|
||||
policies.ConnectionRateLimiter(1, time.Minute*5, 100),
|
||||
)
|
||||
|
||||
relay.StoreEvent = append(relay.StoreEvent, db.SaveEvent)
|
||||
relay.QueryEvents = append(relay.QueryEvents, db.QueryEvents)
|
||||
@ -124,7 +135,6 @@ func main() {
|
||||
relay.Router().HandleFunc("/remove-from-whitelist", removeFromWhitelistHandler)
|
||||
relay.Router().HandleFunc("/cleanup", cleanupStuffFromExcludedUsersHandler)
|
||||
relay.Router().HandleFunc("/reports", reportsViewerHandler)
|
||||
relay.Router().HandleFunc("/browse/", joubleHandler)
|
||||
relay.Router().Handle("/static/", http.FileServer(http.FS(static)))
|
||||
relay.Router().HandleFunc("/favicon.ico", func(w http.ResponseWriter, r *http.Request) {
|
||||
if s.RelayIcon != "" {
|
||||
|
2
relay.go
2
relay.go
@ -68,6 +68,7 @@ var supportedKinds = []uint16{
|
||||
30015,
|
||||
30818,
|
||||
30819,
|
||||
30023,
|
||||
30030,
|
||||
30078,
|
||||
30311,
|
||||
@ -75,6 +76,7 @@ var supportedKinds = []uint16{
|
||||
31923,
|
||||
31924,
|
||||
31925,
|
||||
39701,
|
||||
}
|
||||
|
||||
func validateAndFilterReports(ctx context.Context, event *nostr.Event) (reject bool, msg string) {
|
||||
|
@ -1,12 +1,13 @@
|
||||
package main
|
||||
|
||||
import "github.com/nbd-wtf/go-nostr"
|
||||
import "github.com/nbd-wtf/go-nostr/nip19"
|
||||
|
||||
templ reportsPage(reports chan *nostr.Event, loggedUser string) {
|
||||
@layout(loggedUser) {
|
||||
<div>
|
||||
<div class="max-w-4xl mx-auto">
|
||||
<h1 class="text-xl p-4">reports received</h1>
|
||||
<div>
|
||||
<div class="space-y-4 p-4">
|
||||
for report := range reports {
|
||||
<div>
|
||||
if e := report.Tags.Find("e"); e != nil {
|
||||
@ -23,7 +24,8 @@ templ reportsPage(reports chan *nostr.Event, loggedUser string) {
|
||||
|
||||
templ eventReportComponent(e nostr.Tag, report *nostr.Event) {
|
||||
if res, _ := sys.StoreRelay.QuerySync(ctx, nostr.Filter{IDs: []string{e[1]}}); len(res) > 0 {
|
||||
<div>
|
||||
<div class="bg-white rounded-lg shadow-sm border border-gray-200 p-4">
|
||||
<div class="flex justify-between items-start">
|
||||
<div class="font-lg">
|
||||
<span class="font-semibold">
|
||||
if len(e) >= 3 {
|
||||
@ -32,19 +34,26 @@ templ eventReportComponent(e nostr.Tag, report *nostr.Event) {
|
||||
</span>
|
||||
{ " report" }
|
||||
</div>
|
||||
<div>by @userNameComponent(sys.FetchProfileMetadata(ctx, report.PubKey))</div>
|
||||
<div class="p-3">{ report.Content }</div>
|
||||
<div>
|
||||
event reported:
|
||||
<div class="text-mono">{ res[0].String() }</div>
|
||||
<div class="text-sm text-gray-500">
|
||||
{ report.CreatedAt.Time().Format("Jan 2, 2006 3:04 PM") }
|
||||
</div>
|
||||
</div>
|
||||
{{ npub, _ := nip19.EncodePublicKey(report.PubKey) }}
|
||||
<div class="mt-2 text-sm text-gray-600">by <a class="hover:underline" title={ report.PubKey } href={ templ.SafeURL("nostr:" + npub) }><nostr-name pubkey={ report.PubKey }></nostr-name></a></div>
|
||||
if report.Content != "" {
|
||||
<div class="mt-3 p-3 bg-gray-50 rounded">{ report.Content }</div>
|
||||
}
|
||||
<div class="mt-3">
|
||||
<div class="text-sm text-gray-600">event reported:</div>
|
||||
<div class="mt-1 font-mono text-sm bg-gray-50 p-2 rounded overflow-auto whitespace-pre-wrap break-all">{ res[0].String() }</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
templ profileReportComponent(p nostr.Tag, report *nostr.Event) {
|
||||
if isPublicKeyInWhitelist(p[1]) {
|
||||
<div>
|
||||
<div class="bg-white rounded-lg shadow-sm border border-gray-200 p-4">
|
||||
<div class="flex justify-between items-start">
|
||||
<div class="font-lg">
|
||||
<span class="font-semibold">
|
||||
if len(p) >= 3 {
|
||||
@ -53,14 +62,23 @@ templ profileReportComponent(p nostr.Tag, report *nostr.Event) {
|
||||
</span>
|
||||
{ " report" }
|
||||
</div>
|
||||
<div>by @userNameComponent(sys.FetchProfileMetadata(ctx, report.PubKey))</div>
|
||||
<div class="p-3">{ report.Content }</div>
|
||||
<div>
|
||||
profile reported:
|
||||
<a href={ templ.URL("https://njump.me/p/" + report.PubKey) } target="_blank" class="font-mono py-1">
|
||||
<nostr-name pubkey={ report.PubKey }>{ report.PubKey }</nostr-name>
|
||||
<div class="text-sm text-gray-500">
|
||||
{ report.CreatedAt.Time().Format("Jan 2, 2006 3:04 PM") }
|
||||
</div>
|
||||
</div>
|
||||
{{ npub, _ := nip19.EncodePublicKey(report.PubKey) }}
|
||||
<div class="mt-2 text-sm text-gray-600">by <a class="hover:underline" title={ report.PubKey } href={ templ.SafeURL("nostr:" + npub) }><nostr-name pubkey={ report.PubKey }></nostr-name></a></div>
|
||||
if report.Content != "" {
|
||||
<div class="mt-3 p-3 bg-gray-50 rounded">{ report.Content }</div>
|
||||
}
|
||||
<div class="mt-3">
|
||||
<div class="text-sm text-gray-600">profile reported:</div>
|
||||
<div class="mt-1">
|
||||
{{ npubt, _ := nip19.EncodePublicKey(p[1]) }}
|
||||
<a href={ templ.URL("nostr:" + npubt) } target="_blank" class="text-sm hover:underline">
|
||||
<nostr-name pubkey={ p[1] }></nostr-name>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user