Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wip: validate config with declarative tags #3113

Draft
wants to merge 1 commit into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ require (
github.com/getsentry/sentry-go v0.31.1
github.com/go-errors/errors v1.5.1
github.com/go-git/go-git/v5 v5.13.2
github.com/go-playground/validator/v10 v10.24.0
github.com/go-xmlfmt/xmlfmt v1.1.3
github.com/golang-jwt/jwt/v5 v5.2.1
github.com/golangci/golangci-lint v1.63.4
Expand Down Expand Up @@ -132,6 +133,7 @@ require (
github.com/fsnotify/fsnotify v1.8.0 // indirect
github.com/fvbommel/sortorder v1.1.0 // indirect
github.com/fzipp/gocyclo v0.6.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.8 // indirect
github.com/getkin/kin-openapi v0.124.0 // indirect
github.com/ghostiam/protogetter v0.3.8 // indirect
github.com/go-critic/go-critic v0.11.5 // indirect
Expand All @@ -141,6 +143,8 @@ require (
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-openapi/jsonpointer v0.21.0 // indirect
github.com/go-openapi/swag v0.23.0 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-toolsmith/astcast v1.1.0 // indirect
github.com/go-toolsmith/astcopy v1.1.0 // indirect
github.com/go-toolsmith/astequal v1.2.0 // indirect
Expand Down Expand Up @@ -206,6 +210,7 @@ require (
github.com/ldez/grignotin v0.7.0 // indirect
github.com/ldez/tagliatelle v0.7.1 // indirect
github.com/ldez/usetesting v0.4.2 // indirect
github.com/leodido/go-urn v1.4.0 // indirect
github.com/leonklingele/grouper v1.1.2 // indirect
github.com/lib/pq v1.10.9 // indirect
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
Expand Down Expand Up @@ -327,9 +332,9 @@ require (
golang.org/x/exp v0.0.0-20250103183323-7d7fa50e5329 // indirect
golang.org/x/exp/typeparams v0.0.0-20241108190413-2d47ceb2692f // indirect
golang.org/x/net v0.34.0 // indirect
golang.org/x/sync v0.10.0 // indirect
golang.org/x/sync v0.11.0 // indirect
golang.org/x/sys v0.30.0 // indirect
golang.org/x/text v0.21.0 // indirect
golang.org/x/text v0.22.0 // indirect
golang.org/x/tools v0.28.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250102185135-69823020774d // indirect
Expand Down
20 changes: 16 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,8 @@ github.com/fvbommel/sortorder v1.1.0 h1:fUmoe+HLsBTctBDoaBwpQo5N+nrCp8g/BjKb/6ZQ
github.com/fvbommel/sortorder v1.1.0/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0=
github.com/fzipp/gocyclo v0.6.0 h1:lsblElZG7d3ALtGMx9fmxeTKZaLLpU8mET09yN4BBLo=
github.com/fzipp/gocyclo v0.6.0/go.mod h1:rXPyn8fnlpa0R2csP/31uerbiVBugk5whMdlyaLkLoA=
github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM=
github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8=
github.com/getkin/kin-openapi v0.124.0 h1:VSFNMB9C9rTKBnQ/fpyDU8ytMTr4dWI9QovSKj9kz/M=
github.com/getkin/kin-openapi v0.124.0/go.mod h1:wb1aSZA/iWmorQP9KTAS/phLj/t17B5jT7+fS8ed9NM=
github.com/getsentry/sentry-go v0.31.1 h1:ELVc0h7gwyhnXHDouXkhqTFSO5oslsRDk0++eyE0KJ4=
Expand Down Expand Up @@ -323,6 +325,14 @@ github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1
github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY=
github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE=
github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.24.0 h1:KHQckvo8G6hlWnrPX4NJJ+aBfWNAE/HH+qdL2cBpCmg=
github.com/go-playground/validator/v10 v10.24.0/go.mod h1:GGzBIJMuE98Ic/kJsBXbz1x/7cByt++cQ+YOuDM5wus=
github.com/go-quicktest/qt v1.101.0 h1:O1K29Txy5P2OK0dGo59b7b0LR6wKfIhttaAhHUyn7eI=
github.com/go-quicktest/qt v1.101.0/go.mod h1:14Bz/f7NwaXPtdYEgzsx46kqSxVwTbzVZsDC26tQJow=
github.com/go-sql-driver/mysql v1.3.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
Expand Down Expand Up @@ -639,6 +649,8 @@ github.com/ldez/tagliatelle v0.7.1 h1:bTgKjjc2sQcsgPiT902+aadvMjCeMHrY7ly2XKFORI
github.com/ldez/tagliatelle v0.7.1/go.mod h1:3zjxUpsNB2aEZScWiZTHrAXOl1x25t3cRmzfK1mlo2I=
github.com/ldez/usetesting v0.4.2 h1:J2WwbrFGk3wx4cZwSMiCQQ00kjGR0+tuuyW0Lqm4lwA=
github.com/ldez/usetesting v0.4.2/go.mod h1:eEs46T3PpQ+9RgN9VjpY6qWdiw2/QmfiDeWmdZdrjIQ=
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
github.com/leonklingele/grouper v1.1.2 h1:o1ARBDLOmmasUaNDesWqWCIFH3u7hoFlM84YrjT3mIY=
github.com/leonklingele/grouper v1.1.2/go.mod h1:6D0M/HVkhs2yRKRFZUoGjeDy7EZTfFBE9gl4kjmIGkA=
github.com/lib/pq v0.0.0-20150723085316-0dad96c0b94f/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
Expand Down Expand Up @@ -1209,8 +1221,8 @@ golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
Expand Down Expand Up @@ -1313,8 +1325,8 @@ golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
Expand Down
2 changes: 1 addition & 1 deletion internal/functions/serve/serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ func populatePerFunctionConfigs(cwd, importMapPath string, noVerifyJWT *bool, fs
}
binds := []string{}
for slug, fc := range functionsConfig {
if !fc.IsEnabled() {
if !fc.Enabled {
fmt.Fprintln(os.Stderr, "Skipped serving Function:", slug)
continue
}
Expand Down
4 changes: 2 additions & 2 deletions internal/start/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -502,7 +502,7 @@ EOF
fmt.Sprintf("GOTRUE_MFA_MAX_ENROLLED_FACTORS=%v", utils.Config.Auth.MFA.MaxEnrolledFactors),
}

if utils.Config.Auth.Email.Smtp != nil && utils.Config.Auth.Email.Smtp.IsEnabled() {
if utils.Config.Auth.Email.Smtp != nil && utils.Config.Auth.Email.Smtp.Enabled {
env = append(env,
fmt.Sprintf("GOTRUE_SMTP_HOST=%s", utils.Config.Auth.Email.Smtp.Host),
fmt.Sprintf("GOTRUE_SMTP_PORT=%d", utils.Config.Auth.Email.Smtp.Port),
Expand Down Expand Up @@ -984,7 +984,7 @@ EOF
"SUPABASE_ANON_KEY=" + utils.Config.Auth.AnonKey,
"SUPABASE_SERVICE_KEY=" + utils.Config.Auth.ServiceRoleKey,
"LOGFLARE_API_KEY=" + utils.Config.Analytics.ApiKey,
"OPENAI_API_KEY=" + utils.Config.Studio.OpenaiApiKey,
"OPENAI_API_KEY=" + utils.Config.Studio.OpenaiApiKey.Value,
fmt.Sprintf("LOGFLARE_URL=http://%v:4000", utils.LogflareId),
fmt.Sprintf("NEXT_PUBLIC_ENABLE_LOGS=%v", utils.Config.Analytics.Enabled),
fmt.Sprintf("NEXT_ANALYTICS_BACKEND_PROVIDER=%v", utils.Config.Analytics.Backend),
Expand Down
4 changes: 2 additions & 2 deletions pkg/config/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ type (
// Local only config
Image string `toml:"-"`
KongImage string `toml:"-"`
Port uint16 `toml:"port"`
Port uint16 `toml:"port" validate:"gt=0"`
Tls tlsKong `toml:"tls"`
// TODO: replace [auth|studio].api_url
ExternalUrl string `toml:"external_url"`
ExternalUrl string `toml:"external_url" validate:"http_url"`
}

tlsKong struct {
Expand Down
114 changes: 52 additions & 62 deletions pkg/config/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,15 +72,15 @@ type (
Enabled bool `toml:"enabled"`
Image string `toml:"-"`

SiteUrl string `toml:"site_url" mapstructure:"site_url"`
AdditionalRedirectUrls []string `toml:"additional_redirect_urls"`
SiteUrl string `toml:"site_url" mapstructure:"site_url" validate:"http_url"`
AdditionalRedirectUrls []string `toml:"additional_redirect_urls" validate:"dive,http_url"`
JwtExpiry uint `toml:"jwt_expiry"`
EnableRefreshTokenRotation bool `toml:"enable_refresh_token_rotation"`
RefreshTokenReuseInterval uint `toml:"refresh_token_reuse_interval"`
EnableManualLinking bool `toml:"enable_manual_linking"`
EnableSignup bool `toml:"enable_signup"`
EnableAnonymousSignIns bool `toml:"enable_anonymous_sign_ins"`
MinimumPasswordLength uint `toml:"minimum_password_length"`
MinimumPasswordLength uint `toml:"minimum_password_length" validate:"min=6"`
PasswordRequirements PasswordRequirements `toml:"password_requirements"`

Captcha *captcha `toml:"captcha"`
Expand All @@ -89,7 +89,7 @@ type (
Sessions sessions `toml:"sessions"`
Email email `toml:"email"`
Sms sms `toml:"sms"`
External external `toml:"external"`
External external `toml:"external" validate:"dive"`

// Custom secrets can be injected from .env file
JwtSecret string `toml:"-" mapstructure:"jwt_secret"`
Expand All @@ -102,77 +102,74 @@ type (
external map[string]provider

thirdParty struct {
Firebase tpaFirebase `toml:"firebase"`
Auth0 tpaAuth0 `toml:"auth0"`
Cognito tpaCognito `toml:"aws_cognito"`
Firebase tpaFirebase `toml:"firebase" validate:"excluded_with=Auth0.Enabled Cognito.Enabled"`
Auth0 tpaAuth0 `toml:"auth0" validate:"excluded_with=Firebase.Enabled Cognito.Enabled"`
Cognito tpaCognito `toml:"aws_cognito" validate:"excluded_with=Auth0.Enabled Firebase.Enabled"`
}

tpaFirebase struct {
Enabled bool `toml:"enabled"`

ProjectID string `toml:"project_id"`
Enabled bool `toml:"enabled"`
ProjectID string `toml:"project_id" validate:"required_with=Enabled"`
}

tpaAuth0 struct {
Enabled bool `toml:"enabled"`

Tenant string `toml:"tenant"`
Enabled bool `toml:"enabled"`
Tenant string `toml:"tenant" validate:"required_with=Enabled"`
TenantRegion string `toml:"tenant_region"`
}

tpaCognito struct {
Enabled bool `toml:"enabled"`

UserPoolID string `toml:"user_pool_id"`
UserPoolRegion string `toml:"user_pool_region"`
Enabled bool `toml:"enabled"`
UserPoolID string `toml:"user_pool_id" validate:"required_with=Enabled"`
UserPoolRegion string `toml:"user_pool_region" validate:"required_with=Enabled"`
}

email struct {
EnableSignup bool `toml:"enable_signup"`
DoubleConfirmChanges bool `toml:"double_confirm_changes"`
EnableConfirmations bool `toml:"enable_confirmations"`
SecurePasswordChange bool `toml:"secure_password_change"`
Template map[string]emailTemplate `toml:"template"`
Template map[string]emailTemplate `toml:"template" validate:"dive"`
Smtp *smtp `toml:"smtp"`
MaxFrequency time.Duration `toml:"max_frequency"`
OtpLength uint `toml:"otp_length"`
OtpLength uint `toml:"otp_length" validate:"min=6"`
OtpExpiry uint `toml:"otp_expiry"`
}

smtp struct {
Enabled *bool `toml:"enabled"`
Host string `toml:"host"`
Port uint16 `toml:"port"`
User string `toml:"user"`
Pass Secret `toml:"pass"`
AdminEmail string `toml:"admin_email"`
Enabled bool `toml:"enabled"`
Host string `toml:"host" validate:"required_with=Enabled"`
Port uint16 `toml:"port" validate:"required_with=Enabled"`
User string `toml:"user" validate:"required_with=Enabled"`
Pass Secret `toml:"pass" validate:"required_with=Enabled"`
AdminEmail string `toml:"admin_email" validate:"required_with=Enabled"`
SenderName string `toml:"sender_name"`
}

emailTemplate struct {
Subject *string `toml:"subject"`
Content *string `toml:"content"`
Content *string `toml:"content" validate:"isdefault"`
// Only content path is accepted in config.toml
ContentPath string `toml:"content_path"`
ContentPath string `toml:"content_path" validate:"omitempty,file"`
}

sms struct {
EnableSignup bool `toml:"enable_signup"`
EnableConfirmations bool `toml:"enable_confirmations"`
Template string `toml:"template"`
Twilio twilioConfig `toml:"twilio" mapstructure:"twilio"`
TwilioVerify twilioConfig `toml:"twilio_verify" mapstructure:"twilio_verify"`
Messagebird messagebirdConfig `toml:"messagebird" mapstructure:"messagebird"`
Textlocal textlocalConfig `toml:"textlocal" mapstructure:"textlocal"`
Vonage vonageConfig `toml:"vonage" mapstructure:"vonage"`
Template string `toml:"template" validate:"required"`
Twilio twilioConfig `toml:"twilio" mapstructure:"twilio" validate:"excluded_with=TwilioVerify.Enabled Messagebird.Enabled Textlocal.Enabled Vonage.Enabled"`
TwilioVerify twilioConfig `toml:"twilio_verify" mapstructure:"twilio_verify" validate:"excluded_with=Twilio.Enabled Messagebird.Enabled Textlocal.Enabled Vonage.Enabled"`
Messagebird messagebirdConfig `toml:"messagebird" mapstructure:"messagebird" validate:"excluded_with=Twilio.Enabled TwilioVerify.Enabled Textlocal.Enabled Vonage.Enabled"`
Textlocal textlocalConfig `toml:"textlocal" mapstructure:"textlocal" validate:"excluded_with=Twilio.Enabled TwilioVerify.Enabled Messagebird.Enabled Vonage.Enabled"`
Vonage vonageConfig `toml:"vonage" mapstructure:"vonage" validate:"excluded_with=Twilio.Enabled TwilioVerify.Enabled Messagebird.Enabled Textlocal.Enabled"`
TestOTP map[string]string `toml:"test_otp"`
MaxFrequency time.Duration `toml:"max_frequency"`
}

captcha struct {
Enabled bool `toml:"enabled"`
Provider CaptchaProvider `toml:"provider"`
Secret Secret `toml:"secret"`
Provider CaptchaProvider `toml:"provider" validate:"required_with=Enabled"`
Secret Secret `toml:"secret" validate:"required_with=Enabled"`
}

hook struct {
Expand All @@ -185,13 +182,13 @@ type (

factorTypeConfiguration struct {
EnrollEnabled bool `toml:"enroll_enabled"`
VerifyEnabled bool `toml:"verify_enabled"`
VerifyEnabled bool `toml:"verify_enabled" validate:"required_with=EnrollEnabled"`
}

phoneFactorTypeConfiguration struct {
factorTypeConfiguration
OtpLength uint `toml:"otp_length"`
Template string `toml:"template"`
OtpLength uint `toml:"otp_length" validate:"min=6"`
Template string `toml:"template" validate:"required"`
MaxFrequency time.Duration `toml:"max_frequency"`
}

Expand All @@ -204,7 +201,7 @@ type (

hookConfig struct {
Enabled bool `toml:"enabled"`
URI string `toml:"uri"`
URI string `toml:"uri" validate:"required_with=Enabled,http_url|startswith=pg-functions://postgres/"`
Secrets Secret `toml:"secrets"`
}

Expand All @@ -215,33 +212,33 @@ type (

twilioConfig struct {
Enabled bool `toml:"enabled"`
AccountSid string `toml:"account_sid"`
MessageServiceSid string `toml:"message_service_sid"`
AuthToken Secret `toml:"auth_token" mapstructure:"auth_token"`
AccountSid string `toml:"account_sid" validate:"required_with=Enabled"`
MessageServiceSid string `toml:"message_service_sid" validate:"required_with=Enabled"`
AuthToken Secret `toml:"auth_token" mapstructure:"auth_token" validate:"required_with=Enabled"`
}

messagebirdConfig struct {
Enabled bool `toml:"enabled"`
Originator string `toml:"originator"`
AccessKey Secret `toml:"access_key" mapstructure:"access_key"`
Originator string `toml:"originator" validate:"required_with=Enabled"`
AccessKey Secret `toml:"access_key" mapstructure:"access_key" validate:"required_with=Enabled"`
}

textlocalConfig struct {
Enabled bool `toml:"enabled"`
Sender string `toml:"sender"`
ApiKey Secret `toml:"api_key" mapstructure:"api_key"`
Sender string `toml:"sender" validate:"required_with=Enabled"`
ApiKey Secret `toml:"api_key" mapstructure:"api_key" validate:"required_with=Enabled"`
}

vonageConfig struct {
Enabled bool `toml:"enabled"`
From string `toml:"from"`
ApiKey string `toml:"api_key" mapstructure:"api_key"`
ApiSecret Secret `toml:"api_secret" mapstructure:"api_secret"`
From string `toml:"from" validate:"required_with=Enabled"`
ApiKey string `toml:"api_key" mapstructure:"api_key" validate:"required_with=Enabled"`
ApiSecret Secret `toml:"api_secret" mapstructure:"api_secret" validate:"required_with=Enabled"`
}

provider struct {
Enabled bool `toml:"enabled"`
ClientId string `toml:"client_id"`
ClientId string `toml:"client_id" validate:"required_with=Enabled"`
Secret Secret `toml:"secret"`
Url string `toml:"url"`
RedirectUri string `toml:"redirect_uri"`
Expand Down Expand Up @@ -558,13 +555,8 @@ func (e *email) fromAuthConfig(remoteConfig v1API.AuthConfigResponse) {
}
}

func (s smtp) IsEnabled() bool {
// If Enabled is not defined, or defined and set to true
return cast.Val(s.Enabled, true)
}

func (s smtp) toAuthConfigBody(body *v1API.UpdateAuthConfigBody) {
if !s.IsEnabled() {
if !s.Enabled {
// Setting a single empty string disables SMTP
body.SmtpHost = cast.Ptr("")
return
Expand All @@ -580,14 +572,12 @@ func (s smtp) toAuthConfigBody(body *v1API.UpdateAuthConfigBody) {
}

func (s *smtp) fromAuthConfig(remoteConfig v1API.AuthConfigResponse) {
showDiff := s.IsEnabled()
// Api resets all values when SMTP is disabled
if enabled := remoteConfig.SmtpHost != nil; s.Enabled != nil {
*s.Enabled = enabled
}
if !showDiff {
// When local config is not set, we assume platform defaults should not change
if s == nil {
return
}
// Api resets all values when SMTP is disabled
s.Enabled = remoteConfig.SmtpHost != nil
s.Host = cast.Val(remoteConfig.SmtpHost, "")
s.User = cast.Val(remoteConfig.SmtpUser, "")
if len(s.Pass.SHA256) > 0 {
Expand Down
4 changes: 2 additions & 2 deletions pkg/config/auth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -521,7 +521,7 @@ func TestEmailDiff(t *testing.T) {
},
},
Smtp: &smtp{
Enabled: cast.Ptr(true),
Enabled: true,
Host: "smtp.sendgrid.net",
Port: 587,
User: "apikey",
Expand Down Expand Up @@ -699,7 +699,7 @@ func TestEmailDiff(t *testing.T) {
"reauthentication": {},
},
Smtp: &smtp{
Enabled: cast.Ptr(false),
Enabled: false,
Host: "smtp.sendgrid.net",
Port: 587,
User: "apikey",
Expand Down
Loading
Loading