mirror of
https://github.com/lordmathis/lemma.git
synced 2025-11-06 16:04:23 +00:00
Add secure headers and cors middlewares
This commit is contained in:
@@ -8,8 +8,11 @@ import (
|
|||||||
|
|
||||||
"github.com/go-chi/chi/v5"
|
"github.com/go-chi/chi/v5"
|
||||||
"github.com/go-chi/chi/v5/middleware"
|
"github.com/go-chi/chi/v5/middleware"
|
||||||
|
"github.com/go-chi/cors"
|
||||||
"github.com/go-chi/httprate"
|
"github.com/go-chi/httprate"
|
||||||
|
|
||||||
|
"github.com/unrolled/secure"
|
||||||
|
|
||||||
"novamd/internal/api"
|
"novamd/internal/api"
|
||||||
"novamd/internal/auth"
|
"novamd/internal/auth"
|
||||||
"novamd/internal/config"
|
"novamd/internal/config"
|
||||||
@@ -68,6 +71,25 @@ func main() {
|
|||||||
r.Use(middleware.Recoverer)
|
r.Use(middleware.Recoverer)
|
||||||
r.Use(middleware.RequestID)
|
r.Use(middleware.RequestID)
|
||||||
r.Use(middleware.RealIP)
|
r.Use(middleware.RealIP)
|
||||||
|
|
||||||
|
// Security headers
|
||||||
|
r.Use(secure.New(secure.Options{
|
||||||
|
SSLRedirect: false, // Let proxy handle HTTPS
|
||||||
|
SSLProxyHeaders: map[string]string{"X-Forwarded-Proto": "https"},
|
||||||
|
IsDevelopment: cfg.IsDevelopment,
|
||||||
|
}).Handler)
|
||||||
|
|
||||||
|
// CORS if origins are configured
|
||||||
|
if len(cfg.CORSOrigins) > 0 {
|
||||||
|
r.Use(cors.Handler(cors.Options{
|
||||||
|
AllowedOrigins: cfg.CORSOrigins,
|
||||||
|
AllowedMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},
|
||||||
|
AllowedHeaders: []string{"Accept", "Authorization", "Content-Type", "X-Requested-With"},
|
||||||
|
AllowCredentials: true,
|
||||||
|
MaxAge: 300, // Maximum value not ignored by any major browser
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
r.Use(middleware.Timeout(30 * time.Second))
|
r.Use(middleware.Timeout(30 * time.Second))
|
||||||
|
|
||||||
// Set up routes
|
// Set up routes
|
||||||
|
|||||||
@@ -4,12 +4,14 @@ go 1.23.1
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/go-chi/chi/v5 v5.1.0
|
github.com/go-chi/chi/v5 v5.1.0
|
||||||
|
github.com/go-chi/cors v1.2.1
|
||||||
github.com/go-chi/httprate v0.14.1
|
github.com/go-chi/httprate v0.14.1
|
||||||
github.com/go-git/go-git/v5 v5.12.0
|
github.com/go-git/go-git/v5 v5.12.0
|
||||||
github.com/go-playground/validator/v10 v10.22.1
|
github.com/go-playground/validator/v10 v10.22.1
|
||||||
github.com/golang-jwt/jwt/v5 v5.2.1
|
github.com/golang-jwt/jwt/v5 v5.2.1
|
||||||
github.com/google/uuid v1.6.0
|
github.com/google/uuid v1.6.0
|
||||||
github.com/mattn/go-sqlite3 v1.14.23
|
github.com/mattn/go-sqlite3 v1.14.23
|
||||||
|
github.com/unrolled/secure v1.17.0
|
||||||
golang.org/x/crypto v0.21.0
|
golang.org/x/crypto v0.21.0
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,8 @@ github.com/gliderlabs/ssh v0.3.7 h1:iV3Bqi942d9huXnzEF2Mt+CY9gLu8DNM4Obd+8bODRE=
|
|||||||
github.com/gliderlabs/ssh v0.3.7/go.mod h1:zpHEXBstFnQYtGnB8k8kQLol82umzn/2/snG7alWVD8=
|
github.com/gliderlabs/ssh v0.3.7/go.mod h1:zpHEXBstFnQYtGnB8k8kQLol82umzn/2/snG7alWVD8=
|
||||||
github.com/go-chi/chi/v5 v5.1.0 h1:acVI1TYaD+hhedDJ3r54HyA6sExp3HfXq7QWEEY/xMw=
|
github.com/go-chi/chi/v5 v5.1.0 h1:acVI1TYaD+hhedDJ3r54HyA6sExp3HfXq7QWEEY/xMw=
|
||||||
github.com/go-chi/chi/v5 v5.1.0/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
|
github.com/go-chi/chi/v5 v5.1.0/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
|
||||||
|
github.com/go-chi/cors v1.2.1 h1:xEC8UT3Rlp2QuWNEr4Fs/c2EAGVKBwy/1vHx3bppil4=
|
||||||
|
github.com/go-chi/cors v1.2.1/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58=
|
||||||
github.com/go-chi/httprate v0.14.1 h1:EKZHYEZ58Cg6hWcYzoZILsv7ppb46Wt4uQ738IRtpZs=
|
github.com/go-chi/httprate v0.14.1 h1:EKZHYEZ58Cg6hWcYzoZILsv7ppb46Wt4uQ738IRtpZs=
|
||||||
github.com/go-chi/httprate v0.14.1/go.mod h1:TUepLXaz/pCjmCtf/obgOQJ2Sz6rC8fSf5cAt5cnTt0=
|
github.com/go-chi/httprate v0.14.1/go.mod h1:TUepLXaz/pCjmCtf/obgOQJ2Sz6rC8fSf5cAt5cnTt0=
|
||||||
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI=
|
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI=
|
||||||
@@ -91,6 +93,8 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf
|
|||||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||||
|
github.com/unrolled/secure v1.17.0 h1:Io7ifFgo99Bnh0J7+Q+qcMzWM6kaDPCA5FroFZEdbWU=
|
||||||
|
github.com/unrolled/secure v1.17.0/go.mod h1:BmF5hyM6tXczk3MpQkFf1hpKSRqCyhqcbiQtiAF7+40=
|
||||||
github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
|
github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
|
||||||
github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
|
github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
|
||||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"novamd/internal/crypto"
|
"novamd/internal/crypto"
|
||||||
@@ -15,12 +16,15 @@ type Config struct {
|
|||||||
WorkDir string
|
WorkDir string
|
||||||
StaticPath string
|
StaticPath string
|
||||||
Port string
|
Port string
|
||||||
|
AppURL string
|
||||||
|
CORSOrigins []string
|
||||||
AdminEmail string
|
AdminEmail string
|
||||||
AdminPassword string
|
AdminPassword string
|
||||||
EncryptionKey string
|
EncryptionKey string
|
||||||
JWTSigningKey string
|
JWTSigningKey string
|
||||||
RateLimitRequests int
|
RateLimitRequests int
|
||||||
RateLimitWindow time.Duration
|
RateLimitWindow time.Duration
|
||||||
|
IsDevelopment bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func DefaultConfig() *Config {
|
func DefaultConfig() *Config {
|
||||||
@@ -31,6 +35,7 @@ func DefaultConfig() *Config {
|
|||||||
Port: "8080",
|
Port: "8080",
|
||||||
RateLimitRequests: int(10),
|
RateLimitRequests: int(10),
|
||||||
RateLimitWindow: time.Minute,
|
RateLimitWindow: time.Minute,
|
||||||
|
IsDevelopment: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,6 +56,10 @@ func (c *Config) Validate() error {
|
|||||||
func Load() (*Config, error) {
|
func Load() (*Config, error) {
|
||||||
config := DefaultConfig()
|
config := DefaultConfig()
|
||||||
|
|
||||||
|
if env := os.Getenv("NOVAMD_ENV"); env != "" {
|
||||||
|
config.IsDevelopment = env == "development"
|
||||||
|
}
|
||||||
|
|
||||||
if dbPath := os.Getenv("NOVAMD_DB_PATH"); dbPath != "" {
|
if dbPath := os.Getenv("NOVAMD_DB_PATH"); dbPath != "" {
|
||||||
config.DBPath = dbPath
|
config.DBPath = dbPath
|
||||||
}
|
}
|
||||||
@@ -73,6 +82,14 @@ func Load() (*Config, error) {
|
|||||||
config.Port = port
|
config.Port = port
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if appURL := os.Getenv("NOVAMD_APP_URL"); appURL != "" {
|
||||||
|
config.AppURL = appURL
|
||||||
|
}
|
||||||
|
|
||||||
|
if corsOrigins := os.Getenv("NOVAMD_CORS_ORIGINS"); corsOrigins != "" {
|
||||||
|
config.CORSOrigins = strings.Split(corsOrigins, ",")
|
||||||
|
}
|
||||||
|
|
||||||
config.AdminEmail = os.Getenv("NOVAMD_ADMIN_EMAIL")
|
config.AdminEmail = os.Getenv("NOVAMD_ADMIN_EMAIL")
|
||||||
config.AdminPassword = os.Getenv("NOVAMD_ADMIN_PASSWORD")
|
config.AdminPassword = os.Getenv("NOVAMD_ADMIN_PASSWORD")
|
||||||
config.EncryptionKey = os.Getenv("NOVAMD_ENCRYPTION_KEY")
|
config.EncryptionKey = os.Getenv("NOVAMD_ENCRYPTION_KEY")
|
||||||
|
|||||||
Reference in New Issue
Block a user