diff --git a/Makefile b/Makefile index 52aa5a8c..dea912b9 100644 --- a/Makefile +++ b/Makefile @@ -20,7 +20,7 @@ DOCKER_TAG ?= deluan/navidrome:develop # Taglib version to use in cross-compilation, from https://github.com/navidrome/cross-taglib CROSS_TAGLIB_VERSION ?= 2.1.1-2 -GOLANGCI_LINT_VERSION ?= v2.9.0 +GOLANGCI_LINT_VERSION ?= v2.10.0 UI_SRC_FILES := $(shell find ui -type f -not -path "ui/build/*" -not -path "ui/node_modules/*") diff --git a/adapters/deezer/client_auth.go b/adapters/deezer/client_auth.go index c88c2bcb..d0924b76 100644 --- a/adapters/deezer/client_auth.go +++ b/adapters/deezer/client_auth.go @@ -65,7 +65,7 @@ func (c *client) getJWT(ctx context.Context) (string, error) { } type authResponse struct { - JWT string `json:"jwt"` + JWT string `json:"jwt"` //nolint:gosec } var result authResponse diff --git a/adapters/lastfm/auth_router.go b/adapters/lastfm/auth_router.go index 0052f73d..162ae903 100644 --- a/adapters/lastfm/auth_router.go +++ b/adapters/lastfm/auth_router.go @@ -110,7 +110,7 @@ func (s *Router) callback(w http.ResponseWriter, r *http.Request) { if err != nil { w.Header().Set("Content-Type", "text/plain; charset=utf-8") w.WriteHeader(http.StatusBadRequest) - _, _ = w.Write([]byte("An error occurred while authorizing with Last.fm. \n\nRequest ID: " + middleware.GetReqID(ctx))) + _, _ = w.Write([]byte("An error occurred while authorizing with Last.fm. \n\nRequest ID: " + middleware.GetReqID(ctx))) //nolint:gosec return } diff --git a/adapters/listenbrainz/client.go b/adapters/listenbrainz/client.go index 0427ed07..708f02f2 100644 --- a/adapters/listenbrainz/client.go +++ b/adapters/listenbrainz/client.go @@ -57,7 +57,7 @@ type listenBrainzResponse struct { } type listenBrainzRequest struct { - ApiKey string + ApiKey string //nolint:gosec Body listenBrainzRequestBody } diff --git a/conf/configuration.go b/conf/configuration.go index e2aca6c1..8994c1c8 100644 --- a/conf/configuration.go +++ b/conf/configuration.go @@ -172,8 +172,8 @@ type TagConf struct { type lastfmOptions struct { Enabled bool - ApiKey string - Secret string + ApiKey string //nolint:gosec + Secret string //nolint:gosec Language string ScrobbleFirstArtistOnly bool @@ -183,7 +183,7 @@ type lastfmOptions struct { type spotifyOptions struct { ID string - Secret string + Secret string //nolint:gosec } type deezerOptions struct { @@ -208,7 +208,7 @@ type httpHeaderOptions struct { type prometheusOptions struct { Enabled bool MetricsPath string - Password string + Password string //nolint:gosec } type AudioDeviceDefinition []string @@ -748,7 +748,7 @@ func getConfigFile(cfgFile string) string { } cfgFile = os.Getenv("ND_CONFIGFILE") if cfgFile != "" { - if _, err := os.Stat(cfgFile); err == nil { + if _, err := os.Stat(cfgFile); err == nil { //nolint:gosec return cfgFile } } diff --git a/core/artwork/sources.go b/core/artwork/sources.go index c7da7b19..b1b9b545 100644 --- a/core/artwork/sources.go +++ b/core/artwork/sources.go @@ -230,7 +230,7 @@ func fromURL(ctx context.Context, imageUrl *url.URL) (io.ReadCloser, string, err hc := http.Client{Timeout: 5 * time.Second} req, _ := http.NewRequestWithContext(ctx, http.MethodGet, imageUrl.String(), nil) req.Header.Set("User-Agent", consts.HTTPUserAgent) - resp, err := hc.Do(req) + resp, err := hc.Do(req) //nolint:gosec if err != nil { return nil, "", err } diff --git a/core/metrics/insights.go b/core/metrics/insights.go index 07162ded..849ddd6f 100644 --- a/core/metrics/insights.go +++ b/core/metrics/insights.go @@ -108,7 +108,7 @@ func (c *insightsCollector) sendInsights(ctx context.Context) { return } req.Header.Set("Content-Type", "application/json") - resp, err := hc.Do(req) + resp, err := hc.Do(req) //nolint:gosec if err != nil { log.Trace(ctx, "Could not send Insights data", err) return diff --git a/core/storage/local/local.go b/core/storage/local/local.go index 5c335ddb..cd60c9ef 100644 --- a/core/storage/local/local.go +++ b/core/storage/local/local.go @@ -44,7 +44,7 @@ func newLocalStorage(u url.URL) storage.Storage { func (s *localStorage) FS() (storage.MusicFS, error) { path := s.u.Path - if _, err := os.Stat(path); err != nil { + if _, err := os.Stat(path); err != nil { //nolint:gosec return nil, fmt.Errorf("%w: %s", err, path) } return &localFS{FS: os.DirFS(path), extractor: s.extractor}, nil diff --git a/model/user.go b/model/user.go index 2127b635..1c8541cc 100644 --- a/model/user.go +++ b/model/user.go @@ -22,7 +22,7 @@ type User struct { Password string `structs:"-" json:"-"` // This is used to set or change a password when calling Put. If it is empty, the password is not changed. // It is received from the UI with the name "password" - NewPassword string `structs:"password,omitempty" json:"password,omitempty"` + NewPassword string `structs:"password,omitempty" json:"password,omitempty"` //nolint:gosec // If changing the password, this is also required CurrentPassword string `structs:"current_password,omitempty" json:"currentPassword,omitempty"` } diff --git a/persistence/artist_repository.go b/persistence/artist_repository.go index b888256a..5623bd7f 100644 --- a/persistence/artist_repository.go +++ b/persistence/artist_repository.go @@ -138,7 +138,7 @@ func NewArtistRepository(ctx context.Context, db dbx.Builder) model.ArtistReposi "missing": booleanFilter, "library_id": artistLibraryIdFilter, }) - r.setSortMappings(map[string]string{ + r.setSortMappings(map[string]string{ //nolint:gosec "name": "order_artist_name", "starred_at": "starred, starred_at", "rated_at": "rating, rated_at", diff --git a/scanner/external.go b/scanner/external.go index 75ee2bea..29ca90be 100644 --- a/scanner/external.go +++ b/scanner/external.go @@ -158,7 +158,7 @@ func writeTargetsToFile(targets []model.ScanTarget) (string, error) { for _, target := range targets { if _, err := fmt.Fprintln(tmpFile, target.String()); err != nil { - os.Remove(tmpFile.Name()) + os.Remove(tmpFile.Name()) //nolint:gosec return "", fmt.Errorf("failed to write to temp file: %w", err) } } diff --git a/server/backgrounds/handler.go b/server/backgrounds/handler.go index 61b7d48b..b00a5169 100644 --- a/server/backgrounds/handler.go +++ b/server/backgrounds/handler.go @@ -80,7 +80,7 @@ func (h *Handler) serveImage(ctx context.Context, item cache.Item) (io.Reader, e } c := http.Client{Timeout: imageRequestTimeout} req, _ := http.NewRequestWithContext(ctx, http.MethodGet, imageURL(image), nil) - resp, err := c.Do(req) //nolint:bodyclose // No need to close resp.Body, it will be closed via the CachedStream wrapper + resp, err := c.Do(req) //nolint:bodyclose,gosec // No need to close resp.Body, it will be closed via the CachedStream wrapper if errors.Is(err, context.DeadlineExceeded) { defaultImage, _ := base64.StdEncoding.DecodeString(consts.DefaultUILoginBackgroundOffline) return strings.NewReader(string(defaultImage)), nil diff --git a/server/events/sse.go b/server/events/sse.go index 54a60298..39e21716 100644 --- a/server/events/sse.go +++ b/server/events/sse.go @@ -104,7 +104,7 @@ func writeEvent(ctx context.Context, w io.Writer, event message, timeout time.Du log.Debug(ctx, "Error setting write timeout", err) } - _, err := fmt.Fprintf(w, "id: %d\nevent: %s\ndata: %s\n\n", event.id, event.event, event.data) + _, err := fmt.Fprintf(w, "id: %d\nevent: %s\ndata: %s\n\n", event.id, event.event, event.data) //nolint:gosec if err != nil { return err } diff --git a/server/nativeapi/inspect.go b/server/nativeapi/inspect.go index 3178395c..7c96312e 100644 --- a/server/nativeapi/inspect.go +++ b/server/nativeapi/inspect.go @@ -60,7 +60,7 @@ func inspect(ds model.DataStore) http.HandlerFunc { w.Header().Set("Content-Type", "application/json") - if _, err := w.Write(response); err != nil { + if _, err := w.Write(response); err != nil { //nolint:gosec log.Error(ctx, "Error sending response to client", err) } } diff --git a/server/nativeapi/native_api.go b/server/nativeapi/native_api.go index 91ddd0fa..52e633be 100644 --- a/server/nativeapi/native_api.go +++ b/server/nativeapi/native_api.go @@ -207,7 +207,7 @@ func writeDeleteManyResponse(w http.ResponseWriter, r *http.Request, ids []strin http.Error(w, err.Error(), http.StatusInternalServerError) } } - _, err = w.Write(resp) + _, err = w.Write(resp) //nolint:gosec if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } @@ -243,7 +243,7 @@ func (api *Router) addInsightsRoute(r chi.Router) { r.Get("/insights/*", func(w http.ResponseWriter, r *http.Request) { last, success := api.insights.LastRun(r.Context()) if conf.Server.EnableInsightsCollector { - _, _ = w.Write([]byte(`{"id":"insights_status", "lastRun":"` + last.Format("2006-01-02 15:04:05") + `", "success":` + strconv.FormatBool(success) + `}`)) + _, _ = w.Write([]byte(`{"id":"insights_status", "lastRun":"` + last.Format("2006-01-02 15:04:05") + `", "success":` + strconv.FormatBool(success) + `}`)) //nolint:gosec } else { _, _ = w.Write([]byte(`{"id":"insights_status", "lastRun":"disabled", "success":false}`)) } diff --git a/server/nativeapi/playlists.go b/server/nativeapi/playlists.go index afa964e1..1e2c5e07 100644 --- a/server/nativeapi/playlists.go +++ b/server/nativeapi/playlists.go @@ -59,7 +59,7 @@ func createPlaylistFromM3U(playlists core.Playlists) http.HandlerFunc { return } w.WriteHeader(http.StatusCreated) - _, err = w.Write([]byte(pls.ToM3U8())) + _, err = w.Write([]byte(pls.ToM3U8())) //nolint:gosec if err != nil { log.Error(ctx, "Error sending m3u contents", err) http.Error(w, err.Error(), http.StatusInternalServerError) @@ -90,7 +90,7 @@ func handleExportPlaylist(ds model.DataStore) http.HandlerFunc { disposition := fmt.Sprintf("attachment; filename=\"%s.m3u\"", pls.Name) w.Header().Set("Content-Disposition", disposition) - _, err = w.Write([]byte(pls.ToM3U8())) + _, err = w.Write([]byte(pls.ToM3U8())) //nolint:gosec if err != nil { log.Error(ctx, "Error sending playlist", "name", pls.Name) return @@ -162,7 +162,7 @@ func addToPlaylist(ds model.DataStore) http.HandlerFunc { count += c // Must return an object with an ID, to satisfy ReactAdmin `create` call - _, err = fmt.Fprintf(w, `{"added":%d}`, count) + _, err = fmt.Fprintf(w, `{"added":%d}`, count) //nolint:gosec if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } @@ -204,7 +204,7 @@ func reorderItem(ds model.DataStore) http.HandlerFunc { return } - _, err = w.Write(fmt.Appendf(nil, `{"id":"%d"}`, id)) + _, err = w.Write(fmt.Appendf(nil, `{"id":"%d"}`, id)) //nolint:gosec if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } @@ -225,6 +225,6 @@ func getSongPlaylists(ds model.DataStore) http.HandlerFunc { http.Error(w, err.Error(), http.StatusInternalServerError) return } - _, _ = w.Write(data) + _, _ = w.Write(data) //nolint:gosec } } diff --git a/server/nativeapi/queue.go b/server/nativeapi/queue.go index 0a313666..a7700c02 100644 --- a/server/nativeapi/queue.go +++ b/server/nativeapi/queue.go @@ -87,7 +87,7 @@ func getQueue(ds model.DataStore) http.HandlerFunc { return } w.Header().Set("Content-Type", "application/json") - _, _ = w.Write(resp) + _, _ = w.Write(resp) //nolint:gosec } } diff --git a/server/public/handle_shares.go b/server/public/handle_shares.go index ad8a5da6..36764dec 100644 --- a/server/public/handle_shares.go +++ b/server/public/handle_shares.go @@ -59,7 +59,7 @@ func (pub *Router) handleM3U(w http.ResponseWriter, r *http.Request) { s = pub.mapShareToM3U(r, *s) w.WriteHeader(http.StatusOK) w.Header().Set("Content-Type", "audio/x-mpegurl") - _, _ = w.Write([]byte(s.ToM3U8())) + _, _ = w.Write([]byte(s.ToM3U8())) //nolint:gosec } func checkShareError(ctx context.Context, w http.ResponseWriter, err error, id string) { diff --git a/server/server.go b/server/server.go index aa9043ba..b05c20cc 100644 --- a/server/server.go +++ b/server/server.go @@ -244,7 +244,7 @@ func (s *Server) frontendAssetsHandler() http.Handler { // It provides detailed error messages for common issues like encrypted private keys. func validateTLSCertificates(certFile, keyFile string) error { // Read the key file to check for encryption - keyData, err := os.ReadFile(keyFile) + keyData, err := os.ReadFile(keyFile) //nolint:gosec if err != nil { return fmt.Errorf("reading TLS key file: %w", err) } diff --git a/server/subsonic/api.go b/server/subsonic/api.go index 1d13e2c0..c3108ea5 100644 --- a/server/subsonic/api.go +++ b/server/subsonic/api.go @@ -363,7 +363,7 @@ func sendResponse(w http.ResponseWriter, r *http.Request, payload *responses.Sub } } - if _, err := w.Write(response); err != nil { + if _, err := w.Write(response); err != nil { //nolint:gosec log.Error(r, "Error sending response to client", "endpoint", r.URL.Path, "payload", string(response), err) } }