]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blobdiff - server/lib/job-queue/handlers/activitypub-cleaner.ts
Merge branch 'release/4.0.0' into develop
[github/Chocobozzz/PeerTube.git] / server / lib / job-queue / handlers / activitypub-cleaner.ts
index 0e75b0a6e0141889542154144351deea2e3283ec..d5e4508fea24a2a8e4c01c9dd54336f082e02b2e 100644 (file)
@@ -1,5 +1,5 @@
-import * as Bluebird from 'bluebird'
-import * as Bull from 'bull'
+import { map } from 'bluebird'
+import { Job } from 'bull'
 import { checkUrlsSameHost } from '@server/helpers/activitypub'
 import {
   isAnnounceActivityValid,
@@ -7,25 +7,25 @@ import {
   isLikeActivityValid
 } from '@server/helpers/custom-validators/activitypub/activity'
 import { sanitizeAndCheckVideoCommentObject } from '@server/helpers/custom-validators/activitypub/video-comments'
-import { doRequest } from '@server/helpers/requests'
+import { doJSONRequest, PeerTubeRequestError } from '@server/helpers/requests'
 import { AP_CLEANER_CONCURRENCY } from '@server/initializers/constants'
 import { VideoModel } from '@server/models/video/video'
 import { VideoCommentModel } from '@server/models/video/video-comment'
 import { VideoShareModel } from '@server/models/video/video-share'
-import { HttpStatusCode } from '@shared/core-utils'
+import { HttpStatusCode } from '@shared/models'
 import { logger } from '../../../helpers/logger'
 import { AccountVideoRateModel } from '../../../models/account/account-video-rate'
 
 // Job to clean remote interactions off local videos
 
-async function processActivityPubCleaner (_job: Bull.Job) {
+async function processActivityPubCleaner (_job: Job) {
   logger.info('Processing ActivityPub cleaner.')
 
   {
     const rateUrls = await AccountVideoRateModel.listRemoteRateUrlsOfLocalVideos()
     const { bodyValidator, deleter, updater } = rateOptionsFactory()
 
-    await Bluebird.map(rateUrls, async rateUrl => {
+    await map(rateUrls, async rateUrl => {
       try {
         const result = await updateObjectIfNeeded(rateUrl, bodyValidator, updater, deleter)
 
@@ -44,7 +44,7 @@ async function processActivityPubCleaner (_job: Bull.Job) {
     const shareUrls = await VideoShareModel.listRemoteShareUrlsOfLocalVideos()
     const { bodyValidator, deleter, updater } = shareOptionsFactory()
 
-    await Bluebird.map(shareUrls, async shareUrl => {
+    await map(shareUrls, async shareUrl => {
       try {
         await updateObjectIfNeeded(shareUrl, bodyValidator, updater, deleter)
       } catch (err) {
@@ -57,7 +57,7 @@ async function processActivityPubCleaner (_job: Bull.Job) {
     const commentUrls = await VideoCommentModel.listRemoteCommentUrlsOfLocalVideos()
     const { bodyValidator, deleter, updater } = commentOptionsFactory()
 
-    await Bluebird.map(commentUrls, async commentUrl => {
+    await map(commentUrls, async commentUrl => {
       try {
         await updateObjectIfNeeded(commentUrl, bodyValidator, updater, deleter)
       } catch (err) {
@@ -81,44 +81,44 @@ async function updateObjectIfNeeded <T> (
   updater: (url: string, newUrl: string) => Promise<T>,
   deleter: (url: string) => Promise<T>
 ): Promise<{ data: T, status: 'deleted' | 'updated' } | null> {
-  // Fetch url
-  const { response, body } = await doRequest<any>({
-    uri: url,
-    json: true,
-    activityPub: true
-  })
-
-  // Does not exist anymore, remove entry
-  if (response.statusCode === HttpStatusCode.NOT_FOUND_404) {
+  const on404OrTombstone = async () => {
     logger.info('Removing remote AP object %s.', url)
     const data = await deleter(url)
 
-    return { status: 'deleted', data }
+    return { status: 'deleted' as 'deleted', data }
   }
 
-  // If not same id, check same host and update
-  if (!body || !body.id || !bodyValidator(body)) throw new Error(`Body or body id of ${url} is invalid`)
+  try {
+    const { body } = await doJSONRequest<any>(url, { activityPub: true })
 
-  if (body.type === 'Tombstone') {
-    logger.info('Removing remote AP object %s.', url)
-    const data = await deleter(url)
+    // If not same id, check same host and update
+    if (!body || !body.id || !bodyValidator(body)) throw new Error(`Body or body id of ${url} is invalid`)
 
-    return { status: 'deleted', data }
-  }
+    if (body.type === 'Tombstone') {
+      return on404OrTombstone()
+    }
 
-  const newUrl = body.id
-  if (newUrl !== url) {
-    if (checkUrlsSameHost(newUrl, url) !== true) {
-      throw new Error(`New url ${newUrl} has not the same host than old url ${url}`)
+    const newUrl = body.id
+    if (newUrl !== url) {
+      if (checkUrlsSameHost(newUrl, url) !== true) {
+        throw new Error(`New url ${newUrl} has not the same host than old url ${url}`)
+      }
+
+      logger.info('Updating remote AP object %s.', url)
+      const data = await updater(url, newUrl)
+
+      return { status: 'updated', data }
     }
 
-    logger.info('Updating remote AP object %s.', url)
-    const data = await updater(url, newUrl)
+    return null
+  } catch (err) {
+    // Does not exist anymore, remove entry
+    if ((err as PeerTubeRequestError).statusCode === HttpStatusCode.NOT_FOUND_404) {
+      return on404OrTombstone()
+    }
 
-    return { status: 'updated', data }
+    throw err
   }
-
-  return null
 }
 
 function rateOptionsFactory () {