Skip to content

Commit

Permalink
feat(config): Allow configurable login expiration.
Browse files Browse the repository at this point in the history
Login JWT tokens can now have configurable expiration. It will default
to 7 days; but the staging and production environments will have theirs
increased to 14 days.

Resolves #1263
  • Loading branch information
elliotcourant committed Dec 24, 2022
1 parent bacf437 commit 81f4ab6
Show file tree
Hide file tree
Showing 8 changed files with 59 additions and 6 deletions.
15 changes: 12 additions & 3 deletions pkg/config/configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,14 @@ type Beta struct {
type JWT struct {
LoginJwtSecret string `yaml:"loginJwtSecret"`
RegistrationJwtSecret string `yaml:"registrationJwtSecret"`
// LoginExpiration is the number of days that the issued login JWT token should be considered valid.
LoginExpiration int `yaml:"loginExpiration"`
}

// GetLoginExpirationTimestamp will return a timestamp in the future relative to time.Now. This should be the expiration
// timestamp used for issued JWT tokens for authentication.
func (j JWT) GetLoginExpirationTimestamp() time.Time {
return time.Now().Add(time.Duration(j.LoginExpiration * 24 * int(time.Hour)))
}

type PostgreSQL struct {
Expand Down Expand Up @@ -423,9 +431,6 @@ func getViper(configFilePath *string) *viper.Viper {
v.AddConfigPath(".")
}

setupDefaults(v)
setupEnv(v)

return v
}

Expand All @@ -440,6 +445,9 @@ func LoadConfigurationFromFile(configFilePath *string) Configuration {
}

func LoadConfigurationEx(v *viper.Viper) (config Configuration) {
setupDefaults(v)
setupEnv(v)

if err := v.ReadInConfig(); err != nil {
fmt.Printf("failed to read in config from file: %+v\n", err)
}
Expand Down Expand Up @@ -503,6 +511,7 @@ func setupDefaults(v *viper.Viper) {
v.SetDefault("Logging.Format", "text")
v.SetDefault("Logging.Level", LogLevel) // Info
v.SetDefault("Logging.StackDriver.Enabled", false)
v.SetDefault("JWT.LoginExpiration", 7)
v.SetDefault("KeyManagement.Provider", nil)
v.SetDefault("KeyManagement.AWS", nil)
v.SetDefault("KeyManagement.Google", nil)
Expand Down
30 changes: 30 additions & 0 deletions pkg/config/configuration_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package config_test

import (
"testing"

"github.com/monetr/monetr/pkg/config"
"github.com/spf13/viper"
"github.com/stretchr/testify/assert"
)

func TestLoadConfiguration(t *testing.T) {
t.Run("login expiration default values", func(t *testing.T) {
v := viper.GetViper()
// Don't set a value for login expiration at all.

configuration := config.LoadConfigurationEx(v)
assert.NotZero(t, configuration.JWT.LoginExpiration, "Login expiration should not be zero")
assert.EqualValues(t, 7, configuration.JWT.LoginExpiration, "Login expiration should be 7 days by default")
})

t.Run("login expiration non-default values", func(t *testing.T) {
v := viper.GetViper()
durationString := "30"
v.Set("jwt.loginExpiration", durationString)

configuration := config.LoadConfigurationEx(v)
assert.NotZero(t, configuration.JWT.LoginExpiration, "Login expiration should not be zero")
assert.EqualValues(t, 30, configuration.JWT.LoginExpiration, "when specified, the login expiration should not be the default")
})
}
9 changes: 6 additions & 3 deletions pkg/controller/authentication.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func (c *Controller) updateAuthenticationCookie(ctx iris.Context, token string)
sameSite = http.SameSiteStrictMode
}

expiration := time.Now().Add(7 * 24 * time.Hour)
expiration := c.configuration.JWT.GetLoginExpirationTimestamp()
if token == "" {
expiration = time.Now().Add(-1 * time.Second)
}
Expand Down Expand Up @@ -225,7 +225,7 @@ func (c *Controller) loginEndpoint(ctx iris.Context) {
}

result := map[string]interface{}{
"isActive": true,
"isActive": true,
}

if !loginRequest.IsMobile {
Expand Down Expand Up @@ -881,6 +881,9 @@ func (c *Controller) validateLogin(email, password string) error {

func (c *Controller) generateToken(loginId, userId, accountId uint64) (string, error) {
now := time.Now()

expiration := c.configuration.JWT.GetLoginExpirationTimestamp()

claims := &MonetrClaims{
LoginId: loginId,
UserId: userId,
Expand All @@ -889,7 +892,7 @@ func (c *Controller) generateToken(loginId, userId, accountId uint64) (string, e
Audience: []string{
c.configuration.APIDomainName,
},
ExpiresAt: now.Add(31 * 24 * time.Hour).Unix(),
ExpiresAt: expiration.Unix(),
Id: "",
IssuedAt: now.Unix(),
Issuer: c.configuration.APIDomainName,
Expand Down
1 change: 1 addition & 0 deletions pkg/controller/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ func NewTestApplicationConfig(t *testing.T) config.Configuration {
JWT: config.JWT{
LoginJwtSecret: gofakeit.UUID(),
RegistrationJwtSecret: gofakeit.UUID(),
LoginExpiration: 1,
},
PostgreSQL: config.PostgreSQL{},
Email: config.Email{
Expand Down
4 changes: 4 additions & 0 deletions templates/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,10 @@ data:
server:
{{- toYaml .Values.api.server | nindent 6 }}
{{- if .Values.api.jwt.loginExpiration }}
jwt:
loginExpiration: {{ .Values.api.jwt.loginExpiration }}
{{- end}}
{{- if .Values.api.stripe.initialPlan }}
stripe:
Expand Down
2 changes: 2 additions & 0 deletions values.my.monetr.app.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ api:
webhooksDomain: my.monetr.app
oauthDomain: my.monetr.app
maxNumberOfLinks: 2
jwt:
loginExpiration: 14
cors:
allowedOrigins:
- "https://my.monetr.app"
Expand Down
2 changes: 2 additions & 0 deletions values.my.monetr.dog.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ api:
webhooksDomain: my.monetr.dog
oauthDomain: my.monetr.dog
maxNumberOfLinks: 3
jwt:
loginExpiration: 14
cors:
allowedOrigins:
- "https://my.monetr.dog"
Expand Down
2 changes: 2 additions & 0 deletions values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,8 @@ api:
jwt:
loginJwtSecret: ""
registrationJwtSecret: ""
# Number of days a login JWT token should be considered valid.
loginExpiration: 7
postgreSql:
address: localhost
port: 5432
Expand Down

0 comments on commit 81f4ab6

Please sign in to comment.