aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--server/helpers/activitypub.ts3
-rw-r--r--server/helpers/custom-validators/activitypub/videos.ts1
-rw-r--r--server/lib/activitypub/videos.ts2
-rw-r--r--server/models/video/video-format-utils.ts4
-rw-r--r--server/models/video/video.ts13
-rw-r--r--server/tests/api/check-params/videos.ts16
-rw-r--r--server/tests/api/videos/multiple-servers.ts6
-rw-r--r--shared/utils/videos/videos.ts12
8 files changed, 49 insertions, 8 deletions
diff --git a/server/helpers/activitypub.ts b/server/helpers/activitypub.ts
index 62d78373e..e850efe13 100644
--- a/server/helpers/activitypub.ts
+++ b/server/helpers/activitypub.ts
@@ -34,7 +34,8 @@ function activityPubContextify <T> (data: T) {
34 expires: 'sc:expires', 34 expires: 'sc:expires',
35 support: 'sc:Text', 35 support: 'sc:Text',
36 CacheFile: 'pt:CacheFile', 36 CacheFile: 'pt:CacheFile',
37 Infohash: 'pt:Infohash' 37 Infohash: 'pt:Infohash',
38 originallyPublishedAt: 'sc:DateTime'
38 }, 39 },
39 { 40 {
40 likes: { 41 likes: {
diff --git a/server/helpers/custom-validators/activitypub/videos.ts b/server/helpers/custom-validators/activitypub/videos.ts
index 53ad0588d..d94333151 100644
--- a/server/helpers/custom-validators/activitypub/videos.ts
+++ b/server/helpers/custom-validators/activitypub/videos.ts
@@ -54,6 +54,7 @@ function sanitizeAndCheckVideoTorrentObject (video: any) {
54 isBooleanValid(video.downloadEnabled) && 54 isBooleanValid(video.downloadEnabled) &&
55 isDateValid(video.published) && 55 isDateValid(video.published) &&
56 isDateValid(video.updated) && 56 isDateValid(video.updated) &&
57 (!video.originallyPublishedAt || isDateValid(video.originallyPublishedAt)) &&
57 (!video.content || isRemoteVideoContentValid(video.mediaType, video.content)) && 58 (!video.content || isRemoteVideoContentValid(video.mediaType, video.content)) &&
58 isRemoteVideoIconValid(video.icon) && 59 isRemoteVideoIconValid(video.icon) &&
59 video.url.length !== 0 && 60 video.url.length !== 0 &&
diff --git a/server/lib/activitypub/videos.ts b/server/lib/activitypub/videos.ts
index 710929aac..9ca0502a4 100644
--- a/server/lib/activitypub/videos.ts
+++ b/server/lib/activitypub/videos.ts
@@ -249,6 +249,7 @@ async function updateVideoFromAP (options: {
249 options.video.set('duration', videoData.duration) 249 options.video.set('duration', videoData.duration)
250 options.video.set('createdAt', videoData.createdAt) 250 options.video.set('createdAt', videoData.createdAt)
251 options.video.set('publishedAt', videoData.publishedAt) 251 options.video.set('publishedAt', videoData.publishedAt)
252 options.video.set('originallyPublishedAt', videoData.originallyPublishedAt)
252 options.video.set('privacy', videoData.privacy) 253 options.video.set('privacy', videoData.privacy)
253 options.video.set('channelId', videoData.channelId) 254 options.video.set('channelId', videoData.channelId)
254 options.video.set('views', videoData.views) 255 options.video.set('views', videoData.views)
@@ -511,6 +512,7 @@ async function videoActivityObjectToDBAttributes (
511 duration: parseInt(duration, 10), 512 duration: parseInt(duration, 10),
512 createdAt: new Date(videoObject.published), 513 createdAt: new Date(videoObject.published),
513 publishedAt: new Date(videoObject.published), 514 publishedAt: new Date(videoObject.published),
515 originallyPublishedAt: videoObject.originallyPublishedAt ? new Date(videoObject.originallyPublishedAt) : null,
514 // FIXME: updatedAt does not seems to be considered by Sequelize 516 // FIXME: updatedAt does not seems to be considered by Sequelize
515 updatedAt: new Date(videoObject.updated), 517 updatedAt: new Date(videoObject.updated),
516 views: videoObject.views, 518 views: videoObject.views,
diff --git a/server/models/video/video-format-utils.ts b/server/models/video/video-format-utils.ts
index c63285e25..a62335333 100644
--- a/server/models/video/video-format-utils.ts
+++ b/server/models/video/video-format-utils.ts
@@ -324,9 +324,7 @@ function videoModelToActivityPubObject (video: VideoModel): VideoTorrentObject {
324 commentsEnabled: video.commentsEnabled, 324 commentsEnabled: video.commentsEnabled,
325 downloadEnabled: video.downloadEnabled, 325 downloadEnabled: video.downloadEnabled,
326 published: video.publishedAt.toISOString(), 326 published: video.publishedAt.toISOString(),
327 originallyPublishedAt: video.originallyPublishedAt ? 327 originallyPublishedAt: video.originallyPublishedAt ? video.originallyPublishedAt.toISOString() : null,
328 video.originallyPublishedAt.toISOString() :
329 null,
330 updated: video.updatedAt.toISOString(), 328 updated: video.updatedAt.toISOString(),
331 mediaType: 'text/markdown', 329 mediaType: 'text/markdown',
332 content: video.getTruncatedDescription(), 330 content: video.getTruncatedDescription(),
diff --git a/server/models/video/video.ts b/server/models/video/video.ts
index 73626b6a0..215e26d7d 100644
--- a/server/models/video/video.ts
+++ b/server/models/video/video.ts
@@ -40,7 +40,7 @@ import {
40 isVideoDurationValid, 40 isVideoDurationValid,
41 isVideoLanguageValid, 41 isVideoLanguageValid,
42 isVideoLicenceValid, 42 isVideoLicenceValid,
43 isVideoNameValid, 43 isVideoNameValid, isVideoOriginallyPublishedAtValid,
44 isVideoPrivacyValid, 44 isVideoPrivacyValid,
45 isVideoStateValid, 45 isVideoStateValid,
46 isVideoSupportValid 46 isVideoSupportValid
@@ -103,11 +103,18 @@ const indexes: Sequelize.DefineIndexesOptions[] = [
103 103
104 { fields: [ 'createdAt' ] }, 104 { fields: [ 'createdAt' ] },
105 { fields: [ 'publishedAt' ] }, 105 { fields: [ 'publishedAt' ] },
106 { fields: [ 'originallyPublishedAt' ] },
107 { fields: [ 'duration' ] }, 106 { fields: [ 'duration' ] },
108 { fields: [ 'views' ] }, 107 { fields: [ 'views' ] },
109 { fields: [ 'channelId' ] }, 108 { fields: [ 'channelId' ] },
110 { 109 {
110 fields: [ 'originallyPublishedAt' ],
111 where: {
112 originallyPublishedAt: {
113 [Sequelize.Op.ne]: null
114 }
115 }
116 },
117 {
111 fields: [ 'category' ], // We don't care videos with an unknown category 118 fields: [ 'category' ], // We don't care videos with an unknown category
112 where: { 119 where: {
113 category: { 120 category: {
@@ -741,6 +748,8 @@ export class VideoModel extends Model<VideoModel> {
741 @Column 748 @Column
742 publishedAt: Date 749 publishedAt: Date
743 750
751 @AllowNull(true)
752 @Default(null)
744 @Column 753 @Column
745 originallyPublishedAt: Date 754 originallyPublishedAt: Date
746 755
diff --git a/server/tests/api/check-params/videos.ts b/server/tests/api/check-params/videos.ts
index 878ffe025..3eccaee44 100644
--- a/server/tests/api/check-params/videos.ts
+++ b/server/tests/api/check-params/videos.ts
@@ -185,7 +185,8 @@ describe('Test videos API validator', function () {
185 support: 'my super support text', 185 support: 'my super support text',
186 tags: [ 'tag1', 'tag2' ], 186 tags: [ 'tag1', 'tag2' ],
187 privacy: VideoPrivacy.PUBLIC, 187 privacy: VideoPrivacy.PUBLIC,
188 channelId: channelId 188 channelId: channelId,
189 originallyPublishedAt: new Date().toISOString()
189 } 190 }
190 }) 191 })
191 192
@@ -313,6 +314,13 @@ describe('Test videos API validator', function () {
313 await makeUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches }) 314 await makeUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches })
314 }) 315 })
315 316
317 it('Should fail with a bad originally published at attribute', async function () {
318 const fields = immutableAssign(baseCorrectParams, { 'originallyPublishedAt': 'toto' })
319 const attaches = baseCorrectAttaches
320
321 await makeUploadRequest({ url: server.url, path: path + '/upload', token: server.accessToken, fields, attaches })
322 })
323
316 it('Should fail without an input file', async function () { 324 it('Should fail without an input file', async function () {
317 const fields = baseCorrectParams 325 const fields = baseCorrectParams
318 const attaches = {} 326 const attaches = {}
@@ -534,6 +542,12 @@ describe('Test videos API validator', function () {
534 await makePutBodyRequest({ url: server.url, path: path + videoId, token: server.accessToken, fields }) 542 await makePutBodyRequest({ url: server.url, path: path + videoId, token: server.accessToken, fields })
535 }) 543 })
536 544
545 it('Should fail with a bad originally published at param', async function () {
546 const fields = immutableAssign(baseCorrectParams, { originallyPublishedAt: 'toto' })
547
548 await makePutBodyRequest({ url: server.url, path: path + videoId, token: server.accessToken, fields })
549 })
550
537 it('Should fail with an incorrect thumbnail file', async function () { 551 it('Should fail with an incorrect thumbnail file', async function () {
538 const fields = baseCorrectParams 552 const fields = baseCorrectParams
539 const attaches = { 553 const attaches = {
diff --git a/server/tests/api/videos/multiple-servers.ts b/server/tests/api/videos/multiple-servers.ts
index 1b471ba79..7e2fcb630 100644
--- a/server/tests/api/videos/multiple-servers.ts
+++ b/server/tests/api/videos/multiple-servers.ts
@@ -98,6 +98,7 @@ describe('Test multiple servers', function () {
98 nsfw: true, 98 nsfw: true,
99 description: 'my super description for server 1', 99 description: 'my super description for server 1',
100 support: 'my super support text for server 1', 100 support: 'my super support text for server 1',
101 originallyPublishedAt: '2019-02-10T13:38:14.449Z',
101 tags: [ 'tag1p1', 'tag2p1' ], 102 tags: [ 'tag1p1', 'tag2p1' ],
102 channelId: videoChannelId, 103 channelId: videoChannelId,
103 fixture: 'video_short1.webm' 104 fixture: 'video_short1.webm'
@@ -118,6 +119,7 @@ describe('Test multiple servers', function () {
118 nsfw: true, 119 nsfw: true,
119 description: 'my super description for server 1', 120 description: 'my super description for server 1',
120 support: 'my super support text for server 1', 121 support: 'my super support text for server 1',
122 originallyPublishedAt: '2019-02-10T13:38:14.449Z',
121 account: { 123 account: {
122 name: 'root', 124 name: 'root',
123 host: 'localhost:9001' 125 host: 'localhost:9001'
@@ -625,6 +627,7 @@ describe('Test multiple servers', function () {
625 support: 'my super support text updated', 627 support: 'my super support text updated',
626 tags: [ 'tag_up_1', 'tag_up_2' ], 628 tags: [ 'tag_up_1', 'tag_up_2' ],
627 thumbnailfile: 'thumbnail.jpg', 629 thumbnailfile: 'thumbnail.jpg',
630 originallyPublishedAt: '2019-02-11T13:38:14.449Z',
628 previewfile: 'preview.jpg' 631 previewfile: 'preview.jpg'
629 } 632 }
630 633
@@ -652,6 +655,7 @@ describe('Test multiple servers', function () {
652 nsfw: true, 655 nsfw: true,
653 description: 'my super description updated', 656 description: 'my super description updated',
654 support: 'my super support text updated', 657 support: 'my super support text updated',
658 originallyPublishedAt: '2019-02-11T13:38:14.449Z',
655 account: { 659 account: {
656 name: 'root', 660 name: 'root',
657 host: 'localhost:9003' 661 host: 'localhost:9003'
@@ -983,7 +987,7 @@ describe('Test multiple servers', function () {
983 isLocal, 987 isLocal,
984 duration: 5, 988 duration: 5,
985 commentsEnabled: false, 989 commentsEnabled: false,
986 downloadEnabled: false, 990 downloadEnabled: true,
987 tags: [ ], 991 tags: [ ],
988 privacy: VideoPrivacy.PUBLIC, 992 privacy: VideoPrivacy.PUBLIC,
989 channel: { 993 channel: {
diff --git a/shared/utils/videos/videos.ts b/shared/utils/videos/videos.ts
index 39c808d1f..16ecbfe84 100644
--- a/shared/utils/videos/videos.ts
+++ b/shared/utils/videos/videos.ts
@@ -31,6 +31,7 @@ type VideoAttributes = {
31 downloadEnabled?: boolean 31 downloadEnabled?: boolean
32 waitTranscoding?: boolean 32 waitTranscoding?: boolean
33 description?: string 33 description?: string
34 originallyPublishedAt?: string
34 tags?: string[] 35 tags?: string[]
35 channelId?: number 36 channelId?: number
36 privacy?: VideoPrivacy 37 privacy?: VideoPrivacy
@@ -349,6 +350,9 @@ async function uploadVideo (url: string, accessToken: string, videoAttributesArg
349 if (attributes.licence !== undefined) { 350 if (attributes.licence !== undefined) {
350 req.field('licence', attributes.licence.toString()) 351 req.field('licence', attributes.licence.toString())
351 } 352 }
353 if (attributes.originallyPublishedAt !== undefined) {
354 req.field('originallyPublishedAt', attributes.originallyPublishedAt)
355 }
352 356
353 for (let i = 0; i < attributes.tags.length; i++) { 357 for (let i = 0; i < attributes.tags.length; i++) {
354 req.field('tags[' + i + ']', attributes.tags[i]) 358 req.field('tags[' + i + ']', attributes.tags[i])
@@ -384,6 +388,7 @@ function updateVideo (url: string, accessToken: string, id: number | string, att
384 if (attributes.nsfw !== undefined) body['nsfw'] = JSON.stringify(attributes.nsfw) 388 if (attributes.nsfw !== undefined) body['nsfw'] = JSON.stringify(attributes.nsfw)
385 if (attributes.commentsEnabled !== undefined) body['commentsEnabled'] = JSON.stringify(attributes.commentsEnabled) 389 if (attributes.commentsEnabled !== undefined) body['commentsEnabled'] = JSON.stringify(attributes.commentsEnabled)
386 if (attributes.downloadEnabled !== undefined) body['downloadEnabled'] = JSON.stringify(attributes.downloadEnabled) 390 if (attributes.downloadEnabled !== undefined) body['downloadEnabled'] = JSON.stringify(attributes.downloadEnabled)
391 if (attributes.originallyPublishedAt !== undefined) body['originallyPublishedAt'] = attributes.originallyPublishedAt
387 if (attributes.description) body['description'] = attributes.description 392 if (attributes.description) body['description'] = attributes.description
388 if (attributes.tags) body['tags'] = attributes.tags 393 if (attributes.tags) body['tags'] = attributes.tags
389 if (attributes.privacy) body['privacy'] = attributes.privacy 394 if (attributes.privacy) body['privacy'] = attributes.privacy
@@ -453,6 +458,7 @@ async function completeVideoCheck (
453 description: string 458 description: string
454 publishedAt?: string 459 publishedAt?: string
455 support: string 460 support: string
461 originallyPublishedAt?: string,
456 account: { 462 account: {
457 name: string 463 name: string
458 host: string 464 host: string
@@ -510,6 +516,12 @@ async function completeVideoCheck (
510 expect(video.publishedAt).to.equal(attributes.publishedAt) 516 expect(video.publishedAt).to.equal(attributes.publishedAt)
511 } 517 }
512 518
519 if (attributes.originallyPublishedAt) {
520 expect(video.originallyPublishedAt).to.equal(attributes.originallyPublishedAt)
521 } else {
522 expect(video.originallyPublishedAt).to.be.null
523 }
524
513 const res = await getVideo(url, video.uuid) 525 const res = await getVideo(url, video.uuid)
514 const videoDetails: VideoDetails = res.body 526 const videoDetails: VideoDetails = res.body
515 527