diff --git a/server/constants/env.go b/server/constants/env.go index c14f232..26eb8bd 100644 --- a/server/constants/env.go +++ b/server/constants/env.go @@ -97,6 +97,8 @@ const ( // Not Exposed Keys // EnvKeyClientID key for env variable CLIENT_ID EnvKeyClientID = "CLIENT_ID" + // EnvKeyClientSecret key for env variable CLIENT_SECRET + EnvKeyClientSecret = "CLIENT_SECRET" // EnvKeyEncryptionKey key for env variable ENCRYPTION_KEY EnvKeyEncryptionKey = "ENCRYPTION_KEY" // EnvKeyJWK key for env variable JWK diff --git a/server/env/env.go b/server/env/env.go index 173daa7..a29914e 100644 --- a/server/env/env.go +++ b/server/env/env.go @@ -88,6 +88,13 @@ func InitAllEnv() error { envData.StringEnv[constants.EnvKeyClientID] = clientID } + clientSecret := envData.StringEnv[constants.EnvKeyClientSecret] + // unique client id for each instance + if clientID == "" { + clientSecret = uuid.New().String() + envData.StringEnv[constants.EnvKeyClientSecret] = clientSecret + } + if envData.StringEnv[constants.EnvKeyEnv] == "" { envData.StringEnv[constants.EnvKeyEnv] = os.Getenv(constants.EnvKeyEnv) if envData.StringEnv[constants.EnvKeyEnv] == "" { diff --git a/server/env/persist_env.go b/server/env/persist_env.go index f00ea04..30e93d3 100644 --- a/server/env/persist_env.go +++ b/server/env/persist_env.go @@ -110,7 +110,7 @@ func PersistEnv() error { for key, value := range storeData.StringEnv { // don't override unexposed envs - if key != constants.EnvKeyEncryptionKey && key != constants.EnvKeyClientID && key != constants.EnvKeyJWK { + if key != constants.EnvKeyEncryptionKey && key != constants.EnvKeyClientID && key != constants.EnvKeyClientSecret && key != constants.EnvKeyJWK { // check only for derivative keys // No need to check for ENCRYPTION_KEY which special key we use for encrypting config data // as we have removed it from json diff --git a/server/graph/generated/generated.go b/server/graph/generated/generated.go index 8ccae86..39e22a8 100644 --- a/server/graph/generated/generated.go +++ b/server/graph/generated/generated.go @@ -55,6 +55,7 @@ type ComplexityRoot struct { AllowedOrigins func(childComplexity int) int AppURL func(childComplexity int) int ClientID func(childComplexity int) int + ClientSecret func(childComplexity int) int CookieName func(childComplexity int) int CustomAccessTokenScript func(childComplexity int) int DatabaseName func(childComplexity int) int @@ -290,6 +291,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Env.ClientID(childComplexity), true + case "Env.CLIENT_SECRET": + if e.complexity.Env.ClientSecret == nil { + break + } + + return e.complexity.Env.ClientSecret(childComplexity), true + case "Env.COOKIE_NAME": if e.complexity.Env.CookieName == nil { break @@ -1232,6 +1240,7 @@ type Env { DATABASE_URL: String! DATABASE_TYPE: String! CLIENT_ID: String! + CLIENT_SECRET: String! CUSTOM_ACCESS_TOKEN_SCRIPT: String SMTP_HOST: String SMTP_PORT: String @@ -2055,6 +2064,41 @@ func (ec *executionContext) _Env_CLIENT_ID(ctx context.Context, field graphql.Co return ec.marshalNString2string(ctx, field.Selections, res) } +func (ec *executionContext) _Env_CLIENT_SECRET(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.ClientSecret, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + func (ec *executionContext) _Env_CUSTOM_ACCESS_TOKEN_SCRIPT(ctx context.Context, field graphql.CollectedField, obj *model.Env) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { @@ -7734,6 +7778,11 @@ func (ec *executionContext) _Env(ctx context.Context, sel ast.SelectionSet, obj if out.Values[i] == graphql.Null { invalids++ } + case "CLIENT_SECRET": + out.Values[i] = ec._Env_CLIENT_SECRET(ctx, field, obj) + if out.Values[i] == graphql.Null { + invalids++ + } case "CUSTOM_ACCESS_TOKEN_SCRIPT": out.Values[i] = ec._Env_CUSTOM_ACCESS_TOKEN_SCRIPT(ctx, field, obj) case "SMTP_HOST": diff --git a/server/graph/model/models_gen.go b/server/graph/model/models_gen.go index 5db3db7..b5213b2 100644 --- a/server/graph/model/models_gen.go +++ b/server/graph/model/models_gen.go @@ -27,6 +27,7 @@ type Env struct { DatabaseURL string `json:"DATABASE_URL"` DatabaseType string `json:"DATABASE_TYPE"` ClientID string `json:"CLIENT_ID"` + ClientSecret string `json:"CLIENT_SECRET"` CustomAccessTokenScript *string `json:"CUSTOM_ACCESS_TOKEN_SCRIPT"` SMTPHost *string `json:"SMTP_HOST"` SMTPPort *string `json:"SMTP_PORT"` diff --git a/server/graph/schema.graphqls b/server/graph/schema.graphqls index 7d92c92..cca567e 100644 --- a/server/graph/schema.graphqls +++ b/server/graph/schema.graphqls @@ -91,6 +91,7 @@ type Env { DATABASE_URL: String! DATABASE_TYPE: String! CLIENT_ID: String! + CLIENT_SECRET: String! CUSTOM_ACCESS_TOKEN_SCRIPT: String SMTP_HOST: String SMTP_PORT: String diff --git a/server/handlers/openid_config.go b/server/handlers/openid_config.go index de41ed6..5b98d03 100644 --- a/server/handlers/openid_config.go +++ b/server/handlers/openid_config.go @@ -17,7 +17,7 @@ func OpenIDConfigurationHandler() gin.HandlerFunc { c.JSON(200, gin.H{ "issuer": issuer, "authorization_endpoint": issuer + "/authorize", - "token_endpoint": issuer + "/oauth/token", + "token_endpoint": issuer + "/token", "userinfo_endpoint": issuer + "/userinfo", "jwks_uri": issuer + "/.well-known/jwks.json", "response_types_supported": []string{"code", "token", "id_token", "code token", "code id_token", "token id_token", "code token id_token"}, diff --git a/server/resolvers/env.go b/server/resolvers/env.go index af04c3c..623d6b3 100644 --- a/server/resolvers/env.go +++ b/server/resolvers/env.go @@ -29,6 +29,7 @@ func EnvResolver(ctx context.Context) (*model.Env, error) { store := envstore.EnvStoreObj.GetEnvStoreClone() adminSecret := store.StringEnv[constants.EnvKeyAdminSecret] clientID := store.StringEnv[constants.EnvKeyClientID] + clientSecret := store.StringEnv[constants.EnvKeyClientSecret] databaseURL := store.StringEnv[constants.EnvKeyDatabaseURL] databaseName := store.StringEnv[constants.EnvKeyDatabaseName] databaseType := store.StringEnv[constants.EnvKeyDatabaseType] @@ -70,6 +71,7 @@ func EnvResolver(ctx context.Context) (*model.Env, error) { DatabaseURL: databaseURL, DatabaseType: databaseType, ClientID: clientID, + ClientSecret: clientSecret, CustomAccessTokenScript: &customAccessTokenScript, SMTPHost: &smtpHost, SMTPPort: &smtpPort,