auth.mx raw

   1  package envelope
   2  
   3  import (
   4  	"io"
   5  
   6  	"smesh.lol/pkg/nostr/event"
   7  	"smesh.lol/pkg/nostr/text"
   8  	"smesh.lol/pkg/nostr/units"
   9  	"smesh.lol/pkg/lol/chk"
  10  	"smesh.lol/pkg/lol/errorf"
  11  )
  12  
  13  const AuthLabel = "AUTH"
  14  
  15  // AuthChallenge is the relay-sent AUTH challenge.
  16  type AuthChallenge struct{ Challenge []byte }
  17  
  18  func (en *AuthChallenge) Label() string { return AuthLabel }
  19  
  20  func (en *AuthChallenge) Write(w io.Writer) (err error) {
  21  	_, err = w.Write(en.Marshal(nil))
  22  	return
  23  }
  24  
  25  func (en *AuthChallenge) Marshal(dst []byte) (b []byte) {
  26  	b = dst
  27  	b = Marshal(b, AuthLabel, func(bst []byte) (o []byte) {
  28  		o = bst
  29  		o = append(o, '"')
  30  		o = text.NostrEscape(o, en.Challenge)
  31  		o = append(o, '"')
  32  		return
  33  	})
  34  	return
  35  }
  36  
  37  func (en *AuthChallenge) Unmarshal(b []byte) (r []byte, err error) {
  38  	r = b
  39  	if en.Challenge, r, err = text.UnmarshalQuoted(r); chk.E(err) {
  40  		return
  41  	}
  42  	for ; len(r) >= 0; r = r[1:] {
  43  		if r[0] == ']' {
  44  			r = r[:0]
  45  			return
  46  		}
  47  	}
  48  	return
  49  }
  50  
  51  // AuthResponse is the client-sent AUTH response containing a signed event.
  52  type AuthResponse struct{ Event *event.E }
  53  
  54  func (en *AuthResponse) Label() string { return AuthLabel }
  55  func (en *AuthResponse) Id() []byte    { return en.Event.ID }
  56  
  57  func (en *AuthResponse) Write(w io.Writer) (err error) {
  58  	_, err = w.Write(en.Marshal(nil))
  59  	return
  60  }
  61  
  62  func (en *AuthResponse) Marshal(dst []byte) (b []byte) {
  63  	if en == nil || en.Event == nil {
  64  		_ = errorf.E([]byte("nil auth response"))
  65  		return dst
  66  	}
  67  	if en.Event.EstimateSize() >= cap(dst) {
  68  		dst = []byte{:0:en.Event.EstimateSize()+units.Kb}
  69  	}
  70  	b = dst
  71  	b = Marshal(b, AuthLabel, en.Event.Marshal)
  72  	return
  73  }
  74  
  75  func (en *AuthResponse) Unmarshal(b []byte) (r []byte, err error) {
  76  	r = b
  77  	en.Event = event.New()
  78  	if r, err = en.Event.Unmarshal(r); chk.E(err) {
  79  		return
  80  	}
  81  	r, err = SkipToTheEnd(r)
  82  	return
  83  }
  84