add Cloudflare R2 storage integration and update bug report handling
Some checks failed
Build & Publish Docker Image / build-and-push (push) Failing after 11s
Some checks failed
Build & Publish Docker Image / build-and-push (push) Failing after 11s
This commit is contained in:
@@ -2,6 +2,7 @@ package config
|
||||
|
||||
import (
|
||||
"os"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
@@ -19,16 +20,28 @@ type RateLimitConfig struct {
|
||||
AuthBanDur time.Duration
|
||||
}
|
||||
|
||||
type R2Config struct {
|
||||
AccountID string
|
||||
AccessKeyID string
|
||||
SecretAccessKey string
|
||||
BucketName string
|
||||
Region string
|
||||
Endpoint string
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
Port string
|
||||
DSN string
|
||||
Database string
|
||||
APIKey string
|
||||
AdminKey string
|
||||
MaxOpenConns int
|
||||
MaxIdleConns int
|
||||
ConnMaxLifetime int
|
||||
RateLimit RateLimitConfig
|
||||
Port string
|
||||
DSN string
|
||||
Database string
|
||||
APIKey string
|
||||
AdminKey string
|
||||
MaxOpenConns int
|
||||
MaxIdleConns int
|
||||
ConnMaxLifetime int
|
||||
UpdatesEnabled bool
|
||||
UseS3CompatibleStorage bool
|
||||
RateLimit RateLimitConfig
|
||||
R2 R2Config
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -84,20 +97,39 @@ func load() *Config {
|
||||
if dbName == "" {
|
||||
panic("DATABASE_NAME environment variable is required")
|
||||
}
|
||||
dbNameRegex := regexp.MustCompile("^[a-zA-Z0-9_]+$")
|
||||
// Test the regex against the dbName, otherwise panic to prevent potential SQL injection
|
||||
validDbName, err := regexp.Match(dbNameRegex.String(), []byte(dbName))
|
||||
if err != nil {
|
||||
panic("failed to validate database name: " + err.Error())
|
||||
}
|
||||
if !validDbName {
|
||||
panic("invalid database name: must match regex " + dbNameRegex.String())
|
||||
}
|
||||
|
||||
if os.Getenv("DB_DSN") == "" {
|
||||
panic("DB_DSN environment variable is required")
|
||||
}
|
||||
|
||||
return &Config{
|
||||
Port: port,
|
||||
DSN: os.Getenv("DB_DSN"),
|
||||
Database: dbName,
|
||||
APIKey: apiKey,
|
||||
AdminKey: adminKey,
|
||||
MaxOpenConns: maxOpenConns,
|
||||
MaxIdleConns: maxIdleConns,
|
||||
ConnMaxLifetime: connMaxLifetime,
|
||||
Port: port,
|
||||
DSN: os.Getenv("DB_DSN"),
|
||||
Database: dbName,
|
||||
APIKey: apiKey,
|
||||
AdminKey: adminKey,
|
||||
MaxOpenConns: maxOpenConns,
|
||||
MaxIdleConns: maxIdleConns,
|
||||
ConnMaxLifetime: connMaxLifetime,
|
||||
UpdatesEnabled: strings.ToLower(strings.TrimSpace(os.Getenv("UPDATES_ENABLED"))) == "true",
|
||||
UseS3CompatibleStorage: strings.ToLower(strings.TrimSpace(os.Getenv("USE_S3_COMPATIBLE_STORAGE"))) == "true",
|
||||
R2: R2Config{
|
||||
AccountID: os.Getenv("CF_ACCOUNT_ID"),
|
||||
AccessKeyID: os.Getenv("CF_R2_ACCESS_KEY_ID"),
|
||||
SecretAccessKey: os.Getenv("CF_R2_SECRET_ACCESS_KEY"),
|
||||
BucketName: os.Getenv("CF_R2_BUCKET_NAME"),
|
||||
Region: envString("CF_R2_REGION", "auto"),
|
||||
Endpoint: os.Getenv("CF_R2_ENDPOINT"),
|
||||
},
|
||||
RateLimit: RateLimitConfig{
|
||||
UnauthMaxReqs: envInt("RL_UNAUTH_MAX_REQS", 10),
|
||||
UnauthWindow: envDuration("RL_UNAUTH_WINDOW", 5*time.Minute),
|
||||
@@ -111,6 +143,13 @@ func load() *Config {
|
||||
}
|
||||
}
|
||||
|
||||
func envString(key, fallback string) string {
|
||||
if s := os.Getenv(key); s != "" {
|
||||
return s
|
||||
}
|
||||
return fallback
|
||||
}
|
||||
|
||||
func envInt(key string, fallback int) int {
|
||||
if s := os.Getenv(key); s != "" {
|
||||
if n, err := strconv.Atoi(s); err == nil {
|
||||
|
||||
Reference in New Issue
Block a user