From f9e1f338195fffed14cc1b98de6ec59624bdbf89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9e=20Kooi?= Date: Fri, 7 Aug 2020 11:17:27 +0200 Subject: [PATCH] playlists: stricter checks when moving playlist items (#399) --- src/models/Playlist.js | 7 ++++++- src/plugins/playlists.js | 12 ++++++++---- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/models/Playlist.js b/src/models/Playlist.js index 529978c6..a8bc1cf7 100644 --- a/src/models/Playlist.js +++ b/src/models/Playlist.js @@ -26,7 +26,12 @@ function playlistModel() { }, shared: { type: Boolean, default: false }, nsfw: { type: Boolean, default: false }, - media: [{ type: Types.ObjectId, ref: 'PlaylistItem', index: true }], + media: [{ + type: Types.ObjectId, + ref: 'PlaylistItem', + required: true, + index: true, + }], }, { collection: 'playlists', timestamps: true, diff --git a/src/plugins/playlists.js b/src/plugins/playlists.js index c0bb49fb..0dd57d4c 100644 --- a/src/plugins/playlists.js +++ b/src/plugins/playlists.js @@ -453,12 +453,16 @@ class PlaylistsRepository { async movePlaylistItems(playlistOrID, itemIDs, { afterID }) { const playlist = await this.getPlaylist(playlistOrID); - // Create a plain array instead of a mongoose array because it crashes on splice() - // otherwise. - const newMedia = [...playlist.media].filter((item) => !itemIDs.includes(`${item}`)); + // Use a plain array instead of a mongoose array because we need `splice()`. + const itemsInPlaylist = [...playlist.media]; + const itemIDsInPlaylist = new Set(itemsInPlaylist.map((item) => `${item}`)); + // Only attempt to move items that are actually in the playlist. + const itemIDsToInsert = itemIDs.filter((id) => itemIDsInPlaylist.has(`${id}`)); + + const newMedia = itemsInPlaylist.filter((item) => !itemIDsToInsert.includes(`${item}`)); // Reinsert items at their new position. const insertIndex = newMedia.findIndex((item) => `${item}` === afterID); - newMedia.splice(insertIndex + 1, 0, ...itemIDs); + newMedia.splice(insertIndex + 1, 0, ...itemIDsToInsert); playlist.media = newMedia; await playlist.save();