forked from SherClockHolmes/webpush-go
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathvapid_test.go
128 lines (109 loc) · 3.04 KB
/
vapid_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
package webpush
import (
"encoding/base64"
"fmt"
"strings"
"testing"
"github.com/golang-jwt/jwt"
)
func TestVAPID(t *testing.T) {
for _, subIsURL := range []bool{false, true} {
t.Run(fmt.Sprintf("subIsUrl=%v", subIsURL), func(t *testing.T) {
s := getStandardEncodedTestSubscription()
var sub string
if subIsURL {
sub = "https://test.com/"
} else {
sub = "[email protected]"
}
// Generate vapid keys
vapidPrivateKey, vapidPublicKey, err := GenerateVAPIDKeys()
if err != nil {
t.Fatal(err)
}
// Get authentication header
vapidAuthHeader, err := getVAPIDAuthorizationHeader(
s.Endpoint,
sub,
subIsURL,
vapidPublicKey,
vapidPrivateKey,
)
if err != nil {
t.Fatal(err)
}
// Validate the token in the Authorization header
tokenString := getTokenFromAuthorizationHeader(vapidAuthHeader, t)
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
if _, ok := token.Method.(*jwt.SigningMethodECDSA); !ok {
t.Fatal("Wrong validation method need ECDSA!")
}
// To decode the token it needs the VAPID public key
b64 := base64.RawURLEncoding
decodedVapidPrivateKey, err := b64.DecodeString(vapidPrivateKey)
if err != nil {
t.Fatal("Could not decode VAPID private key")
}
privKey := generateVAPIDHeaderKeys(decodedVapidPrivateKey)
return privKey.Public(), nil
})
// Check the claims on the token
if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
var expectedSub string
if subIsURL {
expectedSub = sub
} else {
expectedSub = fmt.Sprintf("mailto:%s", sub)
}
if expectedSub != claims["sub"] {
t.Fatalf(
"Incorreect mailto, expected=%s, got=%s",
expectedSub,
claims["sub"],
)
}
if claims["aud"] == "" {
t.Fatal("Audience should not be empty")
}
} else {
t.Fatal(err)
}
})
}
}
func TestDecodeVapidKeyAcceptsURLEncoding(t *testing.T) {
_, err := decodeVapidKey("8Xq5BzDqeP9TqEfjt6ZB4TygtMd1ogwstfbAM3KF1W4=")
if err != nil {
t.Fatal(err)
}
}
func TestDecodeVapidKeyAcceptsRawURLEncoding(t *testing.T) {
_, err := decodeVapidKey("MHcCAQEEIHF7ijDrb8gwj_9o7UuSx9t_oGlPMyOsG9YQLp3qJwLuoAoGCCqGSM49AwEHoUQDQgAEhB-nJdg0d5oOkdTYsKqbbuQ06ZUYkS0H-ELXsShIkpmcIVIO16Sj15YMBouesMbY4xPdepwF4Pj3QfaALRAG5Q")
if err != nil {
t.Fatal(err)
}
}
func TestVAPIDKeys(t *testing.T) {
privateKey, publicKey, err := GenerateVAPIDKeys()
if err != nil {
t.Fatal(err)
}
if len(privateKey) != 43 {
t.Fatal("Generated incorrect VAPID private key")
}
if len(publicKey) != 87 {
t.Fatal("Generated incorrect VAPID public key")
}
}
// Helper function for extracting the token from the Authorization header
func getTokenFromAuthorizationHeader(tokenHeader string, t *testing.T) string {
hsplit := strings.Split(tokenHeader, " ")
if len(hsplit) < 3 {
t.Fatal("Failed to auth split header")
}
tsplit := strings.Split(hsplit[1], "=")
if len(tsplit) < 2 {
t.Fatal("Failed to t split header on =")
}
return tsplit[1][:len(tsplit[1])-1]
}