mirror of
https://github.com/github-tijlxyz/khatru-pyramid.git
synced 2025-06-06 18:31:02 +00:00
better relaymaster and fixes
This commit is contained in:
parent
a4bb3f7833
commit
c4ef0a5f25
2
.env
2
.env
@ -5,4 +5,4 @@ RELAY_PUBKEY=""
|
||||
RELAY_CONTACT=""
|
||||
|
||||
# Custom invite-relay settings
|
||||
INVITE_MASTER="" # Master of the relay
|
||||
INVITE_RELAY_MASTER="" # Master of the relay (pubkey hex)
|
||||
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,2 +1,4 @@
|
||||
whitelist.json
|
||||
khatru-invite
|
||||
.env
|
||||
khatru-badgern-db
|
8
README.md
Normal file
8
README.md
Normal file
@ -0,0 +1,8 @@
|
||||
# Khatru Invite
|
||||
|
||||
A relay based on [Khatru](https://github.com/fiatjaf/khatru) with a invite hierarchy feature.
|
||||
|
||||
some notes before running:
|
||||
1. change `ws://localhost:3334` in `ui/src/lib/consts.ts` to your relay url endpoint and build the UI
|
||||
2. configure the relay settings in `.env`
|
||||
3. manually add someone to the `whitelist.json` file, like this: `[{"pk":"07adfda9c5adc80881bb2a5220f6e3181e0c043b90fa115c4f183464022968e6","invited_by":""}]`
|
7
go.mod
7
go.mod
@ -1,15 +1,16 @@
|
||||
module github.com/github-tijlxyz/khatru-invite
|
||||
|
||||
go 1.20
|
||||
go 1.21.1
|
||||
|
||||
require (
|
||||
github.com/fiatjaf/khatru v0.0.2
|
||||
github.com/fiatjaf/khatru v0.0.0-20230916185141-24d1e3aebd67
|
||||
github.com/joho/godotenv v1.5.1
|
||||
github.com/nbd-wtf/go-nostr v0.20.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/andybalholm/brotli v1.0.5 // indirect
|
||||
github.com/bmatsuo/lmdb-go v1.8.0 // indirect
|
||||
github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect
|
||||
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.2 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
||||
@ -28,9 +29,11 @@ require (
|
||||
github.com/golang/protobuf v1.3.1 // indirect
|
||||
github.com/golang/snappy v0.0.3 // indirect
|
||||
github.com/google/flatbuffers v1.12.1 // indirect
|
||||
github.com/jmoiron/sqlx v1.3.1 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/klauspost/compress v1.16.5 // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/mattn/go-sqlite3 v1.14.6 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/puzpuzpuz/xsync v1.5.2 // indirect
|
||||
github.com/rs/cors v1.7.0 // indirect
|
||||
|
14
go.sum
14
go.sum
@ -2,6 +2,8 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
|
||||
github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
||||
github.com/bmatsuo/lmdb-go v1.8.0 h1:ohf3Q4xjXZBKh4AayUY4bb2CXuhRAI8BYGlJq08EfNA=
|
||||
github.com/bmatsuo/lmdb-go v1.8.0/go.mod h1:wWPZmKdOAZsl4qOqkowQ1aCrFie1HU8gWloHMCeAUdM=
|
||||
github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U=
|
||||
github.com/btcsuite/btcd/btcec/v2 v2.3.2/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04=
|
||||
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.2 h1:KdUfX2zKommPRa+PD0sWZUyXe9w277ABlgELO7H04IM=
|
||||
@ -27,8 +29,9 @@ 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.2 h1:+OaARQhrColJG1NypLDWgkaERjJhbLAtUk8RIYETeGU=
|
||||
github.com/fiatjaf/khatru v0.0.2/go.mod h1:XDX+UIURFlTrAAw/ya7M5YRC4ft2Qm2gAAvs3ELoVps=
|
||||
github.com/fiatjaf/khatru v0.0.0-20230916185141-24d1e3aebd67 h1:nsaUBS6rjAZCvPDgGUxG3tzfZnx6DX9iUBqPtDWDT/g=
|
||||
github.com/fiatjaf/khatru v0.0.0-20230916185141-24d1e3aebd67/go.mod h1:XDX+UIURFlTrAAw/ya7M5YRC4ft2Qm2gAAvs3ELoVps=
|
||||
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU=
|
||||
github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM=
|
||||
github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og=
|
||||
@ -50,6 +53,8 @@ github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW
|
||||
github.com/google/flatbuffers v1.12.1 h1:MVlul7pQNoDzWRLTw5imwYsl+usrS1TXG2H4jg6ImGw=
|
||||
github.com/google/flatbuffers v1.12.1/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/jmoiron/sqlx v1.3.1 h1:aLN7YINNZ7cYOPK3QC83dbM6KT0NMqVMw961TqrejlE=
|
||||
github.com/jmoiron/sqlx v1.3.1/go.mod h1:2BljVx/86SuTyjE+aPYlHCTNvZrnJXghYGpNiXLBMCQ=
|
||||
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||
@ -58,8 +63,11 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/compress v1.16.5 h1:IFV2oUNUzZaz+XyusxpLzpzS8Pt5rh0Z16For/djlyI=
|
||||
github.com/klauspost/compress v1.16.5/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
|
||||
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
||||
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/mattn/go-sqlite3 v1.14.6 h1:dNPt6NO46WmLVt2DLNpwczCmdV5boIZ6g/tlDrlRUbg=
|
||||
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||
github.com/nbd-wtf/go-nostr v0.20.0 h1:97SYhg68jWh5G1bW1g454hA0dTV7btwtPg836n4no0o=
|
||||
github.com/nbd-wtf/go-nostr v0.20.0/go.mod h1:iFfiZr8YYSC1vmdUei0VfDB7GH/RjS3cbmiD1I5BKyo=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
@ -75,6 +83,7 @@ github.com/savsgio/gotils v0.0.0-20230208104028-c358bd845dee/go.mod h1:qwtSXrKuJ
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
|
||||
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
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=
|
||||
@ -148,4 +157,5 @@ google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiq
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
|
42
handler.go
42
handler.go
@ -7,20 +7,6 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
func inviteDataApiHandler(w http.ResponseWriter, re *http.Request) {
|
||||
jsonBytes, err := json.Marshal(whitelist)
|
||||
if err != nil {
|
||||
http.Error(w, "internal server error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Header().Set("Access-Control-Allow-Origin", "*")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
if _, err := w.Write(jsonBytes); err != nil {
|
||||
http.Error(w, "internal server error", http.StatusInternalServerError)
|
||||
}
|
||||
}
|
||||
|
||||
// embed ui files
|
||||
//go:embed ui/dist/*
|
||||
var uiContent embed.FS
|
||||
@ -52,3 +38,31 @@ func embeddedUIHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func inviteDataApiHandler(w http.ResponseWriter, re *http.Request) {
|
||||
jsonBytes, err := json.Marshal(whitelist)
|
||||
if err != nil {
|
||||
http.Error(w, "internal server error 00", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Header().Set("Access-Control-Allow-Origin", "*")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
if _, err := w.Write(jsonBytes); err != nil {
|
||||
http.Error(w, "internal server error 01", http.StatusInternalServerError)
|
||||
}
|
||||
}
|
||||
|
||||
func relayMasterApiHandler(w http.ResponseWriter, re *http.Request) {
|
||||
jsonBytes, err := json.Marshal(relayMaster)
|
||||
if err != nil {
|
||||
http.Error(w, "internal server error 10", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Header().Set("Access-Control-Allow-Origin", "*")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
if _, err := w.Write(jsonBytes); err != nil {
|
||||
http.Error(w, "internal server error 11", http.StatusInternalServerError)
|
||||
}
|
||||
}
|
||||
|
7
main.go
7
main.go
@ -40,7 +40,7 @@ func main() {
|
||||
// init relay
|
||||
relay := khatru.NewRelay()
|
||||
|
||||
relayMaster = os.Getenv("INVITE_MASTER")
|
||||
relayMaster = os.Getenv("INVITE_RELAY_MASTER")
|
||||
relay.Name = os.Getenv("RELAY_NAME")
|
||||
relay.Description = os.Getenv("RELAY_DESCRIPTION")
|
||||
relay.PubKey = os.Getenv("RELAY_PUBKEY")
|
||||
@ -52,7 +52,7 @@ func main() {
|
||||
}
|
||||
|
||||
// load db
|
||||
db = badgern.BadgerBackend{Path: "/tmp/khatru-badgern-tmp"}
|
||||
db = badgern.BadgerBackend{Path: "./khatru-badgern-db"}
|
||||
if err := db.Init(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@ -62,11 +62,12 @@ func main() {
|
||||
relay.CountEvents = append(relay.CountEvents, db.CountEvents)
|
||||
relay.DeleteEvent = append(relay.DeleteEvent, db.DeleteEvent)
|
||||
|
||||
|
||||
relay.RejectEvent = append(relay.RejectEvent, whitelistRejecter)
|
||||
|
||||
// invitedata api
|
||||
relay.Router().HandleFunc("/invitedata", inviteDataApiHandler)
|
||||
relay.Router().HandleFunc("/relaymaster", relayMasterApiHandler)
|
||||
|
||||
// ui
|
||||
relay.Router().HandleFunc("/", embeddedUIHandler)
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
import Hieracy from "./components/Hierarchy.svelte";
|
||||
import Invite from "./components/Invite.svelte";
|
||||
import { onMount } from "svelte";
|
||||
import { ndk, userPublickey } from "./lib/nostr";
|
||||
import { ndk, relayMaster, userPublickey } from "./lib/nostr";
|
||||
import { NDKNip07Signer } from "@nostr-dev-kit/ndk";
|
||||
import { buildHierarchy } from "./lib/utils";
|
||||
import { nip19 } from "nostr-tools";
|
||||
@ -20,9 +20,15 @@
|
||||
}
|
||||
|
||||
async function fetchData() {
|
||||
// Fetch Invite Data
|
||||
const response = await fetch("/invitedata");
|
||||
invitedata = Object.values(await response.json());
|
||||
hierarchy = buildHierarchy(invitedata, { pk: "", invited_by: "" });
|
||||
|
||||
// Fetch Relay Master Pubkey
|
||||
const response0 = await fetch("/relaymaster");
|
||||
$relayMaster = await response0.json();
|
||||
relayMaster.set($relayMaster);
|
||||
}
|
||||
|
||||
let invitedata = [];
|
||||
@ -30,21 +36,27 @@
|
||||
|
||||
onMount(() => {
|
||||
addEventListener("load", (e) => {
|
||||
setTimeout(() => {
|
||||
login();
|
||||
}, 1);
|
||||
});
|
||||
fetchData();
|
||||
});
|
||||
</script>
|
||||
|
||||
<article class="font-sans px-4 py-6 lg:max-w-7xl lg:pt-6 lg:pb-28">
|
||||
<h1>Invite Relay</h1>
|
||||
<h1 class="text-xl">Invite Relay</h1>
|
||||
{#if adminView == true}
|
||||
<button
|
||||
on:click={() => adminView = false}
|
||||
on:click={() => (adminView = false)}
|
||||
type="button"
|
||||
class="inline-flex mr-2 items-center px-3 py-2 border border-gray-300 shadow-sm text-sm leading-4 font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-500"
|
||||
>Leave Admin View</button
|
||||
>Leave Reports Viewer</button
|
||||
>
|
||||
<p>
|
||||
You are{$userPublickey == nip19.npubEncode($relayMaster) ? "" : " not"} logged
|
||||
in as a relay master
|
||||
</p>
|
||||
<AdminView />
|
||||
{:else if adminView == false}
|
||||
<div>
|
||||
@ -57,14 +69,16 @@
|
||||
>
|
||||
{/if}
|
||||
</div>
|
||||
{#if $userPublickey !== undefined}
|
||||
<div>
|
||||
<button
|
||||
on:click={() => adminView = true}
|
||||
on:click={() => (adminView = true)}
|
||||
type="button"
|
||||
class="inline-flex mr-2 items-center px-3 py-2 border border-gray-300 shadow-sm text-sm leading-4 font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-500"
|
||||
>Open Admin View</button
|
||||
>Open Reports Viewer</button
|
||||
>
|
||||
</div>
|
||||
{/if}
|
||||
{#if invitedata.find((p) => $userPublickey == nip19.npubEncode(p.pk))}
|
||||
<div>
|
||||
<h3>Invite Someone</h3>
|
||||
|
@ -1,12 +1,9 @@
|
||||
<script lang="js">
|
||||
import {
|
||||
NDKRelay,
|
||||
NDKRelaySet,
|
||||
} from "@nostr-dev-kit/ndk";
|
||||
<script>
|
||||
import { NDKRelay, NDKRelaySet } from "@nostr-dev-kit/ndk";
|
||||
import { ndk } from "../lib/nostr";
|
||||
import { onMount } from "svelte";
|
||||
import ReportEvent from "./ReportEvent.svelte";
|
||||
import { relayUrl } from '../lib/consts';
|
||||
import { relayUrl } from "../lib/consts";
|
||||
|
||||
let events = [];
|
||||
|
||||
@ -17,18 +14,18 @@
|
||||
const relaySet = new NDKRelaySet(specificRelay, $ndk);
|
||||
relaySet.relays.forEach(async (relay) => {
|
||||
await relay.connect().catch((err) => {
|
||||
console.log("RELAY CONNECT ERROR");
|
||||
console.error(err);
|
||||
console.log("error while connecting to relay", err);
|
||||
});
|
||||
relay.on("connect", () => {
|
||||
console.log(relay.url, "connected");
|
||||
console.log("connected");
|
||||
});
|
||||
});
|
||||
|
||||
let filter = { kinds: [1984], limit: 250 };
|
||||
let es = await $ndk.fetchEvents(filter, relaySet);
|
||||
let options = { closeOnEose: true };
|
||||
let es = await $ndk.fetchEvents(filter, options, relaySet);
|
||||
events = Array.from(es);
|
||||
} catch {
|
||||
} catch (error) {
|
||||
console.log("error while getting feed", error);
|
||||
}
|
||||
});
|
||||
@ -36,8 +33,9 @@
|
||||
|
||||
<div>
|
||||
{#each events as event}
|
||||
{#if event.relay.url == relayUrl}
|
||||
<ReportEvent {event} />
|
||||
{/if}
|
||||
{/each}
|
||||
{#if events.length == 0}
|
||||
<span>Didn't found any events</span>
|
||||
{/if}
|
||||
</div>
|
||||
|
@ -1,4 +1,4 @@
|
||||
<script lang="js">
|
||||
<script>
|
||||
import { NDKEvent, NDKRelay, NDKRelaySet } from "@nostr-dev-kit/ndk";
|
||||
import { ndk } from "../lib/nostr";
|
||||
import { nip19 } from "nostr-tools";
|
||||
|
@ -6,11 +6,42 @@
|
||||
|
||||
let show = true;
|
||||
|
||||
async function dismissReportEvent() {
|
||||
let confirmation = confirm(
|
||||
"Are you sure you want to delete this event? (You can only do this if you are a relay master)",
|
||||
);
|
||||
if (confirmation) {
|
||||
try {
|
||||
// remove report event
|
||||
// only publish to the relay in question, dont know why this needs so much code
|
||||
let specificRelay = [new NDKRelay(relayUrl)];
|
||||
const relaySet = new NDKRelaySet(specificRelay, $ndk);
|
||||
relaySet.relays.forEach(async (relay) => {
|
||||
await relay.connect().catch((err) => {
|
||||
console.log("RELAY CONNECT ERROR");
|
||||
console.error(err);
|
||||
});
|
||||
relay.on("connect", () => {
|
||||
console.log(relay.url, "connected");
|
||||
});
|
||||
});
|
||||
|
||||
const newevent = new NDKEvent($ndk);
|
||||
newevent.kind = 20203;
|
||||
newevent.tags.push(["e", event.id]);
|
||||
await newevent.publish(relaySet);
|
||||
show = false;
|
||||
} catch (error) {
|
||||
console.log("error publishing event", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function removeUser(username, pk) {
|
||||
let confirmation = confirm(
|
||||
`Are you sure you want to remove ${
|
||||
username ? username : pk
|
||||
}? All people they invited will also be removed. (you can only do this if you invited this user or are the relay admin)`
|
||||
}? All people they invited will also be removed. (you can only do this if you invited this user or are the relay admin)`,
|
||||
);
|
||||
if (confirmation) {
|
||||
try {
|
||||
@ -26,10 +57,10 @@
|
||||
});
|
||||
});
|
||||
|
||||
const event = new NDKEvent($ndk);
|
||||
event.kind = 20202;
|
||||
event.tags.push(["p", pk]);
|
||||
await event.publish(relaySet).then(() => reload());
|
||||
const newevent = new NDKEvent($ndk);
|
||||
newevent.kind = 20202;
|
||||
newevent.tags.push(["p", pk]);
|
||||
await newevent.publish(relaySet);
|
||||
} catch (error) {
|
||||
console.log("error while publishing", error);
|
||||
}
|
||||
@ -51,7 +82,7 @@
|
||||
JSON.parse(Array.from(profile)[0]?.content)?.picture}
|
||||
alt=""
|
||||
/>
|
||||
<a href={`nostr:${event.author.npub}`}
|
||||
<a class="hover:underline" href={`nostr:${event.author.npub}`}
|
||||
>{profile && JSON.parse(Array.from(profile)[0]?.content)?.name}</a
|
||||
>
|
||||
{/await}
|
||||
@ -72,13 +103,15 @@
|
||||
JSON.parse(Array.from(profile)[0]?.content)?.picture}
|
||||
alt=""
|
||||
/>
|
||||
<a href={`nostr:${event.tags.find((e) => e[0] == "p")?.[1]}`}
|
||||
<a
|
||||
class="hover:underline"
|
||||
href={`nostr:${event.tags.find((e) => e[0] == "p")?.[1]}`}
|
||||
>{profile &&
|
||||
JSON.parse(Array.from(profile)[0]?.content)?.name.length <= 16
|
||||
? JSON.parse(Array.from(profile)[0]?.content)?.name
|
||||
: JSON.parse(Array.from(profile)[0]?.content)?.name.substring(
|
||||
0,
|
||||
13
|
||||
13,
|
||||
) + "..."}</a
|
||||
>
|
||||
{/await}
|
||||
@ -101,7 +134,7 @@
|
||||
<div
|
||||
class="bg-white max-h-64 max-w-full overflow-y-scroll rounded-lg m-0 p-4 mt-2"
|
||||
>
|
||||
{#await $ndk.fetchEvent( { ids: [event?.tags.find((e) => e[0] == "e")?.[1]] } )}
|
||||
{#await $ndk.fetchEvent( { ids: [event?.tags.find((e) => e[0] == "e")?.[1]] }, )}
|
||||
<p class="text-gray-500 p-0 m-0">... (can we find this event?)</p>
|
||||
{:then theevent}
|
||||
<p class="m-0 p-0">{theevent.content}</p>
|
||||
@ -130,22 +163,17 @@
|
||||
Open in client
|
||||
</a>
|
||||
<button
|
||||
class="rounded-lg inline bg-slate-100 p-2 cursor-pointer hover:bg-white"
|
||||
>
|
||||
View in invite tree
|
||||
</button>
|
||||
<button
|
||||
on:click={() => (show = false)}
|
||||
on:click={dismissReportEvent}
|
||||
class="rounded-lg inline bg-green-500 p-2 cursor-pointer hover:bg-green-400"
|
||||
>
|
||||
Dismiss <!-- TO BE IMPLEMENTED: Remove report event? -->
|
||||
Remove This Report Event
|
||||
</button>
|
||||
<button
|
||||
on:click={() =>
|
||||
removeUser("user", event.tags.find((e) => e[0] == "p")?.[1])}
|
||||
class="rounded-lg inline bg-red-500 p-2 cursor-pointer hover:bg-red-400"
|
||||
>
|
||||
Exlude this user
|
||||
Exlude reported user
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,2 +1,2 @@
|
||||
export const relayUrl = "ws://localhost:3334";
|
||||
export const relayUrl = "ws://localhost:3334"; // Important: Change this and rebuild ui if needed
|
||||
export const someRelays = ["wss://nos.lol", "wss://relay.snort.social"];
|
||||
|
@ -10,3 +10,4 @@ Ndk.connect().then(() => console.log("ndk connected"));
|
||||
|
||||
export const ndk: Writable<NDK> = writable(Ndk);
|
||||
export const userPublickey: Writable<string | undefined> = writable(undefined);
|
||||
export const relayMaster: Writable<string> = writable("");
|
||||
|
16
utils.go
16
utils.go
@ -2,6 +2,7 @@ package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log"
|
||||
|
||||
"github.com/nbd-wtf/go-nostr"
|
||||
)
|
||||
@ -15,7 +16,7 @@ func isPkInWhitelist(targetPk string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func deleteFromWhitelistRecursively (target string) {
|
||||
func deleteFromWhitelistRecursively (ctx context.Context, target string) {
|
||||
var updatedWhitelist []User
|
||||
var queue []string
|
||||
|
||||
@ -31,18 +32,19 @@ func deleteFromWhitelistRecursively (target string) {
|
||||
whitelist = updatedWhitelist
|
||||
|
||||
// Remove all events
|
||||
go func () {
|
||||
var filter nostr.Filter = nostr.Filter{
|
||||
filter := nostr.Filter{
|
||||
Authors: []string{target},
|
||||
}
|
||||
events, _ := db.QueryEvents(context.TODO(), filter)
|
||||
events, _ := db.QueryEvents(ctx, filter)
|
||||
for ev := range events {
|
||||
db.DeleteEvent(context.TODO(), ev)
|
||||
err := db.DeleteEvent(ctx, ev)
|
||||
if err != nil {
|
||||
log.Println("error while deleting event", err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
// Recursive
|
||||
for _, pk := range queue {
|
||||
deleteFromWhitelistRecursively(pk)
|
||||
deleteFromWhitelistRecursively(ctx, pk)
|
||||
}
|
||||
}
|
||||
|
27
whitelist.go
27
whitelist.go
@ -3,6 +3,7 @@ package main
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/nbd-wtf/go-nostr"
|
||||
@ -22,23 +23,43 @@ func whitelistRejecter(ctx context.Context, evt *nostr.Event) (reject bool, msg
|
||||
return true, "You are not invited to this relay"
|
||||
}
|
||||
|
||||
// add user(s) if needed
|
||||
// 20201 = user invites new user
|
||||
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, User{Pk: tag.Value(), InvitedBy: evt.PubKey})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// remove user(s) if needed
|
||||
// 20202 = user removes user they invited or admin removes invite
|
||||
if (evt.Kind == 20202) {
|
||||
pTags := evt.Tags.GetAll([]string{"p"})
|
||||
for _, tag := range pTags {
|
||||
for _, user := range whitelist {
|
||||
if user.Pk == tag.Value() && (user.InvitedBy == evt.PubKey || evt.PubKey == relayMaster) {
|
||||
deleteFromWhitelistRecursively(tag.Value())
|
||||
deleteFromWhitelistRecursively(ctx, tag.Value())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 20203 = admin deletes event
|
||||
if (evt.Kind == 20203 && evt.PubKey == relayMaster) {
|
||||
eTags := evt.Tags.GetAll([]string{"e"})
|
||||
for _, tag := range eTags {
|
||||
filter := nostr.Filter{
|
||||
IDs: []string{tag.Value()},
|
||||
}
|
||||
events, _ := db.QueryEvents(ctx, filter);
|
||||
|
||||
for ev := range events {
|
||||
err := db.DeleteEvent(ctx, ev)
|
||||
if err != nil {
|
||||
log.Println("error while deleting event", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user