Fix retrieving of deleted comments when subscribing to a new instance
This commit is contained in:
parent
69222afac8
commit
b5206dfc45
5 changed files with 87 additions and 19 deletions
|
@ -3,11 +3,28 @@ import { ACTIVITY_PUB } from '../../../initializers/constants'
|
|||
import { exists, isArray, isDateValid } from '../misc'
|
||||
import { isActivityPubUrlValid } from './misc'
|
||||
|
||||
function isTypeValid (comment: any): boolean {
|
||||
if (comment.type === 'Note') return true
|
||||
|
||||
if (comment.type === 'Tombstone' && comment.formerType === 'Note') return true
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
function sanitizeAndCheckVideoCommentObject (comment: any) {
|
||||
if (!comment || comment.type !== 'Note') return false
|
||||
if (!comment) return false
|
||||
|
||||
if (!isTypeValid(comment)) return false
|
||||
|
||||
normalizeComment(comment)
|
||||
|
||||
if (comment.type === 'Tombstone') {
|
||||
return isActivityPubUrlValid(comment.id) &&
|
||||
isDateValid(comment.published) &&
|
||||
isDateValid(comment.deleted) &&
|
||||
isActivityPubUrlValid(comment.url)
|
||||
}
|
||||
|
||||
return isActivityPubUrlValid(comment.id) &&
|
||||
isCommentContentValid(comment.content) &&
|
||||
isActivityPubUrlValid(comment.inReplyTo) &&
|
||||
|
|
|
@ -131,9 +131,9 @@ async function resolveParentComment (params: ResolveThreadParams) {
|
|||
}
|
||||
|
||||
const actorUrl = body.attributedTo
|
||||
if (!actorUrl) throw new Error('Miss attributed to in comment')
|
||||
if (!actorUrl && body.type !== 'Tombstone') throw new Error('Miss attributed to in comment')
|
||||
|
||||
if (checkUrlsSameHost(url, actorUrl) !== true) {
|
||||
if (actorUrl && checkUrlsSameHost(url, actorUrl) !== true) {
|
||||
throw new Error(`Actor url ${actorUrl} has not the same host than the comment url ${url}`)
|
||||
}
|
||||
|
||||
|
@ -141,18 +141,19 @@ async function resolveParentComment (params: ResolveThreadParams) {
|
|||
throw new Error(`Comment url ${url} host is different from the AP object id ${body.id}`)
|
||||
}
|
||||
|
||||
const actor = await getOrCreateActorAndServerAndModel(actorUrl, 'all')
|
||||
const actor = actorUrl ? await getOrCreateActorAndServerAndModel(actorUrl, 'all') : null
|
||||
const comment = new VideoCommentModel({
|
||||
url: body.id,
|
||||
text: body.content,
|
||||
text: body.content ? body.content : '',
|
||||
videoId: null,
|
||||
accountId: actor.Account.id,
|
||||
accountId: actor ? actor.Account.id : null,
|
||||
inReplyToCommentId: null,
|
||||
originCommentId: null,
|
||||
createdAt: new Date(body.published),
|
||||
updatedAt: new Date(body.updated)
|
||||
updatedAt: new Date(body.updated),
|
||||
deletedAt: body.deleted ? new Date(body.deleted) : null
|
||||
}) as MCommentOwner
|
||||
comment.Account = actor.Account
|
||||
comment.Account = actor ? actor.Account : null
|
||||
|
||||
return resolveThread({
|
||||
url: body.inReplyTo,
|
||||
|
|
|
@ -507,17 +507,6 @@ export class VideoCommentModel extends Model<VideoCommentModel> {
|
|||
}
|
||||
|
||||
toActivityPubObject (this: MCommentAP, threadParentComments: MCommentOwner[]): VideoCommentObject | ActivityTombstoneObject {
|
||||
if (this.isDeleted()) {
|
||||
return {
|
||||
id: this.url,
|
||||
type: 'Tombstone',
|
||||
formerType: 'Note',
|
||||
published: this.createdAt.toISOString(),
|
||||
updated: this.updatedAt.toISOString(),
|
||||
deleted: this.deletedAt.toISOString()
|
||||
}
|
||||
}
|
||||
|
||||
let inReplyTo: string
|
||||
// New thread, so in AS we reply to the video
|
||||
if (this.inReplyToCommentId === null) {
|
||||
|
@ -526,8 +515,22 @@ export class VideoCommentModel extends Model<VideoCommentModel> {
|
|||
inReplyTo = this.InReplyToVideoComment.url
|
||||
}
|
||||
|
||||
if (this.isDeleted()) {
|
||||
return {
|
||||
id: this.url,
|
||||
type: 'Tombstone',
|
||||
formerType: 'Note',
|
||||
inReplyTo,
|
||||
published: this.createdAt.toISOString(),
|
||||
updated: this.updatedAt.toISOString(),
|
||||
deleted: this.deletedAt.toISOString()
|
||||
}
|
||||
}
|
||||
|
||||
const tag: ActivityTagObject[] = []
|
||||
for (const parentComment of threadParentComments) {
|
||||
if (!parentComment.Account) continue
|
||||
|
||||
const actor = parentComment.Account.Actor
|
||||
|
||||
tag.push({
|
||||
|
|
|
@ -15,6 +15,7 @@ import {
|
|||
createUser,
|
||||
dateIsValid,
|
||||
doubleFollow,
|
||||
flushAndRunServer,
|
||||
flushAndRunMultipleServers,
|
||||
getLocalVideos,
|
||||
getVideo,
|
||||
|
@ -938,7 +939,51 @@ describe('Test multiple servers', function () {
|
|||
}
|
||||
})
|
||||
|
||||
it('Should retrieve all comments when subscribing to a new server', async function () {
|
||||
this.timeout(120000)
|
||||
|
||||
const newServer = await flushAndRunServer(4)
|
||||
|
||||
await setAccessTokensToServers([newServer])
|
||||
await doubleFollow(newServer, servers[0])
|
||||
await doubleFollow(newServer, servers[2])
|
||||
await waitJobs([newServer, ...servers])
|
||||
|
||||
const res = await getVideoCommentThreads(newServer.url, videoUUID, 0, 5)
|
||||
|
||||
expect(res.body.total).to.equal(2)
|
||||
expect(res.body.data).to.be.an('array')
|
||||
expect(res.body.data).to.have.lengthOf(2)
|
||||
|
||||
{
|
||||
const comment: VideoComment = res.body.data[0]
|
||||
expect(comment).to.not.be.undefined
|
||||
expect(comment.inReplyToCommentId).to.be.null
|
||||
expect(comment.account.name).to.equal('root')
|
||||
expect(comment.account.host).to.equal('localhost:' + servers[2].port)
|
||||
expect(comment.totalReplies).to.equal(0)
|
||||
expect(dateIsValid(comment.createdAt as string)).to.be.true
|
||||
expect(dateIsValid(comment.updatedAt as string)).to.be.true
|
||||
}
|
||||
|
||||
{
|
||||
const deletedComment: VideoComment = res.body.data[1]
|
||||
expect(deletedComment).to.not.be.undefined
|
||||
expect(deletedComment.isDeleted).to.be.true
|
||||
expect(deletedComment.deletedAt).to.not.be.null
|
||||
expect(deletedComment.text).to.equal('')
|
||||
expect(deletedComment.inReplyToCommentId).to.be.null
|
||||
expect(deletedComment.account).to.be.null
|
||||
expect(deletedComment.totalReplies).to.equal(3)
|
||||
expect(dateIsValid(deletedComment.createdAt as string)).to.be.true
|
||||
expect(dateIsValid(deletedComment.updatedAt as string)).to.be.true
|
||||
expect(dateIsValid(deletedComment.deletedAt as string)).to.be.true
|
||||
}
|
||||
})
|
||||
|
||||
it('Should delete a remote thread by the origin server', async function () {
|
||||
this.timeout(5000)
|
||||
|
||||
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)
|
||||
|
|
|
@ -93,9 +93,11 @@ export interface ActivityPubAttributedTo {
|
|||
export interface ActivityTombstoneObject {
|
||||
'@context'?: any
|
||||
id: string
|
||||
url?: string
|
||||
type: 'Tombstone'
|
||||
name?: string
|
||||
formerType?: string
|
||||
inReplyTo?: string
|
||||
published: string
|
||||
updated: string
|
||||
deleted: string
|
||||
|
|
Loading…
Reference in a new issue