aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--server/helpers/custom-validators/activitypub/misc.ts3
-rw-r--r--server/lib/activitypub/actors/get.ts42
-rw-r--r--server/lib/activitypub/playlists/create-update.ts2
-rw-r--r--server/lib/activitypub/videos/shared/abstract-builder.ts9
-rw-r--r--shared/models/activitypub/objects/common-objects.ts5
-rw-r--r--shared/models/activitypub/objects/playlist-object.ts4
-rw-r--r--shared/models/activitypub/objects/video-comment-object.ts4
7 files changed, 41 insertions, 28 deletions
diff --git a/server/helpers/custom-validators/activitypub/misc.ts b/server/helpers/custom-validators/activitypub/misc.ts
index 279ad83dc..7df47cf15 100644
--- a/server/helpers/custom-validators/activitypub/misc.ts
+++ b/server/helpers/custom-validators/activitypub/misc.ts
@@ -51,7 +51,8 @@ function setValidAttributedTo (obj: any) {
51 } 51 }
52 52
53 obj.attributedTo = obj.attributedTo.filter(a => { 53 obj.attributedTo = obj.attributedTo.filter(a => {
54 return (a.type === 'Group' || a.type === 'Person') && isActivityPubUrlValid(a.id) 54 return isActivityPubUrlValid(a) ||
55 ((a.type === 'Group' || a.type === 'Person') && isActivityPubUrlValid(a.id))
55 }) 56 })
56 57
57 return true 58 return true
diff --git a/server/lib/activitypub/actors/get.ts b/server/lib/activitypub/actors/get.ts
index e73b7d707..b2be3f5fb 100644
--- a/server/lib/activitypub/actors/get.ts
+++ b/server/lib/activitypub/actors/get.ts
@@ -3,8 +3,9 @@ import { logger } from '@server/helpers/logger'
3import { JobQueue } from '@server/lib/job-queue' 3import { JobQueue } from '@server/lib/job-queue'
4import { ActorLoadByUrlType, loadActorByUrl } from '@server/lib/model-loaders' 4import { ActorLoadByUrlType, loadActorByUrl } from '@server/lib/model-loaders'
5import { MActor, MActorAccountChannelId, MActorAccountChannelIdActor, MActorAccountId, MActorFullActor } from '@server/types/models' 5import { MActor, MActorAccountChannelId, MActorAccountChannelIdActor, MActorAccountId, MActorFullActor } from '@server/types/models'
6import { ActivityPubActor } from '@shared/models' 6import { arrayify } from '@shared/core-utils'
7import { getAPId } from '../activity' 7import { ActivityPubActor, APObjectId } from '@shared/models'
8import { fetchAPObject, getAPId } from '../activity'
8import { checkUrlsSameHost } from '../url' 9import { checkUrlsSameHost } from '../url'
9import { refreshActorIfNeeded } from './refresh' 10import { refreshActorIfNeeded } from './refresh'
10import { APActorCreator, fetchRemoteActor } from './shared' 11import { APActorCreator, fetchRemoteActor } from './shared'
@@ -40,7 +41,7 @@ async function getOrCreateAPActor (
40 const { actorObject } = await fetchRemoteActor(actorUrl) 41 const { actorObject } = await fetchRemoteActor(actorUrl)
41 if (actorObject === undefined) throw new Error('Cannot fetch remote actor ' + actorUrl) 42 if (actorObject === undefined) throw new Error('Cannot fetch remote actor ' + actorUrl)
42 43
43 // actorUrl is just an alias/rediraction, so process object id instead 44 // actorUrl is just an alias/redirection, so process object id instead
44 if (actorObject.id !== actorUrl) return getOrCreateAPActor(actorObject, 'all', recurseIfNeeded, updateCollections) 45 if (actorObject.id !== actorUrl) return getOrCreateAPActor(actorObject, 'all', recurseIfNeeded, updateCollections)
45 46
46 // Create the attributed to actor 47 // Create the attributed to actor
@@ -68,29 +69,48 @@ async function getOrCreateAPActor (
68 return actorRefreshed 69 return actorRefreshed
69} 70}
70 71
71function getOrCreateAPOwner (actorObject: ActivityPubActor, actorUrl: string) { 72async function getOrCreateAPOwner (actorObject: ActivityPubActor, actorUrl: string) {
72 const accountAttributedTo = actorObject.attributedTo.find(a => a.type === 'Person') 73 const accountAttributedTo = await findOwner(actorUrl, actorObject.attributedTo, 'Person')
73 if (!accountAttributedTo) throw new Error('Cannot find account attributed to video channel ' + actorUrl) 74 if (!accountAttributedTo) {
74 75 throw new Error(`Cannot find account attributed to video channel ${actorUrl}`)
75 if (checkUrlsSameHost(accountAttributedTo.id, actorUrl) !== true) {
76 throw new Error(`Account attributed to ${accountAttributedTo.id} does not have the same host than actor url ${actorUrl}`)
77 } 76 }
78 77
79 try { 78 try {
80 // Don't recurse another time 79 // Don't recurse another time
81 const recurseIfNeeded = false 80 const recurseIfNeeded = false
82 return getOrCreateAPActor(accountAttributedTo.id, 'all', recurseIfNeeded) 81 return getOrCreateAPActor(accountAttributedTo, 'all', recurseIfNeeded)
83 } catch (err) { 82 } catch (err) {
84 logger.error('Cannot get or create account attributed to video channel ' + actorUrl) 83 logger.error('Cannot get or create account attributed to video channel ' + actorUrl)
85 throw new Error(err) 84 throw new Error(err)
86 } 85 }
87} 86}
88 87
88async function findOwner (rootUrl: string, attributedTo: APObjectId[] | APObjectId, type: 'Person' | 'Group') {
89 for (const actorToCheck of arrayify(attributedTo)) {
90 const actorObject = await fetchAPObject<ActivityPubActor>(getAPId(actorToCheck))
91
92 if (!actorObject) {
93 logger.warn('Unknown attributed to actor %s for owner %s', actorToCheck, rootUrl)
94 continue
95 }
96
97 if (checkUrlsSameHost(actorObject.id, rootUrl) !== true) {
98 logger.warn(`Account attributed to ${actorObject.id} does not have the same host than owner actor url ${rootUrl}`)
99 continue
100 }
101
102 if (actorObject.type === type) return actorObject
103 }
104
105 return undefined
106}
107
89// --------------------------------------------------------------------------- 108// ---------------------------------------------------------------------------
90 109
91export { 110export {
92 getOrCreateAPOwner, 111 getOrCreateAPOwner,
93 getOrCreateAPActor 112 getOrCreateAPActor,
113 findOwner
94} 114}
95 115
96// --------------------------------------------------------------------------- 116// ---------------------------------------------------------------------------
diff --git a/server/lib/activitypub/playlists/create-update.ts b/server/lib/activitypub/playlists/create-update.ts
index 9339e8ea4..920d3943a 100644
--- a/server/lib/activitypub/playlists/create-update.ts
+++ b/server/lib/activitypub/playlists/create-update.ts
@@ -77,7 +77,7 @@ async function setVideoChannel (playlistObject: PlaylistObject, playlistAttribut
77 throw new Error('Not attributed to for playlist object ' + getAPId(playlistObject)) 77 throw new Error('Not attributed to for playlist object ' + getAPId(playlistObject))
78 } 78 }
79 79
80 const actor = await getOrCreateAPActor(playlistObject.attributedTo[0], 'all') 80 const actor = await getOrCreateAPActor(getAPId(playlistObject.attributedTo[0]), 'all')
81 81
82 if (!actor.VideoChannel) { 82 if (!actor.VideoChannel) {
83 logger.warn('Playlist "attributedTo" %s is not a video channel.', playlistObject.id, { playlistObject, ...lTags(playlistObject.id) }) 83 logger.warn('Playlist "attributedTo" %s is not a video channel.', playlistObject.id, { playlistObject, ...lTags(playlistObject.id) })
diff --git a/server/lib/activitypub/videos/shared/abstract-builder.ts b/server/lib/activitypub/videos/shared/abstract-builder.ts
index 7c5c73139..8af67ecac 100644
--- a/server/lib/activitypub/videos/shared/abstract-builder.ts
+++ b/server/lib/activitypub/videos/shared/abstract-builder.ts
@@ -18,8 +18,7 @@ import {
18 MVideoThumbnail 18 MVideoThumbnail
19} from '@server/types/models' 19} from '@server/types/models'
20import { ActivityTagObject, ThumbnailType, VideoObject, VideoStreamingPlaylistType } from '@shared/models' 20import { ActivityTagObject, ThumbnailType, VideoObject, VideoStreamingPlaylistType } from '@shared/models'
21import { getOrCreateAPActor } from '../../actors' 21import { findOwner, getOrCreateAPActor } from '../../actors'
22import { checkUrlsSameHost } from '../../url'
23import { 22import {
24 getCaptionAttributesFromObject, 23 getCaptionAttributesFromObject,
25 getFileAttributesFromUrl, 24 getFileAttributesFromUrl,
@@ -37,13 +36,9 @@ export abstract class APVideoAbstractBuilder {
37 protected abstract lTags: LoggerTagsFn 36 protected abstract lTags: LoggerTagsFn
38 37
39 protected async getOrCreateVideoChannelFromVideoObject () { 38 protected async getOrCreateVideoChannelFromVideoObject () {
40 const channel = this.videoObject.attributedTo.find(a => a.type === 'Group') 39 const channel = await findOwner(this.videoObject.id, this.videoObject.attributedTo, 'Group')
41 if (!channel) throw new Error('Cannot find associated video channel to video ' + this.videoObject.url) 40 if (!channel) throw new Error('Cannot find associated video channel to video ' + this.videoObject.url)
42 41
43 if (checkUrlsSameHost(channel.id, this.videoObject.id) !== true) {
44 throw new Error(`Video channel url ${channel.id} does not have the same host than video object id ${this.videoObject.id}`)
45 }
46
47 return getOrCreateAPActor(channel.id, 'all') 42 return getOrCreateAPActor(channel.id, 'all')
48 } 43 }
49 44
diff --git a/shared/models/activitypub/objects/common-objects.ts b/shared/models/activitypub/objects/common-objects.ts
index 9bf994379..db9c73658 100644
--- a/shared/models/activitypub/objects/common-objects.ts
+++ b/shared/models/activitypub/objects/common-objects.ts
@@ -114,10 +114,7 @@ export type ActivityUrlObject =
114 | ActivityVideoFileMetadataUrlObject 114 | ActivityVideoFileMetadataUrlObject
115 | ActivityTrackerUrlObject 115 | ActivityTrackerUrlObject
116 116
117export interface ActivityPubAttributedTo { 117export type ActivityPubAttributedTo = { type: 'Group' | 'Person', id: string } | string
118 type: 'Group' | 'Person'
119 id: string
120}
121 118
122export interface ActivityTombstoneObject { 119export interface ActivityTombstoneObject {
123 '@context'?: any 120 '@context'?: any
diff --git a/shared/models/activitypub/objects/playlist-object.ts b/shared/models/activitypub/objects/playlist-object.ts
index 842c03790..0ccb71828 100644
--- a/shared/models/activitypub/objects/playlist-object.ts
+++ b/shared/models/activitypub/objects/playlist-object.ts
@@ -1,4 +1,4 @@
1import { ActivityIconObject } from './common-objects' 1import { ActivityIconObject, ActivityPubAttributedTo } from './common-objects'
2 2
3export interface PlaylistObject { 3export interface PlaylistObject {
4 id: string 4 id: string
@@ -12,7 +12,7 @@ export interface PlaylistObject {
12 uuid: string 12 uuid: string
13 13
14 totalItems: number 14 totalItems: number
15 attributedTo: string[] 15 attributedTo: ActivityPubAttributedTo[]
16 16
17 icon?: ActivityIconObject 17 icon?: ActivityIconObject
18 18
diff --git a/shared/models/activitypub/objects/video-comment-object.ts b/shared/models/activitypub/objects/video-comment-object.ts
index ba9001730..fb1e6f8db 100644
--- a/shared/models/activitypub/objects/video-comment-object.ts
+++ b/shared/models/activitypub/objects/video-comment-object.ts
@@ -1,4 +1,4 @@
1import { ActivityTagObject } from './common-objects' 1import { ActivityPubAttributedTo, ActivityTagObject } from './common-objects'
2 2
3export interface VideoCommentObject { 3export interface VideoCommentObject {
4 type: 'Note' 4 type: 'Note'
@@ -11,6 +11,6 @@ export interface VideoCommentObject {
11 published: string 11 published: string
12 updated: string 12 updated: string
13 url: string 13 url: string
14 attributedTo: string 14 attributedTo: ActivityPubAttributedTo
15 tag: ActivityTagObject[] 15 tag: ActivityTagObject[]
16} 16}