all repos

onasty @ 49ba283475c3e2ad4a464b4d2f923aad6b161b50

a one-time notes service

onasty/internal/config/config.go (view raw)

Olexandr Smirnov Olexandr Smirnov
ss2316544@gmail.com
feat(api): change email (#191)..., 9 months ago
1
package config
2
3
import (
4
	"errors"
5
	"os"
6
	"strconv"
7
	"strings"
8
	"time"
9
)
10
11
// Environment represents current app environment.
12
type Environment string
13
14
func (e Environment) IsDevMode() bool {
15
	return e == "debug" || e == "test"
16
}
17
18
type Config struct {
19
	AppEnv  Environment
20
	AppURL  string
21
	NatsURL string
22
23
	CORSAllowedOrigins []string
24
	CORSMaxAge         time.Duration
25
26
	HTTPPort            int
27
	HTTPWriteTimeout    time.Duration
28
	HTTPReadTimeout     time.Duration
29
	HTTPHeaderMaxSizeMb int
30
31
	PostgresDSN      string
32
	PasswordSalt     string
33
	NotePasswordSalt string
34
35
	RedisAddr     string
36
	RedisPassword string
37
	RedisDB       int
38
39
	CacheUsersTTL time.Duration
40
	CacheNoteTTL  time.Duration
41
42
	JwtSigningKey      string
43
	JwtAccessTokenTTL  time.Duration
44
	JwtRefreshTokenTTL time.Duration
45
46
	GoogleClientID    string
47
	GoogleSecret      string
48
	GoogleRedirectURL string
49
50
	GitHubClientID    string
51
	GitHubSecret      string
52
	GitHubRedirectURL string
53
54
	VerificationTokenTTL  time.Duration
55
	ResetPasswordTokenTTL time.Duration
56
	ChangeEmailTokenTTL   time.Duration
57
58
	MetricsEnabled bool
59
	MetricsPort    int
60
61
	LogLevel    string
62
	LogFormat   string
63
	LogShowLine bool
64
65
	RateLimiterRPS       int
66
	RateLimiterBurst     int
67
	RateLimiterTTL       time.Duration
68
	SlowRateLimiterRPS   int
69
	SlowRateLimiterBurst int
70
	SlowRateLimiterTTL   time.Duration
71
}
72
73
func NewConfig() *Config {
74
	return &Config{
75
		AppEnv:  Environment(getenvOrDefault("APP_ENV", "debug")),
76
		AppURL:  getenvOrDefault("APP_URL", ""),
77
		NatsURL: getenvOrDefault("NATS_URL", ""),
78
79
		CORSAllowedOrigins: strings.Split(getenvOrDefault("CORS_ALLOWED_ORIGINS", "*"), ","),
80
		CORSMaxAge:         mustParseDuration(getenvOrDefault("CORS_MAX_AGE", "12h")),
81
82
		HTTPPort:            mustGetenvOrDefaultInt("HTTP_PORT", 3000),
83
		HTTPWriteTimeout:    mustParseDuration(getenvOrDefault("HTTP_WRITE_TIMEOUT", "10s")),
84
		HTTPReadTimeout:     mustParseDuration(getenvOrDefault("HTTP_READ_TIMEOUT", "10s")),
85
		HTTPHeaderMaxSizeMb: mustGetenvOrDefaultInt("HTTP_HEADER_MAX_SIZE_MB", 1),
86
87
		PostgresDSN:      getenvOrDefault("POSTGRESQL_DSN", ""),
88
		PasswordSalt:     getenvOrDefault("PASSWORD_SALT", ""),
89
		NotePasswordSalt: getenvOrDefault("NOTE_PASSWORD_SALT", ""),
90
91
		RedisAddr:     getenvOrDefault("REDIS_ADDR", ""),
92
		RedisPassword: getenvOrDefault("REDIS_PASSWORD", ""),
93
		RedisDB:       mustGetenvOrDefaultInt(getenvOrDefault("REDIS_DB", "0"), 0),
94
95
		CacheUsersTTL: mustParseDuration(getenvOrDefault("CACHE_USERS_TTL", "1h")),
96
		CacheNoteTTL:  mustParseDuration(getenvOrDefault("CACHE_NOTE_TTL", "1h")),
97
98
		JwtSigningKey: getenvOrDefault("JWT_SIGNING_KEY", ""),
99
		JwtAccessTokenTTL: mustParseDuration(
100
			getenvOrDefault("JWT_ACCESS_TOKEN_TTL", "15m"),
101
		),
102
		JwtRefreshTokenTTL: mustParseDuration(
103
			getenvOrDefault("JWT_REFRESH_TOKEN_TTL", "24h"),
104
		),
105
106
		GoogleClientID:    getenvOrDefault("GOOGLE_CLIENTID", ""),
107
		GoogleSecret:      getenvOrDefault("GOOGLE_SECRET", ""),
108
		GoogleRedirectURL: getenvOrDefault("GOOGLE_REDIRECTURL", ""),
109
110
		GitHubClientID:    getenvOrDefault("GITHUB_CLIENTID", ""),
111
		GitHubSecret:      getenvOrDefault("GITHUB_SECRET", ""),
112
		GitHubRedirectURL: getenvOrDefault("GITHUB_REDIRECTURL", ""),
113
114
		VerificationTokenTTL:  mustParseDuration(getenvOrDefault("VERIFICATION_TOKEN_TTL", "24h")),
115
		ResetPasswordTokenTTL: mustParseDuration(getenvOrDefault("RESET_PASSWORD_TOKEN_TTL", "1h")),
116
		ChangeEmailTokenTTL:   mustParseDuration(getenvOrDefault("CHANGE_EMAIL_TOKEN_TTL", "24h")),
117
118
		MetricsPort:    mustGetenvOrDefaultInt("METRICS_PORT", 3001),
119
		MetricsEnabled: getenvOrDefault("METRICS_ENABLED", "true") == "true",
120
121
		LogLevel:    getenvOrDefault("LOG_LEVEL", "debug"),
122
		LogFormat:   getenvOrDefault("LOG_FORMAT", "json"),
123
		LogShowLine: getenvOrDefault("LOG_SHOW_LINE", "true") == "true",
124
125
		RateLimiterRPS:       mustGetenvOrDefaultInt("RATELIMITER_RPS", 100),
126
		RateLimiterBurst:     mustGetenvOrDefaultInt("RATELIMITER_BURST", 10),
127
		RateLimiterTTL:       mustParseDuration(getenvOrDefault("RATELIMITER_TTL", "1m")),
128
		SlowRateLimiterRPS:   mustGetenvOrDefaultInt("SLOW_RATELIMITER_RPS", 2),
129
		SlowRateLimiterBurst: mustGetenvOrDefaultInt("SLOW_RATELIMITER_BURST", 2),
130
		SlowRateLimiterTTL:   mustParseDuration(getenvOrDefault("SLOW_RATELIMITER_TTL", "1m")),
131
	}
132
}
133
134
func getenvOrDefault(key, def string) string {
135
	if v, ok := os.LookupEnv(key); ok {
136
		return v
137
	}
138
	return def
139
}
140
141
func mustGetenvOrDefaultInt(key string, def int) int {
142
	if v, ok := os.LookupEnv(key); ok {
143
		r, err := strconv.Atoi(v)
144
		if err != nil {
145
			panic(err)
146
		}
147
		return r
148
	}
149
	return def
150
}
151
152
func mustParseDuration(dur string) time.Duration {
153
	d, err := time.ParseDuration(dur)
154
	if err != nil {
155
		panic(errors.Join(errors.New("cannot time.ParseDuration"), err)) //nolint:err113
156
	}
157
158
	return d
159
}