Files
Messenger/server/internal/platform/config/config.go
T
vantablackTea 9d03ea4c51
CI / Go (build + vet + test) (push) Canceled after 0s
CI / Web (build + lint) (push) Canceled after 0s
big update: added reactions, groups, media share
2026-09-27 21:59:48 +03:00

70 lines
2.2 KiB
Go

// Package config loads the server configuration from environment
// variables with sane defaults for local development.
package config
import (
"fmt"
"os"
"strings"
)
// Config holds all runtime configuration for the API server.
type Config struct {
// HTTPAddr is the listen address, e.g. ":8080".
HTTPAddr string
// StaticDir points to the built frontend (React/Vite dist).
// Empty disables static file serving.
StaticDir string
// Environment is "development", "staging" or "production".
Environment string
// AllowedOrigins is a comma-separated list of CORS origins
// allowed to call the API from a browser.
AllowedOrigins []string
// DatabaseURL is the PostgreSQL DSN.
DatabaseURL string
// JWTSecret signs access tokens. Must be set in production.
JWTSecret string
// MediaDir is the local disk location for uploaded attachments.
MediaDir string
}
// Load reads configuration from the environment, falling back to
// development-friendly defaults. Unknown values are validated.
func Load() (*Config, error) {
cfg := &Config{
HTTPAddr: fromEnv("MESSENGER_HTTP_ADDR", ":8080"),
StaticDir: os.Getenv("MESSENGER_STATIC_DIR"),
Environment: fromEnv("MESSENGER_ENV", "development"),
DatabaseURL: fromEnv("MESSENGER_DATABASE_URL", "postgres://messenger:messenger@localhost:5432/messenger?sslmode=disable"),
JWTSecret: fromEnv("MESSENGER_JWT_SECRET", "dev-secret-change-me"),
MediaDir: fromEnv("MESSENGER_MEDIA_DIR", "./media"),
}
for _, origin := range strings.Split(fromEnv("MESSENGER_ALLOWED_ORIGINS", ""), ",") {
if origin = strings.TrimSpace(origin); origin != "" {
cfg.AllowedOrigins = append(cfg.AllowedOrigins, origin)
}
}
switch cfg.Environment {
case "development", "staging", "production":
default:
return nil, fmt.Errorf("MESSENGER_ENV must be one of development|staging|production, got %q", cfg.Environment)
}
if cfg.Environment == "production" && cfg.JWTSecret == "dev-secret-change-me" {
return nil, fmt.Errorf("MESSENGER_JWT_SECRET must be set in production")
}
return cfg, nil
}
// fromEnv returns the value of the environment variable name, or
// fallback if the variable is unset or empty.
func fromEnv(name, fallback string) string {
if v := os.Getenv(name); v != "" {
return v
}
return fallback
}