aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/lib
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2021-03-08 14:24:11 +0100
committerChocobozzz <me@florianbigard.com>2021-03-24 18:18:40 +0100
commitdb4b15f21fbf4e33434e930ffc7fb768cdcf9d42 (patch)
tree418117b84a5c2ee578c210288b698d155422d608 /server/lib
parent71926aae0762facb25243f27eaf45933b5a37353 (diff)
downloadPeerTube-db4b15f21fbf4e33434e930ffc7fb768cdcf9d42.tar.gz
PeerTube-db4b15f21fbf4e33434e930ffc7fb768cdcf9d42.tar.zst
PeerTube-db4b15f21fbf4e33434e930ffc7fb768cdcf9d42.zip
Use got instead of request
Diffstat (limited to 'server/lib')
-rw-r--r--server/lib/activitypub/actor.ts41
-rw-r--r--server/lib/activitypub/crawl.ts25
-rw-r--r--server/lib/activitypub/playlist.ts54
-rw-r--r--server/lib/activitypub/share.ts9
-rw-r--r--server/lib/activitypub/video-comments.ts14
-rw-r--r--server/lib/activitypub/video-rates.ts22
-rw-r--r--server/lib/activitypub/videos.ts31
-rw-r--r--server/lib/files-cache/videos-caption-cache.ts2
-rw-r--r--server/lib/files-cache/videos-preview-cache.ts2
-rw-r--r--server/lib/files-cache/videos-torrent-cache.ts2
-rw-r--r--server/lib/hls.ts4
-rw-r--r--server/lib/job-queue/handlers/activitypub-cleaner.ts11
-rw-r--r--server/lib/job-queue/handlers/activitypub-http-broadcast.ts5
-rw-r--r--server/lib/job-queue/handlers/activitypub-http-unicast.ts5
-rw-r--r--server/lib/job-queue/handlers/utils/activitypub-http-utils.ts9
-rw-r--r--server/lib/plugins/plugin-index.ts26
-rw-r--r--server/lib/schedulers/auto-follow-index-instances.ts8
17 files changed, 108 insertions, 162 deletions
diff --git a/server/lib/activitypub/actor.ts b/server/lib/activitypub/actor.ts
index a726f9e20..52b6c1f56 100644
--- a/server/lib/activitypub/actor.ts
+++ b/server/lib/activitypub/actor.ts
@@ -1,26 +1,28 @@
1import * as Bluebird from 'bluebird' 1import * as Bluebird from 'bluebird'
2import { extname } from 'path'
2import { Op, Transaction } from 'sequelize' 3import { Op, Transaction } from 'sequelize'
3import { URL } from 'url' 4import { URL } from 'url'
4import { v4 as uuidv4 } from 'uuid' 5import { v4 as uuidv4 } from 'uuid'
6import { getServerActor } from '@server/models/application/application'
7import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes'
5import { ActivityPubActor, ActivityPubActorType, ActivityPubOrderedCollection } from '../../../shared/models/activitypub' 8import { ActivityPubActor, ActivityPubActorType, ActivityPubOrderedCollection } from '../../../shared/models/activitypub'
6import { ActivityPubAttributedTo } from '../../../shared/models/activitypub/objects' 9import { ActivityPubAttributedTo } from '../../../shared/models/activitypub/objects'
7import { checkUrlsSameHost, getAPId } from '../../helpers/activitypub' 10import { checkUrlsSameHost, getAPId } from '../../helpers/activitypub'
11import { ActorFetchByUrlType, fetchActorByUrl } from '../../helpers/actor'
8import { sanitizeAndCheckActorObject } from '../../helpers/custom-validators/activitypub/actor' 12import { sanitizeAndCheckActorObject } from '../../helpers/custom-validators/activitypub/actor'
9import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc' 13import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc'
10import { retryTransactionWrapper, updateInstanceWithAnother } from '../../helpers/database-utils' 14import { retryTransactionWrapper, updateInstanceWithAnother } from '../../helpers/database-utils'
11import { logger } from '../../helpers/logger' 15import { logger } from '../../helpers/logger'
12import { createPrivateAndPublicKeys } from '../../helpers/peertube-crypto' 16import { createPrivateAndPublicKeys } from '../../helpers/peertube-crypto'
13import { doRequest } from '../../helpers/requests' 17import { doJSONRequest } from '../../helpers/requests'
14import { getUrlFromWebfinger } from '../../helpers/webfinger' 18import { getUrlFromWebfinger } from '../../helpers/webfinger'
15import { MIMETYPES, WEBSERVER } from '../../initializers/constants' 19import { MIMETYPES, WEBSERVER } from '../../initializers/constants'
20import { sequelizeTypescript } from '../../initializers/database'
16import { AccountModel } from '../../models/account/account' 21import { AccountModel } from '../../models/account/account'
17import { ActorModel } from '../../models/activitypub/actor' 22import { ActorModel } from '../../models/activitypub/actor'
18import { AvatarModel } from '../../models/avatar/avatar' 23import { AvatarModel } from '../../models/avatar/avatar'
19import { ServerModel } from '../../models/server/server' 24import { ServerModel } from '../../models/server/server'
20import { VideoChannelModel } from '../../models/video/video-channel' 25import { VideoChannelModel } from '../../models/video/video-channel'
21import { JobQueue } from '../job-queue'
22import { ActorFetchByUrlType, fetchActorByUrl } from '../../helpers/actor'
23import { sequelizeTypescript } from '../../initializers/database'
24import { 26import {
25 MAccount, 27 MAccount,
26 MAccountDefault, 28 MAccountDefault,
@@ -34,9 +36,7 @@ import {
34 MActorId, 36 MActorId,
35 MChannel 37 MChannel
36} from '../../types/models' 38} from '../../types/models'
37import { extname } from 'path' 39import { JobQueue } from '../job-queue'
38import { getServerActor } from '@server/models/application/application'
39import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes'
40 40
41// Set account keys, this could be long so process after the account creation and do not block the client 41// Set account keys, this could be long so process after the account creation and do not block the client
42async function generateAndSaveActorKeys <T extends MActor> (actor: T) { 42async function generateAndSaveActorKeys <T extends MActor> (actor: T) {
@@ -209,16 +209,10 @@ async function deleteActorAvatarInstance (actor: MActorDefault, t: Transaction)
209} 209}
210 210
211async function fetchActorTotalItems (url: string) { 211async function fetchActorTotalItems (url: string) {
212 const options = {
213 uri: url,
214 method: 'GET',
215 json: true,
216 activityPub: true
217 }
218
219 try { 212 try {
220 const { body } = await doRequest<ActivityPubOrderedCollection<unknown>>(options) 213 const { body } = await doJSONRequest<ActivityPubOrderedCollection<unknown>>(url, { activityPub: true })
221 return body.totalItems ? body.totalItems : 0 214
215 return body.totalItems || 0
222 } catch (err) { 216 } catch (err) {
223 logger.warn('Cannot fetch remote actor count %s.', url, { err }) 217 logger.warn('Cannot fetch remote actor count %s.', url, { err })
224 return 0 218 return 0
@@ -449,26 +443,19 @@ type FetchRemoteActorResult = {
449 attributedTo: ActivityPubAttributedTo[] 443 attributedTo: ActivityPubAttributedTo[]
450} 444}
451async function fetchRemoteActor (actorUrl: string): Promise<{ statusCode?: number, result: FetchRemoteActorResult }> { 445async function fetchRemoteActor (actorUrl: string): Promise<{ statusCode?: number, result: FetchRemoteActorResult }> {
452 const options = {
453 uri: actorUrl,
454 method: 'GET',
455 json: true,
456 activityPub: true
457 }
458
459 logger.info('Fetching remote actor %s.', actorUrl) 446 logger.info('Fetching remote actor %s.', actorUrl)
460 447
461 const requestResult = await doRequest<ActivityPubActor>(options) 448 const requestResult = await doJSONRequest<ActivityPubActor>(actorUrl, { activityPub: true })
462 const actorJSON = requestResult.body 449 const actorJSON = requestResult.body
463 450
464 if (sanitizeAndCheckActorObject(actorJSON) === false) { 451 if (sanitizeAndCheckActorObject(actorJSON) === false) {
465 logger.debug('Remote actor JSON is not valid.', { actorJSON }) 452 logger.debug('Remote actor JSON is not valid.', { actorJSON })
466 return { result: undefined, statusCode: requestResult.response.statusCode } 453 return { result: undefined, statusCode: requestResult.statusCode }
467 } 454 }
468 455
469 if (checkUrlsSameHost(actorJSON.id, actorUrl) !== true) { 456 if (checkUrlsSameHost(actorJSON.id, actorUrl) !== true) {
470 logger.warn('Actor url %s has not the same host than its AP id %s', actorUrl, actorJSON.id) 457 logger.warn('Actor url %s has not the same host than its AP id %s', actorUrl, actorJSON.id)
471 return { result: undefined, statusCode: requestResult.response.statusCode } 458 return { result: undefined, statusCode: requestResult.statusCode }
472 } 459 }
473 460
474 const followersCount = await fetchActorTotalItems(actorJSON.followers) 461 const followersCount = await fetchActorTotalItems(actorJSON.followers)
@@ -496,7 +483,7 @@ async function fetchRemoteActor (actorUrl: string): Promise<{ statusCode?: numbe
496 483
497 const name = actorJSON.name || actorJSON.preferredUsername 484 const name = actorJSON.name || actorJSON.preferredUsername
498 return { 485 return {
499 statusCode: requestResult.response.statusCode, 486 statusCode: requestResult.statusCode,
500 result: { 487 result: {
501 actor, 488 actor,
502 name, 489 name,
diff --git a/server/lib/activitypub/crawl.ts b/server/lib/activitypub/crawl.ts
index 1ed105bbe..278abf7de 100644
--- a/server/lib/activitypub/crawl.ts
+++ b/server/lib/activitypub/crawl.ts
@@ -1,27 +1,26 @@
1import { ACTIVITY_PUB, REQUEST_TIMEOUT, WEBSERVER } from '../../initializers/constants'
2import { doRequest } from '../../helpers/requests'
3import { logger } from '../../helpers/logger'
4import * as Bluebird from 'bluebird' 1import * as Bluebird from 'bluebird'
5import { ActivityPubOrderedCollection } from '../../../shared/models/activitypub'
6import { URL } from 'url' 2import { URL } from 'url'
3import { ActivityPubOrderedCollection } from '../../../shared/models/activitypub'
4import { logger } from '../../helpers/logger'
5import { doJSONRequest } from '../../helpers/requests'
6import { ACTIVITY_PUB, REQUEST_TIMEOUT, WEBSERVER } from '../../initializers/constants'
7 7
8type HandlerFunction<T> = (items: T[]) => (Promise<any> | Bluebird<any>) 8type HandlerFunction<T> = (items: T[]) => (Promise<any> | Bluebird<any>)
9type CleanerFunction = (startedDate: Date) => (Promise<any> | Bluebird<any>) 9type CleanerFunction = (startedDate: Date) => (Promise<any> | Bluebird<any>)
10 10
11async function crawlCollectionPage <T> (uri: string, handler: HandlerFunction<T>, cleaner?: CleanerFunction) { 11async function crawlCollectionPage <T> (argUrl: string, handler: HandlerFunction<T>, cleaner?: CleanerFunction) {
12 logger.info('Crawling ActivityPub data on %s.', uri) 12 let url = argUrl
13
14 logger.info('Crawling ActivityPub data on %s.', url)
13 15
14 const options = { 16 const options = {
15 method: 'GET',
16 uri,
17 json: true,
18 activityPub: true, 17 activityPub: true,
19 timeout: REQUEST_TIMEOUT 18 timeout: REQUEST_TIMEOUT
20 } 19 }
21 20
22 const startDate = new Date() 21 const startDate = new Date()
23 22
24 const response = await doRequest<ActivityPubOrderedCollection<T>>(options) 23 const response = await doJSONRequest<ActivityPubOrderedCollection<T>>(url, options)
25 const firstBody = response.body 24 const firstBody = response.body
26 25
27 const limit = ACTIVITY_PUB.FETCH_PAGE_LIMIT 26 const limit = ACTIVITY_PUB.FETCH_PAGE_LIMIT
@@ -35,9 +34,9 @@ async function crawlCollectionPage <T> (uri: string, handler: HandlerFunction<T>
35 const remoteHost = new URL(nextLink).host 34 const remoteHost = new URL(nextLink).host
36 if (remoteHost === WEBSERVER.HOST) continue 35 if (remoteHost === WEBSERVER.HOST) continue
37 36
38 options.uri = nextLink 37 url = nextLink
39 38
40 const res = await doRequest<ActivityPubOrderedCollection<T>>(options) 39 const res = await doJSONRequest<ActivityPubOrderedCollection<T>>(url, options)
41 body = res.body 40 body = res.body
42 } else { 41 } else {
43 // nextLink is already the object we want 42 // nextLink is already the object we want
@@ -49,7 +48,7 @@ async function crawlCollectionPage <T> (uri: string, handler: HandlerFunction<T>
49 48
50 if (Array.isArray(body.orderedItems)) { 49 if (Array.isArray(body.orderedItems)) {
51 const items = body.orderedItems 50 const items = body.orderedItems
52 logger.info('Processing %i ActivityPub items for %s.', items.length, options.uri) 51 logger.info('Processing %i ActivityPub items for %s.', items.length, url)
53 52
54 await handler(items) 53 await handler(items)
55 } 54 }
diff --git a/server/lib/activitypub/playlist.ts b/server/lib/activitypub/playlist.ts
index d5a3ef7c8..795be60d7 100644
--- a/server/lib/activitypub/playlist.ts
+++ b/server/lib/activitypub/playlist.ts
@@ -1,24 +1,24 @@
1import * as Bluebird from 'bluebird'
2import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes'
3import { PlaylistElementObject } from '../../../shared/models/activitypub/objects/playlist-element-object'
1import { PlaylistObject } from '../../../shared/models/activitypub/objects/playlist-object' 4import { PlaylistObject } from '../../../shared/models/activitypub/objects/playlist-object'
2import { crawlCollectionPage } from './crawl' 5import { VideoPlaylistPrivacy } from '../../../shared/models/videos/playlist/video-playlist-privacy.model'
3import { ACTIVITY_PUB, CRAWL_REQUEST_CONCURRENCY } from '../../initializers/constants' 6import { checkUrlsSameHost } from '../../helpers/activitypub'
7import { isPlaylistElementObjectValid, isPlaylistObjectValid } from '../../helpers/custom-validators/activitypub/playlist'
4import { isArray } from '../../helpers/custom-validators/misc' 8import { isArray } from '../../helpers/custom-validators/misc'
5import { getOrCreateActorAndServerAndModel } from './actor'
6import { logger } from '../../helpers/logger' 9import { logger } from '../../helpers/logger'
10import { doJSONRequest } from '../../helpers/requests'
11import { ACTIVITY_PUB, CRAWL_REQUEST_CONCURRENCY } from '../../initializers/constants'
12import { sequelizeTypescript } from '../../initializers/database'
7import { VideoPlaylistModel } from '../../models/video/video-playlist' 13import { VideoPlaylistModel } from '../../models/video/video-playlist'
8import { doRequest } from '../../helpers/requests'
9import { checkUrlsSameHost } from '../../helpers/activitypub'
10import * as Bluebird from 'bluebird'
11import { PlaylistElementObject } from '../../../shared/models/activitypub/objects/playlist-element-object'
12import { getOrCreateVideoAndAccountAndChannel } from './videos'
13import { isPlaylistElementObjectValid, isPlaylistObjectValid } from '../../helpers/custom-validators/activitypub/playlist'
14import { VideoPlaylistElementModel } from '../../models/video/video-playlist-element' 14import { VideoPlaylistElementModel } from '../../models/video/video-playlist-element'
15import { VideoPlaylistPrivacy } from '../../../shared/models/videos/playlist/video-playlist-privacy.model'
16import { sequelizeTypescript } from '../../initializers/database'
17import { createPlaylistMiniatureFromUrl } from '../thumbnail'
18import { FilteredModelAttributes } from '../../types/sequelize'
19import { MAccountDefault, MAccountId, MVideoId } from '../../types/models' 15import { MAccountDefault, MAccountId, MVideoId } from '../../types/models'
20import { MVideoPlaylist, MVideoPlaylistId, MVideoPlaylistOwner } from '../../types/models/video/video-playlist' 16import { MVideoPlaylist, MVideoPlaylistId, MVideoPlaylistOwner } from '../../types/models/video/video-playlist'
21import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' 17import { FilteredModelAttributes } from '../../types/sequelize'
18import { createPlaylistMiniatureFromUrl } from '../thumbnail'
19import { getOrCreateActorAndServerAndModel } from './actor'
20import { crawlCollectionPage } from './crawl'
21import { getOrCreateVideoAndAccountAndChannel } from './videos'
22 22
23function playlistObjectToDBAttributes (playlistObject: PlaylistObject, byAccount: MAccountId, to: string[]) { 23function playlistObjectToDBAttributes (playlistObject: PlaylistObject, byAccount: MAccountId, to: string[]) {
24 const privacy = to.includes(ACTIVITY_PUB.PUBLIC) 24 const privacy = to.includes(ACTIVITY_PUB.PUBLIC)
@@ -56,11 +56,7 @@ async function createAccountPlaylists (playlistUrls: string[], account: MAccount
56 if (exists === true) return 56 if (exists === true) return
57 57
58 // Fetch url 58 // Fetch url
59 const { body } = await doRequest<PlaylistObject>({ 59 const { body } = await doJSONRequest<PlaylistObject>(playlistUrl, { activityPub: true })
60 uri: playlistUrl,
61 json: true,
62 activityPub: true
63 })
64 60
65 if (!isPlaylistObjectValid(body)) { 61 if (!isPlaylistObjectValid(body)) {
66 throw new Error(`Invalid playlist object when fetch account playlists: ${JSON.stringify(body)}`) 62 throw new Error(`Invalid playlist object when fetch account playlists: ${JSON.stringify(body)}`)
@@ -164,12 +160,7 @@ async function resetVideoPlaylistElements (elementUrls: string[], playlist: MVid
164 160
165 await Bluebird.map(elementUrls, async elementUrl => { 161 await Bluebird.map(elementUrls, async elementUrl => {
166 try { 162 try {
167 // Fetch url 163 const { body } = await doJSONRequest<PlaylistElementObject>(elementUrl, { activityPub: true })
168 const { body } = await doRequest<PlaylistElementObject>({
169 uri: elementUrl,
170 json: true,
171 activityPub: true
172 })
173 164
174 if (!isPlaylistElementObjectValid(body)) throw new Error(`Invalid body in video get playlist element ${elementUrl}`) 165 if (!isPlaylistElementObjectValid(body)) throw new Error(`Invalid body in video get playlist element ${elementUrl}`)
175 166
@@ -199,21 +190,14 @@ async function resetVideoPlaylistElements (elementUrls: string[], playlist: MVid
199} 190}
200 191
201async function fetchRemoteVideoPlaylist (playlistUrl: string): Promise<{ statusCode: number, playlistObject: PlaylistObject }> { 192async function fetchRemoteVideoPlaylist (playlistUrl: string): Promise<{ statusCode: number, playlistObject: PlaylistObject }> {
202 const options = {
203 uri: playlistUrl,
204 method: 'GET',
205 json: true,
206 activityPub: true
207 }
208
209 logger.info('Fetching remote playlist %s.', playlistUrl) 193 logger.info('Fetching remote playlist %s.', playlistUrl)
210 194
211 const { response, body } = await doRequest<any>(options) 195 const { body, statusCode } = await doJSONRequest<any>(playlistUrl, { activityPub: true })
212 196
213 if (isPlaylistObjectValid(body) === false || checkUrlsSameHost(body.id, playlistUrl) !== true) { 197 if (isPlaylistObjectValid(body) === false || checkUrlsSameHost(body.id, playlistUrl) !== true) {
214 logger.debug('Remote video playlist JSON is not valid.', { body }) 198 logger.debug('Remote video playlist JSON is not valid.', { body })
215 return { statusCode: response.statusCode, playlistObject: undefined } 199 return { statusCode, playlistObject: undefined }
216 } 200 }
217 201
218 return { statusCode: response.statusCode, playlistObject: body } 202 return { statusCode, playlistObject: body }
219} 203}
diff --git a/server/lib/activitypub/share.ts b/server/lib/activitypub/share.ts
index dde0c628e..c22fa0893 100644
--- a/server/lib/activitypub/share.ts
+++ b/server/lib/activitypub/share.ts
@@ -3,7 +3,7 @@ import { Transaction } from 'sequelize'
3import { getServerActor } from '@server/models/application/application' 3import { getServerActor } from '@server/models/application/application'
4import { checkUrlsSameHost, getAPId } from '../../helpers/activitypub' 4import { checkUrlsSameHost, getAPId } from '../../helpers/activitypub'
5import { logger, loggerTagsFactory } from '../../helpers/logger' 5import { logger, loggerTagsFactory } from '../../helpers/logger'
6import { doRequest } from '../../helpers/requests' 6import { doJSONRequest } from '../../helpers/requests'
7import { CRAWL_REQUEST_CONCURRENCY } from '../../initializers/constants' 7import { CRAWL_REQUEST_CONCURRENCY } from '../../initializers/constants'
8import { VideoShareModel } from '../../models/video/video-share' 8import { VideoShareModel } from '../../models/video/video-share'
9import { MChannelActorLight, MVideo, MVideoAccountLight, MVideoId } from '../../types/models/video' 9import { MChannelActorLight, MVideo, MVideoAccountLight, MVideoId } from '../../types/models/video'
@@ -40,12 +40,7 @@ async function changeVideoChannelShare (
40async function addVideoShares (shareUrls: string[], video: MVideoId) { 40async function addVideoShares (shareUrls: string[], video: MVideoId) {
41 await Bluebird.map(shareUrls, async shareUrl => { 41 await Bluebird.map(shareUrls, async shareUrl => {
42 try { 42 try {
43 // Fetch url 43 const { body } = await doJSONRequest<any>(shareUrl, { activityPub: true })
44 const { body } = await doRequest<any>({
45 uri: shareUrl,
46 json: true,
47 activityPub: true
48 })
49 if (!body || !body.actor) throw new Error('Body or body actor is invalid') 44 if (!body || !body.actor) throw new Error('Body or body actor is invalid')
50 45
51 const actorUrl = getAPId(body.actor) 46 const actorUrl = getAPId(body.actor)
diff --git a/server/lib/activitypub/video-comments.ts b/server/lib/activitypub/video-comments.ts
index d025ed7f1..f1edfb0ac 100644
--- a/server/lib/activitypub/video-comments.ts
+++ b/server/lib/activitypub/video-comments.ts
@@ -1,13 +1,13 @@
1import * as Bluebird from 'bluebird'
2import { checkUrlsSameHost } from '../../helpers/activitypub'
1import { sanitizeAndCheckVideoCommentObject } from '../../helpers/custom-validators/activitypub/video-comments' 3import { sanitizeAndCheckVideoCommentObject } from '../../helpers/custom-validators/activitypub/video-comments'
2import { logger } from '../../helpers/logger' 4import { logger } from '../../helpers/logger'
3import { doRequest } from '../../helpers/requests' 5import { doJSONRequest } from '../../helpers/requests'
4import { ACTIVITY_PUB, CRAWL_REQUEST_CONCURRENCY } from '../../initializers/constants' 6import { ACTIVITY_PUB, CRAWL_REQUEST_CONCURRENCY } from '../../initializers/constants'
5import { VideoCommentModel } from '../../models/video/video-comment' 7import { VideoCommentModel } from '../../models/video/video-comment'
8import { MCommentOwner, MCommentOwnerVideo, MVideoAccountLightBlacklistAllFiles } from '../../types/models/video'
6import { getOrCreateActorAndServerAndModel } from './actor' 9import { getOrCreateActorAndServerAndModel } from './actor'
7import { getOrCreateVideoAndAccountAndChannel } from './videos' 10import { getOrCreateVideoAndAccountAndChannel } from './videos'
8import * as Bluebird from 'bluebird'
9import { checkUrlsSameHost } from '../../helpers/activitypub'
10import { MCommentOwner, MCommentOwnerVideo, MVideoAccountLightBlacklistAllFiles } from '../../types/models/video'
11 11
12type ResolveThreadParams = { 12type ResolveThreadParams = {
13 url: string 13 url: string
@@ -126,11 +126,7 @@ async function resolveRemoteParentComment (params: ResolveThreadParams) {
126 throw new Error('Recursion limit reached when resolving a thread') 126 throw new Error('Recursion limit reached when resolving a thread')
127 } 127 }
128 128
129 const { body } = await doRequest<any>({ 129 const { body } = await doJSONRequest<any>(url, { activityPub: true })
130 uri: url,
131 json: true,
132 activityPub: true
133 })
134 130
135 if (sanitizeAndCheckVideoCommentObject(body) === false) { 131 if (sanitizeAndCheckVideoCommentObject(body) === false) {
136 throw new Error(`Remote video comment JSON ${url} is not valid:` + JSON.stringify(body)) 132 throw new Error(`Remote video comment JSON ${url} is not valid:` + JSON.stringify(body))
diff --git a/server/lib/activitypub/video-rates.ts b/server/lib/activitypub/video-rates.ts
index e246b1313..f40c07fea 100644
--- a/server/lib/activitypub/video-rates.ts
+++ b/server/lib/activitypub/video-rates.ts
@@ -1,26 +1,22 @@
1import * as Bluebird from 'bluebird'
1import { Transaction } from 'sequelize' 2import { Transaction } from 'sequelize'
2import { sendLike, sendUndoDislike, sendUndoLike } from './send' 3import { doJSONRequest } from '@server/helpers/requests'
3import { VideoRateType } from '../../../shared/models/videos' 4import { VideoRateType } from '../../../shared/models/videos'
4import * as Bluebird from 'bluebird' 5import { checkUrlsSameHost, getAPId } from '../../helpers/activitypub'
5import { getOrCreateActorAndServerAndModel } from './actor'
6import { AccountVideoRateModel } from '../../models/account/account-video-rate'
7import { logger } from '../../helpers/logger' 6import { logger } from '../../helpers/logger'
8import { CRAWL_REQUEST_CONCURRENCY } from '../../initializers/constants' 7import { CRAWL_REQUEST_CONCURRENCY } from '../../initializers/constants'
9import { doRequest } from '../../helpers/requests' 8import { AccountVideoRateModel } from '../../models/account/account-video-rate'
10import { checkUrlsSameHost, getAPId } from '../../helpers/activitypub'
11import { getVideoDislikeActivityPubUrlByLocalActor, getVideoLikeActivityPubUrlByLocalActor } from './url'
12import { sendDislike } from './send/send-dislike'
13import { MAccountActor, MActorUrl, MVideo, MVideoAccountLight, MVideoId } from '../../types/models' 9import { MAccountActor, MActorUrl, MVideo, MVideoAccountLight, MVideoId } from '../../types/models'
10import { getOrCreateActorAndServerAndModel } from './actor'
11import { sendLike, sendUndoDislike, sendUndoLike } from './send'
12import { sendDislike } from './send/send-dislike'
13import { getVideoDislikeActivityPubUrlByLocalActor, getVideoLikeActivityPubUrlByLocalActor } from './url'
14 14
15async function createRates (ratesUrl: string[], video: MVideo, rate: VideoRateType) { 15async function createRates (ratesUrl: string[], video: MVideo, rate: VideoRateType) {
16 await Bluebird.map(ratesUrl, async rateUrl => { 16 await Bluebird.map(ratesUrl, async rateUrl => {
17 try { 17 try {
18 // Fetch url 18 // Fetch url
19 const { body } = await doRequest<any>({ 19 const { body } = await doJSONRequest<any>(rateUrl, { activityPub: true })
20 uri: rateUrl,
21 json: true,
22 activityPub: true
23 })
24 if (!body || !body.actor) throw new Error('Body or body actor is invalid') 20 if (!body || !body.actor) throw new Error('Body or body actor is invalid')
25 21
26 const actorUrl = getAPId(body.actor) 22 const actorUrl = getAPId(body.actor)
diff --git a/server/lib/activitypub/videos.ts b/server/lib/activitypub/videos.ts
index c02578aad..a5f58dd01 100644
--- a/server/lib/activitypub/videos.ts
+++ b/server/lib/activitypub/videos.ts
@@ -2,7 +2,6 @@ import * as Bluebird from 'bluebird'
2import { maxBy, minBy } from 'lodash' 2import { maxBy, minBy } from 'lodash'
3import * as magnetUtil from 'magnet-uri' 3import * as magnetUtil from 'magnet-uri'
4import { basename, join } from 'path' 4import { basename, join } from 'path'
5import * as request from 'request'
6import { Transaction } from 'sequelize/types' 5import { Transaction } from 'sequelize/types'
7import { TrackerModel } from '@server/models/server/tracker' 6import { TrackerModel } from '@server/models/server/tracker'
8import { VideoLiveModel } from '@server/models/video/video-live' 7import { VideoLiveModel } from '@server/models/video/video-live'
@@ -31,7 +30,7 @@ import { isArray } from '../../helpers/custom-validators/misc'
31import { isVideoFileInfoHashValid } from '../../helpers/custom-validators/videos' 30import { isVideoFileInfoHashValid } from '../../helpers/custom-validators/videos'
32import { deleteNonExistingModels, resetSequelizeInstance, retryTransactionWrapper } from '../../helpers/database-utils' 31import { deleteNonExistingModels, resetSequelizeInstance, retryTransactionWrapper } from '../../helpers/database-utils'
33import { logger } from '../../helpers/logger' 32import { logger } from '../../helpers/logger'
34import { doRequest } from '../../helpers/requests' 33import { doJSONRequest } from '../../helpers/requests'
35import { fetchVideoByUrl, getExtFromMimetype, VideoFetchByUrlType } from '../../helpers/video' 34import { fetchVideoByUrl, getExtFromMimetype, VideoFetchByUrlType } from '../../helpers/video'
36import { 35import {
37 ACTIVITY_PUB, 36 ACTIVITY_PUB,
@@ -115,36 +114,26 @@ async function federateVideoIfNeeded (videoArg: MVideoAPWithoutCaption, isNewVid
115 } 114 }
116} 115}
117 116
118async function fetchRemoteVideo (videoUrl: string): Promise<{ response: request.RequestResponse, videoObject: VideoObject }> { 117async function fetchRemoteVideo (videoUrl: string): Promise<{ statusCode: number, videoObject: VideoObject }> {
119 const options = {
120 uri: videoUrl,
121 method: 'GET',
122 json: true,
123 activityPub: true
124 }
125
126 logger.info('Fetching remote video %s.', videoUrl) 118 logger.info('Fetching remote video %s.', videoUrl)
127 119
128 const { response, body } = await doRequest<any>(options) 120 const { statusCode, body } = await doJSONRequest<any>(videoUrl, { activityPub: true })
129 121
130 if (sanitizeAndCheckVideoTorrentObject(body) === false || checkUrlsSameHost(body.id, videoUrl) !== true) { 122 if (sanitizeAndCheckVideoTorrentObject(body) === false || checkUrlsSameHost(body.id, videoUrl) !== true) {
131 logger.debug('Remote video JSON is not valid.', { body }) 123 logger.debug('Remote video JSON is not valid.', { body })
132 return { response, videoObject: undefined } 124 return { statusCode, videoObject: undefined }
133 } 125 }
134 126
135 return { response, videoObject: body } 127 return { statusCode, videoObject: body }
136} 128}
137 129
138async function fetchRemoteVideoDescription (video: MVideoAccountLight) { 130async function fetchRemoteVideoDescription (video: MVideoAccountLight) {
139 const host = video.VideoChannel.Account.Actor.Server.host 131 const host = video.VideoChannel.Account.Actor.Server.host
140 const path = video.getDescriptionAPIPath() 132 const path = video.getDescriptionAPIPath()
141 const options = { 133 const url = REMOTE_SCHEME.HTTP + '://' + host + path
142 uri: REMOTE_SCHEME.HTTP + '://' + host + path,
143 json: true
144 }
145 134
146 const { body } = await doRequest<any>(options) 135 const { body } = await doJSONRequest<any>(url)
147 return body.description ? body.description : '' 136 return body.description || ''
148} 137}
149 138
150function getOrCreateVideoChannelFromVideoObject (videoObject: VideoObject) { 139function getOrCreateVideoChannelFromVideoObject (videoObject: VideoObject) {
@@ -534,8 +523,8 @@ async function refreshVideoIfNeeded (options: {
534 : await VideoModel.loadByUrlAndPopulateAccount(options.video.url) 523 : await VideoModel.loadByUrlAndPopulateAccount(options.video.url)
535 524
536 try { 525 try {
537 const { response, videoObject } = await fetchRemoteVideo(video.url) 526 const { statusCode, videoObject } = await fetchRemoteVideo(video.url)
538 if (response.statusCode === HttpStatusCode.NOT_FOUND_404) { 527 if (statusCode === HttpStatusCode.NOT_FOUND_404) {
539 logger.info('Cannot refresh remote video %s: video does not exist anymore. Deleting it.', video.url) 528 logger.info('Cannot refresh remote video %s: video does not exist anymore. Deleting it.', video.url)
540 529
541 // Video does not exist anymore 530 // Video does not exist anymore
diff --git a/server/lib/files-cache/videos-caption-cache.ts b/server/lib/files-cache/videos-caption-cache.ts
index ee0447010..58e2260b6 100644
--- a/server/lib/files-cache/videos-caption-cache.ts
+++ b/server/lib/files-cache/videos-caption-cache.ts
@@ -41,7 +41,7 @@ class VideosCaptionCache extends AbstractVideoStaticFileCache <string> {
41 const remoteUrl = videoCaption.getFileUrl(video) 41 const remoteUrl = videoCaption.getFileUrl(video)
42 const destPath = join(FILES_CACHE.VIDEO_CAPTIONS.DIRECTORY, videoCaption.filename) 42 const destPath = join(FILES_CACHE.VIDEO_CAPTIONS.DIRECTORY, videoCaption.filename)
43 43
44 await doRequestAndSaveToFile({ uri: remoteUrl }, destPath) 44 await doRequestAndSaveToFile(remoteUrl, destPath)
45 45
46 return { isOwned: false, path: destPath } 46 return { isOwned: false, path: destPath }
47 } 47 }
diff --git a/server/lib/files-cache/videos-preview-cache.ts b/server/lib/files-cache/videos-preview-cache.ts
index ee72cd3f9..dd3a84aca 100644
--- a/server/lib/files-cache/videos-preview-cache.ts
+++ b/server/lib/files-cache/videos-preview-cache.ts
@@ -39,7 +39,7 @@ class VideosPreviewCache extends AbstractVideoStaticFileCache <string> {
39 const destPath = join(FILES_CACHE.PREVIEWS.DIRECTORY, preview.filename) 39 const destPath = join(FILES_CACHE.PREVIEWS.DIRECTORY, preview.filename)
40 40
41 const remoteUrl = preview.getFileUrl(video) 41 const remoteUrl = preview.getFileUrl(video)
42 await doRequestAndSaveToFile({ uri: remoteUrl }, destPath) 42 await doRequestAndSaveToFile(remoteUrl, destPath)
43 43
44 logger.debug('Fetched remote preview %s to %s.', remoteUrl, destPath) 44 logger.debug('Fetched remote preview %s to %s.', remoteUrl, destPath)
45 45
diff --git a/server/lib/files-cache/videos-torrent-cache.ts b/server/lib/files-cache/videos-torrent-cache.ts
index ca0e1770d..881fa9ced 100644
--- a/server/lib/files-cache/videos-torrent-cache.ts
+++ b/server/lib/files-cache/videos-torrent-cache.ts
@@ -41,7 +41,7 @@ class VideosTorrentCache extends AbstractVideoStaticFileCache <string> {
41 const remoteUrl = file.getRemoteTorrentUrl(video) 41 const remoteUrl = file.getRemoteTorrentUrl(video)
42 const destPath = join(FILES_CACHE.TORRENTS.DIRECTORY, file.torrentFilename) 42 const destPath = join(FILES_CACHE.TORRENTS.DIRECTORY, file.torrentFilename)
43 43
44 await doRequestAndSaveToFile({ uri: remoteUrl }, destPath) 44 await doRequestAndSaveToFile(remoteUrl, destPath)
45 45
46 const downloadName = `${video.name}-${file.resolution}p.torrent` 46 const downloadName = `${video.name}-${file.resolution}p.torrent`
47 47
diff --git a/server/lib/hls.ts b/server/lib/hls.ts
index 04187668c..84539e2c1 100644
--- a/server/lib/hls.ts
+++ b/server/lib/hls.ts
@@ -135,7 +135,7 @@ function downloadPlaylistSegments (playlistUrl: string, destinationDir: string,
135 const destPath = join(tmpDirectory, basename(fileUrl)) 135 const destPath = join(tmpDirectory, basename(fileUrl))
136 136
137 const bodyKBLimit = 10 * 1000 * 1000 // 10GB 137 const bodyKBLimit = 10 * 1000 * 1000 // 10GB
138 await doRequestAndSaveToFile({ uri: fileUrl }, destPath, bodyKBLimit) 138 await doRequestAndSaveToFile(fileUrl, destPath, { bodyKBLimit })
139 } 139 }
140 140
141 clearTimeout(timer) 141 clearTimeout(timer)
@@ -156,7 +156,7 @@ function downloadPlaylistSegments (playlistUrl: string, destinationDir: string,
156 } 156 }
157 157
158 async function fetchUniqUrls (playlistUrl: string) { 158 async function fetchUniqUrls (playlistUrl: string) {
159 const { body } = await doRequest<string>({ uri: playlistUrl }) 159 const { body } = await doRequest(playlistUrl)
160 160
161 if (!body) return [] 161 if (!body) return []
162 162
diff --git a/server/lib/job-queue/handlers/activitypub-cleaner.ts b/server/lib/job-queue/handlers/activitypub-cleaner.ts
index 0e75b0a6e..9dcc778fa 100644
--- a/server/lib/job-queue/handlers/activitypub-cleaner.ts
+++ b/server/lib/job-queue/handlers/activitypub-cleaner.ts
@@ -7,7 +7,7 @@ import {
7 isLikeActivityValid 7 isLikeActivityValid
8} from '@server/helpers/custom-validators/activitypub/activity' 8} from '@server/helpers/custom-validators/activitypub/activity'
9import { sanitizeAndCheckVideoCommentObject } from '@server/helpers/custom-validators/activitypub/video-comments' 9import { sanitizeAndCheckVideoCommentObject } from '@server/helpers/custom-validators/activitypub/video-comments'
10import { doRequest } from '@server/helpers/requests' 10import { doJSONRequest } from '@server/helpers/requests'
11import { AP_CLEANER_CONCURRENCY } from '@server/initializers/constants' 11import { AP_CLEANER_CONCURRENCY } from '@server/initializers/constants'
12import { VideoModel } from '@server/models/video/video' 12import { VideoModel } from '@server/models/video/video'
13import { VideoCommentModel } from '@server/models/video/video-comment' 13import { VideoCommentModel } from '@server/models/video/video-comment'
@@ -81,15 +81,10 @@ async function updateObjectIfNeeded <T> (
81 updater: (url: string, newUrl: string) => Promise<T>, 81 updater: (url: string, newUrl: string) => Promise<T>,
82 deleter: (url: string) => Promise<T> 82 deleter: (url: string) => Promise<T>
83): Promise<{ data: T, status: 'deleted' | 'updated' } | null> { 83): Promise<{ data: T, status: 'deleted' | 'updated' } | null> {
84 // Fetch url 84 const { statusCode, body } = await doJSONRequest<any>(url, { activityPub: true })
85 const { response, body } = await doRequest<any>({
86 uri: url,
87 json: true,
88 activityPub: true
89 })
90 85
91 // Does not exist anymore, remove entry 86 // Does not exist anymore, remove entry
92 if (response.statusCode === HttpStatusCode.NOT_FOUND_404) { 87 if (statusCode === HttpStatusCode.NOT_FOUND_404) {
93 logger.info('Removing remote AP object %s.', url) 88 logger.info('Removing remote AP object %s.', url)
94 const data = await deleter(url) 89 const data = await deleter(url)
95 90
diff --git a/server/lib/job-queue/handlers/activitypub-http-broadcast.ts b/server/lib/job-queue/handlers/activitypub-http-broadcast.ts
index 7174786d6..c69ff9e83 100644
--- a/server/lib/job-queue/handlers/activitypub-http-broadcast.ts
+++ b/server/lib/job-queue/handlers/activitypub-http-broadcast.ts
@@ -16,8 +16,7 @@ async function processActivityPubHttpBroadcast (job: Bull.Job) {
16 const httpSignatureOptions = await buildSignedRequestOptions(payload) 16 const httpSignatureOptions = await buildSignedRequestOptions(payload)
17 17
18 const options = { 18 const options = {
19 method: 'POST', 19 method: 'POST' as 'POST',
20 uri: '',
21 json: body, 20 json: body,
22 httpSignature: httpSignatureOptions, 21 httpSignature: httpSignatureOptions,
23 timeout: REQUEST_TIMEOUT, 22 timeout: REQUEST_TIMEOUT,
@@ -28,7 +27,7 @@ async function processActivityPubHttpBroadcast (job: Bull.Job) {
28 const goodUrls: string[] = [] 27 const goodUrls: string[] = []
29 28
30 await Bluebird.map(payload.uris, uri => { 29 await Bluebird.map(payload.uris, uri => {
31 return doRequest(Object.assign({}, options, { uri })) 30 return doRequest(uri, options)
32 .then(() => goodUrls.push(uri)) 31 .then(() => goodUrls.push(uri))
33 .catch(() => badUrls.push(uri)) 32 .catch(() => badUrls.push(uri))
34 }, { concurrency: BROADCAST_CONCURRENCY }) 33 }, { concurrency: BROADCAST_CONCURRENCY })
diff --git a/server/lib/job-queue/handlers/activitypub-http-unicast.ts b/server/lib/job-queue/handlers/activitypub-http-unicast.ts
index 74989d62e..585dad671 100644
--- a/server/lib/job-queue/handlers/activitypub-http-unicast.ts
+++ b/server/lib/job-queue/handlers/activitypub-http-unicast.ts
@@ -16,8 +16,7 @@ async function processActivityPubHttpUnicast (job: Bull.Job) {
16 const httpSignatureOptions = await buildSignedRequestOptions(payload) 16 const httpSignatureOptions = await buildSignedRequestOptions(payload)
17 17
18 const options = { 18 const options = {
19 method: 'POST', 19 method: 'POST' as 'POST',
20 uri,
21 json: body, 20 json: body,
22 httpSignature: httpSignatureOptions, 21 httpSignature: httpSignatureOptions,
23 timeout: REQUEST_TIMEOUT, 22 timeout: REQUEST_TIMEOUT,
@@ -25,7 +24,7 @@ async function processActivityPubHttpUnicast (job: Bull.Job) {
25 } 24 }
26 25
27 try { 26 try {
28 await doRequest(options) 27 await doRequest(uri, options)
29 ActorFollowScoreCache.Instance.updateActorFollowsScore([ uri ], []) 28 ActorFollowScoreCache.Instance.updateActorFollowsScore([ uri ], [])
30 } catch (err) { 29 } catch (err) {
31 ActorFollowScoreCache.Instance.updateActorFollowsScore([], [ uri ]) 30 ActorFollowScoreCache.Instance.updateActorFollowsScore([], [ uri ])
diff --git a/server/lib/job-queue/handlers/utils/activitypub-http-utils.ts b/server/lib/job-queue/handlers/utils/activitypub-http-utils.ts
index c030d31ef..4116a9c0e 100644
--- a/server/lib/job-queue/handlers/utils/activitypub-http-utils.ts
+++ b/server/lib/job-queue/handlers/utils/activitypub-http-utils.ts
@@ -6,21 +6,24 @@ import { getServerActor } from '@server/models/application/application'
6import { buildDigest } from '@server/helpers/peertube-crypto' 6import { buildDigest } from '@server/helpers/peertube-crypto'
7import { ContextType } from '@shared/models/activitypub/context' 7import { ContextType } from '@shared/models/activitypub/context'
8 8
9type Payload = { body: any, contextType?: ContextType, signatureActorId?: number } 9type Payload <T> = { body: T, contextType?: ContextType, signatureActorId?: number }
10 10
11async function computeBody (payload: Payload) { 11async function computeBody <T> (
12 payload: Payload<T>
13): Promise<T | T & { type: 'RsaSignature2017', creator: string, created: string }> {
12 let body = payload.body 14 let body = payload.body
13 15
14 if (payload.signatureActorId) { 16 if (payload.signatureActorId) {
15 const actorSignature = await ActorModel.load(payload.signatureActorId) 17 const actorSignature = await ActorModel.load(payload.signatureActorId)
16 if (!actorSignature) throw new Error('Unknown signature actor id.') 18 if (!actorSignature) throw new Error('Unknown signature actor id.')
19
17 body = await buildSignedActivity(actorSignature, payload.body, payload.contextType) 20 body = await buildSignedActivity(actorSignature, payload.body, payload.contextType)
18 } 21 }
19 22
20 return body 23 return body
21} 24}
22 25
23async function buildSignedRequestOptions (payload: Payload) { 26async function buildSignedRequestOptions (payload: Payload<any>) {
24 let actor: MActor | null 27 let actor: MActor | null
25 28
26 if (payload.signatureActorId) { 29 if (payload.signatureActorId) {
diff --git a/server/lib/plugins/plugin-index.ts b/server/lib/plugins/plugin-index.ts
index 7bcb6ed4c..624f5da1d 100644
--- a/server/lib/plugins/plugin-index.ts
+++ b/server/lib/plugins/plugin-index.ts
@@ -1,22 +1,22 @@
1import { doRequest } from '../../helpers/requests' 1import { sanitizeUrl } from '@server/helpers/core-utils'
2import { CONFIG } from '../../initializers/config' 2import { ResultList } from '../../../shared/models'
3import { PeertubePluginIndexList } from '../../../shared/models/plugins/peertube-plugin-index-list.model'
4import { PeerTubePluginIndex } from '../../../shared/models/plugins/peertube-plugin-index.model'
3import { 5import {
4 PeertubePluginLatestVersionRequest, 6 PeertubePluginLatestVersionRequest,
5 PeertubePluginLatestVersionResponse 7 PeertubePluginLatestVersionResponse
6} from '../../../shared/models/plugins/peertube-plugin-latest-version.model' 8} from '../../../shared/models/plugins/peertube-plugin-latest-version.model'
7import { PeertubePluginIndexList } from '../../../shared/models/plugins/peertube-plugin-index-list.model'
8import { ResultList } from '../../../shared/models'
9import { PeerTubePluginIndex } from '../../../shared/models/plugins/peertube-plugin-index.model'
10import { PluginModel } from '../../models/server/plugin'
11import { PluginManager } from './plugin-manager'
12import { logger } from '../../helpers/logger' 9import { logger } from '../../helpers/logger'
10import { doJSONRequest } from '../../helpers/requests'
11import { CONFIG } from '../../initializers/config'
13import { PEERTUBE_VERSION } from '../../initializers/constants' 12import { PEERTUBE_VERSION } from '../../initializers/constants'
14import { sanitizeUrl } from '@server/helpers/core-utils' 13import { PluginModel } from '../../models/server/plugin'
14import { PluginManager } from './plugin-manager'
15 15
16async function listAvailablePluginsFromIndex (options: PeertubePluginIndexList) { 16async function listAvailablePluginsFromIndex (options: PeertubePluginIndexList) {
17 const { start = 0, count = 20, search, sort = 'npmName', pluginType } = options 17 const { start = 0, count = 20, search, sort = 'npmName', pluginType } = options
18 18
19 const qs: PeertubePluginIndexList = { 19 const searchParams: PeertubePluginIndexList & Record<string, string | number> = {
20 start, 20 start,
21 count, 21 count,
22 sort, 22 sort,
@@ -28,7 +28,7 @@ async function listAvailablePluginsFromIndex (options: PeertubePluginIndexList)
28 const uri = CONFIG.PLUGINS.INDEX.URL + '/api/v1/plugins' 28 const uri = CONFIG.PLUGINS.INDEX.URL + '/api/v1/plugins'
29 29
30 try { 30 try {
31 const { body } = await doRequest<any>({ uri, qs, json: true }) 31 const { body } = await doJSONRequest<any>(uri, { searchParams })
32 32
33 logger.debug('Got result from PeerTube index.', { body }) 33 logger.debug('Got result from PeerTube index.', { body })
34 34
@@ -58,7 +58,11 @@ async function getLatestPluginsVersion (npmNames: string[]): Promise<PeertubePlu
58 58
59 const uri = sanitizeUrl(CONFIG.PLUGINS.INDEX.URL) + '/api/v1/plugins/latest-version' 59 const uri = sanitizeUrl(CONFIG.PLUGINS.INDEX.URL) + '/api/v1/plugins/latest-version'
60 60
61 const { body } = await doRequest<any>({ uri, body: bodyRequest, json: true, method: 'POST' }) 61 const options = {
62 json: bodyRequest,
63 method: 'POST' as 'POST'
64 }
65 const { body } = await doJSONRequest<PeertubePluginLatestVersionResponse>(uri, options)
62 66
63 return body 67 return body
64} 68}
diff --git a/server/lib/schedulers/auto-follow-index-instances.ts b/server/lib/schedulers/auto-follow-index-instances.ts
index f62f52f9c..0b8cd1389 100644
--- a/server/lib/schedulers/auto-follow-index-instances.ts
+++ b/server/lib/schedulers/auto-follow-index-instances.ts
@@ -1,5 +1,5 @@
1import { chunk } from 'lodash' 1import { chunk } from 'lodash'
2import { doRequest } from '@server/helpers/requests' 2import { doJSONRequest } from '@server/helpers/requests'
3import { JobQueue } from '@server/lib/job-queue' 3import { JobQueue } from '@server/lib/job-queue'
4import { ActorFollowModel } from '@server/models/activitypub/actor-follow' 4import { ActorFollowModel } from '@server/models/activitypub/actor-follow'
5import { getServerActor } from '@server/models/application/application' 5import { getServerActor } from '@server/models/application/application'
@@ -34,12 +34,12 @@ export class AutoFollowIndexInstances extends AbstractScheduler {
34 try { 34 try {
35 const serverActor = await getServerActor() 35 const serverActor = await getServerActor()
36 36
37 const qs = { count: 1000 } 37 const searchParams = { count: 1000 }
38 if (this.lastCheck) Object.assign(qs, { since: this.lastCheck.toISOString() }) 38 if (this.lastCheck) Object.assign(searchParams, { since: this.lastCheck.toISOString() })
39 39
40 this.lastCheck = new Date() 40 this.lastCheck = new Date()
41 41
42 const { body } = await doRequest<any>({ uri: indexUrl, qs, json: true }) 42 const { body } = await doJSONRequest<any>(indexUrl, { searchParams })
43 if (!body.data || Array.isArray(body.data) === false) { 43 if (!body.data || Array.isArray(body.data) === false) {
44 logger.error('Cannot auto follow instances of index %s. Please check the auto follow URL.', indexUrl, { body }) 44 logger.error('Cannot auto follow instances of index %s. Please check the auto follow URL.', indexUrl, { body })
45 return 45 return