Files
Hyperia/server/main.go
metacryst eff0c160a5 begin
2025-09-06 20:26:07 -05:00

181 lines
4.3 KiB
Go

package main
import (
"fmt"
"net/http"
"path/filepath"
"hyperia/config"
"hyperia/handlers"
"hyperia/logger"
"runtime/debug"
"strings"
"github.com/golang-jwt/jwt/v5"
"github.com/rs/zerolog/log"
)
func main() {
config.SetConfiguration()
logger.ConfigureLogger()
// err := handlers.InitDB()
// if err != nil {
// log.Fatal().Msgf("failed to connect to database: %v", err)
// } else {
// log.Info().Msg("successfully connected to PostgreSQL")
// }
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
defer func() {
if r := recover(); r != nil {
log.Error().
Interface("panic_reason", r).
Bytes("stack_trace", debug.Stack()).
Msg("panic in http goroutine")
}
}()
subdomain := ""
host := strings.Split(r.Host, ":")[0] // remove port
parts := strings.Split(host, ".")
if len(parts) > 2 || (len(parts) > 1 && parts[1] == "localhost") {
subdomain = parts[0]
}
if strings.HasPrefix(r.URL.Path, "/_") {
handleAsset(w, r)
} else if subdomain == "apply" {
authMiddleware(handleApply)(w, r)
} else if subdomain == "pma" {
authMiddleware(handlePMA)(w, r)
} else {
handlePublic(w, r)
}
})
log.Info().Msgf("Server starting on http://localhost: %s", config.PORT)
err := http.ListenAndServe(":"+config.PORT, nil)
if err != nil {
log.Fatal().Msgf("failed to start server: %v", err)
}
}
func handlePublic(w http.ResponseWriter, r *http.Request) {
if r.URL.Path == "/api/login" {
handlers.HandleLogin(w, r)
return
}
if r.URL.Path == "/api/applicantlogin" {
handlers.HandleApplicantLogin(w, r)
return
}
if r.URL.Path == "/api/join" {
handlers.HandleJoin(w, r)
return
}
if r.URL.Path == "/verify" {
handlers.HandleVerify(w, r)
return
}
servePublicFile(w, r)
}
func handleAsset(w http.ResponseWriter, r *http.Request) {
path := r.URL.Path
filePath := filepath.Join("../ui", path)
log.Debug().Msgf("serving asset: %s", filePath)
http.ServeFile(w, r, filePath)
}
func servePublicFile(w http.ResponseWriter, r *http.Request) {
path := r.URL.Path
if path == "/" {
path = "/index.html"
} else if !strings.Contains(path, ".") {
path = filepath.Join("/pages", path) + ".html"
}
filePath := filepath.Join("../ui/public", path)
log.Debug().Msgf("serving: %s", filePath)
http.ServeFile(w, r, filePath)
}
func authMiddleware(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
cookie, err := r.Cookie("auth_token")
if err != nil {
log.Warn().Msg("Unauthorized - missing auth token")
http.Error(w, "Unauthorized - missing auth token", http.StatusUnauthorized)
return
}
jwtToken := cookie.Value
token, err := jwt.Parse(jwtToken, func(token *jwt.Token) (interface{}, error) {
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
}
return []byte(config.JWT_SECRET), nil
})
if err != nil {
log.Err(err).Msg("error authenticating jwt")
}
if err != nil || !token.Valid {
http.Error(w, "Unauthorized - invalid auth token", http.StatusUnauthorized)
return
}
next(w, r)
}
}
func handleApply(w http.ResponseWriter, r *http.Request) {
// if r.URL.Path == "/api/application-save" {
// handlers.HandleApplicationSubmit(w, r)
// return
// }
// if r.URL.Path == "/api/get-application" {
// handlers.HandleGetApplication(w, r)
// return
// }
// if r.URL.Path == "/logout" {
// handlers.HandleLogout(w, r)
// return
// }
// if r.URL.Path == "/" {
// handlers.CheckApplicationCompleteMiddleware(w, r)
// }
// if r.URL.Path == "/complete" {
// handlers.ApplicationSubmitMiddleware(w, r)
// }
path := r.URL.Path
if path == "/" {
path = "/index.html"
} else if !strings.Contains(path, ".") {
path = filepath.Join("/pages", path) + ".html"
}
filePath := filepath.Join("../ui/apply", path)
log.Debug().Msgf("Serving apply subdomain: %s", filePath)
http.ServeFile(w, r, filePath)
}
func handlePMA(w http.ResponseWriter, r *http.Request) {
path := r.URL.Path
if path == "/" {
path = "/index.html"
} else if !strings.Contains(path, ".") {
path = filepath.Join("/pages", path) + ".html"
}
filePath := filepath.Join("../ui/pma", path)
log.Debug().Msgf("serving pma subdomain: %s", filePath)
http.ServeFile(w, r, filePath)
}