diff options
Diffstat (limited to 'server/helpers/activitypub.ts')
-rw-r--r-- | server/helpers/activitypub.ts | 64 |
1 files changed, 58 insertions, 6 deletions
diff --git a/server/helpers/activitypub.ts b/server/helpers/activitypub.ts index b376b8ca2..c710117cd 100644 --- a/server/helpers/activitypub.ts +++ b/server/helpers/activitypub.ts | |||
@@ -4,13 +4,18 @@ import * as Sequelize from 'sequelize' | |||
4 | import * as url from 'url' | 4 | import * as url from 'url' |
5 | import { ActivityIconObject } from '../../shared/index' | 5 | import { ActivityIconObject } from '../../shared/index' |
6 | import { ActivityPubActor } from '../../shared/models/activitypub/activitypub-actor' | 6 | import { ActivityPubActor } from '../../shared/models/activitypub/activitypub-actor' |
7 | import { VideoChannelObject } from '../../shared/models/activitypub/objects/video-channel-object' | ||
7 | import { ResultList } from '../../shared/models/result-list.model' | 8 | import { ResultList } from '../../shared/models/result-list.model' |
8 | import { database as db, REMOTE_SCHEME } from '../initializers' | 9 | import { database as db, REMOTE_SCHEME } from '../initializers' |
9 | import { ACTIVITY_PUB_ACCEPT_HEADER, CONFIG, STATIC_PATHS } from '../initializers/constants' | 10 | import { ACTIVITY_PUB_ACCEPT_HEADER, CONFIG, STATIC_PATHS } from '../initializers/constants' |
10 | import { sendAnnounce } from '../lib/activitypub/send-request' | 11 | import { videoChannelActivityObjectToDBAttributes } from '../lib/activitypub/misc' |
12 | import { sendVideoAnnounce } from '../lib/activitypub/send-request' | ||
13 | import { sendVideoChannelAnnounce } from '../lib/index' | ||
14 | import { AccountInstance } from '../models/account/account-interface' | ||
11 | import { VideoChannelInstance } from '../models/video/video-channel-interface' | 15 | import { VideoChannelInstance } from '../models/video/video-channel-interface' |
12 | import { VideoInstance } from '../models/video/video-interface' | 16 | import { VideoInstance } from '../models/video/video-interface' |
13 | import { isRemoteAccountValid } from './custom-validators' | 17 | import { isRemoteAccountValid } from './custom-validators' |
18 | import { isVideoChannelObjectValid } from './custom-validators/activitypub/videos' | ||
14 | import { logger } from './logger' | 19 | import { logger } from './logger' |
15 | import { doRequest, doRequestAndSaveToFile } from './requests' | 20 | import { doRequest, doRequestAndSaveToFile } from './requests' |
16 | import { getServerAccount } from './utils' | 21 | import { getServerAccount } from './utils' |
@@ -34,7 +39,7 @@ async function shareVideoChannelByServer (videoChannel: VideoChannelInstance, t: | |||
34 | videoChannelId: videoChannel.id | 39 | videoChannelId: videoChannel.id |
35 | }, { transaction: t }) | 40 | }, { transaction: t }) |
36 | 41 | ||
37 | return sendAnnounce(serverAccount, videoChannel, t) | 42 | return sendVideoChannelAnnounce(serverAccount, videoChannel, t) |
38 | } | 43 | } |
39 | 44 | ||
40 | async function shareVideoByServer (video: VideoInstance, t: Sequelize.Transaction) { | 45 | async function shareVideoByServer (video: VideoInstance, t: Sequelize.Transaction) { |
@@ -45,7 +50,7 @@ async function shareVideoByServer (video: VideoInstance, t: Sequelize.Transactio | |||
45 | videoId: video.id | 50 | videoId: video.id |
46 | }, { transaction: t }) | 51 | }, { transaction: t }) |
47 | 52 | ||
48 | return sendAnnounce(serverAccount, video, t) | 53 | return sendVideoAnnounce(serverAccount, video, t) |
49 | } | 54 | } |
50 | 55 | ||
51 | function getActivityPubUrl (type: 'video' | 'videoChannel' | 'account' | 'videoAbuse', id: string) { | 56 | function getActivityPubUrl (type: 'video' | 'videoChannel' | 'account' | 'videoAbuse', id: string) { |
@@ -66,13 +71,27 @@ async function getOrCreateAccount (accountUrl: string) { | |||
66 | if (res === undefined) throw new Error('Cannot fetch remote account.') | 71 | if (res === undefined) throw new Error('Cannot fetch remote account.') |
67 | 72 | ||
68 | // Save our new account in database | 73 | // Save our new account in database |
69 | const account = res.account | 74 | account = await res.account.save() |
70 | await account.save() | ||
71 | } | 75 | } |
72 | 76 | ||
73 | return account | 77 | return account |
74 | } | 78 | } |
75 | 79 | ||
80 | async function getOrCreateVideoChannel (ownerAccount: AccountInstance, videoChannelUrl: string) { | ||
81 | let videoChannel = await db.VideoChannel.loadByUrl(videoChannelUrl) | ||
82 | |||
83 | // We don't have this account in our database, fetch it on remote | ||
84 | if (!videoChannel) { | ||
85 | videoChannel = await fetchRemoteVideoChannel(ownerAccount, videoChannelUrl) | ||
86 | if (videoChannel === undefined) throw new Error('Cannot fetch remote video channel.') | ||
87 | |||
88 | // Save our new video channel in database | ||
89 | await videoChannel.save() | ||
90 | } | ||
91 | |||
92 | return videoChannel | ||
93 | } | ||
94 | |||
76 | async function fetchRemoteAccountAndCreateServer (accountUrl: string) { | 95 | async function fetchRemoteAccountAndCreateServer (accountUrl: string) { |
77 | const options = { | 96 | const options = { |
78 | uri: accountUrl, | 97 | uri: accountUrl, |
@@ -131,6 +150,38 @@ async function fetchRemoteAccountAndCreateServer (accountUrl: string) { | |||
131 | return { account, server } | 150 | return { account, server } |
132 | } | 151 | } |
133 | 152 | ||
153 | async function fetchRemoteVideoChannel (ownerAccount: AccountInstance, videoChannelUrl: string) { | ||
154 | const options = { | ||
155 | uri: videoChannelUrl, | ||
156 | method: 'GET', | ||
157 | headers: { | ||
158 | 'Accept': ACTIVITY_PUB_ACCEPT_HEADER | ||
159 | } | ||
160 | } | ||
161 | |||
162 | logger.info('Fetching remote video channel %s.', videoChannelUrl) | ||
163 | |||
164 | let requestResult | ||
165 | try { | ||
166 | requestResult = await doRequest(options) | ||
167 | } catch (err) { | ||
168 | logger.warn('Cannot fetch remote video channel %s.', videoChannelUrl, err) | ||
169 | return undefined | ||
170 | } | ||
171 | |||
172 | const videoChannelJSON: VideoChannelObject = JSON.parse(requestResult.body) | ||
173 | if (isVideoChannelObjectValid(videoChannelJSON) === false) { | ||
174 | logger.debug('Remote video channel JSON is not valid.', { videoChannelJSON }) | ||
175 | return undefined | ||
176 | } | ||
177 | |||
178 | const videoChannelAttributes = videoChannelActivityObjectToDBAttributes(videoChannelJSON, ownerAccount) | ||
179 | const videoChannel = db.VideoChannel.build(videoChannelAttributes) | ||
180 | videoChannel.Account = ownerAccount | ||
181 | |||
182 | return videoChannel | ||
183 | } | ||
184 | |||
134 | function fetchRemoteVideoPreview (video: VideoInstance) { | 185 | function fetchRemoteVideoPreview (video: VideoInstance) { |
135 | // FIXME: use url | 186 | // FIXME: use url |
136 | const host = video.VideoChannel.Account.Server.host | 187 | const host = video.VideoChannel.Account.Server.host |
@@ -200,7 +251,8 @@ export { | |||
200 | fetchRemoteVideoPreview, | 251 | fetchRemoteVideoPreview, |
201 | fetchRemoteVideoDescription, | 252 | fetchRemoteVideoDescription, |
202 | shareVideoChannelByServer, | 253 | shareVideoChannelByServer, |
203 | shareVideoByServer | 254 | shareVideoByServer, |
255 | getOrCreateVideoChannel | ||
204 | } | 256 | } |
205 | 257 | ||
206 | // --------------------------------------------------------------------------- | 258 | // --------------------------------------------------------------------------- |