Files
uPortal2/backend/internal/rest/config.go
T

171 lines
4.2 KiB
Go
Raw Normal View History

2026-10-21 13:17:44 +03:00
package rest
import (
"log/slog"
"net/http"
"os"
"strconv"
"strings"
"time"
"goAuth/internal/env"
)
const (
// Binds to loopback by default so a local run is not exposed on the
// network. Override with the ADDR env var (use :8080 to listen on all
// interfaces, e.g. inside a container).
DefaultAddr = "localhost:8080"
DefaultDatabasePath = "gochat.db"
DefaultSessionCookie = "session"
DefaultCsrfCookie = "csrf"
DefaultShortSession = 24 * time.Hour
DefaultLongSession = 30 * 24 * time.Hour
DefaultTokenSize = 32
2026-10-21 20:13:27 +03:00
// DefaultCleanupInterval is how often expired sessions, spent/expired
// invites and never-activated users are purged in the background. A
// non-positive value disables the background cleanup.
DefaultCleanupInterval = 1 * time.Hour
2026-10-21 13:17:44 +03:00
)
type Config struct {
Addr string
DatabasePath string
// PublicBaseURL is the externally reachable base URL of this service, used
// to build absolute links (e.g. the avatar URL embedded in Jitsi JWTs).
// Leave empty to fall back to the request's Host.
PublicBaseURL string
2026-10-21 20:13:27 +03:00
// CleanupInterval controls the background maintenance loop that purges
// expired sessions, spent/expired invites and never-activated users.
// Non-positive disables it.
CleanupInterval time.Duration
Jitsi JitsiConfig
Cors CorsConfig
Sessions SessionConfig
Cookies CookieConfig
2026-10-21 13:17:44 +03:00
}
type JitsiConfig struct {
Secret string
AppId string
AppName string
Domain string
}
type CorsConfig struct {
Origins []string
Methods []string
Headers []string
}
type SessionConfig struct {
ShortDuration time.Duration
LongDuration time.Duration
TokenSize int
}
type CookieConfig struct {
SessionName string
CsrfName string
Secure bool
}
func DefaultConfig() Config {
return Config{
2026-10-21 20:13:27 +03:00
Addr: DefaultAddr,
DatabasePath: DefaultDatabasePath,
CleanupInterval: DefaultCleanupInterval,
2026-10-21 13:17:44 +03:00
Jitsi: JitsiConfig{
Domain: "meet.jit.si",
},
Cors: CorsConfig{
Origins: []string{"http://localhost:3000", "http://localhost:5173"},
Methods: []string{
http.MethodGet,
http.MethodPost,
http.MethodPut,
http.MethodPatch,
http.MethodDelete,
http.MethodOptions,
},
Headers: []string{"Content-Type", "X-CSRF-Token"},
},
Sessions: SessionConfig{
ShortDuration: DefaultShortSession,
LongDuration: DefaultLongSession,
TokenSize: DefaultTokenSize,
},
Cookies: CookieConfig{
SessionName: DefaultSessionCookie,
CsrfName: DefaultCsrfCookie,
Secure: true,
},
}
}
func LoadConfig() Config {
if err := env.LoadEnvDefault(); err != nil {
slog.Debug("env file not loaded", slog.String("op", "rest.LoadConfig"), slog.Any("error", err))
}
return ConfigFromEnvironment()
}
func ConfigFromEnvironment() Config {
cfg := DefaultConfig()
if v := os.Getenv("ADDR"); v != "" {
cfg.Addr = v
}
if v := os.Getenv("DB_PATH"); v != "" {
cfg.DatabasePath = v
}
if v := os.Getenv("PUBLIC_BASE_URL"); v != "" {
cfg.PublicBaseURL = strings.TrimRight(v, "/")
}
if v := os.Getenv("CORS_ORIGINS"); v != "" {
cfg.Cors.Origins = splitAndTrim(v)
}
if v := os.Getenv("COOKIE_SECURE"); v != "" {
if parsed, err := strconv.ParseBool(v); err == nil {
cfg.Cookies.Secure = parsed
}
}
if v := os.Getenv("SESSION_SHORT_DURATION"); v != "" {
if parsed, err := time.ParseDuration(v); err == nil {
cfg.Sessions.ShortDuration = parsed
}
}
if v := os.Getenv("SESSION_LONG_DURATION"); v != "" {
if parsed, err := time.ParseDuration(v); err == nil {
cfg.Sessions.LongDuration = parsed
}
}
2026-10-21 20:13:27 +03:00
if v := os.Getenv("CLEANUP_INTERVAL"); v != "" {
if parsed, err := time.ParseDuration(v); err == nil {
cfg.CleanupInterval = parsed
}
}
2026-10-21 13:17:44 +03:00
cfg.Jitsi.Secret = os.Getenv("JITSI_SECRET")
cfg.Jitsi.AppId = os.Getenv("JITSI_APP_ID")
cfg.Jitsi.AppName = os.Getenv("JITSI_APP_NAME")
if v := os.Getenv("JITSI_DOMAIN"); v != "" {
cfg.Jitsi.Domain = v
}
return cfg
}
func splitAndTrim(value string) []string {
parts := strings.Split(value, ",")
result := make([]string, 0, len(parts))
for _, part := range parts {
if trimmed := strings.TrimSpace(part); trimmed != "" {
result = append(result, trimmed)
}
}
return result
}