diff options
Diffstat (limited to 'server')
-rw-r--r-- | server/controllers/api/videos/comment.ts | 8 | ||||
-rw-r--r-- | server/lib/activitypub/process/process-delete.ts | 6 | ||||
-rw-r--r-- | server/lib/activitypub/send/send-delete.ts | 5 | ||||
-rw-r--r-- | server/models/video/video-comment.ts | 43 | ||||
-rw-r--r-- | server/tests/api/videos/multiple-servers.ts | 41 |
5 files changed, 49 insertions, 54 deletions
diff --git a/server/controllers/api/videos/comment.ts b/server/controllers/api/videos/comment.ts index 39d521f5f..bc6d81a7c 100644 --- a/server/controllers/api/videos/comment.ts +++ b/server/controllers/api/videos/comment.ts | |||
@@ -27,6 +27,10 @@ import { auditLoggerFactory, CommentAuditView, getAuditIdFromRes } from '../../. | |||
27 | import { AccountModel } from '../../../models/account/account' | 27 | import { AccountModel } from '../../../models/account/account' |
28 | import { Notifier } from '../../../lib/notifier' | 28 | import { Notifier } from '../../../lib/notifier' |
29 | import { Hooks } from '../../../lib/plugins/hooks' | 29 | import { Hooks } from '../../../lib/plugins/hooks' |
30 | import { ActorModel } from '../../../models/activitypub/actor' | ||
31 | import { VideoChannelModel } from '../../../models/video/video-channel' | ||
32 | import { VideoModel } from '../../../models/video/video' | ||
33 | import { sendDeleteVideoComment } from '../../../lib/activitypub/send' | ||
30 | 34 | ||
31 | const auditLogger = auditLoggerFactory('comments') | 35 | const auditLogger = auditLoggerFactory('comments') |
32 | const videoCommentRouter = express.Router() | 36 | const videoCommentRouter = express.Router() |
@@ -179,6 +183,10 @@ async function removeVideoComment (req: express.Request, res: express.Response) | |||
179 | 183 | ||
180 | await sequelizeTypescript.transaction(async t => { | 184 | await sequelizeTypescript.transaction(async t => { |
181 | await videoCommentInstance.destroy({ transaction: t }) | 185 | await videoCommentInstance.destroy({ transaction: t }) |
186 | |||
187 | if (videoCommentInstance.isOwned() || videoCommentInstance.Video.isOwned()) { | ||
188 | await sendDeleteVideoComment(videoCommentInstance, t) | ||
189 | } | ||
182 | }) | 190 | }) |
183 | 191 | ||
184 | auditLogger.delete(getAuditIdFromRes(res), new CommentAuditView(videoCommentInstance.toFormattedJSON())) | 192 | auditLogger.delete(getAuditIdFromRes(res), new CommentAuditView(videoCommentInstance.toFormattedJSON())) |
diff --git a/server/lib/activitypub/process/process-delete.ts b/server/lib/activitypub/process/process-delete.ts index 845a7b249..9fcfd9e3a 100644 --- a/server/lib/activitypub/process/process-delete.ts +++ b/server/lib/activitypub/process/process-delete.ts | |||
@@ -34,7 +34,7 @@ async function processDeleteActivity (options: APProcessorOptions<ActivityDelete | |||
34 | } | 34 | } |
35 | 35 | ||
36 | { | 36 | { |
37 | const videoCommentInstance = await VideoCommentModel.loadByUrlAndPopulateAccount(objectUrl) | 37 | const videoCommentInstance = await VideoCommentModel.loadByUrlAndPopulateAccountAndVideo(objectUrl) |
38 | if (videoCommentInstance) { | 38 | if (videoCommentInstance) { |
39 | return retryTransactionWrapper(processDeleteVideoComment, byActor, videoCommentInstance, activity) | 39 | return retryTransactionWrapper(processDeleteVideoComment, byActor, videoCommentInstance, activity) |
40 | } | 40 | } |
@@ -121,8 +121,8 @@ function processDeleteVideoComment (byActor: ActorModel, videoComment: VideoComm | |||
121 | logger.debug('Removing remote video comment "%s".', videoComment.url) | 121 | logger.debug('Removing remote video comment "%s".', videoComment.url) |
122 | 122 | ||
123 | return sequelizeTypescript.transaction(async t => { | 123 | return sequelizeTypescript.transaction(async t => { |
124 | if (videoComment.Account.id !== byActor.Account.id) { | 124 | if (byActor.Account.id !== videoComment.Account.id && byActor.Account.id !== videoComment.Video.VideoChannel.accountId) { |
125 | throw new Error('Account ' + byActor.url + ' does not own video comment ' + videoComment.url) | 125 | throw new Error(`Account ${byActor.url} does not own video comment ${videoComment.url} or video ${videoComment.Video.url}`) |
126 | } | 126 | } |
127 | 127 | ||
128 | await videoComment.destroy({ transaction: t }) | 128 | await videoComment.destroy({ transaction: t }) |
diff --git a/server/lib/activitypub/send/send-delete.ts b/server/lib/activitypub/send/send-delete.ts index 7a1d6f0ba..6c7fb8449 100644 --- a/server/lib/activitypub/send/send-delete.ts +++ b/server/lib/activitypub/send/send-delete.ts | |||
@@ -48,7 +48,10 @@ async function sendDeleteVideoComment (videoComment: VideoCommentModel, t: Trans | |||
48 | const isVideoOrigin = videoComment.Video.isOwned() | 48 | const isVideoOrigin = videoComment.Video.isOwned() |
49 | 49 | ||
50 | const url = getDeleteActivityPubUrl(videoComment.url) | 50 | const url = getDeleteActivityPubUrl(videoComment.url) |
51 | const byActor = videoComment.Account.Actor | 51 | const byActor = videoComment.isOwned() |
52 | ? videoComment.Account.Actor | ||
53 | : videoComment.Video.VideoChannel.Account.Actor | ||
54 | |||
52 | const threadParentComments = await VideoCommentModel.listThreadParentComments(videoComment, t) | 55 | const threadParentComments = await VideoCommentModel.listThreadParentComments(videoComment, t) |
53 | 56 | ||
54 | const actorsInvolvedInComment = await getActorsInvolvedInVideo(videoComment.Video, t) | 57 | const actorsInvolvedInComment = await getActorsInvolvedInVideo(videoComment.Video, t) |
diff --git a/server/models/video/video-comment.ts b/server/models/video/video-comment.ts index 6eda32f05..58b75510d 100644 --- a/server/models/video/video-comment.ts +++ b/server/models/video/video-comment.ts | |||
@@ -106,6 +106,10 @@ enum ScopeNames { | |||
106 | required: true, | 106 | required: true, |
107 | include: [ | 107 | include: [ |
108 | { | 108 | { |
109 | model: ActorModel, | ||
110 | required: true | ||
111 | }, | ||
112 | { | ||
109 | model: AccountModel, | 113 | model: AccountModel, |
110 | required: true, | 114 | required: true, |
111 | include: [ | 115 | include: [ |
@@ -208,41 +212,6 @@ export class VideoCommentModel extends Model<VideoCommentModel> { | |||
208 | }) | 212 | }) |
209 | Account: AccountModel | 213 | Account: AccountModel |
210 | 214 | ||
211 | @BeforeDestroy | ||
212 | static async sendDeleteIfOwned (instance: VideoCommentModel, options) { | ||
213 | if (!instance.Account || !instance.Account.Actor) { | ||
214 | instance.Account = await instance.$get('Account', { | ||
215 | include: [ ActorModel ], | ||
216 | transaction: options.transaction | ||
217 | }) as AccountModel | ||
218 | } | ||
219 | |||
220 | if (!instance.Video) { | ||
221 | instance.Video = await instance.$get('Video', { | ||
222 | include: [ | ||
223 | { | ||
224 | model: VideoChannelModel, | ||
225 | include: [ | ||
226 | { | ||
227 | model: AccountModel, | ||
228 | include: [ | ||
229 | { | ||
230 | model: ActorModel | ||
231 | } | ||
232 | ] | ||
233 | } | ||
234 | ] | ||
235 | } | ||
236 | ], | ||
237 | transaction: options.transaction | ||
238 | }) as VideoModel | ||
239 | } | ||
240 | |||
241 | if (instance.isOwned()) { | ||
242 | await sendDeleteVideoComment(instance, options.transaction) | ||
243 | } | ||
244 | } | ||
245 | |||
246 | static loadById (id: number, t?: Transaction) { | 215 | static loadById (id: number, t?: Transaction) { |
247 | const query: FindOptions = { | 216 | const query: FindOptions = { |
248 | where: { | 217 | where: { |
@@ -269,7 +238,7 @@ export class VideoCommentModel extends Model<VideoCommentModel> { | |||
269 | .findOne(query) | 238 | .findOne(query) |
270 | } | 239 | } |
271 | 240 | ||
272 | static loadByUrlAndPopulateAccount (url: string, t?: Transaction) { | 241 | static loadByUrlAndPopulateAccountAndVideo (url: string, t?: Transaction) { |
273 | const query: FindOptions = { | 242 | const query: FindOptions = { |
274 | where: { | 243 | where: { |
275 | url | 244 | url |
@@ -278,7 +247,7 @@ export class VideoCommentModel extends Model<VideoCommentModel> { | |||
278 | 247 | ||
279 | if (t !== undefined) query.transaction = t | 248 | if (t !== undefined) query.transaction = t |
280 | 249 | ||
281 | return VideoCommentModel.scope([ ScopeNames.WITH_ACCOUNT ]).findOne(query) | 250 | return VideoCommentModel.scope([ ScopeNames.WITH_ACCOUNT, ScopeNames.WITH_VIDEO ]).findOne(query) |
282 | } | 251 | } |
283 | 252 | ||
284 | static loadByUrlAndPopulateReplyAndVideoUrlAndAccount (url: string, t?: Transaction) { | 253 | static loadByUrlAndPopulateReplyAndVideoUrlAndAccount (url: string, t?: Transaction) { |
diff --git a/server/tests/api/videos/multiple-servers.ts b/server/tests/api/videos/multiple-servers.ts index e811ccd8e..651765776 100644 --- a/server/tests/api/videos/multiple-servers.ts +++ b/server/tests/api/videos/multiple-servers.ts | |||
@@ -500,20 +500,18 @@ describe('Test multiple servers', function () { | |||
500 | it('Should view multiple videos on owned servers', async function () { | 500 | it('Should view multiple videos on owned servers', async function () { |
501 | this.timeout(30000) | 501 | this.timeout(30000) |
502 | 502 | ||
503 | const tasks: Promise<any>[] = [] | ||
504 | await viewVideo(servers[2].url, localVideosServer3[0]) | ||
505 | await viewVideo(servers[2].url, localVideosServer3[0]) | ||
506 | await viewVideo(servers[2].url, localVideosServer3[0]) | 503 | await viewVideo(servers[2].url, localVideosServer3[0]) |
507 | await viewVideo(servers[2].url, localVideosServer3[1]) | 504 | await wait(1000) |
508 | |||
509 | await Promise.all(tasks) | ||
510 | await waitJobs(servers) | ||
511 | 505 | ||
512 | await viewVideo(servers[2].url, localVideosServer3[0]) | 506 | await viewVideo(servers[2].url, localVideosServer3[0]) |
507 | await viewVideo(servers[2].url, localVideosServer3[1]) | ||
513 | 508 | ||
514 | await waitJobs(servers) | 509 | await wait(1000) |
515 | 510 | ||
516 | await viewVideo(servers[2].url, localVideosServer3[0]) | 511 | await Promise.all([ |
512 | viewVideo(servers[2].url, localVideosServer3[0]), | ||
513 | viewVideo(servers[2].url, localVideosServer3[0]) | ||
514 | ]) | ||
517 | 515 | ||
518 | await waitJobs(servers) | 516 | await waitJobs(servers) |
519 | 517 | ||
@@ -894,14 +892,14 @@ describe('Test multiple servers', function () { | |||
894 | it('Should delete the thread comments', async function () { | 892 | it('Should delete the thread comments', async function () { |
895 | this.timeout(10000) | 893 | this.timeout(10000) |
896 | 894 | ||
897 | const res1 = await getVideoCommentThreads(servers[0].url, videoUUID, 0, 5) | 895 | const res = await getVideoCommentThreads(servers[ 0 ].url, videoUUID, 0, 5) |
898 | const threadId = res1.body.data.find(c => c.text === 'my super first comment').id | 896 | const threadId = res.body.data.find(c => c.text === 'my super first comment').id |
899 | await deleteVideoComment(servers[0].url, servers[0].accessToken, videoUUID, threadId) | 897 | await deleteVideoComment(servers[ 0 ].url, servers[ 0 ].accessToken, videoUUID, threadId) |
900 | 898 | ||
901 | await waitJobs(servers) | 899 | await waitJobs(servers) |
902 | }) | 900 | }) |
903 | 901 | ||
904 | it('Should have the thread comments deleted on other servers too', async function () { | 902 | it('Should have the threads deleted on other servers too', async function () { |
905 | for (const server of servers) { | 903 | for (const server of servers) { |
906 | const res = await getVideoCommentThreads(server.url, videoUUID, 0, 5) | 904 | const res = await getVideoCommentThreads(server.url, videoUUID, 0, 5) |
907 | 905 | ||
@@ -922,6 +920,23 @@ describe('Test multiple servers', function () { | |||
922 | } | 920 | } |
923 | }) | 921 | }) |
924 | 922 | ||
923 | it('Should delete a remote thread by the origin server', async function () { | ||
924 | const res = await getVideoCommentThreads(servers[ 0 ].url, videoUUID, 0, 5) | ||
925 | const threadId = res.body.data.find(c => c.text === 'my super second comment').id | ||
926 | await deleteVideoComment(servers[ 0 ].url, servers[ 0 ].accessToken, videoUUID, threadId) | ||
927 | |||
928 | await waitJobs(servers) | ||
929 | }) | ||
930 | |||
931 | it('Should have the threads deleted on other servers too', async function () { | ||
932 | for (const server of servers) { | ||
933 | const res = await getVideoCommentThreads(server.url, videoUUID, 0, 5) | ||
934 | |||
935 | expect(res.body.total).to.equal(0) | ||
936 | expect(res.body.data).to.have.lengthOf(0) | ||
937 | } | ||
938 | }) | ||
939 | |||
925 | it('Should disable comments and download', async function () { | 940 | it('Should disable comments and download', async function () { |
926 | this.timeout(20000) | 941 | this.timeout(20000) |
927 | 942 | ||