package api import ( "context" "fmt" "net/http" "os" "strings" core "fr.latosa-escrima/api/core" "fr.latosa-escrima/api/users" "fr.latosa-escrima/utils" "github.com/golang-jwt/jwt/v5" ) func CORS(next http.Handler) http.Handler { CORS_AllowOrigin := os.Getenv("CORS_AllowOrigin") return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // Allow all origins (can restrict to specific origins) w.Header().Set("Access-Control-Allow-Origin", CORS_AllowOrigin) // Allow certain HTTP methods (you can customize these as needed) w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, PATCH") // Allow certain headers (you can add more as needed) w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization, X-CSRF-Token") w.Header().Set("Access-Control-Allow-Credentials", "true") // Handle OPTIONS pre-flight request if r.Method == http.MethodOptions { return } next.ServeHTTP(w, r) }) } func AuthJWT(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // Check if the Authorization header is provided authHeader := r.Header.Get("Authorization") if authHeader == "" { core.JSONError{ Status: core.Error, Message: "Missing Authorization header", }.Respond(w, http.StatusUnauthorized) return } // Bearer token is expected, so split the header into "Bearer " tokenString := strings.TrimPrefix(authHeader, "Bearer ") if tokenString == authHeader { core.JSONError{ Status: core.Error, Message: "Invalid Authorization header format", }.Respond(w, http.StatusUnauthorized) return } // Parse the token token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) { // Ensure that the token's signing method is valid if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok { return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"]) } return users.MySigningKey, nil }) if err != nil || !token.Valid { core.JSONError{ Status: core.Error, Message: "Invalid Token", }.Respond(w, http.StatusUnauthorized) return } ctx := context.WithValue(r.Context(), "token", token) // Call the next handler if the JWT is valid next.ServeHTTP(w, r.WithContext(ctx)) }) } // @param methods string -> HttpMethods separated by commas. func Methods(methods string) core.Middleware { _methods := strings.Split(strings.ToUpper(methods), ",") middleware := func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if len(methods) > 0 { if !utils.Contains(_methods, r.Method) { core.JSONError{ Status: core.Error, Message: "Method is not allowed.", }.Respond(w, http.StatusMethodNotAllowed) return } } next.ServeHTTP(w, r) }) } return middleware }