mirror of
https://github.com/navidrome/navidrome.git
synced 2026-08-31 07:30:32 +00:00
fix(album): bust public share images on cover edits; drop stale stamp copies
Share.CoverArtID built a bare Album{ID}, so public album-share image URLs
were a constant al-<id>_0 — combined with the 10-year cache header, viewers
kept the pre-edit cover forever. Use the loaded album when available so the
URL carries the real timestamps.
Also skip copying cover_art_updated_at in CopyAttributes when the source has
no uploaded_image (a cover removal leaves the stamp set), so an album-ID
merge can't overwrite the destination's valid cover stamp with a stale one.
This commit is contained in:
parent
7c27e9d5a3
commit
5418e88f8e
@ -37,6 +37,10 @@ func (s Share) CoverArtID() ArtworkID {
|
||||
}
|
||||
switch s.ResourceType {
|
||||
case "album":
|
||||
// Use the loaded album when available, so the public URL busts on cover edits
|
||||
if len(s.Albums) > 0 && s.Albums[0].ID == ids[0] {
|
||||
return s.Albums[0].CoverArtID()
|
||||
}
|
||||
return Album{ID: ids[0]}.CoverArtID()
|
||||
case "playlist":
|
||||
return Playlist{ID: ids[0]}.CoverArtID()
|
||||
|
||||
24
model/share_test.go
Normal file
24
model/share_test.go
Normal file
@ -0,0 +1,24 @@
|
||||
package model_test
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
. "github.com/navidrome/navidrome/model"
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
var _ = Describe("Share", func() {
|
||||
Describe("CoverArtID", func() {
|
||||
It("uses the loaded album, so the public URL busts on cover edits", func() {
|
||||
s := Share{ResourceType: "album", ResourceIDs: "al-1"}
|
||||
plain := s.CoverArtID().String()
|
||||
Expect(s.CoverArtID().ID).To(Equal("al-1"))
|
||||
|
||||
stamp := time.Now()
|
||||
s.Albums = Albums{{ID: "al-1", CoverArtUpdatedAt: &stamp}}
|
||||
Expect(s.CoverArtID().ID).To(Equal("al-1"))
|
||||
Expect(s.CoverArtID().String()).ToNot(Equal(plain))
|
||||
})
|
||||
})
|
||||
})
|
||||
@ -299,10 +299,14 @@ func (r *albumRepository) CopyAttributes(fromID, toID string, columns ...string)
|
||||
if col == "created_at" && (!v.Valid || v.String == "" || strings.HasPrefix(v.String, "0001-")) {
|
||||
continue
|
||||
}
|
||||
// A source without an uploaded cover must not wipe one the destination has.
|
||||
// A source without an uploaded cover must not wipe one the destination has,
|
||||
// nor contribute a stale cover stamp left behind by a cover removal.
|
||||
if (col == "uploaded_image" || col == "cover_art_updated_at") && (!v.Valid || v.String == "") {
|
||||
continue
|
||||
}
|
||||
if col == "cover_art_updated_at" && (!from["uploaded_image"].Valid || from["uploaded_image"].String == "") {
|
||||
continue
|
||||
}
|
||||
to[col] = v
|
||||
}
|
||||
if len(to) == 0 {
|
||||
|
||||
@ -174,6 +174,20 @@ var _ = Describe("AlbumRepository", func() {
|
||||
Expect(got.UploadedImage).To(Equal("copy-dst_cover.jpg"))
|
||||
Expect(got.CoverArtUpdatedAt).ToNot(BeNil())
|
||||
})
|
||||
It("does not copy a stale cover stamp left behind by a cover removal", func() {
|
||||
// A removal clears uploaded_image but keeps cover_art_updated_at set
|
||||
Expect(albumRepo.UpdateImage("copy-src", "copy-src_cover.jpg")).To(Succeed())
|
||||
Expect(albumRepo.UpdateImage("copy-src", "")).To(Succeed())
|
||||
Expect(albumRepo.UpdateImage("copy-dst", "copy-dst_cover.jpg")).To(Succeed())
|
||||
before, err := albumRepo.Get("copy-dst")
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
Expect(albumRepo.CopyAttributes("copy-src", "copy-dst", "uploaded_image", "cover_art_updated_at")).To(Succeed())
|
||||
got, err := albumRepo.Get("copy-dst")
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(got.UploadedImage).To(Equal("copy-dst_cover.jpg"))
|
||||
Expect(got.CoverArtUpdatedAt.Equal(*before.CoverArtUpdatedAt)).To(BeTrue())
|
||||
})
|
||||
})
|
||||
|
||||
Describe("GetCursor", func() {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user