package auth import ( "context" "log/slog" "net/http" ) const UserKey = "user" const SessionKey = "session" func (s *Service) NewMiddleware(sessionCookieName string) 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(sessionCookieName) if err != nil || cookie.Value == "" { http.Error(w, "Unauthorized", http.StatusUnauthorized) return } session, err := s.SessionByToken(r.Context(), cookie.Value) if err != nil || !session.IsValid() { if err != nil { slog.Error("session lookup", slog.String("op", "middleware.SessionByToken"), slog.Any("error", err)) } http.Error(w, "Unauthorized", http.StatusUnauthorized) return } user, err := s.u.UserById(r.Context(), session.UserId) if err != nil { slog.Error("load user", slog.String("op", "middleware.UserById"), slog.Int64("user_id", session.UserId), slog.Any("error", err)) http.Error(w, "Internal server error", http.StatusInternalServerError) return } newSession, err := s.BumpSession(r.Context(), session) if err != nil { slog.Error("session bump", slog.String("op", "middleware.BumpSession"), slog.Int64("user_id", session.UserId), slog.Any("error", err)) http.Error(w, "Internal server error", http.StatusInternalServerError) return } ctx := context.WithValue(r.Context(), UserKey, user) ctx = context.WithValue(ctx, SessionKey, newSession) next.ServeHTTP(w, r.WithContext(ctx)) }) } }