Skip to content

Commit

Permalink
Merge pull request #419 from supertokens/fix/emailverification-claim
Browse files Browse the repository at this point in the history
feat!: remove default maxAgeInSeconds in emailverification claim
  • Loading branch information
porcellus authored Jul 12, 2024
2 parents 38c30e0 + 421be56 commit 319c4c2
Show file tree
Hide file tree
Showing 4 changed files with 143 additions and 8 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [unreleased]

## [0.23.0] - 2024-07-10

### Breaking Changes

- Removes the default `maxAgeInSeconds` value (previously 300 seconds) in EmailVerification Claim. If the claim value is true and `maxAgeInSeconds` is not provided, it will not be refetched.

## [0.22.1] - 2024-07-09

### Changes
Expand Down
29 changes: 22 additions & 7 deletions recipe/emailverification/emailverificationClaim.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,7 @@ func NewEmailVerificationClaim() (*claims.TypeSessionClaim, evclaims.TypeEmailVe
}
}

var defaultMaxAge int64 = 300
evClaim, booleanClaimValidators := claims.BooleanClaim("st-ev", fetchValue, &defaultMaxAge)
evClaim, booleanClaimValidators := claims.BooleanClaim("st-ev", fetchValue, nil)

getLastRefetchTime := func(payload map[string]interface{}, userContext supertokens.UserContext) *int64 {
if value, ok := payload[evClaim.Key].(map[string]interface{}); ok {
Expand All @@ -57,15 +56,31 @@ func NewEmailVerificationClaim() (*claims.TypeSessionClaim, evclaims.TypeEmailVe
var defaultTimeout int64 = 10
refetchTimeOnFalseInSeconds = &defaultTimeout
}
if maxAgeInSeconds == nil {
var defaultTimeout int64 = 300
maxAgeInSeconds = &defaultTimeout
}

claimValidator := booleanClaimValidators.HasValue(true, maxAgeInSeconds, nil)
claimValidator.ShouldRefetch = func(payload map[string]interface{}, userContext supertokens.UserContext) bool {
value := evClaim.GetValueFromPayload(payload, userContext)
return value == nil || (*getLastRefetchTime(payload, userContext) < time.Now().UnixNano()/1000000-*maxAgeInSeconds*1000) || (value == false && *getLastRefetchTime(payload, userContext) < time.Now().UnixNano()/1000000-*refetchTimeOnFalseInSeconds*1000)

if value == nil {
return true
}

currentTime := time.Now().UnixNano() / 1000000
lastRefetchTime := getLastRefetchTime(payload, userContext)

if maxAgeInSeconds != nil {
if lastRefetchTime != nil && *lastRefetchTime < currentTime-*maxAgeInSeconds*1000 {
return true
}
}

if value == false {
if lastRefetchTime != nil && *lastRefetchTime < currentTime-*refetchTimeOnFalseInSeconds*1000 {
return true
}
}

return false
}
return claimValidator
},
Expand Down
114 changes: 114 additions & 0 deletions recipe/emailverification/emailverificationClaim_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/*
* Copyright (c) 2024, VRAI Labs and/or its affiliates. All rights reserved.
*
* This software is licensed under the Apache License, Version 2.0 (the
* "License") as published by the Apache Software Foundation.
*
* You may not use this file except in compliance with the License. You may
* obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/

package emailverification

import (
"testing"
"time"

"github.com/stretchr/testify/assert"
"github.com/supertokens/supertokens-golang/recipe/emailverification/evclaims"
)

func TestEmailVerificationClaim(t *testing.T) {
t.Run("value should be fetched if it is nil", func(t *testing.T) {
validator := evclaims.EmailVerificationClaimValidators.IsVerified(nil, nil)

shouldRefreshNil := validator.ShouldRefetch(nil, nil)

assert.True(t, shouldRefreshNil)
})

t.Run("value should be fetched as per maxAgeInSeconds if it is provided", func(t *testing.T) {
refetchTimeOnFalseInSeconds := int64(10)
maxAgeInSeconds := int64(200)
validator := evclaims.EmailVerificationClaimValidators.IsVerified(&refetchTimeOnFalseInSeconds, &maxAgeInSeconds)

payload := map[string]interface{}{
"st-ev": map[string]interface{}{
"v": true,
"t": time.Now().UnixMilli() - 199*1000,
},
}

shouldRefreshValid := validator.ShouldRefetch(payload, nil)

assert.False(t, shouldRefreshValid)

payload = map[string]interface{}{
"st-ev": map[string]interface{}{
"v": true,
"t": time.Now().UnixMilli() - 201*1000,
},
}

shouldRefreshExpired := validator.ShouldRefetch(payload, nil)
assert.True(t, shouldRefreshExpired)
})

t.Run("value should be fetched as per refetchTimeOnFalseInSeconds if it is provided", func(t *testing.T) {
refetchTimeOnFalseInSeconds := int64(8)
validator := evclaims.EmailVerificationClaimValidators.IsVerified(&refetchTimeOnFalseInSeconds, nil)

payload := map[string]interface{}{
"st-ev": map[string]interface{}{
"v": false,
"t": time.Now().UnixMilli() - 7*1000,
},
}

shouldRefreshValid := validator.ShouldRefetch(payload, nil)

assert.False(t, shouldRefreshValid)

payload = map[string]interface{}{
"st-ev": map[string]interface{}{
"v": false,
"t": time.Now().UnixMilli() - 9*1000,
},
}

shouldRefreshExpired := validator.ShouldRefetch(payload, nil)
assert.True(t, shouldRefreshExpired)
})

t.Run("value should be fetched as per default the refetchTimeOnFalseInSeconds if it is not provided", func(t *testing.T) {
validator := evclaims.EmailVerificationClaimValidators.IsVerified(nil, nil)

// NOTE: the default value of refetchTimeOnFalseInSeconds is 10 seconds
payload := map[string]interface{}{
"st-ev": map[string]interface{}{
"v": false,
"t": time.Now().UnixMilli() - 9*1000,
},
}

shouldRefreshValid := validator.ShouldRefetch(payload, nil)

assert.False(t, shouldRefreshValid)

payload = map[string]interface{}{
"st-ev": map[string]interface{}{
"v": false,
"t": time.Now().UnixMilli() - 11*1000,
},
}

shouldRefreshExpired := validator.ShouldRefetch(payload, nil)
assert.True(t, shouldRefreshExpired)
})
}
2 changes: 1 addition & 1 deletion supertokens/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const (
)

// VERSION current version of the lib
const VERSION = "0.22.1"
const VERSION = "0.23.0"

var (
cdiSupported = []string{"3.0"}
Expand Down

0 comments on commit 319c4c2

Please sign in to comment.