2026-05-20 07:01:08 +00:00
|
|
|
package config
|
|
|
|
|
|
|
|
|
|
// Config is member module settings (embedded in gateway root config).
|
2026-05-20 07:14:44 +00:00
|
|
|
type Config struct {
|
2026-05-20 13:03:59 +00:00
|
|
|
OTP OTPConfig `json:",optional"`
|
|
|
|
|
TOTP TOTPConfig `json:",optional"`
|
2026-05-20 07:01:08 +00:00
|
|
|
}
|
|
|
|
|
|
2026-05-20 13:03:59 +00:00
|
|
|
// OTPConfig governs the business OTP primitive (email/phone verification).
|
2026-05-20 07:01:08 +00:00
|
|
|
type OTPConfig struct {
|
|
|
|
|
Length int `json:",optional"`
|
|
|
|
|
TTLSeconds int `json:",optional"`
|
|
|
|
|
MaxAttempts int `json:",optional"`
|
|
|
|
|
ResendCooldownSeconds int `json:",optional"`
|
|
|
|
|
DailyVerifyLimit int `json:",optional"`
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-20 13:03:59 +00:00
|
|
|
// TOTPConfig governs business-tier RFC 6238 TOTP (step-up MFA).
|
|
|
|
|
//
|
|
|
|
|
// SecretKEK is the 32-byte master key used to AES-256-GCM encrypt member
|
|
|
|
|
// secrets at rest. Accepts hex (64 chars) or base64. Empty disables the
|
|
|
|
|
// TOTPUseCase wiring (factory returns an error).
|
|
|
|
|
type TOTPConfig struct {
|
|
|
|
|
Issuer string `json:",optional"`
|
|
|
|
|
Algorithm string `json:",optional"`
|
|
|
|
|
Digits int `json:",optional"`
|
|
|
|
|
PeriodSeconds int `json:",optional"`
|
|
|
|
|
Window int `json:",optional"`
|
|
|
|
|
BackupCodeCount int `json:",optional"`
|
|
|
|
|
BackupCodeLength int `json:",optional"`
|
|
|
|
|
EnrollTTLSeconds int `json:",optional"`
|
|
|
|
|
ReplayTTLSeconds int `json:",optional"`
|
|
|
|
|
SecretKEK string `json:",optional,env=TOTP_SECRET_KEK"`
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-20 07:01:08 +00:00
|
|
|
// Defaults returns zero-value-safe defaults.
|
|
|
|
|
func (c Config) Defaults() Config {
|
|
|
|
|
if c.OTP.Length <= 0 {
|
|
|
|
|
c.OTP.Length = 6
|
|
|
|
|
}
|
|
|
|
|
if c.OTP.TTLSeconds <= 0 {
|
|
|
|
|
c.OTP.TTLSeconds = 300
|
|
|
|
|
}
|
|
|
|
|
if c.OTP.MaxAttempts <= 0 {
|
|
|
|
|
c.OTP.MaxAttempts = 5
|
|
|
|
|
}
|
|
|
|
|
if c.OTP.ResendCooldownSeconds <= 0 {
|
|
|
|
|
c.OTP.ResendCooldownSeconds = 60
|
|
|
|
|
}
|
|
|
|
|
if c.OTP.DailyVerifyLimit <= 0 {
|
|
|
|
|
c.OTP.DailyVerifyLimit = 10
|
|
|
|
|
}
|
2026-05-20 13:03:59 +00:00
|
|
|
if c.TOTP.Issuer == "" {
|
|
|
|
|
c.TOTP.Issuer = "CloudEP"
|
|
|
|
|
}
|
|
|
|
|
if c.TOTP.Algorithm == "" {
|
|
|
|
|
c.TOTP.Algorithm = "SHA1"
|
|
|
|
|
}
|
|
|
|
|
if c.TOTP.Digits <= 0 {
|
|
|
|
|
c.TOTP.Digits = 6
|
|
|
|
|
}
|
|
|
|
|
if c.TOTP.PeriodSeconds <= 0 {
|
|
|
|
|
c.TOTP.PeriodSeconds = 30
|
|
|
|
|
}
|
|
|
|
|
if c.TOTP.Window < 0 {
|
|
|
|
|
c.TOTP.Window = 0
|
|
|
|
|
}
|
|
|
|
|
if c.TOTP.Window == 0 {
|
|
|
|
|
c.TOTP.Window = 1
|
|
|
|
|
}
|
|
|
|
|
if c.TOTP.BackupCodeCount <= 0 {
|
|
|
|
|
c.TOTP.BackupCodeCount = 10
|
|
|
|
|
}
|
|
|
|
|
if c.TOTP.BackupCodeLength <= 0 {
|
|
|
|
|
c.TOTP.BackupCodeLength = 12
|
|
|
|
|
}
|
|
|
|
|
if c.TOTP.EnrollTTLSeconds <= 0 {
|
|
|
|
|
c.TOTP.EnrollTTLSeconds = 600
|
|
|
|
|
}
|
|
|
|
|
if c.TOTP.ReplayTTLSeconds <= 0 {
|
|
|
|
|
c.TOTP.ReplayTTLSeconds = 90
|
|
|
|
|
}
|
2026-05-20 07:01:08 +00:00
|
|
|
return c
|
|
|
|
|
}
|