]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/lib/activitypub/actors/updater.ts
Merge branch 'release/4.2.0' into develop
[github/Chocobozzz/PeerTube.git] / server / lib / activitypub / actors / updater.ts
CommitLineData
28dfb44b 1import { resetSequelizeInstance, runInReadCommittedTransaction } from '@server/helpers/database-utils'
136d7efd 2import { logger } from '@server/helpers/logger'
b5e1cd9a 3import { AccountModel } from '@server/models/account/account'
136d7efd
C
4import { VideoChannelModel } from '@server/models/video/video-channel'
5import { MAccount, MActor, MActorFull, MChannel } from '@server/types/models'
6import { ActivityPubActor, ActorImageType } from '@shared/models'
b5e1cd9a 7import { getOrCreateAPOwner } from './get'
d0800f76 8import { updateActorImages } from './image'
136d7efd 9import { fetchActorFollowsCount } from './shared'
d0800f76 10import { getImagesInfoFromObject } from './shared/object-to-model-attributes'
136d7efd
C
11
12export class APActorUpdater {
13
14 private accountOrChannel: MAccount | MChannel
15
16 private readonly actorFieldsSave: object
17 private readonly accountOrChannelFieldsSave: object
18
19 constructor (
20 private readonly actorObject: ActivityPubActor,
21 private readonly actor: MActorFull
22 ) {
23 this.actorFieldsSave = this.actor.toJSON()
24
25 if (this.actorObject.type === 'Group') this.accountOrChannel = this.actor.VideoChannel
26 else this.accountOrChannel = this.actor.Account
27
28 this.accountOrChannelFieldsSave = this.accountOrChannel.toJSON()
29 }
30
31 async update () {
d0800f76 32 const avatarsInfo = getImagesInfoFromObject(this.actorObject, ActorImageType.AVATAR)
33 const bannersInfo = getImagesInfoFromObject(this.actorObject, ActorImageType.BANNER)
136d7efd
C
34
35 try {
28dfb44b 36 await this.updateActorInstance(this.actor, this.actorObject)
136d7efd 37
28dfb44b
C
38 this.accountOrChannel.name = this.actorObject.name || this.actorObject.preferredUsername
39 this.accountOrChannel.description = this.actorObject.summary
136d7efd 40
b5e1cd9a
C
41 if (this.accountOrChannel instanceof VideoChannelModel) {
42 const owner = await getOrCreateAPOwner(this.actorObject, this.actorObject.url)
43 this.accountOrChannel.accountId = owner.Account.id
44 this.accountOrChannel.Account = owner.Account as AccountModel
45
46 this.accountOrChannel.support = this.actorObject.support
47 }
136d7efd 48
28dfb44b 49 await runInReadCommittedTransaction(async t => {
d0800f76 50 await updateActorImages(this.actor, ActorImageType.BANNER, bannersInfo, t)
51 await updateActorImages(this.actor, ActorImageType.AVATAR, avatarsInfo, t)
136d7efd
C
52 })
53
28dfb44b 54 await runInReadCommittedTransaction(async t => {
bbfdeb39
C
55 await this.actor.save({ transaction: t })
56 await this.accountOrChannel.save({ transaction: t })
28dfb44b
C
57 })
58
136d7efd
C
59 logger.info('Remote account %s updated', this.actorObject.url)
60 } catch (err) {
61 if (this.actor !== undefined && this.actorFieldsSave !== undefined) {
62 resetSequelizeInstance(this.actor, this.actorFieldsSave)
63 }
64
65 if (this.accountOrChannel !== undefined && this.accountOrChannelFieldsSave !== undefined) {
66 resetSequelizeInstance(this.accountOrChannel, this.accountOrChannelFieldsSave)
67 }
68
69 // This is just a debug because we will retry the insert
70 logger.debug('Cannot update the remote account.', { err })
71 throw err
72 }
73 }
74
75 private async updateActorInstance (actorInstance: MActor, actorObject: ActivityPubActor) {
76 const { followersCount, followingCount } = await fetchActorFollowsCount(actorObject)
77
78 actorInstance.type = actorObject.type
79 actorInstance.preferredUsername = actorObject.preferredUsername
80 actorInstance.url = actorObject.id
81 actorInstance.publicKey = actorObject.publicKey.publicKeyPem
82 actorInstance.followersCount = followersCount
83 actorInstance.followingCount = followingCount
84 actorInstance.inboxUrl = actorObject.inbox
85 actorInstance.outboxUrl = actorObject.outbox
86 actorInstance.followersUrl = actorObject.followers
87 actorInstance.followingUrl = actorObject.following
88
89 if (actorObject.published) actorInstance.remoteCreatedAt = new Date(actorObject.published)
90
91 if (actorObject.endpoints?.sharedInbox) {
92 actorInstance.sharedInboxUrl = actorObject.endpoints.sharedInbox
93 }
94
95 // Force actor update
96 actorInstance.changed('updatedAt', true)
97 }
98}