- Add Go modules with required dependencies (Gin, UUID, JWT, etc.) - Implement main web server with landing page endpoint - Add comprehensive API endpoints for health and status - Include proper error handling and request validation - Set up CORS middleware and security headers
239 lines
5.4 KiB
Go
239 lines
5.4 KiB
Go
package config
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/joho/godotenv"
|
|
)
|
|
|
|
type Config struct {
|
|
App AppConfig
|
|
Database DatabaseConfig
|
|
JWT JWTConfig
|
|
Stripe StripeConfig
|
|
OVH OVHConfig
|
|
Cloudron CloudronConfig
|
|
Dolibarr DolibarrConfig
|
|
Email EmailConfig
|
|
Redis RedisConfig
|
|
Logging LoggingConfig
|
|
Security SecurityConfig
|
|
}
|
|
|
|
type AppConfig struct {
|
|
Name string
|
|
Env string
|
|
Port string
|
|
Host string
|
|
}
|
|
|
|
type DatabaseConfig struct {
|
|
Host string
|
|
Port string
|
|
User string
|
|
Password string
|
|
DBName string
|
|
SSLMode string
|
|
}
|
|
|
|
type JWTConfig struct {
|
|
Secret string
|
|
Expiry time.Duration
|
|
}
|
|
|
|
type StripeConfig struct {
|
|
PublicKey string
|
|
SecretKey string
|
|
WebhookSecret string
|
|
PriceID string
|
|
}
|
|
|
|
type OVHConfig struct {
|
|
Endpoint string
|
|
ApplicationKey string
|
|
ApplicationSecret string
|
|
ConsumerKey string
|
|
}
|
|
|
|
type CloudronConfig struct {
|
|
APIVersion string
|
|
InstallTimeout time.Duration
|
|
}
|
|
|
|
type DolibarrConfig struct {
|
|
URL string
|
|
APIToken string
|
|
}
|
|
|
|
type EmailConfig struct {
|
|
SMTPHost string
|
|
SMTPPort string
|
|
SMTPUser string
|
|
SMTPPassword string
|
|
From string
|
|
}
|
|
|
|
type RedisConfig struct {
|
|
Host string
|
|
Port string
|
|
Password string
|
|
DB int
|
|
}
|
|
|
|
type LoggingConfig struct {
|
|
Level string
|
|
Format string
|
|
}
|
|
|
|
type SecurityConfig struct {
|
|
CORSOrigins []string
|
|
RateLimitRequests int
|
|
RateLimitWindow time.Duration
|
|
}
|
|
|
|
func Load() (*Config, error) {
|
|
// Load .env file if it exists
|
|
if err := godotenv.Load("configs/.env"); err != nil && !os.IsNotExist(err) {
|
|
return nil, fmt.Errorf("error loading .env file: %w", err)
|
|
}
|
|
|
|
config := &Config{
|
|
App: AppConfig{
|
|
Name: getEnv("APP_NAME", "YourDreamNameHere"),
|
|
Env: getEnv("APP_ENV", "development"),
|
|
Port: getEnv("APP_PORT", "8080"),
|
|
Host: getEnv("APP_HOST", "0.0.0.0"),
|
|
},
|
|
Database: DatabaseConfig{
|
|
Host: getEnv("DB_HOST", "localhost"),
|
|
Port: getEnv("DB_PORT", "5432"),
|
|
User: getEnv("DB_USER", "ydn_user"),
|
|
Password: getEnv("DB_PASSWORD", ""),
|
|
DBName: getEnv("DB_NAME", "ydn_db"),
|
|
SSLMode: getEnv("DB_SSLMODE", "disable"),
|
|
},
|
|
JWT: JWTConfig{
|
|
Secret: getEnv("JWT_SECRET", ""),
|
|
Expiry: getDurationEnv("JWT_EXPIRY", 24*time.Hour),
|
|
},
|
|
Stripe: StripeConfig{
|
|
PublicKey: getEnv("STRIPE_PUBLIC_KEY", ""),
|
|
SecretKey: getEnv("STRIPE_SECRET_KEY", ""),
|
|
WebhookSecret: getEnv("STRIPE_WEBHOOK_SECRET", ""),
|
|
PriceID: getEnv("STRIPE_PRICE_ID", ""),
|
|
},
|
|
OVH: OVHConfig{
|
|
Endpoint: getEnv("OVH_ENDPOINT", "ovh-eu"),
|
|
ApplicationKey: getEnv("OVH_APPLICATION_KEY", ""),
|
|
ApplicationSecret: getEnv("OVH_APPLICATION_SECRET", ""),
|
|
ConsumerKey: getEnv("OVH_CONSUMER_KEY", ""),
|
|
},
|
|
Cloudron: CloudronConfig{
|
|
APIVersion: getEnv("CLOUDRON_API_VERSION", "v1"),
|
|
InstallTimeout: getDurationEnv("CLOUDRON_INSTALL_TIMEOUT", 30*time.Minute),
|
|
},
|
|
Dolibarr: DolibarrConfig{
|
|
URL: getEnv("DOLIBARR_URL", ""),
|
|
APIToken: getEnv("DOLIBARR_API_TOKEN", ""),
|
|
},
|
|
Email: EmailConfig{
|
|
SMTPHost: getEnv("SMTP_HOST", ""),
|
|
SMTPPort: getEnv("SMTP_PORT", "587"),
|
|
SMTPUser: getEnv("SMTP_USER", ""),
|
|
SMTPPassword: getEnv("SMTP_PASSWORD", ""),
|
|
From: getEnv("SMTP_FROM", "noreply@yourdreamnamehere.com"),
|
|
},
|
|
Redis: RedisConfig{
|
|
Host: getEnv("REDIS_HOST", "localhost"),
|
|
Port: getEnv("REDIS_PORT", "6379"),
|
|
Password: getEnv("REDIS_PASSWORD", ""),
|
|
DB: getIntEnv("REDIS_DB", 0),
|
|
},
|
|
Logging: LoggingConfig{
|
|
Level: getEnv("LOG_LEVEL", "info"),
|
|
Format: getEnv("LOG_FORMAT", "json"),
|
|
},
|
|
Security: SecurityConfig{
|
|
CORSOrigins: strings.Split(getEnv("CORS_ORIGINS", "http://localhost:3000"), ","),
|
|
RateLimitRequests: getIntEnv("RATE_LIMIT_REQUESTS", 100),
|
|
RateLimitWindow: getDurationEnv("RATE_LIMIT_WINDOW", time.Minute),
|
|
},
|
|
}
|
|
|
|
// Validate required configuration
|
|
if err := config.validate(); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return config, nil
|
|
}
|
|
|
|
func (c *Config) validate() error {
|
|
if c.JWT.Secret == "" {
|
|
return fmt.Errorf("JWT_SECRET is required")
|
|
}
|
|
if c.Stripe.SecretKey == "" {
|
|
return fmt.Errorf("STRIPE_SECRET_KEY is required")
|
|
}
|
|
if c.Stripe.PriceID == "" {
|
|
return fmt.Errorf("STRIPE_PRICE_ID is required")
|
|
}
|
|
if c.OVH.ApplicationKey == "" {
|
|
return fmt.Errorf("OVH_APPLICATION_KEY is required")
|
|
}
|
|
if c.OVH.ApplicationSecret == "" {
|
|
return fmt.Errorf("OVH_APPLICATION_SECRET is required")
|
|
}
|
|
if c.OVH.ConsumerKey == "" {
|
|
return fmt.Errorf("OVH_CONSUMER_KEY is required")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func getEnv(key, defaultValue string) string {
|
|
if value := os.Getenv(key); value != "" {
|
|
return value
|
|
}
|
|
return defaultValue
|
|
}
|
|
|
|
func getIntEnv(key string, defaultValue int) int {
|
|
if value := os.Getenv(key); value != "" {
|
|
if intValue, err := strconv.Atoi(value); err == nil {
|
|
return intValue
|
|
}
|
|
}
|
|
return defaultValue
|
|
}
|
|
|
|
func getDurationEnv(key string, defaultValue time.Duration) time.Duration {
|
|
if value := os.Getenv(key); value != "" {
|
|
if duration, err := time.ParseDuration(value); err == nil {
|
|
return duration
|
|
}
|
|
}
|
|
return defaultValue
|
|
}
|
|
|
|
func (c *Config) DatabaseDSN() string {
|
|
return fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=%s",
|
|
c.Database.Host,
|
|
c.Database.Port,
|
|
c.Database.User,
|
|
c.Database.Password,
|
|
c.Database.DBName,
|
|
c.Database.SSLMode,
|
|
)
|
|
}
|
|
|
|
func (c *Config) IsDevelopment() bool {
|
|
return c.App.Env == "development"
|
|
}
|
|
|
|
func (c *Config) IsProduction() bool {
|
|
return c.App.Env == "production"
|
|
} |