Files
MiauInv/server/server.go

117 lines
4.6 KiB
Go

package server
import (
"MiauInv/auth"
"MiauInv/config"
"MiauInv/frontend"
"MiauInv/handlers"
"MiauInv/models"
utils "MiauInv/util"
"log"
"net/http"
"os"
"time"
)
type Server struct {
Port string
JWTSecret []byte
DatabasePath string
CertificatePath string
PrivateKeyPath string
AllowRegistration bool
}
func InitServer() *Server {
err := config.CheckIfExists()
if err != nil {
log.Fatal(err)
return nil
}
cfg, err := config.LoadConfig()
if err != nil {
log.Fatal(err)
return nil
}
jwtSecret := os.Getenv("JWT_SECRET")
if jwtSecret == "" {
log.Fatal("JWT_SECRET environment variable not set.")
return nil
}
if len(jwtSecret) < 32 {
log.Fatal("JWT_SECRET must be at least 32 characters long.")
return nil
}
models.JWTSecret = []byte(jwtSecret)
return &Server{
Port: cfg.Port,
JWTSecret: []byte(jwtSecret),
DatabasePath: cfg.DatabasePath,
CertificatePath: cfg.CertificatePath,
PrivateKeyPath: cfg.PrivateKeyPath,
AllowRegistration: cfg.AllowRegistration,
}
}
func (this *Server) Run() {
log.Println("Starting server...")
mux := http.NewServeMux()
//
// FRONTEND
//
mux.HandleFunc("/", frontend.Home)
mux.HandleFunc("/login", utils.RenderFile("frontend/htmx/login.html"))
mux.Handle("/dashboard", auth.AuthMiddleware(this.JWTSecret)(http.HandlerFunc(frontend.Dashboard)))
mux.Handle("/inventory", auth.AuthMiddleware(this.JWTSecret)(http.HandlerFunc(frontend.Inventory)))
mux.Handle("/items", auth.AuthMiddleware(this.JWTSecret)(http.HandlerFunc(frontend.Items)))
mux.Handle("/locations", auth.AuthMiddleware(this.JWTSecret)(http.HandlerFunc(frontend.Locations)))
mux.Handle("/projects", auth.AuthMiddleware(this.JWTSecret)(http.HandlerFunc(frontend.Projects)))
mux.Handle("/profile/settings", auth.AuthMiddleware(this.JWTSecret)(http.HandlerFunc(frontend.AccountSettings)))
mux.HandleFunc("/profile/", utils.RenderFile("frontend/htmx/under-construction.html"))
if this.AllowRegistration {
mux.HandleFunc("/register", utils.RenderFile("frontend/htmx/register.html"))
} else {
mux.HandleFunc("/register", utils.RenderFile("frontend/htmx/register-blocked.html"))
}
//
// API
//
loginLimiter := newRateLimiter(10, time.Minute, 5*time.Minute)
accountLimiter := newRateLimiter(20, time.Minute, 2*time.Minute)
mux.Handle("/api/login", loginLimiter.Middleware(http.HandlerFunc(handlers.APILogin)))
mux.Handle("/api/login/2fa", loginLimiter.Middleware(http.HandlerFunc(handlers.APILoginTwoFactor)))
mux.Handle("/api/refresh", loginLimiter.Middleware(http.HandlerFunc(handlers.RefreshToken)))
mux.Handle("/api/logout", auth.AuthMiddleware(this.JWTSecret)(http.HandlerFunc(handlers.Logout)))
mux.Handle("/api/profile", auth.AuthMiddleware(this.JWTSecret)(http.HandlerFunc(handlers.UserInfo)))
mux.Handle("/api/2fa/setup", accountLimiter.Middleware(auth.AuthMiddleware(this.JWTSecret)(http.HandlerFunc(handlers.TwoFactorSetup))))
mux.Handle("/api/2fa/enable", loginLimiter.Middleware(auth.AuthMiddleware(this.JWTSecret)(http.HandlerFunc(handlers.TwoFactorEnable))))
mux.Handle("/api/2fa/disable", loginLimiter.Middleware(auth.AuthMiddleware(this.JWTSecret)(http.HandlerFunc(handlers.TwoFactorDisable))))
mux.Handle("/api/2fa/recovery-codes/regenerate", loginLimiter.Middleware(auth.AuthMiddleware(this.JWTSecret)(http.HandlerFunc(handlers.TwoFactorRegenerateRecoveryCodes))))
mux.Handle("/api/userinfo", auth.AuthMiddleware(this.JWTSecret)(http.HandlerFunc(handlers.UserInfo)))
mux.Handle("/api/account/username", accountLimiter.Middleware(auth.AuthMiddleware(this.JWTSecret)(http.HandlerFunc(handlers.AccountUpdateUsername))))
mux.Handle("/api/account/password", loginLimiter.Middleware(auth.AuthMiddleware(this.JWTSecret)(http.HandlerFunc(handlers.AccountUpdatePassword))))
if this.AllowRegistration {
mux.Handle("/api/register", loginLimiter.Middleware(http.HandlerFunc(handlers.APIRegister)))
}
mux.Handle("/api/item", auth.AuthMiddleware(this.JWTSecret)(http.HandlerFunc(handlers.Item)))
mux.Handle("/api/location", auth.AuthMiddleware(this.JWTSecret)(http.HandlerFunc(handlers.Location)))
mux.Handle("/api/project", auth.AuthMiddleware(this.JWTSecret)(http.HandlerFunc(handlers.Project)))
mux.Handle("/api/stock", auth.AuthMiddleware(this.JWTSecret)(http.HandlerFunc(handlers.Stock)))
mux.Handle("/api/association", auth.AuthMiddleware(this.JWTSecret)(http.HandlerFunc(handlers.Associations)))
// Assets
mux.HandleFunc("/assets/", frontend.Assets)
log.Printf("Listening on port %s", this.Port)
log.Fatal(http.ListenAndServeTLS(":"+this.Port, this.CertificatePath, this.PrivateKeyPath, mux))
}