diff options
Diffstat (limited to 'server/lib/activitypub/actors/updater.ts')
-rw-r--r-- | server/lib/activitypub/actors/updater.ts | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/server/lib/activitypub/actors/updater.ts b/server/lib/activitypub/actors/updater.ts new file mode 100644 index 000000000..471688f11 --- /dev/null +++ b/server/lib/activitypub/actors/updater.ts | |||
@@ -0,0 +1,90 @@ | |||
1 | import { resetSequelizeInstance } from '@server/helpers/database-utils' | ||
2 | import { logger } from '@server/helpers/logger' | ||
3 | import { sequelizeTypescript } from '@server/initializers/database' | ||
4 | import { VideoChannelModel } from '@server/models/video/video-channel' | ||
5 | import { MAccount, MActor, MActorFull, MChannel } from '@server/types/models' | ||
6 | import { ActivityPubActor, ActorImageType } from '@shared/models' | ||
7 | import { updateActorImageInstance } from './image' | ||
8 | import { fetchActorFollowsCount } from './shared' | ||
9 | import { getImageInfoFromObject } from './shared/object-to-model-attributes' | ||
10 | |||
11 | export class APActorUpdater { | ||
12 | |||
13 | private accountOrChannel: MAccount | MChannel | ||
14 | |||
15 | private readonly actorFieldsSave: object | ||
16 | private readonly accountOrChannelFieldsSave: object | ||
17 | |||
18 | constructor ( | ||
19 | private readonly actorObject: ActivityPubActor, | ||
20 | private readonly actor: MActorFull | ||
21 | ) { | ||
22 | this.actorFieldsSave = this.actor.toJSON() | ||
23 | |||
24 | if (this.actorObject.type === 'Group') this.accountOrChannel = this.actor.VideoChannel | ||
25 | else this.accountOrChannel = this.actor.Account | ||
26 | |||
27 | this.accountOrChannelFieldsSave = this.accountOrChannel.toJSON() | ||
28 | } | ||
29 | |||
30 | async update () { | ||
31 | const avatarInfo = getImageInfoFromObject(this.actorObject, ActorImageType.AVATAR) | ||
32 | const bannerInfo = getImageInfoFromObject(this.actorObject, ActorImageType.BANNER) | ||
33 | |||
34 | try { | ||
35 | await sequelizeTypescript.transaction(async t => { | ||
36 | await this.updateActorInstance(this.actor, this.actorObject) | ||
37 | |||
38 | await updateActorImageInstance(this.actor, ActorImageType.AVATAR, avatarInfo, t) | ||
39 | await updateActorImageInstance(this.actor, ActorImageType.BANNER, bannerInfo, t) | ||
40 | |||
41 | await this.actor.save({ transaction: t }) | ||
42 | |||
43 | this.accountOrChannel.name = this.actorObject.name || this.actorObject.preferredUsername | ||
44 | this.accountOrChannel.description = this.actorObject.summary | ||
45 | |||
46 | if (this.accountOrChannel instanceof VideoChannelModel) this.accountOrChannel.support = this.actorObject.support | ||
47 | |||
48 | await this.accountOrChannel.save({ transaction: t }) | ||
49 | }) | ||
50 | |||
51 | logger.info('Remote account %s updated', this.actorObject.url) | ||
52 | } catch (err) { | ||
53 | if (this.actor !== undefined && this.actorFieldsSave !== undefined) { | ||
54 | resetSequelizeInstance(this.actor, this.actorFieldsSave) | ||
55 | } | ||
56 | |||
57 | if (this.accountOrChannel !== undefined && this.accountOrChannelFieldsSave !== undefined) { | ||
58 | resetSequelizeInstance(this.accountOrChannel, this.accountOrChannelFieldsSave) | ||
59 | } | ||
60 | |||
61 | // This is just a debug because we will retry the insert | ||
62 | logger.debug('Cannot update the remote account.', { err }) | ||
63 | throw err | ||
64 | } | ||
65 | } | ||
66 | |||
67 | private async updateActorInstance (actorInstance: MActor, actorObject: ActivityPubActor) { | ||
68 | const { followersCount, followingCount } = await fetchActorFollowsCount(actorObject) | ||
69 | |||
70 | actorInstance.type = actorObject.type | ||
71 | actorInstance.preferredUsername = actorObject.preferredUsername | ||
72 | actorInstance.url = actorObject.id | ||
73 | actorInstance.publicKey = actorObject.publicKey.publicKeyPem | ||
74 | actorInstance.followersCount = followersCount | ||
75 | actorInstance.followingCount = followingCount | ||
76 | actorInstance.inboxUrl = actorObject.inbox | ||
77 | actorInstance.outboxUrl = actorObject.outbox | ||
78 | actorInstance.followersUrl = actorObject.followers | ||
79 | actorInstance.followingUrl = actorObject.following | ||
80 | |||
81 | if (actorObject.published) actorInstance.remoteCreatedAt = new Date(actorObject.published) | ||
82 | |||
83 | if (actorObject.endpoints?.sharedInbox) { | ||
84 | actorInstance.sharedInboxUrl = actorObject.endpoints.sharedInbox | ||
85 | } | ||
86 | |||
87 | // Force actor update | ||
88 | actorInstance.changed('updatedAt', true) | ||
89 | } | ||
90 | } | ||