auth.mx raw
1 package envelope
2
3 import (
4 "io"
5
6 "git.smesh.lol/nostr/pkg/event"
7 "git.smesh.lol/nostr/pkg/text"
8 "git.smesh.lol/nostr/pkg/units"
9 "git.smesh.lol/nostr/pkg/lol/chk"
10 "git.smesh.lol/nostr/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() (s 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 = o | "\""
30 o = text.NostrEscape(o, en.Challenge)
31 o = 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 // len(r) >= 0 is always true, so this read one past the end of any input
43 // that did not contain ']' and the RELAY PANICKED on a malformed AUTH frame.
44 for ; len(r) > 0; r = r[1:] {
45 if r[0] == ']' {
46 r = r[:0]
47 return
48 }
49 }
50 return
51 }
52
53 // AuthResponse is the client-sent AUTH response containing a signed event.
54 type AuthResponse struct{ Event *event.E }
55
56 func (en *AuthResponse) Label() (s string) { return AuthLabel }
57 func (en *AuthResponse) Id() (buf []byte) { return en.Event.ID }
58
59 func (en *AuthResponse) Write(w io.Writer) (err error) {
60 _, err = w.Write(en.Marshal(nil))
61 return
62 }
63
64 func (en *AuthResponse) Marshal(dst []byte) (b []byte) {
65 if en == nil || en.Event == nil {
66 _ = errorf.E([]byte("nil auth response"))
67 return dst
68 }
69 if en.Event.EstimateSize() >= cap(dst) {
70 dst = []byte{:0:en.Event.EstimateSize()+units.Kb}
71 }
72 b = dst
73 b = Marshal(b, AuthLabel, en.Event.Marshal)
74 return
75 }
76
77 func (en *AuthResponse) Unmarshal(b []byte) (r []byte, err error) {
78 r = b
79 en.Event = event.New()
80 if r, err = en.Event.Unmarshal(r); chk.E(err) {
81 return
82 }
83 r, err = SkipToTheEnd(r)
84 return
85 }
86