117 lines
3.3 KiB
Go
117 lines
3.3 KiB
Go
package middleware
|
|
|
|
import (
|
|
"os"
|
|
"strings"
|
|
|
|
"git.sendico.io/tech/sxchnge/bff/pkg/merrors"
|
|
)
|
|
|
|
type CORSSettings struct {
|
|
MaxAge int `yaml:"max_age"`
|
|
AllowedOrigins []string `yaml:"allowed_origins"`
|
|
AllowedMethods []string `yaml:"allowed_methods"`
|
|
AllowedHeaders []string `yaml:"allowed_headers"`
|
|
ExposedHeaders []string `yaml:"exposed_headers"`
|
|
AllowCredentials bool `yaml:"allow_credentials"`
|
|
}
|
|
|
|
func (c CORSSettings) Validate() error {
|
|
if !c.AllowCredentials {
|
|
return nil
|
|
}
|
|
if len(c.AllowedOrigins) == 0 {
|
|
return merrors.InvalidArgument("credentialed CORS requires explicit allowed origins", "middleware.CORS.allowed_origins")
|
|
}
|
|
for _, origin := range c.AllowedOrigins {
|
|
if strings.TrimSpace(origin) == "*" {
|
|
return merrors.InvalidArgument("credentialed CORS does not allow wildcard origins", "middleware.CORS.allowed_origins")
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
type Signature struct {
|
|
PublicKey any
|
|
PrivateKey []byte
|
|
Algorithm string
|
|
}
|
|
|
|
type SignatureConfig struct {
|
|
PublicKeyEnv string `yaml:"public_key_env,omitempty"`
|
|
PrivateKeyEnv string `yaml:"secret_key_env"`
|
|
Algorithm string `yaml:"algorithm"`
|
|
}
|
|
|
|
type TokenExpiration struct {
|
|
Account int `yaml:"account"`
|
|
Refresh int `yaml:"refresh"`
|
|
}
|
|
|
|
type TokenConfig struct {
|
|
Expiration TokenExpiration `yaml:"expiration_hours"`
|
|
Length int `yaml:"length"`
|
|
}
|
|
|
|
const MaxAccessTokenTTLHours = 1
|
|
|
|
func (c TokenConfig) Validate() error {
|
|
if c.Expiration.Account <= 0 || c.Expiration.Account > MaxAccessTokenTTLHours {
|
|
return merrors.InvalidArgument("access token expiration must be between 1 and 1 hour", "middleware.token.expiration_hours.account")
|
|
}
|
|
if c.Expiration.Refresh <= c.Expiration.Account {
|
|
return merrors.InvalidArgument("refresh token expiration must exceed access token expiration", "middleware.token.expiration_hours.refresh")
|
|
}
|
|
if c.Length < 32 {
|
|
return merrors.InvalidArgument("refresh token length must be at least 32 bytes", "middleware.token.length")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
type WebSocketConfig struct {
|
|
EndpointEnv string `yaml:"endpoint_env"`
|
|
Timeout int `yaml:"timeout"`
|
|
}
|
|
|
|
type PasswordChecks struct {
|
|
Digit bool `yaml:"digit"`
|
|
Upper bool `yaml:"upper"`
|
|
Lower bool `yaml:"lower"`
|
|
Special bool `yaml:"special"`
|
|
MinLength int `yaml:"min_length"`
|
|
}
|
|
|
|
type PasswordConfig struct {
|
|
TokenLength int `yaml:"token_length"`
|
|
Check PasswordChecks `yaml:"check"`
|
|
}
|
|
|
|
type Config struct {
|
|
DomainEnv string `yaml:"domain_env"`
|
|
EndPointEnv string `yaml:"api_endpoint_env"`
|
|
APIProtocolEnv string `yaml:"api_protocol_env"`
|
|
Signature SignatureConfig `yaml:"signature"`
|
|
CORS CORSSettings `yaml:"CORS"`
|
|
WebSocket WebSocketConfig `yaml:"websocket"`
|
|
Token TokenConfig `yaml:"token"`
|
|
Password PasswordConfig `yaml:"password"`
|
|
LoginRateLimits *LoginRateLimitsConfig `yaml:"login_rate_limits"`
|
|
}
|
|
|
|
type MapClaims = map[string]any
|
|
|
|
func getKey(osEnv string) any {
|
|
if len(osEnv) == 0 {
|
|
return nil
|
|
}
|
|
return []byte(os.Getenv(osEnv))
|
|
}
|
|
|
|
func SignatureConf(conf *Config) Signature {
|
|
return Signature{
|
|
PrivateKey: []byte(os.Getenv(conf.Signature.PrivateKeyEnv)),
|
|
PublicKey: getKey(conf.Signature.PublicKeyEnv),
|
|
Algorithm: conf.Signature.Algorithm,
|
|
}
|
|
}
|