| 1 | package daemon |
| 2 | |
| 3 | import ( |
| 4 | "context" |
| 5 | "net/http/httptest" |
| 6 | "strings" |
| 7 | "testing" |
| 8 | "time" |
| 9 | |
| 10 | "github.com/FelineStateMachine/tinyrelay/internal/event" |
| 11 | "github.com/coder/websocket" |
| 12 | ) |
| 13 | |
| 14 | func TestNostrConnectRepliesArriveBeforeAuthentication(t *testing.T) { |
| 15 | ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) |
| 16 | defer cancel() |
| 17 | app, tenant := testTenant(t) |
| 18 | policy := tenant.Policy() |
| 19 | policy.Reads, policy.Writes = "members" , "owner" |
| 20 | policy.Features.Signer = true |
| 21 | if err := tenant.applyPolicy(ctx, policy); err != nil { |
| 22 | t.Fatal(err) |
| 23 | } |
| 24 | server := httptest.NewServer(app) |
| 25 | defer server.Close() |
| 26 | url := "ws" + strings.TrimPrefix(server.URL, "http" ) |
| 27 | subscriber, _, err := websocket.Dial(ctx, url, nil) |
| 28 | if err != nil { |
| 29 | t.Fatal(err) |
| 30 | } |
| 31 | defer subscriber.CloseNow() |
| 32 | publisher, _, err := websocket.Dial(ctx, url, nil) |
| 33 | if err != nil { |
| 34 | t.Fatal(err) |
| 35 | } |
| 36 | defer publisher.CloseNow() |
| 37 | readRelayMessage(t, ctx, subscriber) // AUTH challenge; the signer is not connected yet. |
| 38 | readRelayMessage(t, ctx, publisher) |
| 39 | recipient := strings.Repeat("b" , 64) |
| 40 | if err := writeRelayMessage(ctx, subscriber, []any{"REQ" , "signer" , map[string]any{"kinds" : []int{24133}, "#p" : []string{recipient}, "limit" : 0}}); err != nil { |
| 41 | t.Fatal(err) |
| 42 | } |
| 43 | if data := readRelayMessage(t, ctx, subscriber); !strings.Contains(string(data), `"EOSE","signer"` ) { |
| 44 | t.Fatalf("subscription rejected: %s" , data) |
| 45 | } |
| 46 | message := event.Event{Kind: 24133, CreatedAt: time.Now().Unix(), Tags: [][]string{{"p" , recipient}}, Content: "encrypted signer reply" } |
| 47 | if err := event.Sign(&message, strings.Repeat("0" , 63)+"2" ); err != nil { |
| 48 | t.Fatal(err) |
| 49 | } |
| 50 | if err := writeRelayMessage(ctx, publisher, []any{"EVENT" , message}); err != nil { |
| 51 | t.Fatal(err) |
| 52 | } |
| 53 | if data := readRelayMessage(t, ctx, publisher); !strings.Contains(string(data), `"` +message.ID+`",true` ) { |
| 54 | t.Fatalf("signer reply rejected: %s" , data) |
| 55 | } |
| 56 | if data := readRelayMessage(t, ctx, subscriber); !strings.Contains(string(data), `"EVENT","signer"` ) || !strings.Contains(string(data), message.ID) { |
| 57 | t.Fatalf("signer reply not delivered: %s" , data) |
| 58 | } |
| 59 | } |