import { AccountModel } from '../../../models/account/account'
import { Notifier } from '../../../lib/notifier'
import { Hooks } from '../../../lib/plugins/hooks'
+import { ActorModel } from '../../../models/activitypub/actor'
+import { VideoChannelModel } from '../../../models/video/video-channel'
+import { VideoModel } from '../../../models/video/video'
+import { sendDeleteVideoComment } from '../../../lib/activitypub/send'
const auditLogger = auditLoggerFactory('comments')
const videoCommentRouter = express.Router()
await sequelizeTypescript.transaction(async t => {
await videoCommentInstance.destroy({ transaction: t })
+
+ if (videoCommentInstance.isOwned() || videoCommentInstance.Video.isOwned()) {
+ await sendDeleteVideoComment(videoCommentInstance, t)
+ }
})
auditLogger.delete(getAuditIdFromRes(res), new CommentAuditView(videoCommentInstance.toFormattedJSON()))
}
{
- const videoCommentInstance = await VideoCommentModel.loadByUrlAndPopulateAccount(objectUrl)
+ const videoCommentInstance = await VideoCommentModel.loadByUrlAndPopulateAccountAndVideo(objectUrl)
if (videoCommentInstance) {
return retryTransactionWrapper(processDeleteVideoComment, byActor, videoCommentInstance, activity)
}
logger.debug('Removing remote video comment "%s".', videoComment.url)
return sequelizeTypescript.transaction(async t => {
- if (videoComment.Account.id !== byActor.Account.id) {
- throw new Error('Account ' + byActor.url + ' does not own video comment ' + videoComment.url)
+ if (byActor.Account.id !== videoComment.Account.id && byActor.Account.id !== videoComment.Video.VideoChannel.accountId) {
+ throw new Error(`Account ${byActor.url} does not own video comment ${videoComment.url} or video ${videoComment.Video.url}`)
}
await videoComment.destroy({ transaction: t })
const isVideoOrigin = videoComment.Video.isOwned()
const url = getDeleteActivityPubUrl(videoComment.url)
- const byActor = videoComment.Account.Actor
+ const byActor = videoComment.isOwned()
+ ? videoComment.Account.Actor
+ : videoComment.Video.VideoChannel.Account.Actor
+
const threadParentComments = await VideoCommentModel.listThreadParentComments(videoComment, t)
const actorsInvolvedInComment = await getActorsInvolvedInVideo(videoComment.Video, t)
model: VideoChannelModel.unscoped(),
required: true,
include: [
+ {
+ model: ActorModel,
+ required: true
+ },
{
model: AccountModel,
required: true,
})
Account: AccountModel
- @BeforeDestroy
- static async sendDeleteIfOwned (instance: VideoCommentModel, options) {
- if (!instance.Account || !instance.Account.Actor) {
- instance.Account = await instance.$get('Account', {
- include: [ ActorModel ],
- transaction: options.transaction
- }) as AccountModel
- }
-
- if (!instance.Video) {
- instance.Video = await instance.$get('Video', {
- include: [
- {
- model: VideoChannelModel,
- include: [
- {
- model: AccountModel,
- include: [
- {
- model: ActorModel
- }
- ]
- }
- ]
- }
- ],
- transaction: options.transaction
- }) as VideoModel
- }
-
- if (instance.isOwned()) {
- await sendDeleteVideoComment(instance, options.transaction)
- }
- }
-
static loadById (id: number, t?: Transaction) {
const query: FindOptions = {
where: {
.findOne(query)
}
- static loadByUrlAndPopulateAccount (url: string, t?: Transaction) {
+ static loadByUrlAndPopulateAccountAndVideo (url: string, t?: Transaction) {
const query: FindOptions = {
where: {
url
if (t !== undefined) query.transaction = t
- return VideoCommentModel.scope([ ScopeNames.WITH_ACCOUNT ]).findOne(query)
+ return VideoCommentModel.scope([ ScopeNames.WITH_ACCOUNT, ScopeNames.WITH_VIDEO ]).findOne(query)
}
static loadByUrlAndPopulateReplyAndVideoUrlAndAccount (url: string, t?: Transaction) {
it('Should view multiple videos on owned servers', async function () {
this.timeout(30000)
- const tasks: Promise<any>[] = []
- await viewVideo(servers[2].url, localVideosServer3[0])
- await viewVideo(servers[2].url, localVideosServer3[0])
await viewVideo(servers[2].url, localVideosServer3[0])
- await viewVideo(servers[2].url, localVideosServer3[1])
-
- await Promise.all(tasks)
- await waitJobs(servers)
+ await wait(1000)
await viewVideo(servers[2].url, localVideosServer3[0])
+ await viewVideo(servers[2].url, localVideosServer3[1])
- await waitJobs(servers)
+ await wait(1000)
- await viewVideo(servers[2].url, localVideosServer3[0])
+ await Promise.all([
+ viewVideo(servers[2].url, localVideosServer3[0]),
+ viewVideo(servers[2].url, localVideosServer3[0])
+ ])
await waitJobs(servers)
it('Should delete the thread comments', async function () {
this.timeout(10000)
- const res1 = await getVideoCommentThreads(servers[0].url, videoUUID, 0, 5)
- const threadId = res1.body.data.find(c => c.text === 'my super first comment').id
- await deleteVideoComment(servers[0].url, servers[0].accessToken, videoUUID, threadId)
+ const res = await getVideoCommentThreads(servers[ 0 ].url, videoUUID, 0, 5)
+ const threadId = res.body.data.find(c => c.text === 'my super first comment').id
+ await deleteVideoComment(servers[ 0 ].url, servers[ 0 ].accessToken, videoUUID, threadId)
await waitJobs(servers)
})
- it('Should have the thread comments deleted on other servers too', async function () {
+ it('Should have the threads deleted on other servers too', async function () {
for (const server of servers) {
const res = await getVideoCommentThreads(server.url, videoUUID, 0, 5)
}
})
+ it('Should delete a remote thread by the origin server', async function () {
+ const res = await getVideoCommentThreads(servers[ 0 ].url, videoUUID, 0, 5)
+ const threadId = res.body.data.find(c => c.text === 'my super second comment').id
+ await deleteVideoComment(servers[ 0 ].url, servers[ 0 ].accessToken, videoUUID, threadId)
+
+ await waitJobs(servers)
+ })
+
+ it('Should have the threads deleted on other servers too', async function () {
+ for (const server of servers) {
+ const res = await getVideoCommentThreads(server.url, videoUUID, 0, 5)
+
+ expect(res.body.total).to.equal(0)
+ expect(res.body.data).to.have.lengthOf(0)
+ }
+ })
+
it('Should disable comments and download', async function () {
this.timeout(20000)