Initial commit

This commit is contained in:
2025-11-29 16:59:02 -06:00
commit da4f051282
25 changed files with 1144 additions and 0 deletions

View File

@@ -0,0 +1,56 @@
package middleware
import (
"context"
"errors"
"log"
"net/http"
"strings"
"git.kling.dev/jared/WorkoutTrackerAPI/internal/auth"
)
type contextKey string
const (
UserIDKey contextKey = "user_id"
EmailKey contextKey = "email"
)
func ValidateJWT(jwtManager auth.JWTManager) func(http.HandlerFunc) http.HandlerFunc {
return func(next http.HandlerFunc) http.HandlerFunc {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
log.Printf("Starting ValidateJWT handler")
auth_header := r.Header.Get("Authorization")
if auth_header == "" {
w.WriteHeader(http.StatusUnauthorized)
w.Write([]byte("Missing authorization header"))
return
}
parts := strings.Split(auth_header, " ")
if len(parts) != 2 || strings.ToLower(strings.Trim(parts[0], " ")) != "bearer" {
w.WriteHeader(http.StatusUnauthorized)
w.Write([]byte("Invalid authorization header format"))
return
}
tokenString := parts[1]
claims, err := jwtManager.ValidateToken(tokenString)
if err != nil {
w.WriteHeader(http.StatusUnauthorized)
if errors.Is(err, auth.ErrExpiredToken) {
w.Write([]byte("Token has expired"))
return
}
w.Write([]byte("Invalid token"))
return
}
ctx := context.WithValue(r.Context(), UserIDKey, claims.Subject)
ctx = context.WithValue(ctx, EmailKey, claims.Email)
next.ServeHTTP(w, r.WithContext(ctx))
})
}
}

View File

@@ -0,0 +1,18 @@
package middleware
import "net/http"
func CORS(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")
if r.Method == "OPTIONS" {
w.WriteHeader(http.StatusOK)
return
}
next.ServeHTTP(w, r)
})
}

View File

@@ -0,0 +1,30 @@
package middleware
import (
"log"
"net/http"
"time"
)
func Logging(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
wrapped := &responseWriter{ResponseWriter: w, statusCode: http.StatusOK}
next.ServeHTTP(wrapped, r)
log.Printf(
"%s %s %d %s",
r.Method,
r.URL.Path,
wrapped.statusCode,
time.Since(start),
)
})
}
type responseWriter struct {
http.ResponseWriter
statusCode int
}