mirror of
https://github.com/nbd-wtf/go-nostr.git
synced 2025-06-20 13:50:55 +02:00
nip46: bunker implementation changes for more streamlined authorization prompts.
This commit is contained in:
parent
5aa4fbcc72
commit
d690fd7f07
@ -3,9 +3,8 @@ package nip46
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"sync"
|
|
||||||
|
|
||||||
"slices"
|
"slices"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"github.com/mailru/easyjson"
|
"github.com/mailru/easyjson"
|
||||||
"github.com/nbd-wtf/go-nostr"
|
"github.com/nbd-wtf/go-nostr"
|
||||||
@ -73,24 +72,23 @@ func (p *DynamicSigner) HandleRequest(event *nostr.Event) (
|
|||||||
req Request,
|
req Request,
|
||||||
resp Response,
|
resp Response,
|
||||||
eventResponse nostr.Event,
|
eventResponse nostr.Event,
|
||||||
harmless bool,
|
|
||||||
err error,
|
err error,
|
||||||
) {
|
) {
|
||||||
if event.Kind != nostr.KindNostrConnect {
|
if event.Kind != nostr.KindNostrConnect {
|
||||||
return req, resp, eventResponse, false,
|
return req, resp, eventResponse,
|
||||||
fmt.Errorf("event kind is %d, but we expected %d", event.Kind, nostr.KindNostrConnect)
|
fmt.Errorf("event kind is %d, but we expected %d", event.Kind, nostr.KindNostrConnect)
|
||||||
}
|
}
|
||||||
|
|
||||||
targetUser := event.Tags.GetFirst([]string{"p", ""})
|
targetUser := event.Tags.GetFirst([]string{"p", ""})
|
||||||
if targetUser == nil || !nostr.IsValid32ByteHex((*targetUser)[1]) {
|
if targetUser == nil || !nostr.IsValid32ByteHex((*targetUser)[1]) {
|
||||||
return req, resp, eventResponse, false, fmt.Errorf("invalid \"p\" tag")
|
return req, resp, eventResponse, fmt.Errorf("invalid \"p\" tag")
|
||||||
}
|
}
|
||||||
|
|
||||||
targetPubkey := (*targetUser)[1]
|
targetPubkey := (*targetUser)[1]
|
||||||
|
|
||||||
privateKey, err := p.getPrivateKey(targetPubkey)
|
privateKey, err := p.getPrivateKey(targetPubkey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return req, resp, eventResponse, false, fmt.Errorf("no private key for %s: %w", targetPubkey, err)
|
return req, resp, eventResponse, fmt.Errorf("no private key for %s: %w", targetPubkey, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var session Session
|
var session Session
|
||||||
@ -102,13 +100,13 @@ func (p *DynamicSigner) HandleRequest(event *nostr.Event) (
|
|||||||
|
|
||||||
session.SharedKey, err = nip04.ComputeSharedSecret(event.PubKey, privateKey)
|
session.SharedKey, err = nip04.ComputeSharedSecret(event.PubKey, privateKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return req, resp, eventResponse, false, fmt.Errorf("failed to compute shared secret: %w", err)
|
return req, resp, eventResponse, fmt.Errorf("failed to compute shared secret: %w", err)
|
||||||
}
|
}
|
||||||
p.setSession(event.PubKey, session)
|
p.setSession(event.PubKey, session)
|
||||||
|
|
||||||
req, err = session.ParseRequest(event)
|
req, err = session.ParseRequest(event)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return req, resp, eventResponse, false, fmt.Errorf("error parsing request: %w", err)
|
return req, resp, eventResponse, fmt.Errorf("error parsing request: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,10 +116,8 @@ func (p *DynamicSigner) HandleRequest(event *nostr.Event) (
|
|||||||
switch req.Method {
|
switch req.Method {
|
||||||
case "connect":
|
case "connect":
|
||||||
result = "ack"
|
result = "ack"
|
||||||
harmless = true
|
|
||||||
case "get_public_key":
|
case "get_public_key":
|
||||||
result = targetPubkey
|
result = targetPubkey
|
||||||
harmless = true
|
|
||||||
case "sign_event":
|
case "sign_event":
|
||||||
if len(req.Params) != 1 {
|
if len(req.Params) != 1 {
|
||||||
resultErr = fmt.Errorf("wrong number of arguments to 'sign_event'")
|
resultErr = fmt.Errorf("wrong number of arguments to 'sign_event'")
|
||||||
@ -147,7 +143,6 @@ func (p *DynamicSigner) HandleRequest(event *nostr.Event) (
|
|||||||
case "get_relays":
|
case "get_relays":
|
||||||
jrelays, _ := json.Marshal(p.RelaysToAdvertise)
|
jrelays, _ := json.Marshal(p.RelaysToAdvertise)
|
||||||
result = string(jrelays)
|
result = string(jrelays)
|
||||||
harmless = true
|
|
||||||
case "nip04_encrypt":
|
case "nip04_encrypt":
|
||||||
if len(req.Params) != 2 {
|
if len(req.Params) != 2 {
|
||||||
resultErr = fmt.Errorf("wrong number of arguments to 'nip04_encrypt'")
|
resultErr = fmt.Errorf("wrong number of arguments to 'nip04_encrypt'")
|
||||||
@ -201,19 +196,19 @@ func (p *DynamicSigner) HandleRequest(event *nostr.Event) (
|
|||||||
}
|
}
|
||||||
result = plaintext
|
result = plaintext
|
||||||
default:
|
default:
|
||||||
return req, resp, eventResponse, false,
|
return req, resp, eventResponse,
|
||||||
fmt.Errorf("unknown method '%s'", req.Method)
|
fmt.Errorf("unknown method '%s'", req.Method)
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, eventResponse, err = session.MakeResponse(req.ID, event.PubKey, result, resultErr)
|
resp, eventResponse, err = session.MakeResponse(req.ID, event.PubKey, result, resultErr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return req, resp, eventResponse, harmless, err
|
return req, resp, eventResponse, err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = eventResponse.Sign(privateKey)
|
err = eventResponse.Sign(privateKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return req, resp, eventResponse, harmless, err
|
return req, resp, eventResponse, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return req, resp, eventResponse, harmless, err
|
return req, resp, eventResponse, err
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ type Response struct {
|
|||||||
|
|
||||||
type Signer interface {
|
type Signer interface {
|
||||||
GetSession(clientPubkey string) (Session, bool)
|
GetSession(clientPubkey string) (Session, bool)
|
||||||
HandleRequest(event *nostr.Event) (req Request, resp Response, eventResponse nostr.Event, harmless bool, err error)
|
HandleRequest(event *nostr.Event) (req Request, resp Response, eventResponse nostr.Event, err error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type Session struct {
|
type Session struct {
|
||||||
@ -73,7 +73,6 @@ func (s Session) MakeResponse(
|
|||||||
return resp, evt, fmt.Errorf("failed to encrypt result: %w", err)
|
return resp, evt, fmt.Errorf("failed to encrypt result: %w", err)
|
||||||
}
|
}
|
||||||
evt.Content = ciphertext
|
evt.Content = ciphertext
|
||||||
|
|
||||||
evt.CreatedAt = nostr.Now()
|
evt.CreatedAt = nostr.Now()
|
||||||
evt.Kind = nostr.KindNostrConnect
|
evt.Kind = nostr.KindNostrConnect
|
||||||
evt.Tags = nostr.Tags{nostr.Tag{"p", requester}}
|
evt.Tags = nostr.Tags{nostr.Tag{"p", requester}}
|
||||||
|
@ -3,9 +3,8 @@ package nip46
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"sync"
|
|
||||||
|
|
||||||
"slices"
|
"slices"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"github.com/mailru/easyjson"
|
"github.com/mailru/easyjson"
|
||||||
"github.com/nbd-wtf/go-nostr"
|
"github.com/nbd-wtf/go-nostr"
|
||||||
@ -23,6 +22,7 @@ type StaticKeySigner struct {
|
|||||||
sync.Mutex
|
sync.Mutex
|
||||||
|
|
||||||
RelaysToAdvertise map[string]RelayReadWrite
|
RelaysToAdvertise map[string]RelayReadWrite
|
||||||
|
AuthorizeRequest func(harmless bool, from string) bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewStaticKeySigner(secretKey string) StaticKeySigner {
|
func NewStaticKeySigner(secretKey string) StaticKeySigner {
|
||||||
@ -73,24 +73,24 @@ func (p *StaticKeySigner) HandleRequest(event *nostr.Event) (
|
|||||||
req Request,
|
req Request,
|
||||||
resp Response,
|
resp Response,
|
||||||
eventResponse nostr.Event,
|
eventResponse nostr.Event,
|
||||||
harmless bool,
|
|
||||||
err error,
|
err error,
|
||||||
) {
|
) {
|
||||||
if event.Kind != nostr.KindNostrConnect {
|
if event.Kind != nostr.KindNostrConnect {
|
||||||
return req, resp, eventResponse, false,
|
return req, resp, eventResponse,
|
||||||
fmt.Errorf("event kind is %d, but we expected %d", event.Kind, nostr.KindNostrConnect)
|
fmt.Errorf("event kind is %d, but we expected %d", event.Kind, nostr.KindNostrConnect)
|
||||||
}
|
}
|
||||||
|
|
||||||
session, err := p.getOrCreateSession(event.PubKey)
|
session, err := p.getOrCreateSession(event.PubKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return req, resp, eventResponse, false, err
|
return req, resp, eventResponse, err
|
||||||
}
|
}
|
||||||
|
|
||||||
req, err = session.ParseRequest(event)
|
req, err = session.ParseRequest(event)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return req, resp, eventResponse, false, fmt.Errorf("error parsing request: %w", err)
|
return req, resp, eventResponse, fmt.Errorf("error parsing request: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var harmless bool
|
||||||
var result string
|
var result string
|
||||||
var resultErr error
|
var resultErr error
|
||||||
|
|
||||||
@ -174,19 +174,25 @@ func (p *StaticKeySigner) HandleRequest(event *nostr.Event) (
|
|||||||
}
|
}
|
||||||
result = plaintext
|
result = plaintext
|
||||||
default:
|
default:
|
||||||
return req, resp, eventResponse, false,
|
return req, resp, eventResponse,
|
||||||
fmt.Errorf("unknown method '%s'", req.Method)
|
fmt.Errorf("unknown method '%s'", req.Method)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if resultErr == nil && p.AuthorizeRequest != nil {
|
||||||
|
if !p.AuthorizeRequest(harmless, event.PubKey) {
|
||||||
|
resultErr = fmt.Errorf("unauthorized")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
resp, eventResponse, err = session.MakeResponse(req.ID, event.PubKey, result, resultErr)
|
resp, eventResponse, err = session.MakeResponse(req.ID, event.PubKey, result, resultErr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return req, resp, eventResponse, harmless, err
|
return req, resp, eventResponse, err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = eventResponse.Sign(p.secretKey)
|
err = eventResponse.Sign(p.secretKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return req, resp, eventResponse, harmless, err
|
return req, resp, eventResponse, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return req, resp, eventResponse, harmless, err
|
return req, resp, eventResponse, err
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user