diff --git a/server/controllers/api/video-playlist.ts b/server/controllers/api/video-playlist.ts index a17136401..62490e63b 100644 --- a/server/controllers/api/video-playlist.ts +++ b/server/controllers/api/video-playlist.ts @@ -203,7 +203,9 @@ async function updateVideoPlaylist (req: express.Request, res: express.Response) const videoPlaylistInstance = res.locals.videoPlaylist const videoPlaylistFieldsSave = videoPlaylistInstance.toJSON() const videoPlaylistInfoToUpdate = req.body as VideoPlaylistUpdate + const wasPrivatePlaylist = videoPlaylistInstance.privacy === VideoPlaylistPrivacy.PRIVATE + const wasNotPrivatePlaylist = videoPlaylistInstance.privacy !== VideoPlaylistPrivacy.PRIVATE const thumbnailField = req.files['thumbnailfile'] const thumbnailModel = thumbnailField @@ -232,6 +234,10 @@ async function updateVideoPlaylist (req: express.Request, res: express.Response) if (videoPlaylistInfoToUpdate.privacy !== undefined) { videoPlaylistInstance.privacy = parseInt(videoPlaylistInfoToUpdate.privacy.toString(), 10) + + if (wasNotPrivatePlaylist === true && videoPlaylistInstance.privacy === VideoPlaylistPrivacy.PRIVATE) { + await sendDeleteVideoPlaylist(videoPlaylistInstance, t) + } } const playlistUpdated = await videoPlaylistInstance.save(sequelizeOptions) diff --git a/server/middlewares/validators/videos/video-playlists.ts b/server/middlewares/validators/videos/video-playlists.ts index f68eeeeb3..9c88dd291 100644 --- a/server/middlewares/validators/videos/video-playlists.ts +++ b/server/middlewares/validators/videos/video-playlists.ts @@ -24,6 +24,9 @@ import { VideoPlaylistPrivacy } from '../../../../shared/models/videos/playlist/ import { VideoPlaylistType } from '../../../../shared/models/videos/playlist/video-playlist-type.model' const videoPlaylistsAddValidator = getCommonPlaylistEditAttributes().concat([ + body('displayName') + .custom(isVideoPlaylistNameValid).withMessage('Should have a valid display name'), + async (req: express.Request, res: express.Response, next: express.NextFunction) => { logger.debug('Checking videoPlaylistsAddValidator parameters', { parameters: req.body }) @@ -46,6 +49,10 @@ const videoPlaylistsUpdateValidator = getCommonPlaylistEditAttributes().concat([ param('playlistId') .custom(isIdOrUUIDValid).withMessage('Should have a valid playlist id/uuid'), + body('displayName') + .optional() + .custom(isVideoPlaylistNameValid).withMessage('Should have a valid display name'), + async (req: express.Request, res: express.Response, next: express.NextFunction) => { logger.debug('Checking videoPlaylistsUpdateValidator parameters', { parameters: req.body }) @@ -61,12 +68,6 @@ const videoPlaylistsUpdateValidator = getCommonPlaylistEditAttributes().concat([ const body: VideoPlaylistUpdate = req.body - if (videoPlaylist.privacy !== VideoPlaylistPrivacy.PRIVATE && body.privacy === VideoPlaylistPrivacy.PRIVATE) { - cleanUpReqFiles(req) - return res.status(400) - .json({ error: 'Cannot set "private" a video playlist that was not private.' }) - } - const newPrivacy = body.privacy || videoPlaylist.privacy if (newPrivacy === VideoPlaylistPrivacy.PUBLIC && ( @@ -368,8 +369,6 @@ function getCommonPlaylistEditAttributes () { + CONSTRAINTS_FIELDS.VIDEO_PLAYLISTS.IMAGE.EXTNAME.join(', ') ), - body('displayName') - .custom(isVideoPlaylistNameValid).withMessage('Should have a valid display name'), body('description') .optional() .customSanitizer(toValueOrNull) diff --git a/server/tests/api/check-params/video-playlists.ts b/server/tests/api/check-params/video-playlists.ts index b7b94c035..8c5e44bdd 100644 --- a/server/tests/api/check-params/video-playlists.ts +++ b/server/tests/api/check-params/video-playlists.ts @@ -205,7 +205,6 @@ describe('Test video playlists API validator', function () { const params = getBase({ displayName: undefined }) await createVideoPlaylist(params) - await updateVideoPlaylist(getUpdate(params, playlistUUID)) }) it('Should fail with an incorrect display name', async function () { @@ -269,17 +268,6 @@ describe('Test video playlists API validator', function () { )) }) - it('Should fail to update to private a public/unlisted playlist', async function () { - const params = getBase({ privacy: VideoPlaylistPrivacy.PUBLIC }, { expectedStatus: 200 }) - - const res = await createVideoPlaylist(params) - const playlist = res.body.videoPlaylist - - const paramsUpdate = getBase({ privacy: VideoPlaylistPrivacy.PRIVATE }, { expectedStatus: 400 }) - - await updateVideoPlaylist(getUpdate(paramsUpdate, playlist.id)) - }) - it('Should fail to update the watch later playlist', async function () { await updateVideoPlaylist(getUpdate( getBase({}, { expectedStatus: 400 }), diff --git a/server/tests/api/videos/video-playlists.ts b/server/tests/api/videos/video-playlists.ts index 3ebb1df0b..8690327c4 100644 --- a/server/tests/api/videos/video-playlists.ts +++ b/server/tests/api/videos/video-playlists.ts @@ -754,6 +754,40 @@ describe('Test video playlists', function () { } }) + + it('Should be able to create a public playlist, and set it to private', async function () { + this.timeout(30000) + + const res = await createVideoPlaylist({ + url: servers[0].url, + token: servers[0].accessToken, + playlistAttrs: { + displayName: 'my super public playlist', + privacy: VideoPlaylistPrivacy.PUBLIC, + videoChannelId: servers[0].videoChannel.id + } + }) + const videoPlaylistIds = res.body.videoPlaylist + + await waitJobs(servers) + + for (const server of servers) { + await getVideoPlaylist(server.url, videoPlaylistIds.uuid, 200) + } + + const playlistAttrs = { privacy: VideoPlaylistPrivacy.PRIVATE } + await updateVideoPlaylist({ url: servers[0].url, token: servers[0].accessToken, playlistId: videoPlaylistIds.id, playlistAttrs }) + + await waitJobs(servers) + + for (const server of [ servers[1], servers[2] ]) { + await getVideoPlaylist(server.url, videoPlaylistIds.uuid, 404) + } + await getVideoPlaylist(servers[0].url, videoPlaylistIds.uuid, 401) + + await getVideoPlaylistWithToken(servers[0].url, servers[0].accessToken, videoPlaylistIds.uuid, 200) + }) + it('Should delete the playlist on server 1 and delete on server 2 and 3', async function () { this.timeout(30000) diff --git a/shared/models/videos/playlist/video-playlist-update.model.ts b/shared/models/videos/playlist/video-playlist-update.model.ts index 0ff5bcb0f..a6a3f74d9 100644 --- a/shared/models/videos/playlist/video-playlist-update.model.ts +++ b/shared/models/videos/playlist/video-playlist-update.model.ts @@ -1,8 +1,8 @@ import { VideoPlaylistPrivacy } from './video-playlist-privacy.model' export interface VideoPlaylistUpdate { - displayName: string - privacy: VideoPlaylistPrivacy + displayName?: string + privacy?: VideoPlaylistPrivacy description?: string videoChannelId?: number