mirror of
https://github.com/knadh/listmonk.git
synced 2024-09-20 07:16:33 +08:00
Merge 6fb515097d
into 51e3f1789b
This commit is contained in:
commit
6e30d0eefb
|
@ -3,13 +3,12 @@ package main
|
|||
import (
|
||||
"bytes"
|
||||
"crypto/subtle"
|
||||
"net/http"
|
||||
"path"
|
||||
"regexp"
|
||||
|
||||
"github.com/knadh/paginator"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/labstack/echo/v4/middleware"
|
||||
"net/http"
|
||||
"path"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -65,6 +64,23 @@ func initHTTPHandlers(e *echo.Echo, app *App) {
|
|||
e.DefaultHTTPErrorHandler(err, c)
|
||||
}
|
||||
|
||||
// CORS middleware
|
||||
if ko.Bool("cors.enabled") {
|
||||
var allowedOrigins = ko.Strings("cors.allowed_origins")
|
||||
// If the allowed origins are not set, the middleware will not be used.
|
||||
if len(allowedOrigins) > 0 {
|
||||
e.Use(middleware.CORSWithConfig(middleware.CORSConfig{
|
||||
AllowOrigins: ko.Strings("cors.allowed_origins"),
|
||||
AllowHeaders: []string{echo.HeaderOrigin, echo.HeaderContentType, echo.HeaderAccept},
|
||||
}))
|
||||
app.log.Println("CORS middleware enabled")
|
||||
app.log.Printf("Allowed origins: %v", allowedOrigins)
|
||||
} else {
|
||||
app.log.Println("CORS middleware not enabled as allowed origins are not set properly")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Admin JS app views.
|
||||
// /admin/static/* file server is registered in initHTTPServer().
|
||||
e.GET("/", func(c echo.Context) error {
|
||||
|
|
59
cmd/main.go
59
cmd/main.go
|
@ -7,6 +7,8 @@ import (
|
|||
"log"
|
||||
"os"
|
||||
"os/signal"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"syscall"
|
||||
|
@ -115,14 +117,43 @@ func init() {
|
|||
// Load config files to pick up the database settings first.
|
||||
initConfigFiles(ko.Strings("config"), ko)
|
||||
|
||||
// Load environment variables and merge into the loaded config.
|
||||
if err := ko.Load(env.Provider("LISTMONK_", ".", func(s string) string {
|
||||
return strings.Replace(strings.ToLower(
|
||||
strings.TrimPrefix(s, "LISTMONK_")), "__", ".", -1)
|
||||
}), nil); err != nil {
|
||||
lo.Fatalf("error loading config from env: %v", err)
|
||||
// Map to store array-like variables
|
||||
arrayMap := make(map[string]map[int]string)
|
||||
|
||||
// Custom function to process environment variables
|
||||
processor := func(key string, value string) (string, interface{}) {
|
||||
// Remove prefix and convert to lowercase
|
||||
processedKey := strings.ToLower(strings.TrimPrefix(key, "LISTMONK_"))
|
||||
|
||||
// Replace double underscores with dots for nested keys
|
||||
processedKey = strings.Replace(processedKey, "__", ".", -1)
|
||||
|
||||
// Check if the key ends with a number (potential array index)
|
||||
parts := strings.Split(processedKey, ".")
|
||||
lastPart := parts[len(parts)-1]
|
||||
if index, err := strconv.Atoi(lastPart); err == nil {
|
||||
// It's an array item
|
||||
arrayKey := strings.Join(parts[:len(parts)-1], ".")
|
||||
if _, exists := arrayMap[arrayKey]; !exists {
|
||||
arrayMap[arrayKey] = make(map[int]string)
|
||||
}
|
||||
arrayMap[arrayKey][index] = value
|
||||
|
||||
return arrayKey, mapToSortedArray(arrayMap[arrayKey])
|
||||
}
|
||||
|
||||
return processedKey, value
|
||||
}
|
||||
|
||||
// Load environment variables
|
||||
if err := ko.Load(env.ProviderWithValue("LISTMONK_", ".", processor), nil); err != nil {
|
||||
fmt.Printf("error loading config from env: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Debug print the config.
|
||||
// fmt.Println(ko.Sprint())
|
||||
|
||||
// Connect to the database, load the filesystem to read SQL queries.
|
||||
db = initDB()
|
||||
fs = initFS(appDir, frontendDir, ko.String("static-dir"), ko.String("i18n-dir"))
|
||||
|
@ -162,6 +193,22 @@ func init() {
|
|||
queries = prepareQueries(qMap, db, ko)
|
||||
}
|
||||
|
||||
// mapToSortedArray converts a map[int]string to a sorted []string
|
||||
func mapToSortedArray(indexMap map[int]string) []string {
|
||||
var keys []int
|
||||
for k := range indexMap {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
sort.Ints(keys)
|
||||
|
||||
var array []string
|
||||
for _, k := range keys {
|
||||
array = append(array, indexMap[k])
|
||||
}
|
||||
|
||||
return array
|
||||
}
|
||||
|
||||
func main() {
|
||||
// Initialize the main app controller that wraps all of the app's
|
||||
// components. This is passed around HTTP handlers.
|
||||
|
|
|
@ -12,6 +12,10 @@ address = "localhost:9000"
|
|||
admin_username = "listmonk"
|
||||
admin_password = "listmonk"
|
||||
|
||||
[cors]
|
||||
enabled = false
|
||||
allowed_origins = ["*", "localhost:3000"]
|
||||
|
||||
# Database.
|
||||
[db]
|
||||
host = "localhost"
|
||||
|
|
|
@ -10,17 +10,20 @@ Variables in config.toml can also be provided as environment variables prefixed
|
|||
|
||||
Example:
|
||||
|
||||
| **Environment variable** | Example value |
|
||||
| ------------------------------ | -------------- |
|
||||
| `LISTMONK_app__address` | "0.0.0.0:9000" |
|
||||
| `LISTMONK_app__admin_username` | listmonk |
|
||||
| `LISTMONK_app__admin_password` | listmonk |
|
||||
| `LISTMONK_db__host` | db |
|
||||
| `LISTMONK_db__port` | 9432 |
|
||||
| `LISTMONK_db__user` | listmonk |
|
||||
| `LISTMONK_db__password` | listmonk |
|
||||
| `LISTMONK_db__database` | listmonk |
|
||||
| `LISTMONK_db__ssl_mode` | disable |
|
||||
| **Environment variable** | Example value |
|
||||
|-------------------------------------|----------------|
|
||||
| `LISTMONK_app__address` | "0.0.0.0:9000" |
|
||||
| `LISTMONK_app__admin_username` | listmonk |
|
||||
| `LISTMONK_app__admin_password` | listmonk |
|
||||
| `LISTMONK_db__host` | db |
|
||||
| `LISTMONK_db__port` | 9432 |
|
||||
| `LISTMONK_db__user` | listmonk |
|
||||
| `LISTMONK_db__password` | listmonk |
|
||||
| `LISTMONK_db__database` | listmonk |
|
||||
| `LISTMONK_db__ssl_mode` | disable |
|
||||
| `LISTMONK_cors__enabled` | false |
|
||||
| `LISTMONK_cors__allowed_origins__0` | example.com |
|
||||
| `LISTMONK_cors__allowed_origins__1` | another.com |
|
||||
|
||||
|
||||
### Customizing system templates
|
||||
|
|
Loading…
Reference in a new issue