well-goknown/nostr/nostr.go

96 lines
2.3 KiB
Go
Raw Normal View History

package nostr
import (
2023-02-03 04:56:15 +00:00
"encoding/json"
2024-08-10 23:55:16 +00:00
"net"
"net/http"
"strings"
2024-08-10 23:55:16 +00:00
"git.minhas.io/asara/gologger"
"git.minhas.io/asara/well-goknown/config"
"github.com/jmoiron/sqlx"
)
2024-08-10 23:55:16 +00:00
var (
DB *sqlx.DB
)
2024-08-10 23:55:16 +00:00
type nostrUser struct {
Pubkey string `db:"pubkey"`
Relays *string `db:"relays,omitempty"`
2023-05-05 05:15:09 +00:00
}
2024-08-10 23:55:16 +00:00
type nostrWellKnown struct {
Names map[string]string `json:"names"`
Relays map[string][]string `json:"relays,omitempty"`
}
func GetNostrAddr(w http.ResponseWriter, r *http.Request) {
2024-08-10 23:55:16 +00:00
l := gologger.Get(config.GetConfig().LogLevel).With().Str("context", "nostr").Logger()
// get query string for username
r.ParseForm()
2024-08-10 23:55:16 +00:00
name := strings.ToLower(r.FormValue("name"))
2024-08-10 23:55:16 +00:00
// normalize domain
domain, _, err := net.SplitHostPort(r.Host)
if err != nil {
2024-08-10 23:55:16 +00:00
domain = r.Host
}
2024-08-10 23:55:16 +00:00
// get owner id for nip05 request
var uid int
DB.QueryRow("SELECT owner_id FROM nip05s WHERE name=$1 AND domain=$2", name, domain).Scan(&uid)
// get the pubkey and relays associated with the nip05
user := nostrUser{}
err = DB.QueryRow("SELECT pubkey, relays FROM users WHERE id=$1", uid).Scan(&user.Pubkey, &user.Relays)
2023-04-29 19:25:28 +00:00
if err != nil {
2024-08-10 23:55:16 +00:00
l.Error().Msgf("unable to get user for uid %v: %s", uid, err.Error())
2024-08-11 04:03:19 +00:00
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
2023-04-29 19:25:28 +00:00
return
}
2024-08-10 23:55:16 +00:00
// get all names associated with the pubkey
names := []string{}
err = DB.Select(&names, "SELECT nip05s.name FROM nip05s JOIN users ON nip05s.owner_id = users.id WHERE nip05s.owner_id = $1", uid)
2023-02-04 22:46:13 +00:00
if err != nil {
2024-08-10 23:55:16 +00:00
l.Error().Msgf("unable to get user for uid %v: %s", uid, err.Error())
2024-08-11 04:03:19 +00:00
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
2024-08-10 23:55:16 +00:00
return
2023-02-04 22:46:13 +00:00
}
2023-02-04 05:32:25 +00:00
2024-08-10 23:55:16 +00:00
// map of names
n := make(map[string]string)
for _, name := range names {
n[name] = user.Pubkey
2023-02-03 04:56:15 +00:00
}
2024-08-10 23:55:16 +00:00
// map of relays
s := make(map[string][]string)
if user.Relays != nil {
if strings.Contains(*user.Relays, ",") {
s[user.Pubkey] = strings.Split(*user.Relays, ",")
} else {
s[user.Pubkey] = []string{*user.Relays}
}
}
2023-02-03 04:56:15 +00:00
2024-08-10 23:55:16 +00:00
ret := nostrWellKnown{
Names: n,
Relays: s,
2023-02-03 04:56:15 +00:00
}
2024-08-10 23:55:16 +00:00
j, err := json.Marshal(ret)
if err != nil {
2024-08-10 23:55:16 +00:00
l.Error().Msg(err.Error())
2024-08-11 04:03:19 +00:00
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
2024-08-10 23:55:16 +00:00
return
}
2024-08-10 23:55:16 +00:00
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
w.Write(j)
return
2023-02-04 23:52:50 +00:00
}