backend barebone done, big chunk of work done
This commit is contained in:
@@ -20,6 +20,10 @@ type Config struct {
|
||||
// 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
|
||||
}
|
||||
|
||||
// Load reads configuration from the environment, falling back to
|
||||
@@ -29,6 +33,8 @@ func Load() (*Config, error) {
|
||||
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"),
|
||||
}
|
||||
|
||||
for _, origin := range strings.Split(fromEnv("MESSENGER_ALLOWED_ORIGINS", ""), ",") {
|
||||
@@ -43,6 +49,10 @@ func Load() (*Config, error) {
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ func TestLoadFromEnv(t *testing.T) {
|
||||
t.Setenv("MESSENGER_HTTP_ADDR", ":9000")
|
||||
t.Setenv("MESSENGER_ENV", "production")
|
||||
t.Setenv("MESSENGER_ALLOWED_ORIGINS", "https://a.example, https://b.example")
|
||||
t.Setenv("MESSENGER_JWT_SECRET", "prod-secret-at-least-32-chars-long!!")
|
||||
|
||||
cfg, err := Load()
|
||||
if err != nil {
|
||||
@@ -38,6 +39,9 @@ func TestLoadFromEnv(t *testing.T) {
|
||||
if len(cfg.AllowedOrigins) != 2 || cfg.AllowedOrigins[1] != "https://b.example" {
|
||||
t.Errorf("AllowedOrigins = %v, want [https://a.example https://b.example]", cfg.AllowedOrigins)
|
||||
}
|
||||
if cfg.DatabaseURL == "" {
|
||||
t.Error("DatabaseURL = empty, want default DSN")
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadInvalidEnv(t *testing.T) {
|
||||
@@ -47,3 +51,12 @@ func TestLoadInvalidEnv(t *testing.T) {
|
||||
t.Fatal("Load() error = nil, want validation error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadRequiresJWTSecretInProduction(t *testing.T) {
|
||||
t.Setenv("MESSENGER_ENV", "production")
|
||||
t.Setenv("MESSENGER_JWT_SECRET", "")
|
||||
|
||||
if _, err := Load(); err == nil {
|
||||
t.Fatal("Load() error = nil, want missing JWT secret error")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user