enhancement: add access_token_expiry_time env variable
This commit is contained in:
@@ -21,6 +21,8 @@ const (
|
||||
// EnvKeyPort key for env variable PORT
|
||||
EnvKeyPort = "PORT"
|
||||
|
||||
// EnvKeyAccessTokenExpiryTime key for env variable ACCESS_TOKEN_EXPIRY_TIME
|
||||
EnvKeyAccessTokenExpiryTime = "ACCESS_TOKEN_EXPIRY_TIME"
|
||||
// EnvKeyAdminSecret key for env variable ADMIN_SECRET
|
||||
EnvKeyAdminSecret = "ADMIN_SECRET"
|
||||
// EnvKeyDatabaseType key for env variable DATABASE_TYPE
|
||||
|
4
server/env/env.go
vendored
4
server/env/env.go
vendored
@@ -120,6 +120,10 @@ func InitAllEnv() error {
|
||||
}
|
||||
}
|
||||
|
||||
if envData.StringEnv[constants.EnvKeyAccessTokenExpiryTime] == "" {
|
||||
envData.StringEnv[constants.EnvKeyAccessTokenExpiryTime] = os.Getenv(constants.EnvKeyAccessTokenExpiryTime)
|
||||
}
|
||||
|
||||
if envData.StringEnv[constants.EnvKeyAdminSecret] == "" {
|
||||
envData.StringEnv[constants.EnvKeyAdminSecret] = os.Getenv(constants.EnvKeyAdminSecret)
|
||||
}
|
||||
|
@@ -53,6 +53,7 @@ type ComplexityRoot struct {
|
||||
}
|
||||
|
||||
Env struct {
|
||||
AccessTokenExpiryTime func(childComplexity int) int
|
||||
AdminSecret func(childComplexity int) int
|
||||
AllowedOrigins func(childComplexity int) int
|
||||
AppURL func(childComplexity int) int
|
||||
@@ -276,6 +277,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
|
||||
|
||||
return e.complexity.AuthResponse.User(childComplexity), true
|
||||
|
||||
case "Env.ACCESS_TOKEN_EXPIRY_TIME":
|
||||
if e.complexity.Env.AccessTokenExpiryTime == nil {
|
||||
break
|
||||
}
|
||||
|
||||
return e.complexity.Env.AccessTokenExpiryTime(childComplexity), true
|
||||
|
||||
case "Env.ADMIN_SECRET":
|
||||
if e.complexity.Env.AdminSecret == nil {
|
||||
break
|
||||
@@ -1247,6 +1255,7 @@ type Response {
|
||||
}
|
||||
|
||||
type Env {
|
||||
ACCESS_TOKEN_EXPIRY_TIME: String
|
||||
ADMIN_SECRET: String
|
||||
DATABASE_NAME: String!
|
||||
DATABASE_URL: String!
|
||||
@@ -1287,6 +1296,7 @@ type Env {
|
||||
}
|
||||
|
||||
input UpdateEnvInput {
|
||||
ACCESS_TOKEN_EXPIRY_TIME: String
|
||||
ADMIN_SECRET: String
|
||||
CUSTOM_ACCESS_TOKEN_SCRIPT: String
|
||||
OLD_ADMIN_SECRET: String
|
||||
@@ -1975,6 +1985,38 @@ func (ec *executionContext) _AuthResponse_user(ctx context.Context, field graphq
|
||||
return ec.marshalOUser2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐUser(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) _Env_ACCESS_TOKEN_EXPIRY_TIME(ctx context.Context, field graphql.CollectedField, obj *model.Env) (ret graphql.Marshaler) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
ec.Error(ctx, ec.Recover(ctx, r))
|
||||
ret = graphql.Null
|
||||
}
|
||||
}()
|
||||
fc := &graphql.FieldContext{
|
||||
Object: "Env",
|
||||
Field: field,
|
||||
Args: nil,
|
||||
IsMethod: false,
|
||||
IsResolver: false,
|
||||
}
|
||||
|
||||
ctx = graphql.WithFieldContext(ctx, fc)
|
||||
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
|
||||
ctx = rctx // use context from middleware stack in children
|
||||
return obj.AccessTokenExpiryTime, nil
|
||||
})
|
||||
if err != nil {
|
||||
ec.Error(ctx, err)
|
||||
return graphql.Null
|
||||
}
|
||||
if resTmp == nil {
|
||||
return graphql.Null
|
||||
}
|
||||
res := resTmp.(*string)
|
||||
fc.Result = res
|
||||
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) _Env_ADMIN_SECRET(ctx context.Context, field graphql.CollectedField, obj *model.Env) (ret graphql.Marshaler) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
@@ -7322,6 +7364,14 @@ func (ec *executionContext) unmarshalInputUpdateEnvInput(ctx context.Context, ob
|
||||
|
||||
for k, v := range asMap {
|
||||
switch k {
|
||||
case "ACCESS_TOKEN_EXPIRY_TIME":
|
||||
var err error
|
||||
|
||||
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("ACCESS_TOKEN_EXPIRY_TIME"))
|
||||
it.AccessTokenExpiryTime, err = ec.unmarshalOString2ᚖstring(ctx, v)
|
||||
if err != nil {
|
||||
return it, err
|
||||
}
|
||||
case "ADMIN_SECRET":
|
||||
var err error
|
||||
|
||||
@@ -7893,6 +7943,8 @@ func (ec *executionContext) _Env(ctx context.Context, sel ast.SelectionSet, obj
|
||||
switch field.Name {
|
||||
case "__typename":
|
||||
out.Values[i] = graphql.MarshalString("Env")
|
||||
case "ACCESS_TOKEN_EXPIRY_TIME":
|
||||
out.Values[i] = ec._Env_ACCESS_TOKEN_EXPIRY_TIME(ctx, field, obj)
|
||||
case "ADMIN_SECRET":
|
||||
out.Values[i] = ec._Env_ADMIN_SECRET(ctx, field, obj)
|
||||
case "DATABASE_NAME":
|
||||
|
@@ -24,6 +24,7 @@ type DeleteUserInput struct {
|
||||
}
|
||||
|
||||
type Env struct {
|
||||
AccessTokenExpiryTime *string `json:"ACCESS_TOKEN_EXPIRY_TIME"`
|
||||
AdminSecret *string `json:"ADMIN_SECRET"`
|
||||
DatabaseName string `json:"DATABASE_NAME"`
|
||||
DatabaseURL string `json:"DATABASE_URL"`
|
||||
@@ -157,6 +158,7 @@ type SignUpInput struct {
|
||||
}
|
||||
|
||||
type UpdateEnvInput struct {
|
||||
AccessTokenExpiryTime *string `json:"ACCESS_TOKEN_EXPIRY_TIME"`
|
||||
AdminSecret *string `json:"ADMIN_SECRET"`
|
||||
CustomAccessTokenScript *string `json:"CUSTOM_ACCESS_TOKEN_SCRIPT"`
|
||||
OldAdminSecret *string `json:"OLD_ADMIN_SECRET"`
|
||||
|
@@ -85,6 +85,7 @@ type Response {
|
||||
}
|
||||
|
||||
type Env {
|
||||
ACCESS_TOKEN_EXPIRY_TIME: String
|
||||
ADMIN_SECRET: String
|
||||
DATABASE_NAME: String!
|
||||
DATABASE_URL: String!
|
||||
@@ -125,6 +126,7 @@ type Env {
|
||||
}
|
||||
|
||||
input UpdateEnvInput {
|
||||
ACCESS_TOKEN_EXPIRY_TIME: String
|
||||
ADMIN_SECRET: String
|
||||
CUSTOM_ACCESS_TOKEN_SCRIPT: String
|
||||
OLD_ADMIN_SECRET: String
|
||||
|
@@ -4,6 +4,7 @@ import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/authorizerdev/authorizer/server/constants"
|
||||
"github.com/authorizerdev/authorizer/server/cookie"
|
||||
@@ -276,7 +277,11 @@ func AuthorizeHandler() gin.HandlerFunc {
|
||||
sessionstore.SetState(authToken.FingerPrintHash, authToken.FingerPrint+"@"+user.ID)
|
||||
sessionstore.SetState(authToken.AccessToken.Token, authToken.FingerPrint+"@"+user.ID)
|
||||
cookie.SetSession(gc, authToken.FingerPrintHash)
|
||||
expiresIn := int64(1800)
|
||||
|
||||
expiresIn := authToken.AccessToken.ExpiresAt - time.Now().Unix()
|
||||
if expiresIn <= 0 {
|
||||
expiresIn = 1
|
||||
}
|
||||
|
||||
// used of query mode
|
||||
params := "access_token=" + authToken.AccessToken.Token + "&token_type=bearer&expires_in=" + strconv.FormatInt(expiresIn, 10) + "&state=" + state + "&id_token=" + authToken.IDToken.Token
|
||||
|
@@ -150,7 +150,12 @@ func OAuthCallbackHandler() gin.HandlerFunc {
|
||||
if err != nil {
|
||||
c.JSON(500, gin.H{"error": err.Error()})
|
||||
}
|
||||
expiresIn := int64(1800)
|
||||
|
||||
expiresIn := authToken.AccessToken.ExpiresAt - time.Now().Unix()
|
||||
if expiresIn <= 0 {
|
||||
expiresIn = 1
|
||||
}
|
||||
|
||||
params := "access_token=" + authToken.AccessToken.Token + "&token_type=bearer&expires_in=" + strconv.FormatInt(expiresIn, 10) + "&state=" + stateValue + "&id_token=" + authToken.IDToken.Token
|
||||
|
||||
cookie.SetSession(c, authToken.FingerPrintHash)
|
||||
|
@@ -5,6 +5,7 @@ import (
|
||||
"encoding/base64"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/authorizerdev/authorizer/server/constants"
|
||||
"github.com/authorizerdev/authorizer/server/cookie"
|
||||
@@ -174,7 +175,11 @@ func TokenHandler() gin.HandlerFunc {
|
||||
sessionstore.SetState(authToken.AccessToken.Token, authToken.FingerPrint+"@"+user.ID)
|
||||
cookie.SetSession(gc, authToken.FingerPrintHash)
|
||||
|
||||
expiresIn := int64(1800)
|
||||
expiresIn := authToken.AccessToken.ExpiresAt - time.Now().Unix()
|
||||
if expiresIn <= 0 {
|
||||
expiresIn = 1
|
||||
}
|
||||
|
||||
res := map[string]interface{}{
|
||||
"access_token": authToken.AccessToken.Token,
|
||||
"id_token": authToken.IDToken.Token,
|
||||
|
@@ -82,7 +82,12 @@ func VerifyEmailHandler() gin.HandlerFunc {
|
||||
c.JSON(500, errorRes)
|
||||
return
|
||||
}
|
||||
expiresIn := int64(1800)
|
||||
|
||||
expiresIn := authToken.AccessToken.ExpiresAt - time.Now().Unix()
|
||||
if expiresIn <= 0 {
|
||||
expiresIn = 1
|
||||
}
|
||||
|
||||
params := "access_token=" + authToken.AccessToken.Token + "&token_type=bearer&expires_in=" + strconv.FormatInt(expiresIn, 10) + "&state=" + state + "&id_token=" + authToken.IDToken.Token
|
||||
|
||||
cookie.SetSession(c, authToken.FingerPrintHash)
|
||||
|
@@ -27,6 +27,7 @@ func EnvResolver(ctx context.Context) (*model.Env, error) {
|
||||
|
||||
// get clone of store
|
||||
store := envstore.EnvStoreObj.GetEnvStoreClone()
|
||||
accessTokenExpiryTime := store.StringEnv[constants.EnvKeyAccessTokenExpiryTime]
|
||||
adminSecret := store.StringEnv[constants.EnvKeyAdminSecret]
|
||||
clientID := store.StringEnv[constants.EnvKeyClientID]
|
||||
clientSecret := store.StringEnv[constants.EnvKeyClientSecret]
|
||||
@@ -66,6 +67,7 @@ func EnvResolver(ctx context.Context) (*model.Env, error) {
|
||||
organizationLogo := store.StringEnv[constants.EnvKeyOrganizationLogo]
|
||||
|
||||
res = &model.Env{
|
||||
AccessTokenExpiryTime: &accessTokenExpiryTime,
|
||||
AdminSecret: &adminSecret,
|
||||
DatabaseName: databaseName,
|
||||
DatabaseURL: databaseURL,
|
||||
|
@@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
"log"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/authorizerdev/authorizer/server/constants"
|
||||
"github.com/authorizerdev/authorizer/server/cookie"
|
||||
@@ -69,7 +70,11 @@ func LoginResolver(ctx context.Context, params model.LoginInput) (*model.AuthRes
|
||||
return res, err
|
||||
}
|
||||
|
||||
expiresIn := int64(1800)
|
||||
expiresIn := authToken.AccessToken.ExpiresAt - time.Now().Unix()
|
||||
if expiresIn <= 0 {
|
||||
expiresIn = 1
|
||||
}
|
||||
|
||||
res = &model.AuthResponse{
|
||||
Message: `Logged in successfully`,
|
||||
AccessToken: &authToken.AccessToken.Token,
|
||||
|
@@ -3,6 +3,7 @@ package resolvers
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/authorizerdev/authorizer/server/cookie"
|
||||
"github.com/authorizerdev/authorizer/server/db"
|
||||
@@ -69,7 +70,11 @@ func SessionResolver(ctx context.Context, params *model.SessionQueryInput) (*mod
|
||||
sessionstore.SetState(authToken.AccessToken.Token, authToken.FingerPrint+"@"+user.ID)
|
||||
cookie.SetSession(gc, authToken.FingerPrintHash)
|
||||
|
||||
expiresIn := int64(1800)
|
||||
expiresIn := authToken.AccessToken.ExpiresAt - time.Now().Unix()
|
||||
if expiresIn <= 0 {
|
||||
expiresIn = 1
|
||||
}
|
||||
|
||||
res = &model.AuthResponse{
|
||||
Message: `Session token refreshed`,
|
||||
AccessToken: &authToken.AccessToken.Token,
|
||||
|
@@ -164,7 +164,10 @@ func SignupResolver(ctx context.Context, params model.SignUpInput) (*model.AuthR
|
||||
cookie.SetSession(gc, authToken.FingerPrintHash)
|
||||
go utils.SaveSessionInDB(gc, user.ID)
|
||||
|
||||
expiresIn := int64(1800)
|
||||
expiresIn := authToken.AccessToken.ExpiresAt - time.Now().Unix()
|
||||
if expiresIn <= 0 {
|
||||
expiresIn = 1
|
||||
}
|
||||
|
||||
res = &model.AuthResponse{
|
||||
Message: `Signed up successfully.`,
|
||||
|
@@ -64,7 +64,11 @@ func VerifyEmailResolver(ctx context.Context, params model.VerifyEmailInput) (*m
|
||||
cookie.SetSession(gc, authToken.FingerPrintHash)
|
||||
go utils.SaveSessionInDB(gc, user.ID)
|
||||
|
||||
expiresIn := int64(1800)
|
||||
expiresIn := authToken.AccessToken.ExpiresAt - time.Now().Unix()
|
||||
if expiresIn <= 0 {
|
||||
expiresIn = 1
|
||||
}
|
||||
|
||||
res = &model.AuthResponse{
|
||||
Message: `Email verified successfully.`,
|
||||
AccessToken: &authToken.AccessToken.Token,
|
||||
|
@@ -130,7 +130,11 @@ func CreateRefreshToken(user models.User, roles, scopes []string, hostname, nonc
|
||||
// CreateAccessToken util to create JWT token, based on
|
||||
// user information, roles config and CUSTOM_ACCESS_TOKEN_SCRIPT
|
||||
func CreateAccessToken(user models.User, roles, scopes []string, hostName, nonce string) (string, int64, error) {
|
||||
expiryBound := time.Minute * 30
|
||||
expiryBound, err := utils.ParseDurationInSeconds(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAccessTokenExpiryTime))
|
||||
if err != nil {
|
||||
expiryBound = time.Minute * 15
|
||||
}
|
||||
|
||||
expiresAt := time.Now().Add(expiryBound).Unix()
|
||||
|
||||
customClaims := jwt.MapClaims{
|
||||
@@ -277,7 +281,11 @@ func ValidateBrowserSession(gc *gin.Context, encryptedSession string) (*SessionD
|
||||
// CreateIDToken util to create JWT token, based on
|
||||
// user information, roles config and CUSTOM_ACCESS_TOKEN_SCRIPT
|
||||
func CreateIDToken(user models.User, roles []string, hostname, nonce string) (string, int64, error) {
|
||||
expiryBound := time.Minute * 30
|
||||
expiryBound, err := utils.ParseDurationInSeconds(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAccessTokenExpiryTime))
|
||||
if err != nil {
|
||||
expiryBound = time.Minute * 15
|
||||
}
|
||||
|
||||
expiresAt := time.Now().Add(expiryBound).Unix()
|
||||
|
||||
resUser := user.AsAPIUser()
|
||||
|
21
server/utils/parser.go
Normal file
21
server/utils/parser.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"time"
|
||||
)
|
||||
|
||||
// ParseDurationInSeconds parses input s, removes ms/us/ns and returns result duration
|
||||
func ParseDurationInSeconds(s string) (time.Duration, error) {
|
||||
d, err := time.ParseDuration(s)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
d = d.Truncate(time.Second)
|
||||
if d <= 0 {
|
||||
return 0, errors.New(`duration must be greater than 0s`)
|
||||
}
|
||||
|
||||
return d, nil
|
||||
}
|
Reference in New Issue
Block a user