diff --git a/jwt/validation.go b/jwt/validation.go index 98f4a056..045d5dfb 100644 --- a/jwt/validation.go +++ b/jwt/validation.go @@ -94,18 +94,20 @@ func (c Claims) ValidateWithLeeway(e Expected, leeway time.Duration) error { } } - if !e.Time.IsZero() && e.Time.Add(leeway).Before(c.NotBefore.Time()) { - return ErrNotValidYet - } + if !e.Time.IsZero() { + if c.NotBefore != nil && e.Time.Add(leeway).Before(c.NotBefore.Time()) { + return ErrNotValidYet + } - if !e.Time.IsZero() && e.Time.Add(-leeway).After(c.Expiry.Time()) { - return ErrExpired - } + if c.Expiry != nil && e.Time.Add(-leeway).After(c.Expiry.Time()) { + return ErrExpired + } - // IssuedAt is optional but cannot be in the future. This is not required by the RFC, but - // something is misconfigured if this happens and we should not trust it. - if !e.Time.IsZero() && e.Time.Add(leeway).Before(c.IssuedAt.Time()) { - return ErrIssuedInTheFuture + // IssuedAt is optional but cannot be in the future. This is not required by the RFC, but + // something is misconfigured if this happens and we should not trust it. + if c.IssuedAt != nil && e.Time.Add(leeway).Before(c.IssuedAt.Time()) { + return ErrIssuedInTheFuture + } } return nil diff --git a/jwt/validation_test.go b/jwt/validation_test.go index adf2920a..6edcabd3 100644 --- a/jwt/validation_test.go +++ b/jwt/validation_test.go @@ -126,3 +126,42 @@ func TestIssuedInFuture(t *testing.T) { assert.Equal(t, err, ErrIssuedInTheFuture) } } + +func TestOptionalDateClaims(t *testing.T) { + var epoch time.Time + + testCases := []struct { + name string + claim Claims + want error + }{ + { + "no claims", + Claims{}, + nil, + }, + { + "fail nbf", + Claims{NotBefore: NewNumericDate(time.Now())}, + ErrNotValidYet, + }, + { + "fail exp", + Claims{Expiry: NewNumericDate(epoch.Add(-7 * 24 * time.Hour))}, + ErrExpired, + }, + { + "fail iat", + Claims{IssuedAt: NewNumericDate(time.Now())}, + ErrIssuedInTheFuture, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + expect := Expected{}.WithTime(epoch.Add(-24 * time.Hour)) + err := tc.claim.Validate(expect) + assert.Equal(t, tc.want, err) + }) + } +}