Michael Thomson e55d419d44
All checks were successful
ci/woodpecker/pr/build Pipeline was successful
ci/woodpecker/pr/lint Pipeline was successful
ci/woodpecker/pr/test Pipeline was successful
auth services, middleware, and other stuff
2025-05-22 13:55:43 -04:00

61 lines
1.3 KiB
Go

package middleware
import (
"context"
"log/slog"
"net/http"
"github.com/golang-jwt/jwt/v5"
)
const EmailKey contextKey = "email"
func AuthMiddleware(logger *slog.Logger, jwtKey []byte) func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
cookie, err := r.Cookie("token")
if err == http.ErrNoCookie {
logger.WarnContext(r.Context(), "token not provided")
w.WriteHeader(http.StatusUnauthorized)
return
}
if err != nil {
logger.ErrorContext(r.Context(), err.Error())
w.WriteHeader(http.StatusInternalServerError)
return
}
tokenString := cookie.Value
token, err := jwt.Parse(tokenString, func(t *jwt.Token) (any, error) {
return jwtKey, nil
})
if !token.Valid {
logger.WarnContext(r.Context(), err.Error())
w.WriteHeader(http.StatusUnauthorized)
return
}
if err != nil {
logger.ErrorContext(r.Context(), err.Error())
w.WriteHeader(http.StatusInternalServerError)
return
}
email, err := token.Claims.GetSubject()
if err != nil {
logger.ErrorContext(r.Context(), err.Error())
w.WriteHeader(http.StatusInternalServerError)
return
}
ctx := context.WithValue(r.Context(), EmailKey, email)
newReq := r.WithContext(ctx)
next.ServeHTTP(w, newReq)
})
}
}