mirror of
https://github.com/teamhanko/hanko.git
synced 2025-10-27 22:27:23 +08:00
Merge branch 'main' into fix/1027-improve-passkey-naming
This commit is contained in:
@ -11,6 +11,7 @@ import (
|
|||||||
"github.com/knadh/koanf/providers/file"
|
"github.com/knadh/koanf/providers/file"
|
||||||
"github.com/teamhanko/hanko/backend/ee/saml/config"
|
"github.com/teamhanko/hanko/backend/ee/saml/config"
|
||||||
"golang.org/x/exp/slices"
|
"golang.org/x/exp/slices"
|
||||||
|
zeroLogger "github.com/rs/zerolog/log"
|
||||||
"log"
|
"log"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
@ -20,6 +21,7 @@ import (
|
|||||||
type Config struct {
|
type Config struct {
|
||||||
Server Server `yaml:"server" json:"server,omitempty" koanf:"server"`
|
Server Server `yaml:"server" json:"server,omitempty" koanf:"server"`
|
||||||
Webauthn WebauthnSettings `yaml:"webauthn" json:"webauthn,omitempty" koanf:"webauthn"`
|
Webauthn WebauthnSettings `yaml:"webauthn" json:"webauthn,omitempty" koanf:"webauthn"`
|
||||||
|
Smtp SMTP `yaml:"smtp" json:"smtp,omitempty" koanf:"smtp"`
|
||||||
Passcode Passcode `yaml:"passcode" json:"passcode" koanf:"passcode"`
|
Passcode Passcode `yaml:"passcode" json:"passcode" koanf:"passcode"`
|
||||||
Password Password `yaml:"password" json:"password,omitempty" koanf:"password"`
|
Password Password `yaml:"password" json:"password,omitempty" koanf:"password"`
|
||||||
Database Database `yaml:"database" json:"database" koanf:"database"`
|
Database Database `yaml:"database" json:"database" koanf:"database"`
|
||||||
@ -83,6 +85,8 @@ func Load(cfgFile *string) (*Config, error) {
|
|||||||
return nil, fmt.Errorf("failed to post process config: %w", err)
|
return nil, fmt.Errorf("failed to post process config: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c.arrangeSmtpSettings()
|
||||||
|
|
||||||
if err = c.Validate(); err != nil {
|
if err = c.Validate(); err != nil {
|
||||||
return nil, fmt.Errorf("failed to validate config: %s", err)
|
return nil, fmt.Errorf("failed to validate config: %s", err)
|
||||||
}
|
}
|
||||||
@ -109,15 +113,18 @@ func DefaultConfig() *Config {
|
|||||||
UserVerification: "preferred",
|
UserVerification: "preferred",
|
||||||
Timeout: 60000,
|
Timeout: 60000,
|
||||||
},
|
},
|
||||||
Passcode: Passcode{
|
|
||||||
Smtp: SMTP{
|
Smtp: SMTP{
|
||||||
Port: "465",
|
Port: "465",
|
||||||
},
|
},
|
||||||
|
Passcode: Passcode{
|
||||||
TTL: 300,
|
TTL: 300,
|
||||||
Email: Email{
|
Email: Email{
|
||||||
FromAddress: "passcode@hanko.io",
|
FromAddress: "passcode@hanko.io",
|
||||||
FromName: "Hanko",
|
FromName: "Hanko",
|
||||||
},
|
},
|
||||||
|
Smtp: SMTP{
|
||||||
|
Port: "465",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Password: Password{
|
Password: Password{
|
||||||
MinPasswordLength: 8,
|
MinPasswordLength: 8,
|
||||||
@ -175,6 +182,10 @@ func (c *Config) Validate() error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to validate webauthn settings: %w", err)
|
return fmt.Errorf("failed to validate webauthn settings: %w", err)
|
||||||
}
|
}
|
||||||
|
err = c.Smtp.Validate()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to validate smtp settings: %w", err)
|
||||||
|
}
|
||||||
err = c.Passcode.Validate()
|
err = c.Passcode.Validate()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to validate passcode settings: %w", err)
|
return fmt.Errorf("failed to validate passcode settings: %w", err)
|
||||||
@ -360,8 +371,9 @@ func (e *Email) Validate() error {
|
|||||||
|
|
||||||
type Passcode struct {
|
type Passcode struct {
|
||||||
Email Email `yaml:"email" json:"email,omitempty" koanf:"email"`
|
Email Email `yaml:"email" json:"email,omitempty" koanf:"email"`
|
||||||
Smtp SMTP `yaml:"smtp" json:"smtp" koanf:"smtp"`
|
|
||||||
TTL int `yaml:"ttl" json:"ttl,omitempty" koanf:"ttl" jsonschema:"default=300"`
|
TTL int `yaml:"ttl" json:"ttl,omitempty" koanf:"ttl" jsonschema:"default=300"`
|
||||||
|
//Deprecated: Use root level Smtp instead
|
||||||
|
Smtp SMTP `yaml:"smtp" json:"smtp,omitempty" koanf:"smtp,omitempty" required:"false" envconfig:"smtp,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Passcode) Validate() error {
|
func (p *Passcode) Validate() error {
|
||||||
@ -369,10 +381,6 @@ func (p *Passcode) Validate() error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to validate email settings: %w", err)
|
return fmt.Errorf("failed to validate email settings: %w", err)
|
||||||
}
|
}
|
||||||
err = p.Smtp.Validate()
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to validate smtp settings: %w", err)
|
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -651,6 +659,17 @@ func (c *Config) PostProcess() error {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Config) arrangeSmtpSettings() {
|
||||||
|
if c.Passcode.Smtp.Validate() == nil {
|
||||||
|
if c.Smtp.Validate() == nil {
|
||||||
|
zeroLogger.Warn().Msg("Both root smtp and passcode.smtp are set. Using smtp settings from root configuration")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Smtp = c.Passcode.Smtp
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type LoggerConfig struct {
|
type LoggerConfig struct {
|
||||||
LogHealthAndMetrics bool `yaml:"log_health_and_metrics,omitempty" json:"log_health_and_metrics" koanf:"log_health_and_metrics" jsonschema:"default=true"`
|
LogHealthAndMetrics bool `yaml:"log_health_and_metrics,omitempty" json:"log_health_and_metrics" koanf:"log_health_and_metrics" jsonschema:"default=true"`
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,13 +4,13 @@ database:
|
|||||||
host: localhost
|
host: localhost
|
||||||
port: 5432
|
port: 5432
|
||||||
dialect: postgres
|
dialect: postgres
|
||||||
passcode:
|
|
||||||
email:
|
|
||||||
from_address: no-reply@hanko.io
|
|
||||||
smtp:
|
smtp:
|
||||||
host: smtp.example.com
|
host: smtp.example.com
|
||||||
user: example
|
user: example
|
||||||
password: example
|
password: example
|
||||||
|
passcode:
|
||||||
|
email:
|
||||||
|
from_address: no-reply@hanko.io
|
||||||
secrets:
|
secrets:
|
||||||
keys:
|
keys:
|
||||||
- abcedfghijklmnopqrstuvwxyz
|
- abcedfghijklmnopqrstuvwxyz
|
||||||
|
|||||||
@ -21,6 +21,11 @@ func TestDefaultConfigAccountParameters(t *testing.T) {
|
|||||||
assert.Equal(t, cfg.Account.AllowSignup, true)
|
assert.Equal(t, cfg.Account.AllowSignup, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDefaultConfigSmtpParameters(t *testing.T) {
|
||||||
|
cfg := DefaultConfig()
|
||||||
|
assert.Equal(t, cfg.Smtp.Port, "465")
|
||||||
|
}
|
||||||
|
|
||||||
func TestParseValidConfig(t *testing.T) {
|
func TestParseValidConfig(t *testing.T) {
|
||||||
configPath := "./config.yaml"
|
configPath := "./config.yaml"
|
||||||
cfg, err := Load(&configPath)
|
cfg, err := Load(&configPath)
|
||||||
@ -32,6 +37,28 @@ func TestParseValidConfig(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPasscodeSmtpSettingsCopiedToRootLevelSmtp(t *testing.T) {
|
||||||
|
configPath := "./passcode-smtp-config.yaml"
|
||||||
|
cfg, err := Load(&configPath)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
if err := cfg.Validate(); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.Equal(t, cfg.Smtp.Port, cfg.Passcode.Smtp.Port)
|
||||||
|
assert.Equal(t, cfg.Smtp.Host, cfg.Passcode.Smtp.Host)
|
||||||
|
assert.Equal(t, cfg.Smtp.Password, cfg.Passcode.Smtp.Password)
|
||||||
|
assert.Equal(t, cfg.Smtp.User, cfg.Passcode.Smtp.User)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRootSmtpPasscodeSmtpConflict(t *testing.T) {
|
||||||
|
configPath := "./root-passcode-smtp-config.yaml"
|
||||||
|
_, err := Load(&configPath)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
func TestMinimalConfigValidates(t *testing.T) {
|
func TestMinimalConfigValidates(t *testing.T) {
|
||||||
configPath := "./minimal-config.yaml"
|
configPath := "./minimal-config.yaml"
|
||||||
cfg, err := Load(&configPath)
|
cfg, err := Load(&configPath)
|
||||||
@ -76,7 +103,7 @@ func TestRateLimiterConfig(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestEnvironmentVariables(t *testing.T) {
|
func TestEnvironmentVariables(t *testing.T) {
|
||||||
err := os.Setenv("PASSCODE_SMTP_HOST", "valueFromEnvVars")
|
err := os.Setenv("SMTP_HOST", "valueFromEnvVars")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
err = os.Setenv("WEBAUTHN_RELYING_PARTY_ORIGINS", "https://hanko.io,https://auth.hanko.io")
|
err = os.Setenv("WEBAUTHN_RELYING_PARTY_ORIGINS", "https://hanko.io,https://auth.hanko.io")
|
||||||
@ -86,6 +113,6 @@ func TestEnvironmentVariables(t *testing.T) {
|
|||||||
cfg, err := Load(&configPath)
|
cfg, err := Load(&configPath)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
assert.Equal(t, "valueFromEnvVars", cfg.Passcode.Smtp.Host)
|
assert.Equal(t, "valueFromEnvVars", cfg.Smtp.Host)
|
||||||
assert.True(t, reflect.DeepEqual([]string{"https://hanko.io", "https://auth.hanko.io"}, cfg.Webauthn.RelyingParty.Origins))
|
assert.True(t, reflect.DeepEqual([]string{"https://hanko.io", "https://auth.hanko.io"}, cfg.Webauthn.RelyingParty.Origins))
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
passcode:
|
|
||||||
smtp:
|
smtp:
|
||||||
host: smtp.example.com
|
host: smtp.example.com
|
||||||
user: example
|
user: example
|
||||||
|
|||||||
18
backend/config/passcode-smtp-config.yaml
Normal file
18
backend/config/passcode-smtp-config.yaml
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
database:
|
||||||
|
user: hanko
|
||||||
|
password: hanko
|
||||||
|
host: localhost
|
||||||
|
port: 5432
|
||||||
|
dialect: postgres
|
||||||
|
passcode:
|
||||||
|
email:
|
||||||
|
from_address: no-reply@hanko.io
|
||||||
|
smtp:
|
||||||
|
host: smtp.example.com
|
||||||
|
user: example
|
||||||
|
password: example
|
||||||
|
secrets:
|
||||||
|
keys:
|
||||||
|
- abcedfghijklmnopqrstuvwxyz
|
||||||
|
service:
|
||||||
|
name: Hanko Authentication Service
|
||||||
22
backend/config/root-passcode-smtp-config.yaml
Normal file
22
backend/config/root-passcode-smtp-config.yaml
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
database:
|
||||||
|
user: hanko
|
||||||
|
password: hanko
|
||||||
|
host: localhost
|
||||||
|
port: 5432
|
||||||
|
dialect: postgres
|
||||||
|
smtp:
|
||||||
|
host: smtp1.example.com
|
||||||
|
user: example1
|
||||||
|
password: example1
|
||||||
|
passcode:
|
||||||
|
email:
|
||||||
|
from_address: no-reply@hanko.io
|
||||||
|
smtp:
|
||||||
|
host: smtp2.example.com
|
||||||
|
user: example2
|
||||||
|
password: example2
|
||||||
|
secrets:
|
||||||
|
keys:
|
||||||
|
- abcedfghijklmnopqrstuvwxyz
|
||||||
|
service:
|
||||||
|
name: Hanko Authentication Service
|
||||||
@ -38,8 +38,8 @@ func (s *passcodeSuite) TestPasscodeHandler_Init() {
|
|||||||
|
|
||||||
cfg := func() *config.Config {
|
cfg := func() *config.Config {
|
||||||
cfg := &test.DefaultConfig
|
cfg := &test.DefaultConfig
|
||||||
cfg.Passcode.Smtp.Host = "localhost"
|
cfg.Smtp.Host = s.EmailServer.SmtpHost
|
||||||
cfg.Passcode.Smtp.Port = s.EmailServer.SmtpPort
|
cfg.Smtp.Port = s.EmailServer.SmtpPort
|
||||||
return cfg
|
return cfg
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -70,7 +70,7 @@ func NewPublicRouter(cfg *config.Config, persister persistence.Persister, promet
|
|||||||
|
|
||||||
sessionMiddleware := hankoMiddleware.Session(cfg, sessionManager)
|
sessionMiddleware := hankoMiddleware.Session(cfg, sessionManager)
|
||||||
|
|
||||||
mailer, err := mail.NewMailer(cfg.Passcode.Smtp)
|
mailer, err := mail.NewMailer(cfg.Smtp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Errorf("failed to create mailer: %w", err))
|
panic(fmt.Errorf("failed to create mailer: %w", err))
|
||||||
}
|
}
|
||||||
|
|||||||
@ -343,10 +343,10 @@ var defaultConfig = config.Config{
|
|||||||
Secrets: config.Secrets{
|
Secrets: config.Secrets{
|
||||||
Keys: []string{"abcdefghijklmnop"},
|
Keys: []string{"abcdefghijklmnop"},
|
||||||
},
|
},
|
||||||
Passcode: config.Passcode{Smtp: config.SMTP{
|
Smtp: config.SMTP{
|
||||||
Host: "localhost",
|
Host: "localhost",
|
||||||
Port: "2500",
|
Port: "2500",
|
||||||
}},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
type sessionManager struct {
|
type sessionManager struct {
|
||||||
|
|||||||
@ -16,11 +16,11 @@ var DefaultConfig = config.Config{
|
|||||||
Secrets: config.Secrets{
|
Secrets: config.Secrets{
|
||||||
Keys: []string{"abcdefghijklmnop"},
|
Keys: []string{"abcdefghijklmnop"},
|
||||||
},
|
},
|
||||||
Passcode: config.Passcode{
|
|
||||||
Smtp: config.SMTP{
|
Smtp: config.SMTP{
|
||||||
Host: "localhost",
|
Host: "localhost",
|
||||||
Port: "2500",
|
Port: "2500",
|
||||||
},
|
},
|
||||||
|
Passcode: config.Passcode{
|
||||||
Email: config.Email{
|
Email: config.Email{
|
||||||
FromAddress: "test@hanko.io",
|
FromAddress: "test@hanko.io",
|
||||||
FromName: "Hanko Test",
|
FromName: "Hanko Test",
|
||||||
|
|||||||
@ -18,6 +18,7 @@ type TestMailslurper struct {
|
|||||||
pool *dockertest.Pool
|
pool *dockertest.Pool
|
||||||
resource *dockertest.Resource
|
resource *dockertest.Resource
|
||||||
httpUrl string
|
httpUrl string
|
||||||
|
SmtpHost string
|
||||||
SmtpPort string
|
SmtpPort string
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,6 +75,7 @@ func StartMailslurper() (*TestMailslurper, error) {
|
|||||||
pool: pool,
|
pool: pool,
|
||||||
resource: resource,
|
resource: resource,
|
||||||
httpUrl: dsn,
|
httpUrl: dsn,
|
||||||
|
SmtpHost: "localhost",
|
||||||
SmtpPort: smtpPort,
|
SmtpPort: smtpPort,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,12 +4,12 @@ database:
|
|||||||
host: postgresd
|
host: postgresd
|
||||||
port: 5432
|
port: 5432
|
||||||
dialect: postgres
|
dialect: postgres
|
||||||
passcode:
|
|
||||||
email:
|
|
||||||
from_address: no-reply@hanko.io
|
|
||||||
smtp:
|
smtp:
|
||||||
host: "mailslurper"
|
host: "mailslurper"
|
||||||
port: "2500"
|
port: "2500"
|
||||||
|
passcode:
|
||||||
|
email:
|
||||||
|
from_address: no-reply@hanko.io
|
||||||
secrets:
|
secrets:
|
||||||
keys:
|
keys:
|
||||||
- abcedfghijklmnopqrstuvwxyz
|
- abcedfghijklmnopqrstuvwxyz
|
||||||
|
|||||||
@ -4,12 +4,12 @@ database:
|
|||||||
host: postgresd
|
host: postgresd
|
||||||
port: 5432
|
port: 5432
|
||||||
dialect: postgres
|
dialect: postgres
|
||||||
passcode:
|
|
||||||
email:
|
|
||||||
from_address: no-reply@hanko.io
|
|
||||||
smtp:
|
smtp:
|
||||||
host: "mailslurper"
|
host: "mailslurper"
|
||||||
port: "2500"
|
port: "2500"
|
||||||
|
passcode:
|
||||||
|
email:
|
||||||
|
from_address: no-reply@hanko.io
|
||||||
secrets:
|
secrets:
|
||||||
keys:
|
keys:
|
||||||
- abcedfghijklmnopqrstuvwxyz
|
- abcedfghijklmnopqrstuvwxyz
|
||||||
|
|||||||
@ -4,12 +4,12 @@ database:
|
|||||||
host: postgresd
|
host: postgresd
|
||||||
port: 5432
|
port: 5432
|
||||||
dialect: postgres
|
dialect: postgres
|
||||||
passcode:
|
|
||||||
email:
|
|
||||||
from_address: no-reply@hanko.io
|
|
||||||
smtp:
|
smtp:
|
||||||
host: "mailslurper"
|
host: "mailslurper"
|
||||||
port: "2500"
|
port: "2500"
|
||||||
|
passcode:
|
||||||
|
email:
|
||||||
|
from_address: no-reply@hanko.io
|
||||||
secrets:
|
secrets:
|
||||||
keys:
|
keys:
|
||||||
- abcedfghijklmnopqrstuvwxyz
|
- abcedfghijklmnopqrstuvwxyz
|
||||||
|
|||||||
@ -4,12 +4,12 @@ database:
|
|||||||
host: postgres
|
host: postgres
|
||||||
port: 5432
|
port: 5432
|
||||||
dialect: postgres
|
dialect: postgres
|
||||||
passcode:
|
|
||||||
email:
|
|
||||||
from_address: no-reply@hanko.io
|
|
||||||
smtp:
|
smtp:
|
||||||
host: "mailhog"
|
host: "mailhog"
|
||||||
port: "2500"
|
port: "2500"
|
||||||
|
passcode:
|
||||||
|
email:
|
||||||
|
from_address: no-reply@hanko.io
|
||||||
secrets:
|
secrets:
|
||||||
keys:
|
keys:
|
||||||
- abcedfghijklmnopqrstuvwxyz
|
- abcedfghijklmnopqrstuvwxyz
|
||||||
|
|||||||
@ -1 +1 @@
|
|||||||
v16.15.1
|
v18.6.0
|
||||||
|
|||||||
Reference in New Issue
Block a user