aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/lib/activitypub/process/process-delete.ts
blob: 07e6a0075d40423545b9fbeaf03cc2b826f3d500 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
import { ActivityDelete } from '../../../../shared/models/activitypub'
import { retryTransactionWrapper } from '../../../helpers/database-utils'
import { logger } from '../../../helpers/logger'
import { sequelizeTypescript } from '../../../initializers'
import { AccountModel } from '../../../models/account/account'
import { ActorModel } from '../../../models/activitypub/actor'
import { VideoModel } from '../../../models/video/video'
import { VideoChannelModel } from '../../../models/video/video-channel'
import { VideoCommentModel } from '../../../models/video/video-comment'
import { getOrCreateActorAndServerAndModel } from '../actor'

async function processDeleteActivity (activity: ActivityDelete) {
  const actor = await getOrCreateActorAndServerAndModel(activity.actor)
  const objectUrl = typeof activity.object === 'string' ? activity.object : activity.object.id

  if (actor.url === objectUrl) {
    if (actor.type === 'Person') {
      if (!actor.Account) throw new Error('Actor ' + actor.url + ' is a person but we cannot find it in database.')

      return processDeleteAccount(actor.Account)
    } else if (actor.type === 'Group') {
      if (!actor.VideoChannel) throw new Error('Actor ' + actor.url + ' is a group but we cannot find it in database.')

      return processDeleteVideoChannel(actor.VideoChannel)
    }
  }

  {
    const videoCommentInstance = await VideoCommentModel.loadByUrlAndPopulateAccount(objectUrl)
    if (videoCommentInstance) {
      return processDeleteVideoComment(actor, videoCommentInstance)
    }
  }

  {
    const videoInstance = await VideoModel.loadByUrlAndPopulateAccount(objectUrl)
    if (videoInstance) {
      return processDeleteVideo(actor, videoInstance)
    }
  }

  return
}

// ---------------------------------------------------------------------------

export {
  processDeleteActivity
}

// ---------------------------------------------------------------------------

async function processDeleteVideo (actor: ActorModel, videoToDelete: VideoModel) {
  const options = {
    arguments: [ actor, videoToDelete ],
    errorMessage: 'Cannot remove the remote video with many retries.'
  }

  await retryTransactionWrapper(deleteRemoteVideo, options)
}

async function deleteRemoteVideo (actor: ActorModel, videoToDelete: VideoModel) {
  logger.debug('Removing remote video "%s".', videoToDelete.uuid)

  await sequelizeTypescript.transaction(async t => {
    if (videoToDelete.VideoChannel.Account.Actor.id !== actor.id) {
      throw new Error('Account ' + actor.url + ' does not own video channel ' + videoToDelete.VideoChannel.Actor.url)
    }

    await videoToDelete.destroy({ transaction: t })
  })

  logger.info('Remote video with uuid %s removed.', videoToDelete.uuid)
}

async function processDeleteAccount (accountToRemove: AccountModel) {
  const options = {
    arguments: [ accountToRemove ],
    errorMessage: 'Cannot remove the remote account with many retries.'
  }

  await retryTransactionWrapper(deleteRemoteAccount, options)
}

async function deleteRemoteAccount (accountToRemove: AccountModel) {
  logger.debug('Removing remote account "%s".', accountToRemove.Actor.uuid)

  await sequelizeTypescript.transaction(async t => {
    await accountToRemove.destroy({ transaction: t })
  })

  logger.info('Remote account with uuid %s removed.', accountToRemove.Actor.uuid)
}

async function processDeleteVideoChannel (videoChannelToRemove: VideoChannelModel) {
  const options = {
    arguments: [ videoChannelToRemove ],
    errorMessage: 'Cannot remove the remote video channel with many retries.'
  }

  await retryTransactionWrapper(deleteRemoteVideoChannel, options)
}

async function deleteRemoteVideoChannel (videoChannelToRemove: VideoChannelModel) {
  logger.debug('Removing remote video channel "%s".', videoChannelToRemove.Actor.uuid)

  await sequelizeTypescript.transaction(async t => {
    await videoChannelToRemove.destroy({ transaction: t })
  })

  logger.info('Remote video channel with uuid %s removed.', videoChannelToRemove.Actor.uuid)
}

async function processDeleteVideoComment (actor: ActorModel, videoComment: VideoCommentModel) {
  const options = {
    arguments: [ actor, videoComment ],
    errorMessage: 'Cannot remove the remote video comment with many retries.'
  }

  await retryTransactionWrapper(deleteRemoteVideoComment, options)
}

function deleteRemoteVideoComment (actor: ActorModel, videoComment: VideoCommentModel) {
  logger.debug('Removing remote video comment "%s".', videoComment.url)

  return sequelizeTypescript.transaction(async t => {
    await videoComment.destroy({ transaction: t })

    logger.info('Remote video comment %s removed.', videoComment.url)
  })
}