clone

a self-hosted multitenant nostr relay with sites, file storage, git hosting, and inbox and outbox delivery

feat/standalone-relay
tinyrelay / protocol / testdata / auth / consumer_test.go
consumer_test.go 2.6K
1package consumer_test23import (4 "encoding/base64"5 "errors"6 "strings"7 "testing"8 "time"910 "github.com/FelineStateMachine/tinyrelay/protocol/auth"11 "github.com/FelineStateMachine/tinyrelay/protocol/nostr"12)1314func TestPublicProofVerifierReplayContracts(t *testing.T) {15 now := time.Unix(1700000000, 0)16 v := auth.NewValidator(func() time.Time { return now })17 sign := func(kind int, tags [][]string) (nostr.Event, string) {18 t.Helper()19 e := nostr.Event{Kind: kind, CreatedAt: now.Unix(), Tags: tags}20 if err := nostr.Sign(&e, strings.Repeat("0", 63)+"1"); err != nil {21 t.Fatal(err)22 }23 raw, err := nostr.Canonical(e)24 if err != nil {25 t.Fatal(err)26 }27 return e, "Nostr " + base64.StdEncoding.EncodeToString(raw)28 }29 _, header := sign(27235, [][]string{{"u", "https://relay.example/api?a=1"}, {"method", "GET"}})30 if _, err := v.VerifyNIP98(header, "https://relay.example/api?a=2", "GET", ""); err == nil {31 t.Fatal("query mismatch accepted")32 }33 var proof nostr.Event34 var err error35 proof, err = v.VerifyNIP98(header, "https://RELAY.example/api?a=1", "get", "")36 if err != nil || proof.PubKey == "" {37 t.Fatalf("NIP-98 proof: %v", err)38 }39 if _, err := v.VerifyNIP98(header, "https://relay.example/api?a=1", "GET", ""); err == nil || !strings.Contains(err.Error(), "replay") {40 t.Fatalf("NIP-98 replay: %v", err)41 }42 if _, err := v.VerifyNIP98("", "https://relay.example/api", "GET", ""); !errors.Is(err, auth.ErrMissingAuthorization) {43 t.Fatalf("missing header: %v", err)44 }4546 _, header = sign(24242, [][]string{{"t", "get"}, {"expiration", "1700000300"}})47 if !auth.IsBlossomAuthorization(header) {48 t.Fatal("Blossom classification")49 }50 for range 2 {51 if _, err := v.VerifyBlossomRequest(header, "get", "relay.example", ""); err != nil {52 t.Fatalf("reusable Blossom: %v", err)53 }54 }55 root := "https://relay.example/owner/repo.git"56 _, header = sign(27235, [][]string{{"u", root}, {"method", "GET"}})57 for _, suffix := range []string{"/info/refs?service=git-upload-pack", "/git-upload-pack"} {58 if _, err := v.VerifyGRASP08(header, root+suffix); err != nil {59 t.Fatalf("reusable GRASP-08: %v", err)60 }61 }62 if _, err := v.VerifyGRASP08(header, root+"/objects"); err != auth.ErrGRASP08Unauthorized {63 t.Fatalf("GRASP-08 error identity: %v", err)64 }65 m := auth.NewChallengeManager("wss://relay.example", func() time.Time { return now })66 challenge, err := m.Issue()67 if err != nil {68 t.Fatal(err)69 }70 e, _ := sign(22242, [][]string{{"relay", "wss://relay.example"}, {"challenge", challenge}})71 if err := m.Verify(e); err != nil {72 t.Fatal(err)73 }74 if err := m.Verify(e); err == nil {75 t.Fatal("NIP-42 challenge reused")76 }77}