63 lines
1.7 KiB
Go
63 lines
1.7 KiB
Go
package bouncer
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/golang-jwt/jwt/v5"
|
|
)
|
|
|
|
func TestMintClaims(t *testing.T) {
|
|
issuer := "https://app.test/_user/api/v1/login"
|
|
before := time.Now().Add(-2 * time.Second)
|
|
token, jti, err := Mint(secret, "42", issuer, 60*time.Minute)
|
|
after := time.Now().Add(2 * time.Second)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if jti == "" {
|
|
t.Fatal("empty jti")
|
|
}
|
|
claims := decodeClaims(t, token, secret)
|
|
if claims["iss"] != issuer || claims["sub"] != "42" || claims["prv"] != "a867434cbc213adfbe78a02bed7082a6bd99c883" {
|
|
t.Fatalf("claims = %#v", claims)
|
|
}
|
|
if claims["jti"] != jti {
|
|
t.Fatalf("jti claim %v != returned %s", claims["jti"], jti)
|
|
}
|
|
iat := claimUnix(t, claims, "iat")
|
|
nbf := claimUnix(t, claims, "nbf")
|
|
exp := claimUnix(t, claims, "exp")
|
|
if iat.Before(before) || iat.After(after) || nbf.Before(before) || nbf.After(after) {
|
|
t.Fatalf("iat=%s nbf=%s want near now", iat, nbf)
|
|
}
|
|
if exp.Before(iat.Add(59*time.Minute)) || exp.After(iat.Add(61*time.Minute)) {
|
|
t.Fatalf("exp=%s iat=%s", exp, iat)
|
|
}
|
|
sub, err := Verify(token, secret)
|
|
if err != nil || sub != "42" {
|
|
t.Fatalf("Verify = %q %v", sub, err)
|
|
}
|
|
}
|
|
|
|
func decodeClaims(t *testing.T, token, key string) jwt.MapClaims {
|
|
t.Helper()
|
|
parser := jwt.NewParser(jwt.WithValidMethods([]string{"HS256"}), jwt.WithoutClaimsValidation())
|
|
claims := jwt.MapClaims{}
|
|
if _, err := parser.ParseWithClaims(token, claims, func(*jwt.Token) (any, error) {
|
|
return []byte(key), nil
|
|
}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
return claims
|
|
}
|
|
|
|
func claimUnix(t *testing.T, claims jwt.MapClaims, key string) time.Time {
|
|
t.Helper()
|
|
v, ok := claims[key].(float64)
|
|
if !ok {
|
|
t.Fatalf("%s = %#v", key, claims[key])
|
|
}
|
|
return time.Unix(int64(v), 0)
|
|
}
|