aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/lib/activitypub/actor.ts
diff options
context:
space:
mode:
Diffstat (limited to 'server/lib/activitypub/actor.ts')
-rw-r--r--server/lib/activitypub/actor.ts75
1 files changed, 52 insertions, 23 deletions
diff --git a/server/lib/activitypub/actor.ts b/server/lib/activitypub/actor.ts
index 9f5d12eb4..7862b0f00 100644
--- a/server/lib/activitypub/actor.ts
+++ b/server/lib/activitypub/actor.ts
@@ -22,13 +22,25 @@ import { JobQueue } from '../job-queue'
22import { getServerActor } from '../../helpers/utils' 22import { getServerActor } from '../../helpers/utils'
23import { ActorFetchByUrlType, fetchActorByUrl } from '../../helpers/actor' 23import { ActorFetchByUrlType, fetchActorByUrl } from '../../helpers/actor'
24import { sequelizeTypescript } from '../../initializers/database' 24import { sequelizeTypescript } from '../../initializers/database'
25import {
26 MAccount,
27 MActor,
28 MActorAccountChannelId,
29 MActorAccountId,
30 MActorDefault,
31 MActorFull,
32 MActorId,
33 MActorAccountChannelIdActor,
34 MChannel,
35 MActorFullActor, MAccountActorDefault, MChannelActorDefault, MChannelActorAccountDefault
36} from '../../typings/models'
25 37
26// Set account keys, this could be long so process after the account creation and do not block the client 38// Set account keys, this could be long so process after the account creation and do not block the client
27function setAsyncActorKeys (actor: ActorModel) { 39function setAsyncActorKeys (actor: MActor) {
28 return createPrivateAndPublicKeys() 40 return createPrivateAndPublicKeys()
29 .then(({ publicKey, privateKey }) => { 41 .then(({ publicKey, privateKey }) => {
30 actor.set('publicKey', publicKey) 42 actor.publicKey = publicKey
31 actor.set('privateKey', privateKey) 43 actor.privateKey = privateKey
32 return actor.save() 44 return actor.save()
33 }) 45 })
34 .catch(err => { 46 .catch(err => {
@@ -37,12 +49,26 @@ function setAsyncActorKeys (actor: ActorModel) {
37 }) 49 })
38} 50}
39 51
52function getOrCreateActorAndServerAndModel (
53 activityActor: string | ActivityPubActor,
54 fetchType: 'all',
55 recurseIfNeeded?: boolean,
56 updateCollections?: boolean
57): Promise<MActorFullActor>
58
59function getOrCreateActorAndServerAndModel (
60 activityActor: string | ActivityPubActor,
61 fetchType?: 'association-ids',
62 recurseIfNeeded?: boolean,
63 updateCollections?: boolean
64): Promise<MActorAccountChannelId>
65
40async function getOrCreateActorAndServerAndModel ( 66async function getOrCreateActorAndServerAndModel (
41 activityActor: string | ActivityPubActor, 67 activityActor: string | ActivityPubActor,
42 fetchType: ActorFetchByUrlType = 'actor-and-association-ids', 68 fetchType: ActorFetchByUrlType = 'association-ids',
43 recurseIfNeeded = true, 69 recurseIfNeeded = true,
44 updateCollections = false 70 updateCollections = false
45) { 71): Promise<MActorFullActor | MActorAccountChannelId> {
46 const actorUrl = getAPId(activityActor) 72 const actorUrl = getAPId(activityActor)
47 let created = false 73 let created = false
48 let accountPlaylistsUrl: string 74 let accountPlaylistsUrl: string
@@ -61,7 +87,7 @@ async function getOrCreateActorAndServerAndModel (
61 87
62 // Create the attributed to actor 88 // Create the attributed to actor
63 // In PeerTube a video channel is owned by an account 89 // In PeerTube a video channel is owned by an account
64 let ownerActor: ActorModel = undefined 90 let ownerActor: MActorFullActor
65 if (recurseIfNeeded === true && result.actor.type === 'Group') { 91 if (recurseIfNeeded === true && result.actor.type === 'Group') {
66 const accountAttributedTo = result.attributedTo.find(a => a.type === 'Person') 92 const accountAttributedTo = result.attributedTo.find(a => a.type === 'Person')
67 if (!accountAttributedTo) throw new Error('Cannot find account attributed to video channel ' + actor.url) 93 if (!accountAttributedTo) throw new Error('Cannot find account attributed to video channel ' + actor.url)
@@ -85,8 +111,8 @@ async function getOrCreateActorAndServerAndModel (
85 accountPlaylistsUrl = result.playlists 111 accountPlaylistsUrl = result.playlists
86 } 112 }
87 113
88 if (actor.Account) actor.Account.Actor = actor 114 if (actor.Account) (actor as MActorAccountChannelIdActor).Account.Actor = actor
89 if (actor.VideoChannel) actor.VideoChannel.Actor = actor 115 if (actor.VideoChannel) (actor as MActorAccountChannelIdActor).VideoChannel.Actor = actor
90 116
91 const { actor: actorRefreshed, refreshed } = await retryTransactionWrapper(refreshActorIfNeeded, actor, fetchType) 117 const { actor: actorRefreshed, refreshed } = await retryTransactionWrapper(refreshActorIfNeeded, actor, fetchType)
92 if (!actorRefreshed) throw new Error('Actor ' + actorRefreshed.url + ' does not exist anymore.') 118 if (!actorRefreshed) throw new Error('Actor ' + actorRefreshed.url + ' does not exist anymore.')
@@ -140,7 +166,8 @@ async function updateActorInstance (actorInstance: ActorModel, attributes: Activ
140 actorInstance.followingUrl = attributes.following 166 actorInstance.followingUrl = attributes.following
141} 167}
142 168
143async function updateActorAvatarInstance (actor: ActorModel, info: { name: string, onDisk: boolean, fileUrl: string }, t: Transaction) { 169type AvatarInfo = { name: string, onDisk: boolean, fileUrl: string }
170async function updateActorAvatarInstance (actor: MActorDefault, info: AvatarInfo, t: Transaction) {
144 if (info.name !== undefined) { 171 if (info.name !== undefined) {
145 if (actor.avatarId) { 172 if (actor.avatarId) {
146 try { 173 try {
@@ -212,14 +239,16 @@ async function addFetchOutboxJob (actor: Pick<ActorModel, 'id' | 'outboxUrl'>) {
212 return JobQueue.Instance.createJob({ type: 'activitypub-http-fetcher', payload }) 239 return JobQueue.Instance.createJob({ type: 'activitypub-http-fetcher', payload })
213} 240}
214 241
215async function refreshActorIfNeeded ( 242async function refreshActorIfNeeded <T extends MActorFull | MActorAccountChannelId> (
216 actorArg: ActorModel, 243 actorArg: T,
217 fetchedType: ActorFetchByUrlType 244 fetchedType: ActorFetchByUrlType
218): Promise<{ actor: ActorModel, refreshed: boolean }> { 245): Promise<{ actor: T | MActorFull, refreshed: boolean }> {
219 if (!actorArg.isOutdated()) return { actor: actorArg, refreshed: false } 246 if (!actorArg.isOutdated()) return { actor: actorArg, refreshed: false }
220 247
221 // We need more attributes 248 // We need more attributes
222 const actor = fetchedType === 'all' ? actorArg : await ActorModel.loadByUrlAndPopulateAccountAndChannel(actorArg.url) 249 const actor = fetchedType === 'all'
250 ? actorArg as MActorFull
251 : await ActorModel.loadByUrlAndPopulateAccountAndChannel(actorArg.url)
223 252
224 try { 253 try {
225 let actorUrl: string 254 let actorUrl: string
@@ -297,9 +326,9 @@ export {
297 326
298function saveActorAndServerAndModelIfNotExist ( 327function saveActorAndServerAndModelIfNotExist (
299 result: FetchRemoteActorResult, 328 result: FetchRemoteActorResult,
300 ownerActor?: ActorModel, 329 ownerActor?: MActorFullActor,
301 t?: Transaction 330 t?: Transaction
302): Bluebird<ActorModel> | Promise<ActorModel> { 331): Bluebird<MActorFullActor> | Promise<MActorFullActor> {
303 let actor = result.actor 332 let actor = result.actor
304 333
305 if (t !== undefined) return save(t) 334 if (t !== undefined) return save(t)
@@ -336,7 +365,7 @@ function saveActorAndServerAndModelIfNotExist (
336 365
337 // Force the actor creation, sometimes Sequelize skips the save() when it thinks the instance already exists 366 // Force the actor creation, sometimes Sequelize skips the save() when it thinks the instance already exists
338 // (which could be false in a retried query) 367 // (which could be false in a retried query)
339 const [ actorCreated ] = await ActorModel.findOrCreate({ 368 const [ actorCreated ] = await ActorModel.findOrCreate<MActorFullActor>({
340 defaults: actor.toJSON(), 369 defaults: actor.toJSON(),
341 where: { 370 where: {
342 url: actor.url 371 url: actor.url
@@ -345,10 +374,10 @@ function saveActorAndServerAndModelIfNotExist (
345 }) 374 })
346 375
347 if (actorCreated.type === 'Person' || actorCreated.type === 'Application') { 376 if (actorCreated.type === 'Person' || actorCreated.type === 'Application') {
348 actorCreated.Account = await saveAccount(actorCreated, result, t) 377 actorCreated.Account = await saveAccount(actorCreated, result, t) as MAccountActorDefault
349 actorCreated.Account.Actor = actorCreated 378 actorCreated.Account.Actor = actorCreated
350 } else if (actorCreated.type === 'Group') { // Video channel 379 } else if (actorCreated.type === 'Group') { // Video channel
351 actorCreated.VideoChannel = await saveVideoChannel(actorCreated, result, ownerActor, t) 380 actorCreated.VideoChannel = await saveVideoChannel(actorCreated, result, ownerActor, t) as MChannelActorAccountDefault
352 actorCreated.VideoChannel.Actor = actorCreated 381 actorCreated.VideoChannel.Actor = actorCreated
353 actorCreated.VideoChannel.Account = ownerActor.Account 382 actorCreated.VideoChannel.Account = ownerActor.Account
354 } 383 }
@@ -360,7 +389,7 @@ function saveActorAndServerAndModelIfNotExist (
360} 389}
361 390
362type FetchRemoteActorResult = { 391type FetchRemoteActorResult = {
363 actor: ActorModel 392 actor: MActor
364 name: string 393 name: string
365 summary: string 394 summary: string
366 support?: string 395 support?: string
@@ -429,7 +458,7 @@ async function fetchRemoteActor (actorUrl: string): Promise<{ statusCode?: numbe
429 } 458 }
430} 459}
431 460
432async function saveAccount (actor: ActorModel, result: FetchRemoteActorResult, t: Transaction) { 461async function saveAccount (actor: MActorId, result: FetchRemoteActorResult, t: Transaction) {
433 const [ accountCreated ] = await AccountModel.findOrCreate({ 462 const [ accountCreated ] = await AccountModel.findOrCreate({
434 defaults: { 463 defaults: {
435 name: result.name, 464 name: result.name,
@@ -442,10 +471,10 @@ async function saveAccount (actor: ActorModel, result: FetchRemoteActorResult, t
442 transaction: t 471 transaction: t
443 }) 472 })
444 473
445 return accountCreated 474 return accountCreated as MAccount
446} 475}
447 476
448async function saveVideoChannel (actor: ActorModel, result: FetchRemoteActorResult, ownerActor: ActorModel, t: Transaction) { 477async function saveVideoChannel (actor: MActorId, result: FetchRemoteActorResult, ownerActor: MActorAccountId, t: Transaction) {
449 const [ videoChannelCreated ] = await VideoChannelModel.findOrCreate({ 478 const [ videoChannelCreated ] = await VideoChannelModel.findOrCreate({
450 defaults: { 479 defaults: {
451 name: result.name, 480 name: result.name,
@@ -460,5 +489,5 @@ async function saveVideoChannel (actor: ActorModel, result: FetchRemoteActorResu
460 transaction: t 489 transaction: t
461 }) 490 })
462 491
463 return videoChannelCreated 492 return videoChannelCreated as MChannel
464} 493}