]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blobdiff - server/lib/activitypub/actor.ts
Stronger actor association typing in AP functions
[github/Chocobozzz/PeerTube.git] / server / lib / activitypub / actor.ts
index 63e8106421f9fc49cd9ac2861e109bfa861a978c..04296864b96c88038ed4726ca166679a10558550 100644 (file)
@@ -5,14 +5,14 @@ import * as uuidv4 from 'uuid/v4'
 import { ActivityPubActor, ActivityPubActorType } from '../../../shared/models/activitypub'
 import { ActivityPubAttributedTo } from '../../../shared/models/activitypub/objects'
 import { checkUrlsSameHost, getAPId } from '../../helpers/activitypub'
-import { isActorObjectValid, normalizeActor } from '../../helpers/custom-validators/activitypub/actor'
+import { sanitizeAndCheckActorObject } from '../../helpers/custom-validators/activitypub/actor'
 import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc'
 import { retryTransactionWrapper, updateInstanceWithAnother } from '../../helpers/database-utils'
 import { logger } from '../../helpers/logger'
 import { createPrivateAndPublicKeys } from '../../helpers/peertube-crypto'
 import { doRequest, downloadImage } from '../../helpers/requests'
 import { getUrlFromWebfinger } from '../../helpers/webfinger'
-import { AVATARS_SIZE, CONFIG, MIMETYPES, sequelizeTypescript } from '../../initializers'
+import { AVATARS_SIZE, MIMETYPES, WEBSERVER } from '../../initializers/constants'
 import { AccountModel } from '../../models/account/account'
 import { ActorModel } from '../../models/activitypub/actor'
 import { AvatarModel } from '../../models/avatar/avatar'
@@ -21,6 +21,8 @@ import { VideoChannelModel } from '../../models/video/video-channel'
 import { JobQueue } from '../job-queue'
 import { getServerActor } from '../../helpers/utils'
 import { ActorFetchByUrlType, fetchActorByUrl } from '../../helpers/actor'
+import { CONFIG } from '../../initializers/config'
+import { sequelizeTypescript } from '../../initializers/database'
 
 // Set account keys, this could be long so process after the account creation and do not block the client
 function setAsyncActorKeys (actor: ActorModel) {
@@ -31,7 +33,7 @@ function setAsyncActorKeys (actor: ActorModel) {
       return actor.save()
     })
     .catch(err => {
-      logger.error('Cannot set public/private keys of actor %d.', actor.uuid, { err })
+      logger.error('Cannot set public/private keys of actor %d.', actor.url, { err })
       return actor
     })
 }
@@ -116,7 +118,7 @@ function buildActorInstance (type: ActivityPubActorType, url: string, preferredU
     followingCount: 0,
     inboxUrl: url + '/inbox',
     outboxUrl: url + '/outbox',
-    sharedInboxUrl: CONFIG.WEBSERVER.URL + '/inbox',
+    sharedInboxUrl: WEBSERVER.URL + '/inbox',
     followersUrl: url + '/followers',
     followingUrl: url + '/following'
   })
@@ -126,18 +128,17 @@ async function updateActorInstance (actorInstance: ActorModel, attributes: Activ
   const followersCount = await fetchActorTotalItems(attributes.followers)
   const followingCount = await fetchActorTotalItems(attributes.following)
 
-  actorInstance.set('type', attributes.type)
-  actorInstance.set('uuid', attributes.uuid)
-  actorInstance.set('preferredUsername', attributes.preferredUsername)
-  actorInstance.set('url', attributes.id)
-  actorInstance.set('publicKey', attributes.publicKey.publicKeyPem)
-  actorInstance.set('followersCount', followersCount)
-  actorInstance.set('followingCount', followingCount)
-  actorInstance.set('inboxUrl', attributes.inbox)
-  actorInstance.set('outboxUrl', attributes.outbox)
-  actorInstance.set('sharedInboxUrl', attributes.endpoints.sharedInbox)
-  actorInstance.set('followersUrl', attributes.followers)
-  actorInstance.set('followingUrl', attributes.following)
+  actorInstance.type = attributes.type
+  actorInstance.preferredUsername = attributes.preferredUsername
+  actorInstance.url = attributes.id
+  actorInstance.publicKey = attributes.publicKey.publicKeyPem
+  actorInstance.followersCount = followersCount
+  actorInstance.followingCount = followingCount
+  actorInstance.inboxUrl = attributes.inbox
+  actorInstance.outboxUrl = attributes.outbox
+  actorInstance.sharedInboxUrl = attributes.endpoints.sharedInbox
+  actorInstance.followersUrl = attributes.followers
+  actorInstance.followingUrl = attributes.following
 }
 
 async function updateActorAvatarInstance (actorInstance: ActorModel, avatarName: string, t: Transaction) {
@@ -194,7 +195,7 @@ async function fetchAvatarIfExists (actorJSON: ActivityPubActor) {
   return undefined
 }
 
-async function addFetchOutboxJob (actor: ActorModel) {
+async function addFetchOutboxJob (actor: Pick<ActorModel, 'id' | 'outboxUrl'>) {
   // Don't fetch ourselves
   const serverActor = await getServerActor()
   if (serverActor.id === actor.id) {
@@ -253,14 +254,14 @@ async function refreshActorIfNeeded (
       await actor.save({ transaction: t })
 
       if (actor.Account) {
-        actor.Account.set('name', result.name)
-        actor.Account.set('description', result.summary)
+        actor.Account.name = result.name
+        actor.Account.description = result.summary
 
         await actor.Account.save({ transaction: t })
       } else if (actor.VideoChannel) {
-        actor.VideoChannel.set('name', result.name)
-        actor.VideoChannel.set('description', result.summary)
-        actor.VideoChannel.set('support', result.support)
+        actor.VideoChannel.name = result.name
+        actor.VideoChannel.description = result.summary
+        actor.VideoChannel.support = result.support
 
         await actor.VideoChannel.save({ transaction: t })
       }
@@ -268,7 +269,7 @@ async function refreshActorIfNeeded (
       return { refreshed: true, actor }
     })
   } catch (err) {
-    logger.warn('Cannot refresh actor.', { err })
+    logger.warn('Cannot refresh actor %s.', actor.url, { err })
     return { actor, refreshed: false }
   }
 }
@@ -342,6 +343,8 @@ function saveActorAndServerAndModelIfNotExist (
       actorCreated.VideoChannel.Account = ownerActor.Account
     }
 
+    actorCreated.Server = server
+
     return actorCreated
   }
 }
@@ -366,10 +369,9 @@ async function fetchRemoteActor (actorUrl: string): Promise<{ statusCode?: numbe
   logger.info('Fetching remote actor %s.', actorUrl)
 
   const requestResult = await doRequest<ActivityPubActor>(options)
-  normalizeActor(requestResult.body)
-
   const actorJSON = requestResult.body
-  if (isActorObjectValid(actorJSON) === false) {
+
+  if (sanitizeAndCheckActorObject(actorJSON) === false) {
     logger.debug('Remote actor JSON is not valid.', { actorJSON })
     return { result: undefined, statusCode: requestResult.response.statusCode }
   }
@@ -384,7 +386,6 @@ async function fetchRemoteActor (actorUrl: string): Promise<{ statusCode?: numbe
 
   const actor = new ActorModel({
     type: actorJSON.type,
-    uuid: actorJSON.uuid,
     preferredUsername: actorJSON.preferredUsername,
     url: actorJSON.id,
     publicKey: actorJSON.publicKey.publicKeyPem,