From 30eed99c92ee5ec031db607f1177c51e24cb5b57 Mon Sep 17 00:00:00 2001 From: Chris Gibson Date: Fri, 1 Aug 2025 16:54:28 +0100 Subject: [PATCH 1/4] closes 455 --- parser_option.go | 8 ++ validator.go | 8 +- validator_test.go | 220 +++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 213 insertions(+), 23 deletions(-) diff --git a/parser_option.go b/parser_option.go index 43157355..d845865d 100644 --- a/parser_option.go +++ b/parser_option.go @@ -66,6 +66,14 @@ func WithExpirationRequired() ParserOption { } } +// WithNotBeforeRequired returns the ParserOption to make nbf claim required. +// By default nbf claim is optional. +func WithNotBeforeRequired() ParserOption { + return func(p *Parser) { + p.validator.requireNbf = true + } +} + // WithAudience configures the validator to require any of the specified // audiences in the `aud` claim. Validation will fail if the audience is not // listed in the token or the `aud` claim is missing. diff --git a/validator.go b/validator.go index 92b5c057..7e9e536b 100644 --- a/validator.go +++ b/validator.go @@ -44,6 +44,9 @@ type Validator struct { // requireExp specifies whether the exp claim is required requireExp bool + // requireExp specifies whether the exp claim is required + requireNbf bool + // verifyIat specifies whether the iat (Issued At) claim will be verified. // According to https://www.rfc-editor.org/rfc/rfc7519#section-4.1.6 this // only specifies the age of the token, but no validation check is @@ -111,8 +114,9 @@ func (v *Validator) Validate(claims Claims) error { } // We always need to check not-before, but usage of the claim itself is - // OPTIONAL. - if err = v.verifyNotBefore(claims, now, false); err != nil { + // OPTIONAL by default. requireNbf overrides this behavior and makes + // the nbf claim mandatory. + if err = v.verifyNotBefore(claims, now, v.requireNbf); err != nil { errs = append(errs, err) } diff --git a/validator_test.go b/validator_test.go index 9fdaafab..2c5e4d37 100644 --- a/validator_test.go +++ b/validator_test.go @@ -89,15 +89,20 @@ func Test_Validator_Validate(t *testing.T) { } func Test_Validator_verifyExpiresAt(t *testing.T) { + times, err := test_Validator_CreateStaticTimes(t) + if err != nil { + t.Fatal(err) + } + type fields struct { - leeway time.Duration - timeFunc func() time.Time + leeway time.Duration } + type args struct { claims Claims - cmp time.Time required bool } + tests := []struct { name string fields fields @@ -105,33 +110,184 @@ func Test_Validator_verifyExpiresAt(t *testing.T) { wantErr error }{ { - name: "good claim", - fields: fields{timeFunc: time.Now}, - args: args{claims: RegisteredClaims{ExpiresAt: NewNumericDate(time.Now().Add(10 * time.Minute))}}, + name: "required claim present and valid", + args: args{claims: RegisteredClaims{ExpiresAt: NewNumericDate(times.AfterNow)}, required: true}, wantErr: nil, }, { - name: "claims with invalid type", - fields: fields{}, - args: args{claims: MapClaims{"exp": "string"}}, + name: "required claim present and expired", + args: args{claims: RegisteredClaims{ExpiresAt: NewNumericDate(times.BeforeNow)}, required: true}, + wantErr: ErrTokenExpired, + }, + { + name: "required claim present and expired with leeway", + fields: fields{leeway: time.Hour * 2}, + args: args{claims: RegisteredClaims{ExpiresAt: NewNumericDate(times.BeforeNow)}, required: true}, + wantErr: nil, + }, + { + name: "required claim present and expired past leeway", + fields: fields{leeway: time.Minute * 1}, + args: args{claims: RegisteredClaims{ExpiresAt: NewNumericDate(times.BeforeNow)}, required: true}, + wantErr: ErrTokenExpired, + }, + { + name: "required claim not provided", + args: args{claims: RegisteredClaims{}, required: true}, + wantErr: ErrTokenRequiredClaimMissing, + }, + { + name: "required claim present with invalid type", + args: args{claims: MapClaims{"exp": "string"}, required: true}, + wantErr: ErrInvalidType, + }, + + { + name: "not required claim present and valid", + args: args{claims: RegisteredClaims{ExpiresAt: NewNumericDate(times.AfterNow)}, required: false}, + wantErr: nil, + }, + { + name: "not required claim present and expired", + args: args{claims: RegisteredClaims{ExpiresAt: NewNumericDate(times.BeforeNow)}, required: false}, + wantErr: ErrTokenExpired, + }, + { + name: "not required claim present and expired with leeway", + fields: fields{leeway: time.Hour * 2}, + args: args{claims: RegisteredClaims{ExpiresAt: NewNumericDate(times.BeforeNow)}, required: false}, + wantErr: nil, + }, + { + name: "not required claim present and expired past leeway", + fields: fields{leeway: time.Minute * 1}, + args: args{claims: RegisteredClaims{ExpiresAt: NewNumericDate(times.BeforeNow)}, required: false}, + wantErr: ErrTokenExpired, + }, + { + name: "not required claim not provided", + args: args{claims: RegisteredClaims{}, required: false}, + wantErr: nil, + }, + { + name: "not required claim present with invalid type", + args: args{claims: MapClaims{"exp": "string"}, required: false}, wantErr: ErrInvalidType, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { v := &Validator{ - leeway: tt.fields.leeway, - timeFunc: tt.fields.timeFunc, + leeway: tt.fields.leeway, } - err := v.verifyExpiresAt(tt.args.claims, tt.args.cmp, tt.args.required) - if (err != nil) && !errors.Is(err, tt.wantErr) { + err := v.verifyExpiresAt(tt.args.claims, times.Now, tt.args.required) + if (err != nil || tt.wantErr != nil) && !errors.Is(err, tt.wantErr) { t.Errorf("validator.verifyExpiresAt() error = %v, wantErr %v", err, tt.wantErr) } }) } } +func Test_Validator_verifyNotBefore(t *testing.T) { + times, err := test_Validator_CreateStaticTimes(t) + if err != nil { + t.Fatal(err) + } + + type fields struct { + leeway time.Duration + } + type args struct { + claims Claims + required bool + } + tests := []struct { + name string + fields fields + args args + wantErr error + }{ + { + name: "required claim present and valid", + args: args{claims: RegisteredClaims{NotBefore: NewNumericDate(times.BeforeNow)}, required: true}, + wantErr: nil, + }, + { + name: "required claim present and in future", + args: args{claims: RegisteredClaims{NotBefore: NewNumericDate(times.AfterNow)}, required: true}, + wantErr: ErrTokenNotValidYet, + }, + { + name: "required claim present and in future with leeway", + fields: fields{leeway: time.Hour * 2}, + args: args{claims: RegisteredClaims{NotBefore: NewNumericDate(times.AfterNow)}, required: true}, + wantErr: nil, + }, + { + name: "required claim present and in future past leeway", + fields: fields{leeway: time.Minute * 1}, + args: args{claims: RegisteredClaims{NotBefore: NewNumericDate(times.AfterNow)}, required: true}, + wantErr: ErrTokenNotValidYet, + }, + { + name: "required claim not provided", + args: args{claims: RegisteredClaims{}, required: true}, + wantErr: ErrTokenRequiredClaimMissing, + }, + { + name: "required claim present with invalid type", + args: args{claims: MapClaims{"nbf": "string"}, required: true}, + wantErr: ErrInvalidType, + }, + + { + name: "not required claim present and valid", + args: args{claims: RegisteredClaims{NotBefore: NewNumericDate(times.BeforeNow)}, required: false}, + wantErr: nil, + }, + { + name: "not required claim present and in future", + args: args{claims: RegisteredClaims{NotBefore: NewNumericDate(times.AfterNow)}, required: false}, + wantErr: ErrTokenNotValidYet, + }, + { + name: "not required claim present and in future with leeway", + fields: fields{leeway: time.Hour * 2}, + args: args{claims: RegisteredClaims{NotBefore: NewNumericDate(times.AfterNow)}, required: false}, + wantErr: nil, + }, + { + name: "not required claim present and in future past leeway", + fields: fields{leeway: time.Minute * 1}, + args: args{claims: RegisteredClaims{NotBefore: NewNumericDate(times.AfterNow)}, required: false}, + wantErr: ErrTokenNotValidYet, + }, + { + name: "not required claim not provided", + args: args{claims: RegisteredClaims{}, required: false}, + wantErr: nil, + }, + { + name: "not required claim present with invalid type", + args: args{claims: MapClaims{"nbf": "string"}, required: false}, + wantErr: ErrInvalidType, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + v := &Validator{ + leeway: tt.fields.leeway, + } + + err := v.verifyNotBefore(tt.args.claims, times.Now, tt.args.required) + if (err != nil || tt.wantErr != nil) && !errors.Is(err, tt.wantErr) { + t.Errorf("validator.verifyNotBefore() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + func Test_Validator_verifyIssuer(t *testing.T) { type fields struct { expectedIss string @@ -216,15 +372,15 @@ func Test_Validator_verifySubject(t *testing.T) { func Test_Validator_verifyIssuedAt(t *testing.T) { type fields struct { - leeway time.Duration - timeFunc func() time.Time verifyIat bool } + type args struct { claims Claims cmp time.Time required bool } + tests := []struct { name string fields fields @@ -250,12 +406,8 @@ func Test_Validator_verifyIssuedAt(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - v := &Validator{ - leeway: tt.fields.leeway, - timeFunc: tt.fields.timeFunc, - verifyIat: tt.fields.verifyIat, - } - if err := v.verifyIssuedAt(tt.args.claims, tt.args.cmp, tt.args.required); (err != nil) && !errors.Is(err, tt.wantErr) { + v := &Validator{} + if err := v.verifyIssuedAt(tt.args.claims, tt.args.cmp, tt.args.required); (err != nil || tt.wantErr != nil) && !errors.Is(err, tt.wantErr) { t.Errorf("validator.verifyIssuedAt() error = %v, wantErr %v", err, tt.wantErr) } }) @@ -374,3 +526,29 @@ func Test_Validator_verifyAudience(t *testing.T) { }) } } + +// testStaticTimes is a struct that contains 3 timestamps, that are intended to be used to validate functionality +// of registered claim validation. +type testStaticTimes struct { + BeforeNow time.Time + Now time.Time + AfterNow time.Time +} + +// test_Validator_CreateStaticTimes returns a set of timestamps that can be used to validate functionality +// without requiring the use of "time.Now()", which can cause "flakey" tests if there is a delay in when the tests +// run vs when they were started. +func test_Validator_CreateStaticTimes(t *testing.T) (testStaticTimes, error) { + t.Helper() + + staticNow, err := time.Parse(time.RFC3339, "2025-01-02T15:04:05Z") + if err != nil { + return testStaticTimes{}, err + } + + return testStaticTimes{ + BeforeNow: staticNow.Add(time.Hour * -1), + Now: staticNow, + AfterNow: staticNow.Add(time.Hour * 1), + }, nil +} From bd12f6bd7fe1f60cbdfa692d25ed4a43ea697f54 Mon Sep 17 00:00:00 2001 From: Chris Gibson Date: Fri, 1 Aug 2025 17:13:32 +0100 Subject: [PATCH 2/4] Change 'now' instantiation for validator.Validate --- validator.go | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/validator.go b/validator.go index 7e9e536b..6dc33597 100644 --- a/validator.go +++ b/validator.go @@ -44,7 +44,7 @@ type Validator struct { // requireExp specifies whether the exp claim is required requireExp bool - // requireExp specifies whether the exp claim is required + // requireNbf specifies whether the nbf claim is required requireNbf bool // verifyIat specifies whether the iat (Issued At) claim will be verified. @@ -94,16 +94,14 @@ func NewValidator(opts ...ParserOption) *Validator { // verified. func (v *Validator) Validate(claims Claims) error { var ( - now time.Time - errs = make([]error, 0, 6) + now time.Time = time.Now() + errs = make([]error, 0, 6) err error ) // Check, if we have a time func if v.timeFunc != nil { now = v.timeFunc() - } else { - now = time.Now() } // We always need to check the expiration time, but usage of the claim From 703b7e056e11acc98886423c4fb7313a08a88f46 Mon Sep 17 00:00:00 2001 From: Chris Gibson Date: Mon, 4 Aug 2025 23:14:12 +0100 Subject: [PATCH 3/4] Remove changes to testing format, and timefuncs --- validator.go | 6 +- validator_test.go | 278 +++++++++++++--------------------------------- 2 files changed, 83 insertions(+), 201 deletions(-) diff --git a/validator.go b/validator.go index 6dc33597..c82dfcae 100644 --- a/validator.go +++ b/validator.go @@ -94,14 +94,16 @@ func NewValidator(opts ...ParserOption) *Validator { // verified. func (v *Validator) Validate(claims Claims) error { var ( - now time.Time = time.Now() - errs = make([]error, 0, 6) + now time.Time + errs = make([]error, 0, 6) err error ) // Check, if we have a time func if v.timeFunc != nil { now = v.timeFunc() + } else { + now = time.Now() } // We always need to check the expiration time, but usage of the claim diff --git a/validator_test.go b/validator_test.go index 2c5e4d37..8b57b57c 100644 --- a/validator_test.go +++ b/validator_test.go @@ -89,20 +89,15 @@ func Test_Validator_Validate(t *testing.T) { } func Test_Validator_verifyExpiresAt(t *testing.T) { - times, err := test_Validator_CreateStaticTimes(t) - if err != nil { - t.Fatal(err) - } - type fields struct { - leeway time.Duration + leeway time.Duration + timeFunc func() time.Time } - type args struct { claims Claims + cmp time.Time required bool } - tests := []struct { name string fields fields @@ -110,184 +105,33 @@ func Test_Validator_verifyExpiresAt(t *testing.T) { wantErr error }{ { - name: "required claim present and valid", - args: args{claims: RegisteredClaims{ExpiresAt: NewNumericDate(times.AfterNow)}, required: true}, - wantErr: nil, - }, - { - name: "required claim present and expired", - args: args{claims: RegisteredClaims{ExpiresAt: NewNumericDate(times.BeforeNow)}, required: true}, - wantErr: ErrTokenExpired, - }, - { - name: "required claim present and expired with leeway", - fields: fields{leeway: time.Hour * 2}, - args: args{claims: RegisteredClaims{ExpiresAt: NewNumericDate(times.BeforeNow)}, required: true}, - wantErr: nil, - }, - { - name: "required claim present and expired past leeway", - fields: fields{leeway: time.Minute * 1}, - args: args{claims: RegisteredClaims{ExpiresAt: NewNumericDate(times.BeforeNow)}, required: true}, - wantErr: ErrTokenExpired, - }, - { - name: "required claim not provided", - args: args{claims: RegisteredClaims{}, required: true}, - wantErr: ErrTokenRequiredClaimMissing, - }, - { - name: "required claim present with invalid type", - args: args{claims: MapClaims{"exp": "string"}, required: true}, - wantErr: ErrInvalidType, - }, - - { - name: "not required claim present and valid", - args: args{claims: RegisteredClaims{ExpiresAt: NewNumericDate(times.AfterNow)}, required: false}, - wantErr: nil, - }, - { - name: "not required claim present and expired", - args: args{claims: RegisteredClaims{ExpiresAt: NewNumericDate(times.BeforeNow)}, required: false}, - wantErr: ErrTokenExpired, - }, - { - name: "not required claim present and expired with leeway", - fields: fields{leeway: time.Hour * 2}, - args: args{claims: RegisteredClaims{ExpiresAt: NewNumericDate(times.BeforeNow)}, required: false}, - wantErr: nil, - }, - { - name: "not required claim present and expired past leeway", - fields: fields{leeway: time.Minute * 1}, - args: args{claims: RegisteredClaims{ExpiresAt: NewNumericDate(times.BeforeNow)}, required: false}, - wantErr: ErrTokenExpired, - }, - { - name: "not required claim not provided", - args: args{claims: RegisteredClaims{}, required: false}, + name: "good claim", + fields: fields{timeFunc: time.Now}, + args: args{claims: RegisteredClaims{ExpiresAt: NewNumericDate(time.Now().Add(10 * time.Minute))}}, wantErr: nil, }, { - name: "not required claim present with invalid type", - args: args{claims: MapClaims{"exp": "string"}, required: false}, + name: "claims with invalid type", + fields: fields{}, + args: args{claims: MapClaims{"exp": "string"}}, wantErr: ErrInvalidType, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { v := &Validator{ - leeway: tt.fields.leeway, + leeway: tt.fields.leeway, + timeFunc: tt.fields.timeFunc, } - err := v.verifyExpiresAt(tt.args.claims, times.Now, tt.args.required) - if (err != nil || tt.wantErr != nil) && !errors.Is(err, tt.wantErr) { + err := v.verifyExpiresAt(tt.args.claims, tt.args.cmp, tt.args.required) + if (err != nil) && !errors.Is(err, tt.wantErr) { t.Errorf("validator.verifyExpiresAt() error = %v, wantErr %v", err, tt.wantErr) } }) } } -func Test_Validator_verifyNotBefore(t *testing.T) { - times, err := test_Validator_CreateStaticTimes(t) - if err != nil { - t.Fatal(err) - } - - type fields struct { - leeway time.Duration - } - type args struct { - claims Claims - required bool - } - tests := []struct { - name string - fields fields - args args - wantErr error - }{ - { - name: "required claim present and valid", - args: args{claims: RegisteredClaims{NotBefore: NewNumericDate(times.BeforeNow)}, required: true}, - wantErr: nil, - }, - { - name: "required claim present and in future", - args: args{claims: RegisteredClaims{NotBefore: NewNumericDate(times.AfterNow)}, required: true}, - wantErr: ErrTokenNotValidYet, - }, - { - name: "required claim present and in future with leeway", - fields: fields{leeway: time.Hour * 2}, - args: args{claims: RegisteredClaims{NotBefore: NewNumericDate(times.AfterNow)}, required: true}, - wantErr: nil, - }, - { - name: "required claim present and in future past leeway", - fields: fields{leeway: time.Minute * 1}, - args: args{claims: RegisteredClaims{NotBefore: NewNumericDate(times.AfterNow)}, required: true}, - wantErr: ErrTokenNotValidYet, - }, - { - name: "required claim not provided", - args: args{claims: RegisteredClaims{}, required: true}, - wantErr: ErrTokenRequiredClaimMissing, - }, - { - name: "required claim present with invalid type", - args: args{claims: MapClaims{"nbf": "string"}, required: true}, - wantErr: ErrInvalidType, - }, - - { - name: "not required claim present and valid", - args: args{claims: RegisteredClaims{NotBefore: NewNumericDate(times.BeforeNow)}, required: false}, - wantErr: nil, - }, - { - name: "not required claim present and in future", - args: args{claims: RegisteredClaims{NotBefore: NewNumericDate(times.AfterNow)}, required: false}, - wantErr: ErrTokenNotValidYet, - }, - { - name: "not required claim present and in future with leeway", - fields: fields{leeway: time.Hour * 2}, - args: args{claims: RegisteredClaims{NotBefore: NewNumericDate(times.AfterNow)}, required: false}, - wantErr: nil, - }, - { - name: "not required claim present and in future past leeway", - fields: fields{leeway: time.Minute * 1}, - args: args{claims: RegisteredClaims{NotBefore: NewNumericDate(times.AfterNow)}, required: false}, - wantErr: ErrTokenNotValidYet, - }, - { - name: "not required claim not provided", - args: args{claims: RegisteredClaims{}, required: false}, - wantErr: nil, - }, - { - name: "not required claim present with invalid type", - args: args{claims: MapClaims{"nbf": "string"}, required: false}, - wantErr: ErrInvalidType, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - v := &Validator{ - leeway: tt.fields.leeway, - } - - err := v.verifyNotBefore(tt.args.claims, times.Now, tt.args.required) - if (err != nil || tt.wantErr != nil) && !errors.Is(err, tt.wantErr) { - t.Errorf("validator.verifyNotBefore() error = %v, wantErr %v", err, tt.wantErr) - } - }) - } -} - func Test_Validator_verifyIssuer(t *testing.T) { type fields struct { expectedIss string @@ -372,15 +216,15 @@ func Test_Validator_verifySubject(t *testing.T) { func Test_Validator_verifyIssuedAt(t *testing.T) { type fields struct { + leeway time.Duration + timeFunc func() time.Time verifyIat bool } - type args struct { claims Claims cmp time.Time required bool } - tests := []struct { name string fields fields @@ -406,14 +250,76 @@ func Test_Validator_verifyIssuedAt(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - v := &Validator{} - if err := v.verifyIssuedAt(tt.args.claims, tt.args.cmp, tt.args.required); (err != nil || tt.wantErr != nil) && !errors.Is(err, tt.wantErr) { + v := &Validator{ + leeway: tt.fields.leeway, + timeFunc: tt.fields.timeFunc, + verifyIat: tt.fields.verifyIat, + } + if err := v.verifyIssuedAt(tt.args.claims, tt.args.cmp, tt.args.required); (err != nil) && !errors.Is(err, tt.wantErr) { t.Errorf("validator.verifyIssuedAt() error = %v, wantErr %v", err, tt.wantErr) } }) } } +func Test_Validator_requireNotBefore(t *testing.T) { + type fields struct { + leeway time.Duration + timeFunc func() time.Time + requireNbf bool + } + type args struct { + claims Claims + cmp time.Time + required bool + } + tests := []struct { + name string + fields fields + args args + wantErr error + }{ + { + name: "good claim without nbf", + fields: fields{requireNbf: false}, + args: args{claims: MapClaims{}, required: false}, + wantErr: nil, + }, + { + name: "good claim with nbf", + fields: fields{requireNbf: true}, + args: args{ + claims: RegisteredClaims{NotBefore: NewNumericDate(time.Now().Add(time.Minute * -10))}, + cmp: time.Now().Add(10 * time.Minute), + required: true, + }, + wantErr: nil, + }, + { + name: "token nbf time is in future", + fields: fields{requireNbf: true, timeFunc: time.Now}, + args: args{ + claims: RegisteredClaims{NotBefore: NewNumericDate(time.Now().Add(time.Minute * +10))}, + cmp: time.Now().Add(10 * time.Minute), + required: true, + }, + wantErr: ErrTokenNotValidYet, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + v := &Validator{ + leeway: tt.fields.leeway, + timeFunc: tt.fields.timeFunc, + verifyIat: tt.fields.requireNbf, + } + if err := v.verifyNotBefore(tt.args.claims, tt.args.cmp, tt.args.required); (err != nil) && !errors.Is(err, tt.wantErr) { + t.Errorf("validator.requireNotBefore() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + func Test_Validator_verifyAudience(t *testing.T) { type fields struct { expectedAud []string @@ -526,29 +432,3 @@ func Test_Validator_verifyAudience(t *testing.T) { }) } } - -// testStaticTimes is a struct that contains 3 timestamps, that are intended to be used to validate functionality -// of registered claim validation. -type testStaticTimes struct { - BeforeNow time.Time - Now time.Time - AfterNow time.Time -} - -// test_Validator_CreateStaticTimes returns a set of timestamps that can be used to validate functionality -// without requiring the use of "time.Now()", which can cause "flakey" tests if there is a delay in when the tests -// run vs when they were started. -func test_Validator_CreateStaticTimes(t *testing.T) (testStaticTimes, error) { - t.Helper() - - staticNow, err := time.Parse(time.RFC3339, "2025-01-02T15:04:05Z") - if err != nil { - return testStaticTimes{}, err - } - - return testStaticTimes{ - BeforeNow: staticNow.Add(time.Hour * -1), - Now: staticNow, - AfterNow: staticNow.Add(time.Hour * 1), - }, nil -} From 734a9292dbc587d5f0e7086af8e622d3541af21c Mon Sep 17 00:00:00 2001 From: Chris Gibson Date: Tue, 5 Aug 2025 08:35:40 +0100 Subject: [PATCH 4/4] Change test to use NewValidator with opts --- validator_test.go | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/validator_test.go b/validator_test.go index 8b57b57c..1790be1f 100644 --- a/validator_test.go +++ b/validator_test.go @@ -308,11 +308,20 @@ func Test_Validator_requireNotBefore(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - v := &Validator{ - leeway: tt.fields.leeway, - timeFunc: tt.fields.timeFunc, - verifyIat: tt.fields.requireNbf, + opts := []ParserOption{ + WithLeeway(tt.fields.leeway), + } + + if tt.fields.requireNbf { + opts = append(opts, WithNotBeforeRequired()) } + + if tt.fields.timeFunc != nil { + opts = append(opts, WithTimeFunc(tt.fields.timeFunc)) + } + + v := NewValidator(opts...) + if err := v.verifyNotBefore(tt.args.claims, tt.args.cmp, tt.args.required); (err != nil) && !errors.Is(err, tt.wantErr) { t.Errorf("validator.requireNotBefore() error = %v, wantErr %v", err, tt.wantErr) }