Compare commits
8 Commits
main
...
v0.1.1-dev
Author | SHA1 | Date | |
---|---|---|---|
a55f4be7db | |||
406b288223 | |||
f06846b51c | |||
12d9d2d215 | |||
4d5561d132 | |||
28d04b7e0c | |||
a0689ea568 | |||
14c6770a72 |
@@ -12,6 +12,8 @@ services:
|
||||
RELAY_NAME: "LUMINA Relay"
|
||||
RELAY_DESCRIPTION: "LUMINA Nostr Relay"
|
||||
POSTGRES_URL: "postgres://postgres:postgres@postgres/postgres?sslmode=disable"
|
||||
RELAY_ADMINS: "480ec1a7516406090dc042ddf67780ef30f26f3a864e83b417c053a5a611c838"
|
||||
RELAY_SERVICE_URL: "https://relay.lumina.rocks"
|
||||
restart: unless-stopped
|
||||
scraper:
|
||||
depends_on:
|
||||
@@ -31,8 +33,8 @@ services:
|
||||
POSTGRES_DB: postgres
|
||||
volumes:
|
||||
- ./postgres:/var/lib/postgresql/data
|
||||
ports:
|
||||
- 5432:5432
|
||||
# ports:
|
||||
# - 5432:5432
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U postgres"]
|
||||
interval: 5s
|
||||
|
194
relay/database.go
Normal file
194
relay/database.go
Normal file
@@ -0,0 +1,194 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
|
||||
_ "github.com/lib/pq"
|
||||
)
|
||||
|
||||
// DBManager handles the normal PostgreSQL connection for non-event data
|
||||
type DBManager struct {
|
||||
db *sql.DB
|
||||
}
|
||||
|
||||
// NewDBManager creates a new database manager with the given database URL.
|
||||
// It establishes a connection, verifies connectivity, and initializes required tables.
|
||||
func NewDBManager(databaseURL string) (*DBManager, error) {
|
||||
db, err := sql.Open("postgres", databaseURL)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to open database connection: %w", err)
|
||||
}
|
||||
|
||||
if err := db.Ping(); err != nil {
|
||||
db.Close()
|
||||
return nil, fmt.Errorf("failed to ping database: %w", err)
|
||||
}
|
||||
|
||||
manager := &DBManager{db: db}
|
||||
if err := manager.initTables(); err != nil {
|
||||
db.Close()
|
||||
return nil, fmt.Errorf("failed to initialize database tables: %w", err)
|
||||
}
|
||||
|
||||
return manager, nil
|
||||
}
|
||||
|
||||
// initTables creates the necessary tables for the application.
|
||||
// This method is called automatically during DBManager initialization.
|
||||
func (dbm *DBManager) initTables() error {
|
||||
query := `
|
||||
CREATE TABLE IF NOT EXISTS banned_pubkeys (
|
||||
pubkey VARCHAR(64) PRIMARY KEY,
|
||||
reason TEXT,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);`
|
||||
|
||||
if _, err := dbm.db.Exec(query); err != nil {
|
||||
return fmt.Errorf("failed to create banned_pubkeys table: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// AddBannedPubkey adds a pubkey to the banned list with an optional reason.
|
||||
// If the pubkey already exists, the operation is ignored (no error returned).
|
||||
func (dbm *DBManager) AddBannedPubkey(pubkey, reason string) error {
|
||||
if pubkey == "" {
|
||||
return fmt.Errorf("pubkey cannot be empty")
|
||||
}
|
||||
|
||||
query := `INSERT INTO banned_pubkeys (pubkey, reason) VALUES ($1, $2) ON CONFLICT (pubkey) DO NOTHING`
|
||||
if _, err := dbm.db.Exec(query, pubkey, reason); err != nil {
|
||||
return fmt.Errorf("failed to add banned pubkey %s: %w", pubkey, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// RemoveBannedPubkey removes a pubkey from the banned list.
|
||||
// Returns an error if the pubkey is not found in the banned list.
|
||||
func (dbm *DBManager) RemoveBannedPubkey(pubkey string) error {
|
||||
if pubkey == "" {
|
||||
return fmt.Errorf("pubkey cannot be empty")
|
||||
}
|
||||
|
||||
query := `DELETE FROM banned_pubkeys WHERE pubkey = $1`
|
||||
result, err := dbm.db.Exec(query, pubkey)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to remove banned pubkey %s: %w", pubkey, err)
|
||||
}
|
||||
|
||||
rowsAffected, err := result.RowsAffected()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get rows affected for pubkey %s: %w", pubkey, err)
|
||||
}
|
||||
|
||||
if rowsAffected == 0 {
|
||||
return fmt.Errorf("pubkey %s not found in banned list", pubkey)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// IsBannedPubkey checks if a pubkey is in the banned list.
|
||||
// Returns true if the pubkey is banned, false otherwise.
|
||||
func (dbm *DBManager) IsBannedPubkey(pubkey string) (bool, error) {
|
||||
if pubkey == "" {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
var exists bool
|
||||
query := `SELECT EXISTS(SELECT 1 FROM banned_pubkeys WHERE pubkey = $1)`
|
||||
if err := dbm.db.QueryRow(query, pubkey).Scan(&exists); err != nil {
|
||||
return false, fmt.Errorf("failed to check if pubkey %s is banned: %w", pubkey, err)
|
||||
}
|
||||
|
||||
return exists, nil
|
||||
}
|
||||
|
||||
// GetBannedPubkeysWithReasons returns all banned pubkeys with their reasons ordered by creation time.
|
||||
// Returns an empty slice if no pubkeys are found.
|
||||
func (dbm *DBManager) GetBannedPubkeysWithReasons() ([]struct {
|
||||
Pubkey string
|
||||
Reason string
|
||||
}, error) {
|
||||
query := `SELECT pubkey, reason FROM banned_pubkeys ORDER BY created_at`
|
||||
rows, err := dbm.db.Query(query)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to query banned pubkeys with reasons: %w", err)
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var results []struct {
|
||||
Pubkey string
|
||||
Reason string
|
||||
}
|
||||
for rows.Next() {
|
||||
var result struct {
|
||||
Pubkey string
|
||||
Reason string
|
||||
}
|
||||
if err := rows.Scan(&result.Pubkey, &result.Reason); err != nil {
|
||||
return nil, fmt.Errorf("failed to scan pubkey and reason row: %w", err)
|
||||
}
|
||||
results = append(results, result)
|
||||
}
|
||||
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, fmt.Errorf("error occurred while iterating over pubkey and reason rows: %w", err)
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
||||
|
||||
// GetBannedPubkeys returns all banned pubkeys ordered by creation time.
|
||||
// Returns an empty slice if no pubkeys are found.
|
||||
func (dbm *DBManager) GetBannedPubkeys() ([]string, error) {
|
||||
query := `SELECT pubkey FROM banned_pubkeys ORDER BY created_at`
|
||||
rows, err := dbm.db.Query(query)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to query banned pubkeys: %w", err)
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var pubkeys []string
|
||||
for rows.Next() {
|
||||
var pubkey string
|
||||
if err := rows.Scan(&pubkey); err != nil {
|
||||
return nil, fmt.Errorf("failed to scan pubkey row: %w", err)
|
||||
}
|
||||
pubkeys = append(pubkeys, pubkey)
|
||||
}
|
||||
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, fmt.Errorf("error occurred while iterating over pubkey rows: %w", err)
|
||||
}
|
||||
|
||||
return pubkeys, nil
|
||||
}
|
||||
|
||||
// Close closes the database connection.
|
||||
// This should be called when the DBManager is no longer needed.
|
||||
func (dbm *DBManager) Close() error {
|
||||
if dbm.db != nil {
|
||||
if err := dbm.db.Close(); err != nil {
|
||||
return fmt.Errorf("failed to close database connection: %w", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Health checks the database connection health.
|
||||
// Returns nil if the connection is healthy, an error otherwise.
|
||||
func (dbm *DBManager) Health() error {
|
||||
if dbm.db == nil {
|
||||
return fmt.Errorf("database connection is nil")
|
||||
}
|
||||
|
||||
if err := dbm.db.Ping(); err != nil {
|
||||
return fmt.Errorf("database ping failed: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
11
relay/go.mod
11
relay/go.mod
@@ -2,6 +2,13 @@ module git.highperfocused.tech/highperfocused/lumina-relay/relay
|
||||
|
||||
go 1.23.4
|
||||
|
||||
require (
|
||||
github.com/fiatjaf/eventstore v0.16.0
|
||||
github.com/fiatjaf/khatru v0.15.2
|
||||
github.com/lib/pq v1.10.9
|
||||
github.com/nbd-wtf/go-nostr v0.46.0
|
||||
)
|
||||
|
||||
require (
|
||||
fiatjaf.com/lib v0.2.0 // indirect
|
||||
github.com/andybalholm/brotli v1.0.5 // indirect
|
||||
@@ -12,17 +19,13 @@ require (
|
||||
github.com/decred/dcrd/crypto/blake256 v1.1.0 // indirect
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect
|
||||
github.com/fasthttp/websocket v1.5.7 // indirect
|
||||
github.com/fiatjaf/eventstore v0.16.0
|
||||
github.com/fiatjaf/khatru v0.15.2
|
||||
github.com/jmoiron/sqlx v1.4.0 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/klauspost/compress v1.17.11 // indirect
|
||||
github.com/lib/pq v1.10.9 // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/nbd-wtf/go-nostr v0.46.0 // indirect
|
||||
github.com/puzpuzpuz/xsync/v3 v3.4.0 // indirect
|
||||
github.com/rs/cors v1.11.1 // indirect
|
||||
github.com/savsgio/gotils v0.0.0-20230208104028-c358bd845dee // indirect
|
||||
|
12
relay/go.sum
12
relay/go.sum
@@ -1,5 +1,6 @@
|
||||
fiatjaf.com/lib v0.2.0 h1:TgIJESbbND6GjOgGHxF5jsO6EMjuAxIzZHPo5DXYexs=
|
||||
fiatjaf.com/lib v0.2.0/go.mod h1:Ycqq3+mJ9jAWu7XjbQI1cVr+OFgnHn79dQR5oTII47g=
|
||||
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
|
||||
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
|
||||
github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
|
||||
github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
||||
@@ -12,6 +13,7 @@ github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0/go.mod h1:7SFka0XMvUgj3hfZtyd
|
||||
github.com/coder/websocket v1.8.12 h1:5bUXkEPPIbewrnkU8LTCLVaxi4N4J8ahufH2vlo4NAo=
|
||||
github.com/coder/websocket v1.8.12/go.mod h1:LNVeNrXQZfe5qhS9ALED3uA+l5pPqvwXg3CKoDBB2gs=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/decred/dcrd/crypto/blake256 v1.1.0 h1:zPMNGQCm0g4QTY27fOCorQW7EryeQ/U0x++OzVrdms8=
|
||||
github.com/decred/dcrd/crypto/blake256 v1.1.0/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo=
|
||||
@@ -19,12 +21,11 @@ github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnN
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0=
|
||||
github.com/fasthttp/websocket v1.5.7 h1:0a6o2OfeATvtGgoMKleURhLT6JqWPg7fYfWnH4KHau4=
|
||||
github.com/fasthttp/websocket v1.5.7/go.mod h1:bC4fxSono9czeXHQUVKxsC0sNjbm7lPJR04GDFqClfU=
|
||||
github.com/fiatjaf/eventstore v0.15.0 h1:5UXe0+vIb30/cYcOWipks8nR3g+X8W224TFy5yPzivk=
|
||||
github.com/fiatjaf/eventstore v0.15.0/go.mod h1:KAsld5BhkmSck48aF11Txu8X+OGNmoabw4TlYVWqInc=
|
||||
github.com/fiatjaf/eventstore v0.16.0 h1:r26aJeOwJTCbEevU8RVqp9FlcAgzKKqUWFH//x+Y+7M=
|
||||
github.com/fiatjaf/eventstore v0.16.0/go.mod h1:KAsld5BhkmSck48aF11Txu8X+OGNmoabw4TlYVWqInc=
|
||||
github.com/fiatjaf/khatru v0.15.2 h1:4p0LGUFh+C0zFAPTQdzUdhZDabjmktyov9h5V32EdSw=
|
||||
github.com/fiatjaf/khatru v0.15.2/go.mod h1:GBQJXZpitDatXF9RookRXcWB5zCJclCE4ufDK3jk80g=
|
||||
github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
|
||||
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/jmoiron/sqlx v1.4.0 h1:1PLqN7S1UYp5t4SrVVnt4nUVNemrDAtxlulVe+Qgm3o=
|
||||
@@ -40,12 +41,15 @@ github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
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.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
||||
github.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBWDRM=
|
||||
github.com/mattn/go-sqlite3 v1.14.24/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/nbd-wtf/go-nostr v0.46.0 h1:aR+xXEC6MPutNMIRhNdi+2iBPEHW7SO10sFaOAVSz3Y=
|
||||
github.com/nbd-wtf/go-nostr v0.46.0/go.mod h1:xVNOqkn0GImeTmaF6VDwgYsuSkfG3yrIbd0dT6NZDIQ=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/puzpuzpuz/xsync/v3 v3.4.0 h1:DuVBAdXuGFHv8adVXjWWZ63pJq+NRXOWVXlKDBZ+mJ4=
|
||||
github.com/puzpuzpuz/xsync/v3 v3.4.0/go.mod h1:VjzYrABPabuM4KyBh1Ftq6u8nhwY5tBPKP9jpmh0nnA=
|
||||
@@ -55,6 +59,8 @@ github.com/savsgio/gotils v0.0.0-20230208104028-c358bd845dee h1:8Iv5m6xEo1NR1Avp
|
||||
github.com/savsgio/gotils v0.0.0-20230208104028-c358bd845dee/go.mod h1:qwtSXrKuJh/zsFQ12yEE89xfCrGKK63Rr7ctU/uCo4g=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY=
|
||||
github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
||||
@@ -70,3 +76,5 @@ golang.org/x/exp v0.0.0-20241204233417-43b7b7cde48d h1:0olWaB5pg3+oychR51GUVCEsG
|
||||
golang.org/x/exp v0.0.0-20241204233417-43b7b7cde48d/go.mod h1:qj5a5QZpwLU2NLQudwIN5koi3beDhSAlJwa67PuM98c=
|
||||
golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI=
|
||||
golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
@@ -1,11 +1,13 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"git.highperfocused.tech/highperfocused/lumina-relay/relay/cache"
|
||||
@@ -13,6 +15,8 @@ import (
|
||||
"github.com/fiatjaf/eventstore/postgresql"
|
||||
"github.com/fiatjaf/khatru"
|
||||
"github.com/fiatjaf/khatru/policies"
|
||||
"github.com/nbd-wtf/go-nostr"
|
||||
"github.com/nbd-wtf/go-nostr/nip86"
|
||||
)
|
||||
|
||||
// Cache for storing generic data like event counts
|
||||
@@ -79,7 +83,18 @@ func main() {
|
||||
relay.Info.Description = getEnv("RELAY_DESCRIPTION", "LUMINA Relay")
|
||||
relay.Info.Icon = getEnv("RELAY_ICON", "https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Fliquipedia.net%2Fcommons%2Fimages%2F3%2F35%2FSCProbe.jpg&f=1&nofb=1&ipt=0cbbfef25bce41da63d910e86c3c343e6c3b9d63194ca9755351bb7c2efa3359&ipo=images")
|
||||
relay.Info.Software = "lumina-relay"
|
||||
relay.Info.Version = "0.1.0"
|
||||
relay.Info.Version = "0.1.1"
|
||||
|
||||
// Set the service URL explicitly to avoid 'u' tag validation issues
|
||||
serviceUrl := getEnv("RELAY_SERVICE_URL", "")
|
||||
if serviceUrl != "" {
|
||||
relay.ServiceURL = serviceUrl
|
||||
}
|
||||
|
||||
// load relay admins
|
||||
admins := strings.Split(getEnv("RELAY_ADMINS", ""), ",")
|
||||
// add default admin (relay pubkey)
|
||||
admins = append(admins, relay.Info.PubKey)
|
||||
|
||||
// Print relay information
|
||||
fmt.Printf("Name: %s\n", relay.Info.Name)
|
||||
@@ -93,6 +108,13 @@ func main() {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Initialize the normal database manager for other data
|
||||
dbManager, dberr := NewDBManager(postgresURL)
|
||||
if dberr != nil {
|
||||
panic(fmt.Sprintf("Failed to initialize database manager: %v", dberr))
|
||||
}
|
||||
defer dbManager.Close()
|
||||
|
||||
// Initialize trending system to start background calculations
|
||||
fmt.Println("Initializing trending system...")
|
||||
if err := trending.Initialize(db.DB.DB); err != nil {
|
||||
@@ -118,8 +140,63 @@ func main() {
|
||||
policies.PreventLargeTags(120),
|
||||
policies.PreventTimestampsInThePast(time.Hour*2),
|
||||
policies.PreventTimestampsInTheFuture(time.Minute*30),
|
||||
func(ctx context.Context, event *nostr.Event) (reject bool, msg string) {
|
||||
// Check if the pubkey is banned
|
||||
isBanned, err := dbManager.IsBannedPubkey(event.PubKey)
|
||||
if err != nil {
|
||||
fmt.Printf("Error checking banned pubkey: %v\n", err)
|
||||
return false, "" // Allow the event if there's an error checking ban status
|
||||
}
|
||||
if isBanned {
|
||||
return true, fmt.Sprintf("banned pubkey: %s", event.PubKey)
|
||||
}
|
||||
return false, ""
|
||||
},
|
||||
)
|
||||
|
||||
// management endpoints
|
||||
relay.ManagementAPI.RejectAPICall = append(relay.ManagementAPI.RejectAPICall,
|
||||
func(ctx context.Context, mp nip86.MethodParams) (reject bool, msg string) {
|
||||
user := khatru.GetAuthed(ctx)
|
||||
// Check if the user is in the admins array
|
||||
isAdmin := false
|
||||
for _, admin := range admins {
|
||||
if user == admin {
|
||||
isAdmin = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !isAdmin {
|
||||
return true, "unauthorized: admin access required"
|
||||
}
|
||||
return false, ""
|
||||
})
|
||||
|
||||
relay.ManagementAPI.AllowPubKey = func(ctx context.Context, pubkey string, reason string) error {
|
||||
return dbManager.RemoveBannedPubkey(pubkey)
|
||||
}
|
||||
|
||||
relay.ManagementAPI.BanPubKey = func(ctx context.Context, pubkey string, reason string) error {
|
||||
return dbManager.AddBannedPubkey(pubkey, reason)
|
||||
}
|
||||
|
||||
relay.ManagementAPI.ListBannedPubKeys = func(ctx context.Context) ([]nip86.PubKeyReason, error) {
|
||||
results, err := dbManager.GetBannedPubkeysWithReasons()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var pubkeyReasons []nip86.PubKeyReason
|
||||
for _, result := range results {
|
||||
pubkeyReasons = append(pubkeyReasons, nip86.PubKeyReason{
|
||||
PubKey: result.Pubkey,
|
||||
Reason: result.Reason,
|
||||
})
|
||||
}
|
||||
return pubkeyReasons, nil
|
||||
}
|
||||
|
||||
mux := relay.Router()
|
||||
// set up other http handlers
|
||||
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||
|
Reference in New Issue
Block a user