aboutsummaryrefslogtreecommitdiff
path: root/internal/ui
diff options
context:
space:
mode:
Diffstat (limited to 'internal/ui')
-rw-r--r--internal/ui/api_key_remove.go4
-rw-r--r--internal/ui/api_key_save.go5
-rw-r--r--internal/ui/category_save.go5
-rw-r--r--internal/ui/category_update.go5
-rw-r--r--internal/ui/feed_refresh.go9
-rw-r--r--internal/ui/feed_update.go5
-rw-r--r--internal/ui/integration_pocket.go12
-rw-r--r--internal/ui/login_check.go27
-rw-r--r--internal/ui/logout.go4
-rw-r--r--internal/ui/middleware.go58
-rw-r--r--internal/ui/oauth2_callback.go37
-rw-r--r--internal/ui/oauth2_redirect.go9
-rw-r--r--internal/ui/oauth2_unlink.go9
-rw-r--r--internal/ui/opml_upload.go30
-rw-r--r--internal/ui/proxy.go27
-rw-r--r--internal/ui/session_remove.go4
-rw-r--r--internal/ui/settings_update.go5
-rw-r--r--internal/ui/subscription_submit.go4
-rw-r--r--internal/ui/ui.go3
-rw-r--r--internal/ui/user_remove.go2
-rw-r--r--internal/ui/user_save.go5
-rw-r--r--internal/ui/user_update.go5
22 files changed, 173 insertions, 101 deletions
diff --git a/internal/ui/api_key_remove.go b/internal/ui/api_key_remove.go
index c478cd98..3730240c 100644
--- a/internal/ui/api_key_remove.go
+++ b/internal/ui/api_key_remove.go
@@ -9,14 +9,14 @@ import (
"miniflux.app/v2/internal/http/request"
"miniflux.app/v2/internal/http/response/html"
"miniflux.app/v2/internal/http/route"
- "miniflux.app/v2/internal/logger"
)
func (h *handler) removeAPIKey(w http.ResponseWriter, r *http.Request) {
keyID := request.RouteInt64Param(r, "keyID")
err := h.store.RemoveAPIKey(request.UserID(r), keyID)
if err != nil {
- logger.Error("[UI:RemoveAPIKey] %v", err)
+ html.ServerError(w, r, err)
+ return
}
html.Redirect(w, r, route.Path(h.router, "apiKeys"))
diff --git a/internal/ui/api_key_save.go b/internal/ui/api_key_save.go
index f311e311..ebadd300 100644
--- a/internal/ui/api_key_save.go
+++ b/internal/ui/api_key_save.go
@@ -9,7 +9,6 @@ import (
"miniflux.app/v2/internal/http/request"
"miniflux.app/v2/internal/http/response/html"
"miniflux.app/v2/internal/http/route"
- "miniflux.app/v2/internal/logger"
"miniflux.app/v2/internal/model"
"miniflux.app/v2/internal/ui/form"
"miniflux.app/v2/internal/ui/session"
@@ -47,9 +46,7 @@ func (h *handler) saveAPIKey(w http.ResponseWriter, r *http.Request) {
apiKey := model.NewAPIKey(user.ID, apiKeyForm.Description)
if err = h.store.CreateAPIKey(apiKey); err != nil {
- logger.Error("[UI:SaveAPIKey] %v", err)
- view.Set("errorMessage", "error.unable_to_create_api_key")
- html.OK(w, r, view.Render("create_api_key"))
+ html.ServerError(w, r, err)
return
}
diff --git a/internal/ui/category_save.go b/internal/ui/category_save.go
index bfdd3afe..e4708b5a 100644
--- a/internal/ui/category_save.go
+++ b/internal/ui/category_save.go
@@ -9,7 +9,6 @@ import (
"miniflux.app/v2/internal/http/request"
"miniflux.app/v2/internal/http/response/html"
"miniflux.app/v2/internal/http/route"
- "miniflux.app/v2/internal/logger"
"miniflux.app/v2/internal/model"
"miniflux.app/v2/internal/ui/form"
"miniflux.app/v2/internal/ui/session"
@@ -43,9 +42,7 @@ func (h *handler) saveCategory(w http.ResponseWriter, r *http.Request) {
}
if _, err = h.store.CreateCategory(loggedUser.ID, categoryRequest); err != nil {
- logger.Error("[UI:SaveCategory] %v", err)
- view.Set("errorMessage", "error.unable_to_create_category")
- html.OK(w, r, view.Render("create_category"))
+ html.ServerError(w, r, err)
return
}
diff --git a/internal/ui/category_update.go b/internal/ui/category_update.go
index 5a8483fa..8dad9375 100644
--- a/internal/ui/category_update.go
+++ b/internal/ui/category_update.go
@@ -9,7 +9,6 @@ import (
"miniflux.app/v2/internal/http/request"
"miniflux.app/v2/internal/http/response/html"
"miniflux.app/v2/internal/http/route"
- "miniflux.app/v2/internal/logger"
"miniflux.app/v2/internal/model"
"miniflux.app/v2/internal/ui/form"
"miniflux.app/v2/internal/ui/session"
@@ -60,9 +59,7 @@ func (h *handler) updateCategory(w http.ResponseWriter, r *http.Request) {
categoryRequest.Patch(category)
if err := h.store.UpdateCategory(category); err != nil {
- logger.Error("[UI:UpdateCategory] %v", err)
- view.Set("errorMessage", "error.unable_to_update_category")
- html.OK(w, r, view.Render("edit_category"))
+ html.ServerError(w, r, err)
return
}
diff --git a/internal/ui/feed_refresh.go b/internal/ui/feed_refresh.go
index 22f87d01..11c5cff5 100644
--- a/internal/ui/feed_refresh.go
+++ b/internal/ui/feed_refresh.go
@@ -4,12 +4,12 @@
package ui // import "miniflux.app/v2/internal/ui"
import (
+ "log/slog"
"net/http"
"miniflux.app/v2/internal/http/request"
"miniflux.app/v2/internal/http/response/html"
"miniflux.app/v2/internal/http/route"
- "miniflux.app/v2/internal/logger"
feedHandler "miniflux.app/v2/internal/reader/handler"
)
@@ -17,7 +17,12 @@ func (h *handler) refreshFeed(w http.ResponseWriter, r *http.Request) {
feedID := request.RouteInt64Param(r, "feedID")
forceRefresh := request.QueryBoolParam(r, "forceRefresh", false)
if err := feedHandler.RefreshFeed(h.store, request.UserID(r), feedID, forceRefresh); err != nil {
- logger.Error("[UI:RefreshFeed] %v", err)
+ slog.Warn("Unable to refresh feed",
+ slog.Int64("user_id", request.UserID(r)),
+ slog.Int64("feed_id", feedID),
+ slog.Bool("force_refresh", forceRefresh),
+ slog.Any("error", err),
+ )
}
html.Redirect(w, r, route.Path(h.router, "feedEntries", "feedID", feedID))
diff --git a/internal/ui/feed_update.go b/internal/ui/feed_update.go
index cdefab35..773c61b2 100644
--- a/internal/ui/feed_update.go
+++ b/internal/ui/feed_update.go
@@ -10,7 +10,6 @@ import (
"miniflux.app/v2/internal/http/request"
"miniflux.app/v2/internal/http/response/html"
"miniflux.app/v2/internal/http/route"
- "miniflux.app/v2/internal/logger"
"miniflux.app/v2/internal/model"
"miniflux.app/v2/internal/ui/form"
"miniflux.app/v2/internal/ui/session"
@@ -74,9 +73,7 @@ func (h *handler) updateFeed(w http.ResponseWriter, r *http.Request) {
err = h.store.UpdateFeed(feedForm.Merge(feed))
if err != nil {
- logger.Error("[UI:UpdateFeed] %v", err)
- view.Set("errorMessage", "error.unable_to_update_feed")
- html.OK(w, r, view.Render("edit_feed"))
+ html.ServerError(w, r, err)
return
}
diff --git a/internal/ui/integration_pocket.go b/internal/ui/integration_pocket.go
index 752394f5..7da6b072 100644
--- a/internal/ui/integration_pocket.go
+++ b/internal/ui/integration_pocket.go
@@ -4,6 +4,7 @@
package ui // import "miniflux.app/v2/internal/ui"
import (
+ "log/slog"
"net/http"
"miniflux.app/v2/internal/config"
@@ -12,7 +13,6 @@ import (
"miniflux.app/v2/internal/http/route"
"miniflux.app/v2/internal/integration/pocket"
"miniflux.app/v2/internal/locale"
- "miniflux.app/v2/internal/logger"
"miniflux.app/v2/internal/ui/session"
)
@@ -35,7 +35,10 @@ func (h *handler) pocketAuthorize(w http.ResponseWriter, r *http.Request) {
redirectURL := config.Opts.RootURL() + route.Path(h.router, "pocketCallback")
requestToken, err := connector.RequestToken(redirectURL)
if err != nil {
- logger.Error("[Pocket:Authorize] %v", err)
+ slog.Warn("Pocket authorization request failed",
+ slog.Any("user_id", user.ID),
+ slog.Any("error", err),
+ )
sess.NewFlashErrorMessage(printer.Printf("error.pocket_request_token"))
html.Redirect(w, r, route.Path(h.router, "integrations"))
return
@@ -64,7 +67,10 @@ func (h *handler) pocketCallback(w http.ResponseWriter, r *http.Request) {
connector := pocket.NewConnector(config.Opts.PocketConsumerKey(integration.PocketConsumerKey))
accessToken, err := connector.AccessToken(request.PocketRequestToken(r))
if err != nil {
- logger.Error("[Pocket:Callback] %v", err)
+ slog.Warn("Unable to get Pocket access token",
+ slog.Any("user_id", user.ID),
+ slog.Any("error", err),
+ )
sess.NewFlashErrorMessage(printer.Printf("error.pocket_access_token"))
html.Redirect(w, r, route.Path(h.router, "integrations"))
return
diff --git a/internal/ui/login_check.go b/internal/ui/login_check.go
index ba15b7c6..9ae56c47 100644
--- a/internal/ui/login_check.go
+++ b/internal/ui/login_check.go
@@ -4,6 +4,7 @@
package ui // import "miniflux.app/v2/internal/ui"
import (
+ "log/slog"
"net/http"
"miniflux.app/v2/internal/config"
@@ -11,7 +12,6 @@ import (
"miniflux.app/v2/internal/http/request"
"miniflux.app/v2/internal/http/response/html"
"miniflux.app/v2/internal/http/route"
- "miniflux.app/v2/internal/logger"
"miniflux.app/v2/internal/ui/form"
"miniflux.app/v2/internal/ui/session"
"miniflux.app/v2/internal/ui/view"
@@ -27,13 +27,25 @@ func (h *handler) checkLogin(w http.ResponseWriter, r *http.Request) {
view.Set("form", authForm)
if err := authForm.Validate(); err != nil {
- logger.Error("[UI:CheckLogin] %v", err)
+ slog.Warn("Validation error during login check",
+ slog.Bool("authentication_failed", true),
+ slog.String("client_ip", clientIP),
+ slog.String("user_agent", r.UserAgent()),
+ slog.String("username", authForm.Username),
+ slog.Any("error", err),
+ )
html.OK(w, r, view.Render("login"))
return
}
if err := h.store.CheckPassword(authForm.Username, authForm.Password); err != nil {
- logger.Error("[UI:CheckLogin] [ClientIP=%s] %v", clientIP, err)
+ slog.Warn("Incorrect username or password",
+ slog.Bool("authentication_failed", true),
+ slog.String("client_ip", clientIP),
+ slog.String("user_agent", r.UserAgent()),
+ slog.String("username", authForm.Username),
+ slog.Any("error", err),
+ )
html.OK(w, r, view.Render("login"))
return
}
@@ -44,7 +56,14 @@ func (h *handler) checkLogin(w http.ResponseWriter, r *http.Request) {
return
}
- logger.Info("[UI:CheckLogin] username=%s just logged in", authForm.Username)
+ slog.Info("User authenticated successfully with username/password",
+ slog.Bool("authentication_successful", true),
+ slog.String("client_ip", clientIP),
+ slog.String("user_agent", r.UserAgent()),
+ slog.Int64("user_id", userID),
+ slog.String("username", authForm.Username),
+ )
+
h.store.SetLastLogin(userID)
user, err := h.store.UserByID(userID)
diff --git a/internal/ui/logout.go b/internal/ui/logout.go
index 40e51b0d..92896050 100644
--- a/internal/ui/logout.go
+++ b/internal/ui/logout.go
@@ -11,7 +11,6 @@ import (
"miniflux.app/v2/internal/http/request"
"miniflux.app/v2/internal/http/response/html"
"miniflux.app/v2/internal/http/route"
- "miniflux.app/v2/internal/logger"
"miniflux.app/v2/internal/ui/session"
)
@@ -27,7 +26,8 @@ func (h *handler) logout(w http.ResponseWriter, r *http.Request) {
sess.SetTheme(user.Theme)
if err := h.store.RemoveUserSessionByToken(user.ID, request.UserSessionToken(r)); err != nil {
- logger.Error("[UI:Logout] %v", err)
+ html.ServerError(w, r, err)
+ return
}
http.SetCookie(w, cookie.Expired(
diff --git a/internal/ui/middleware.go b/internal/ui/middleware.go
index e06fb98e..7df1c6af 100644
--- a/internal/ui/middleware.go
+++ b/internal/ui/middleware.go
@@ -6,6 +6,7 @@ package ui // import "miniflux.app/v2/internal/ui"
import (
"context"
"errors"
+ "log/slog"
"net/http"
"miniflux.app/v2/internal/config"
@@ -13,7 +14,6 @@ import (
"miniflux.app/v2/internal/http/request"
"miniflux.app/v2/internal/http/response/html"
"miniflux.app/v2/internal/http/route"
- "miniflux.app/v2/internal/logger"
"miniflux.app/v2/internal/model"
"miniflux.app/v2/internal/storage"
"miniflux.app/v2/internal/ui/session"
@@ -38,11 +38,17 @@ func (m *middleware) handleUserSession(next http.Handler) http.Handler {
if m.isPublicRoute(r) {
next.ServeHTTP(w, r)
} else {
- logger.Debug("[UI:UserSession] Session not found, redirect to login page")
+ slog.Debug("Redirecting to login page because no user session has been found",
+ slog.Any("url", r.RequestURI),
+ )
html.Redirect(w, r, route.Path(m.router, "login"))
}
} else {
- logger.Debug("[UI:UserSession] %s", session)
+ slog.Debug("User session found",
+ slog.Any("url", r.RequestURI),
+ slog.Int64("user_id", session.UserID),
+ slog.Int64("user_session_id", session.ID),
+ )
ctx := r.Context()
ctx = context.WithValue(ctx, request.UserIDContextKey, session.UserID)
@@ -62,14 +68,16 @@ func (m *middleware) handleAppSession(next http.Handler) http.Handler {
if session == nil {
if request.IsAuthenticated(r) {
userID := request.UserID(r)
- logger.Debug("[UI:AppSession] Cookie expired but user #%d is logged: creating a new session", userID)
+ slog.Debug("Cookie expired but user is logged: creating a new app session",
+ slog.Int64("user_id", userID),
+ )
session, err = m.store.CreateAppSessionWithUserPrefs(userID)
if err != nil {
html.ServerError(w, r, err)
return
}
} else {
- logger.Debug("[UI:AppSession] Session not found, creating a new one")
+ slog.Debug("App session not found, creating a new one")
session, err = m.store.CreateAppSession()
if err != nil {
html.ServerError(w, r, err)
@@ -78,8 +86,6 @@ func (m *middleware) handleAppSession(next http.Handler) http.Handler {
}
http.SetCookie(w, cookie.New(cookie.CookieAppSessionID, session.ID, config.Opts.HTTPS, config.Opts.BasePath()))
- } else {
- logger.Debug("[UI:AppSession] %s", session)
}
if r.Method == http.MethodPost {
@@ -87,7 +93,11 @@ func (m *middleware) handleAppSession(next http.Handler) http.Handler {
headerValue := r.Header.Get("X-Csrf-Token")
if session.Data.CSRF != formValue && session.Data.CSRF != headerValue {
- logger.Error(`[UI:AppSession] Invalid or missing CSRF token: Form="%s", Header="%s"`, formValue, headerValue)
+ slog.Warn("Invalid or missing CSRF token",
+ slog.Any("url", r.RequestURI),
+ slog.String("form_csrf", formValue),
+ slog.String("header_csrf", headerValue),
+ )
if mux.CurrentRoute(r).GetName() == "checkLogin" {
html.Redirect(w, r, route.Path(m.router, "login"))
@@ -121,7 +131,10 @@ func (m *middleware) getAppSessionValueFromCookie(r *http.Request) *model.Sessio
session, err := m.store.AppSession(cookieValue)
if err != nil {
- logger.Error("[UI:AppSession] %v", err)
+ slog.Debug("Unable to fetch app session from the database; another session will be created",
+ slog.Any("cookie_value", cookieValue),
+ slog.Any("error", err),
+ )
return nil
}
@@ -159,7 +172,10 @@ func (m *middleware) getUserSessionFromCookie(r *http.Request) *model.UserSessio
session, err := m.store.UserSessionByToken(cookieValue)
if err != nil {
- logger.Error("[UI:UserSession] %v", err)
+ slog.Error("Unable to fetch user session from the database",
+ slog.Any("cookie_value", cookieValue),
+ slog.Any("error", err),
+ )
return nil
}
@@ -180,7 +196,11 @@ func (m *middleware) handleAuthProxy(next http.Handler) http.Handler {
}
clientIP := request.ClientIP(r)
- logger.Info("[AuthProxy] [ClientIP=%s] Received authenticated requested for %q", clientIP, username)
+ slog.Debug("[AuthProxy] Received authenticated requested",
+ slog.String("client_ip", clientIP),
+ slog.String("user_agent", r.UserAgent()),
+ slog.String("username", username),
+ )
user, err := m.store.UserByUsername(username)
if err != nil {
@@ -189,9 +209,13 @@ func (m *middleware) handleAuthProxy(next http.Handler) http.Handler {
}
if user == nil {
- logger.Error("[AuthProxy] [ClientIP=%s] %q doesn't exist", clientIP, username)
-
if !config.Opts.IsAuthProxyUserCreationAllowed() {
+ slog.Debug("[AuthProxy] User doesn't exist and user creation is not allowed",
+ slog.Bool("authentication_failed", true),
+ slog.String("client_ip", clientIP),
+ slog.String("user_agent", r.UserAgent()),
+ slog.String("username", username),
+ )
html.Forbidden(w, r)
return
}
@@ -208,7 +232,13 @@ func (m *middleware) handleAuthProxy(next http.Handler) http.Handler {
return
}
- logger.Info("[AuthProxy] [ClientIP=%s] username=%s just logged in", clientIP, user.Username)
+ slog.Info("[AuthProxy] User authenticated successfully",
+ slog.Bool("authentication_successful", true),
+ slog.String("client_ip", clientIP),
+ slog.String("user_agent", r.UserAgent()),
+ slog.Int64("user_id", user.ID),
+ slog.String("username", user.Username),
+ )
m.store.SetLastLogin(user.ID)
diff --git a/internal/ui/oauth2_callback.go b/internal/ui/oauth2_callback.go
index 01e7abdc..4810afab 100644
--- a/internal/ui/oauth2_callback.go
+++ b/internal/ui/oauth2_callback.go
@@ -6,6 +6,7 @@ package ui // import "miniflux.app/v2/internal/ui"
import (
"crypto/subtle"
"errors"
+ "log/slog"
"net/http"
"miniflux.app/v2/internal/config"
@@ -14,7 +15,6 @@ import (
"miniflux.app/v2/internal/http/response/html"
"miniflux.app/v2/internal/http/route"
"miniflux.app/v2/internal/locale"
- "miniflux.app/v2/internal/logger"
"miniflux.app/v2/internal/model"
"miniflux.app/v2/internal/ui/session"
)
@@ -26,41 +26,48 @@ func (h *handler) oauth2Callback(w http.ResponseWriter, r *http.Request) {
provider := request.RouteStringParam(r, "provider")
if provider == "" {
- logger.Error("[OAuth2] Invalid or missing provider")
+ slog.Warn("Invalid or missing OAuth2 provider")
html.Redirect(w, r, route.Path(h.router, "login"))
return
}
code := request.QueryStringParam(r, "code", "")
if code == "" {
- logger.Error("[OAuth2] No code received on callback")
+ slog.Warn("No code received on OAuth2 callback")
html.Redirect(w, r, route.Path(h.router, "login"))
return
}
state := request.QueryStringParam(r, "state", "")
if subtle.ConstantTimeCompare([]byte(state), []byte(request.OAuth2State(r))) == 0 {
- logger.Error(`[OAuth2] Invalid state value: got "%s" instead of "%s"`, state, request.OAuth2State(r))
+ slog.Warn("Invalid OAuth2 state value received",
+ slog.String("expected", request.OAuth2State(r)),
+ slog.String("received", state),
+ )
html.Redirect(w, r, route.Path(h.router, "login"))
return
}
authProvider, err := getOAuth2Manager(r.Context()).FindProvider(provider)
if err != nil {
- logger.Error("[OAuth2] %v", err)
+ slog.Error("Unable to initialize OAuth2 provider",
+ slog.String("provider", provider),
+ slog.Any("error", err),
+ )
html.Redirect(w, r, route.Path(h.router, "login"))
return
}
profile, err := authProvider.GetProfile(r.Context(), code, request.OAuth2CodeVerifier(r))
if err != nil {
- logger.Error("[OAuth2] %v", err)
+ slog.Warn("Unable to get OAuth2 profile from provider",
+ slog.String("provider", provider),
+ slog.Any("error", err),
+ )
html.Redirect(w, r, route.Path(h.router, "login"))
return
}
- logger.Info("[OAuth2] [ClientIP=%s] Successful auth for %s", clientIP, profile)
-
if request.IsAuthenticated(r) {
loggedUser, err := h.store.UserByID(request.UserID(r))
if err != nil {
@@ -69,7 +76,11 @@ func (h *handler) oauth2Callback(w http.ResponseWriter, r *http.Request) {
}
if h.store.AnotherUserWithFieldExists(loggedUser.ID, profile.Key, profile.ID) {
- logger.Error("[OAuth2] User #%d cannot be associated because it is already associated with another user", loggedUser.ID)
+ slog.Error("Oauth2 user cannot be associated because it is already associated with another user",
+ slog.Int64("user_id", loggedUser.ID),
+ slog.String("oauth2_provider", provider),
+ slog.String("oauth2_profile_id", profile.ID),
+ )
sess.NewFlashErrorMessage(printer.Printf("error.duplicate_linked_account"))
html.Redirect(w, r, route.Path(h.router, "settings"))
return
@@ -119,7 +130,13 @@ func (h *handler) oauth2Callback(w http.ResponseWriter, r *http.Request) {
return
}
- logger.Info("[OAuth2] [ClientIP=%s] username=%s (%s) just logged in", clientIP, user.Username, profile)
+ slog.Info("User authenticated successfully using OAuth2",
+ slog.Bool("authentication_successful", true),
+ slog.String("client_ip", clientIP),
+ slog.String("user_agent", r.UserAgent()),
+ slog.Int64("user_id", user.ID),
+ slog.String("username", user.Username),
+ )
h.store.SetLastLogin(user.ID)
sess.SetLanguage(user.Language)
diff --git a/internal/ui/oauth2_redirect.go b/internal/ui/oauth2_redirect.go
index 622b544c..78f9fd1a 100644
--- a/internal/ui/oauth2_redirect.go
+++ b/internal/ui/oauth2_redirect.go
@@ -4,12 +4,12 @@
package ui // import "miniflux.app/v2/internal/ui"
import (
+ "log/slog"
"net/http"
"miniflux.app/v2/internal/http/request"
"miniflux.app/v2/internal/http/response/html"
"miniflux.app/v2/internal/http/route"
- "miniflux.app/v2/internal/logger"
"miniflux.app/v2/internal/oauth2"
"miniflux.app/v2/internal/ui/session"
)
@@ -19,14 +19,17 @@ func (h *handler) oauth2Redirect(w http.ResponseWriter, r *http.Request) {
provider := request.RouteStringParam(r, "provider")
if provider == "" {
- logger.Error("[OAuth2] Invalid or missing provider: %s", provider)
+ slog.Warn("Invalid or missing OAuth2 provider")
html.Redirect(w, r, route.Path(h.router, "login"))
return
}
authProvider, err := getOAuth2Manager(r.Context()).FindProvider(provider)
if err != nil {
- logger.Error("[OAuth2] %v", err)
+ slog.Error("Unable to initialize OAuth2 provider",
+ slog.String("provider", provider),
+ slog.Any("error", err),
+ )
html.Redirect(w, r, route.Path(h.router, "login"))
return
}
diff --git a/internal/ui/oauth2_unlink.go b/internal/ui/oauth2_unlink.go
index 6fe44cbb..8a698a3e 100644
--- a/internal/ui/oauth2_unlink.go
+++ b/internal/ui/oauth2_unlink.go
@@ -4,13 +4,13 @@
package ui // import "miniflux.app/v2/internal/ui"
import (
+ "log/slog"
"net/http"
"miniflux.app/v2/internal/http/request"
"miniflux.app/v2/internal/http/response/html"
"miniflux.app/v2/internal/http/route"
"miniflux.app/v2/internal/locale"
- "miniflux.app/v2/internal/logger"
"miniflux.app/v2/internal/ui/session"
)
@@ -18,14 +18,17 @@ func (h *handler) oauth2Unlink(w http.ResponseWriter, r *http.Request) {
printer := locale.NewPrinter(request.UserLanguage(r))
provider := request.RouteStringParam(r, "provider")
if provider == "" {
- logger.Info("[OAuth2] Invalid or missing provider")
+ slog.Warn("Invalid or missing OAuth2 provider")
html.Redirect(w, r, route.Path(h.router, "login"))
return
}
authProvider, err := getOAuth2Manager(r.Context()).FindProvider(provider)
if err != nil {
- logger.Error("[OAuth2] %v", err)
+ slog.Error("Unable to initialize OAuth2 provider",
+ slog.String("provider", provider),
+ slog.Any("error", err),
+ )
html.Redirect(w, r, route.Path(h.router, "settings"))
return
}
diff --git a/internal/ui/opml_upload.go b/internal/ui/opml_upload.go
index 0d7c0507..0121952a 100644
--- a/internal/ui/opml_upload.go
+++ b/internal/ui/opml_upload.go
@@ -4,6 +4,7 @@
package ui // import "miniflux.app/v2/internal/ui"
import (
+ "log/slog"
"net/http"
"miniflux.app/v2/internal/config"
@@ -11,14 +12,14 @@ import (
"miniflux.app/v2/internal/http/request"
"miniflux.app/v2/internal/http/response/html"
"miniflux.app/v2/internal/http/route"
- "miniflux.app/v2/internal/logger"
"miniflux.app/v2/internal/reader/opml"
"miniflux.app/v2/internal/ui/session"
"miniflux.app/v2/internal/ui/view"
)
func (h *handler) uploadOPML(w http.ResponseWriter, r *http.Request) {
- user, err := h.store.UserByID(request.UserID(r))
+ loggedUserID := request.UserID(r)
+ user, err := h.store.UserByID(loggedUserID)
if err != nil {
html.ServerError(w, r, err)
return
@@ -26,17 +27,20 @@ func (h *handler) uploadOPML(w http.ResponseWriter, r *http.Request) {
file, fileHeader, err := r.FormFile("file")
if err != nil {
- logger.Error("[UI:UploadOPML] %v", err)
+ slog.Error("OPML file upload error",
+ slog.Int64("user_id", loggedUserID),
+ slog.Any("error", err),
+ )
+
html.Redirect(w, r, route.Path(h.router, "import"))
return
}
defer file.Close()
- logger.Debug(
- "[UI:UploadOPML] User #%d uploaded this file: %s (%d bytes)",
- user.ID,
- fileHeader.Filename,
- fileHeader.Size,
+ slog.Info("OPML file uploaded",
+ slog.Int64("user_id", loggedUserID),
+ slog.String("file_name", fileHeader.Filename),
+ slog.Int64("file_size", fileHeader.Size),
)
sess := session.New(h.store, request.SessionID(r))
@@ -62,7 +66,8 @@ func (h *handler) uploadOPML(w http.ResponseWriter, r *http.Request) {
}
func (h *handler) fetchOPML(w http.ResponseWriter, r *http.Request) {
- user, err := h.store.UserByID(request.UserID(r))
+ loggedUserID := request.UserID(r)
+ user, err := h.store.UserByID(loggedUserID)
if err != nil {
html.ServerError(w, r, err)
return
@@ -74,10 +79,9 @@ func (h *handler) fetchOPML(w http.ResponseWriter, r *http.Request) {
return
}
- logger.Debug(
- "[UI:FetchOPML] User #%d fetching this URL: %s",
- user.ID,
- url,
+ slog.Info("Fetching OPML file remotely",
+ slog.Int64("user_id", loggedUserID),
+ slog.String("opml_file_url", url),
)
sess := session.New(h.store, request.SessionID(r))
diff --git a/internal/ui/proxy.go b/internal/ui/proxy.go
index ce0c39b1..1af18ec1 100644
--- a/internal/ui/proxy.go
+++ b/internal/ui/proxy.go
@@ -8,6 +8,7 @@ import (
"crypto/sha256"
"encoding/base64"
"errors"
+ "log/slog"
"net/http"
"time"
@@ -16,7 +17,6 @@ import (
"miniflux.app/v2/internal/http/request"
"miniflux.app/v2/internal/http/response"
"miniflux.app/v2/internal/http/response/html"
- "miniflux.app/v2/internal/logger"
)
func (h *handler) mediaProxy(w http.ResponseWriter, r *http.Request) {
@@ -29,19 +29,19 @@ func (h *handler) mediaProxy(w http.ResponseWriter, r *http.Request) {
encodedDigest := request.RouteStringParam(r, "encodedDigest")
encodedURL := request.RouteStringParam(r, "encodedURL")
if encodedURL == "" {
- html.BadRequest(w, r, errors.New("No URL provided"))
+ html.BadRequest(w, r, errors.New("no URL provided"))
return
}
decodedDigest, err := base64.URLEncoding.DecodeString(encodedDigest)
if err != nil {
- html.BadRequest(w, r, errors.New("Unable to decode this Digest"))
+ html.BadRequest(w, r, errors.New("unable to decode this digest"))
return
}
decodedURL, err := base64.URLEncoding.DecodeString(encodedURL)
if err != nil {
- html.BadRequest(w, r, errors.New("Unable to decode this URL"))
+ html.BadRequest(w, r, errors.New("unable to decode this URL"))
return
}
@@ -55,7 +55,9 @@ func (h *handler) mediaProxy(w http.ResponseWriter, r *http.Request) {
}
mediaURL := string(decodedURL)
- logger.Debug(`[Proxy] Fetching %q`, mediaURL)
+ slog.Debug("MediaProxy: Fetching remote resource",
+ slog.String("media_url", mediaURL),
+ )
req, err := http.NewRequest("GET", mediaURL, nil)
if err != nil {
@@ -82,19 +84,28 @@ func (h *handler) mediaProxy(w http.ResponseWriter, r *http.Request) {
resp, err := clt.Do(req)
if err != nil {
- logger.Error(`[Proxy] Unable to initialize HTTP client: %v`, err)
+ slog.Error("MediaProxy: Unable to initialize HTTP client",
+ slog.String("media_url", mediaURL),
+ slog.Any("error", err),
+ )
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return
}
defer resp.Body.Close()
if resp.StatusCode == http.StatusRequestedRangeNotSatisfiable {
- logger.Error(`[Proxy] Status Code is %d for URL %q`, resp.StatusCode, mediaURL)
+ slog.Warn("MediaProxy: "+http.StatusText(http.StatusRequestedRangeNotSatisfiable),
+ slog.String("media_url", mediaURL),
+ slog.Int("status_code", resp.StatusCode),
+ )
html.RequestedRangeNotSatisfiable(w, r, resp.Header.Get("Content-Range"))
return
}
if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusPartialContent {
- logger.Error(`[Proxy] Status Code is %d for URL %q`, resp.StatusCode, mediaURL)
+ slog.Warn("MediaProxy: Unexpected response status code",
+ slog.String("media_url", mediaURL),
+ slog.Int("status_code", resp.StatusCode),
+ )
html.NotFound(w, r)
return
}
diff --git a/internal/ui/session_remove.go b/internal/ui/session_remove.go
index 59e58881..84ed63b9 100644
--- a/internal/ui/session_remove.go
+++ b/internal/ui/session_remove.go
@@ -9,14 +9,14 @@ import (
"miniflux.app/v2/internal/http/request"
"miniflux.app/v2/internal/http/response/html"
"miniflux.app/v2/internal/http/route"
- "miniflux.app/v2/internal/logger"
)
func (h *handler) removeSession(w http.ResponseWriter, r *http.Request) {
sessionID := request.RouteInt64Param(r, "sessionID")
err := h.store.RemoveUserSessionByID(request.UserID(r), sessionID)
if err != nil {
- logger.Error("[UI:RemoveSession] %v", err)
+ html.ServerError(w, r, err)
+ return
}
html.Redirect(w, r, route.Path(h.router, "sessions"))
diff --git a/internal/ui/settings_update.go b/internal/ui/settings_update.go
index 9bd51552..a9a8b519 100644
--- a/internal/ui/settings_update.go
+++ b/internal/ui/settings_update.go
@@ -10,7 +10,6 @@ import (
"miniflux.app/v2/internal/http/response/html"
"miniflux.app/v2/internal/http/route"
"miniflux.app/v2/internal/locale"
- "miniflux.app/v2/internal/logger"
"miniflux.app/v2/internal/model"
"miniflux.app/v2/internal/ui/form"
"miniflux.app/v2/internal/ui/session"
@@ -74,9 +73,7 @@ func (h *handler) updateSettings(w http.ResponseWriter, r *http.Request) {
err = h.store.UpdateUser(settingsForm.Merge(loggedUser))
if err != nil {
- logger.Error("[UI:UpdateSettings] %v", err)
- view.Set("errorMessage", "error.unable_to_update_user")
- html.OK(w, r, view.Render("settings"))
+ html.ServerError(w, r, err)
return
}
diff --git a/internal/ui/subscription_submit.go b/internal/ui/subscription_submit.go
index 42a5c8e6..75774c2e 100644
--- a/internal/ui/subscription_submit.go
+++ b/internal/ui/subscription_submit.go
@@ -10,7 +10,6 @@ import (
"miniflux.app/v2/internal/http/request"
"miniflux.app/v2/internal/http/response/html"
"miniflux.app/v2/internal/http/route"
- "miniflux.app/v2/internal/logger"
"miniflux.app/v2/internal/model"
feedHandler "miniflux.app/v2/internal/reader/handler"
"miniflux.app/v2/internal/reader/subscription"
@@ -61,15 +60,12 @@ func (h *handler) submitSubscription(w http.ResponseWriter, r *http.Request) {
subscriptionForm.AllowSelfSignedCertificates,
)
if findErr != nil {
- logger.Error("[UI:SubmitSubscription] %q -> %s", subscriptionForm.URL, findErr)
v.Set("form", subscriptionForm)
v.Set("errorMessage", findErr)
html.OK(w, r, v.Render("add_subscription"))
return
}
- logger.Debug("[UI:SubmitSubscription] %s", subscriptions)
-
n := len(subscriptions)
switch {
case n == 0:
diff --git a/internal/ui/ui.go b/internal/ui/ui.go
index 3acc32ad..64149658 100644
--- a/internal/ui/ui.go
+++ b/internal/ui/ui.go
@@ -6,7 +6,6 @@ package ui // import "miniflux.app/v2/internal/ui"
import (
"net/http"
- "miniflux.app/v2/internal/logger"
"miniflux.app/v2/internal/storage"
"miniflux.app/v2/internal/template"
"miniflux.app/v2/internal/worker"
@@ -20,7 +19,7 @@ func Serve(router *mux.Router, store *storage.Storage, pool *worker.Pool) {
templateEngine := template.NewEngine(router)
if err := templateEngine.ParseTemplates(); err != nil {
- logger.Fatal(`Unable to parse templates: %v`, err)
+ panic(err)
}
handler := &handler{router, store, templateEngine, pool}
diff --git a/internal/ui/user_remove.go b/internal/ui/user_remove.go
index eab3eec4..bd2a9caf 100644
--- a/internal/ui/user_remove.go
+++ b/internal/ui/user_remove.go
@@ -37,7 +37,7 @@ func (h *handler) removeUser(w http.ResponseWriter, r *http.Request) {
}
if selectedUser.ID == loggedUser.ID {
- html.BadRequest(w, r, errors.New("You cannot remove yourself"))
+ html.BadRequest(w, r, errors.New("you cannot remove yourself"))
return
}
diff --git a/internal/ui/user_save.go b/internal/ui/user_save.go
index 79b4bc36..982c4973 100644
--- a/internal/ui/user_save.go
+++ b/internal/ui/user_save.go
@@ -9,7 +9,6 @@ import (
"miniflux.app/v2/internal/http/request"
"miniflux.app/v2/internal/http/response/html"
"miniflux.app/v2/internal/http/route"
- "miniflux.app/v2/internal/logger"
"miniflux.app/v2/internal/model"
"miniflux.app/v2/internal/ui/form"
"miniflux.app/v2/internal/ui/session"
@@ -64,9 +63,7 @@ func (h *handler) saveUser(w http.ResponseWriter, r *http.Request) {
}
if _, err := h.store.CreateUser(userCreationRequest); err != nil {
- logger.Error("[UI:SaveUser] %v", err)
- view.Set("errorMessage", "error.unable_to_create_user")
- html.OK(w, r, view.Render("create_user"))
+ html.ServerError(w, r, err)
return
}
diff --git a/internal/ui/user_update.go b/internal/ui/user_update.go
index a3eb5b8d..3e4229c1 100644
--- a/internal/ui/user_update.go
+++ b/internal/ui/user_update.go
@@ -9,7 +9,6 @@ import (
"miniflux.app/v2/internal/http/request"
"miniflux.app/v2/internal/http/response/html"
"miniflux.app/v2/internal/http/route"
- "miniflux.app/v2/internal/logger"
"miniflux.app/v2/internal/ui/form"
"miniflux.app/v2/internal/ui/session"
"miniflux.app/v2/internal/ui/view"
@@ -64,9 +63,7 @@ func (h *handler) updateUser(w http.ResponseWriter, r *http.Request) {
userForm.Merge(selectedUser)
if err := h.store.UpdateUser(selectedUser); err != nil {
- logger.Error("[UI:UpdateUser] %v", err)
- view.Set("errorMessage", "error.unable_to_update_user")
- html.OK(w, r, view.Render("edit_user"))
+ html.ServerError(w, r, err)
return
}