forked from bitcoin-sv/spv-wallet-go-client
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtotp_test.go
133 lines (110 loc) · 3.68 KB
/
totp_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package walletclient
import (
"encoding/hex"
"fmt"
"net/http"
"net/http/httptest"
"testing"
bip32 "github.com/bitcoin-sv/go-sdk/compat/bip32"
"github.com/bitcoin-sv/spv-wallet-go-client/fixtures"
"github.com/bitcoin-sv/spv-wallet-go-client/xpriv"
"github.com/bitcoin-sv/spv-wallet/models"
"github.com/stretchr/testify/require"
)
func TestGenerateTotpForContact(t *testing.T) {
t.Run("success", func(t *testing.T) {
// given
sut, err := NewWithXPriv("localhost:3001", fixtures.XPrivString)
require.NoError(t, err)
require.NotNil(t, sut.xPriv)
contact := models.Contact{PubKey: fixtures.PubKey}
// when
pass, err := sut.GenerateTotpForContact(&contact, 30, 2)
// then
require.NoError(t, err)
require.Len(t, pass, 2)
})
t.Run("WalletClient without xPriv - returns error", func(t *testing.T) {
// given
sut, err := NewWithXPub("localhost:3001", fixtures.XPubString)
require.NoError(t, err)
require.NotNil(t, sut.xPub)
// when
_, err = sut.GenerateTotpForContact(nil, 30, 2)
// then
require.ErrorIs(t, err, ErrMissingXpriv)
})
t.Run("contact has invalid PubKey - returns error", func(t *testing.T) {
// given
sut, err := NewWithXPriv("localhost:3001", fixtures.XPrivString)
require.NoError(t, err)
require.NotNil(t, sut.xPriv)
contact := models.Contact{PubKey: "invalid-pk-format"}
// when
_, err = sut.GenerateTotpForContact(&contact, 30, 2)
// then
require.ErrorIs(t, err, ErrContactPubKeyInvalid)
})
}
func TestValidateTotpForContact(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// This handler could be adjusted depending on the expected API endpoints
w.WriteHeader(http.StatusOK)
w.Write([]byte("123456")) // Simulate a TOTP response for any requests
}))
defer server.Close()
serverURL := fmt.Sprintf("%s/v1", server.URL)
t.Run("success", func(t *testing.T) {
aliceKeys, err := xpriv.Generate()
require.NoError(t, err)
bobKeys, err := xpriv.Generate()
require.NoError(t, err)
// Set up the WalletClient for Alice and Bob
clientAlice, err := NewWithXPriv(serverURL, aliceKeys.XPriv())
require.NoError(t, err)
require.NotNil(t, clientAlice.xPriv)
clientBob, err := NewWithXPriv(serverURL, bobKeys.XPriv())
require.NoError(t, err)
require.NotNil(t, clientBob.xPriv)
aliceContact := &models.Contact{
PubKey: makeMockPKI(aliceKeys.XPub().String()),
Paymail: "[email protected]",
}
bobContact := &models.Contact{
PubKey: makeMockPKI(bobKeys.XPub().String()),
Paymail: "[email protected]",
}
// Generate and validate TOTP
passcode, err := clientAlice.GenerateTotpForContact(bobContact, 3600, 6)
require.NoError(t, err)
result, err := clientBob.ValidateTotpForContact(aliceContact, passcode, bobContact.Paymail, 3600, 6)
require.NoError(t, err)
require.True(t, result)
})
t.Run("contact has invalid PubKey - returns error", func(t *testing.T) {
sut, err := NewWithXPriv(serverURL, fixtures.XPrivString)
require.NoError(t, err)
invalidContact := &models.Contact{
PubKey: "invalid_pub_key_format",
Paymail: "[email protected]",
}
_, err = sut.ValidateTotpForContact(invalidContact, "123456", "[email protected]", 3600, 6)
require.Error(t, err)
require.Contains(t, err.Error(), "contact's PubKey is invalid")
})
}
func makeMockPKI(xpub string) string {
xPub, _ := bip32.NewKeyFromString(xpub)
var err error
for i := 0; i < 3; i++ { //magicNumberOfInheritance is 3 -> 2+1; 2: because of the way spv-wallet stores xpubs in db; 1: to make a PKI
xPub, err = xPub.Child(0)
if err != nil {
panic(err)
}
}
pubKey, err := xPub.ECPubKey()
if err != nil {
panic(err)
}
return hex.EncodeToString(pubKey.SerializeCompressed())
}