all repos

onasty @ 4073d2b

a one-time notes service

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
package config

import (
	"errors"
	"os"
	"strconv"
	"time"
)

type Config struct {
	AppEnv     string
	AppURL     string
	ServerPort string
	NatsURL    string

	PostgresDSN      string
	PasswordSalt     string
	NotePassowrdSalt string

	RedisAddr     string
	RedisPassword string
	RedisDB       int

	CacheUsersTTL time.Duration

	JwtSigningKey      string
	JwtAccessTokenTTL  time.Duration
	JwtRefreshTokenTTL time.Duration

	MailgunFrom          string
	MailgunDomain        string
	MailgunAPIKey        string
	VerificationTokenTTL time.Duration

	MetricsEnabled bool
	MetricsPort    string

	LogLevel    string
	LogFormat   string
	LogShowLine bool

	RateLimiterRPS   int
	RateLimiterBurst int
	RateLimiterTTL   time.Duration
}

func NewConfig() *Config {
	return &Config{
		AppEnv:     getenvOrDefault("APP_ENV", "debug"),
		AppURL:     getenvOrDefault("APP_URL", ""),
		ServerPort: getenvOrDefault("SERVER_PORT", "3000"),
		NatsURL:    getenvOrDefault("NATS_URL", ""),

		PostgresDSN:      getenvOrDefault("POSTGRESQL_DSN", ""),
		PasswordSalt:     getenvOrDefault("PASSWORD_SALT", ""),
		NotePassowrdSalt: getenvOrDefault("NOTE_PASSWORD_SALT", ""),

		RedisAddr:     getenvOrDefault("REDIS_ADDR", ""),
		RedisPassword: getenvOrDefault("REDIS_PASSWORD", ""),
		RedisDB:       mustGetenvOrDefaultInt(getenvOrDefault("REDIS_DB", "0"), 0),

		CacheUsersTTL: mustParseDuration(getenvOrDefault("CACHE_USERS_TTL", "1h")),

		JwtSigningKey: getenvOrDefault("JWT_SIGNING_KEY", ""),
		JwtAccessTokenTTL: mustParseDuration(
			getenvOrDefault("JWT_ACCESS_TOKEN_TTL", "15m"),
		),
		JwtRefreshTokenTTL: mustParseDuration(
			getenvOrDefault("JWT_REFRESH_TOKEN_TTL", "24h"),
		),

		MailgunFrom:   getenvOrDefault("MAILGUN_FROM", ""),
		MailgunDomain: getenvOrDefault("MAILGUN_DOMAIN", ""),
		MailgunAPIKey: getenvOrDefault("MAILGUN_API_KEY", ""),
		VerificationTokenTTL: mustParseDuration(
			getenvOrDefault("VERIFICATION_TOKEN_TTL", "24h"),
		),

		MetricsPort:    getenvOrDefault("METRICS_PORT", "3001"),
		MetricsEnabled: getenvOrDefault("METRICS_ENABLED", "true") == "true",

		LogLevel:    getenvOrDefault("LOG_LEVEL", "debug"),
		LogFormat:   getenvOrDefault("LOG_FORMAT", "json"),
		LogShowLine: getenvOrDefault("LOG_SHOW_LINE", "true") == "true",

		RateLimiterRPS:   mustGetenvOrDefaultInt("RATELIMITER_RPS", 100),
		RateLimiterBurst: mustGetenvOrDefaultInt("RATELIMITER_BURST", 10),
		RateLimiterTTL:   mustParseDuration(getenvOrDefault("RATELIMITER_TTL", "1m")),
	}
}

func (c *Config) IsDevMode() bool {
	return c.AppEnv == "debug" || c.AppEnv == "test"
}

func getenvOrDefault(key, def string) string {
	if v, ok := os.LookupEnv(key); ok {
		return v
	}
	return def
}

func mustGetenvOrDefaultInt(key string, def int) int {
	if v, ok := os.LookupEnv(key); ok {
		r, err := strconv.Atoi(v)
		if err != nil {
			panic(err)
		}
		return r
	}
	return def
}

func mustParseDuration(dur string) time.Duration {
	d, err := time.ParseDuration(dur)
	if err != nil {
		panic(errors.Join(errors.New("cannot time.ParseDuration"), err)) //nolint:err113
	}

	return d
}