X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=server%2Flib%2Factivitypub%2Fsend-request.ts;h=abc1b598db58b8ee887c4d72734f0ff4b990537c;hb=21e0727a84734cb0c81c1c9bb22a49b13e46fe5f;hp=6a31c226d5ebf2c3546280d36dacf4689bede128;hpb=e4f97babf701481b55cc10fb3448feab5f97c867;p=github%2FChocobozzz%2FPeerTube.git diff --git a/server/lib/activitypub/send-request.ts b/server/lib/activitypub/send-request.ts index 6a31c226d..abc1b598d 100644 --- a/server/lib/activitypub/send-request.ts +++ b/server/lib/activitypub/send-request.ts @@ -1,5 +1,6 @@ import * as Sequelize from 'sequelize' +import { database as db } from '../../initializers' import { AccountInstance, VideoInstance, @@ -7,60 +8,153 @@ import { } from '../../models' import { httpRequestJobScheduler } from '../jobs' import { signObject, activityPubContextify } from '../../helpers' -import { Activity } from '../../../shared' +import { Activity, VideoAbuseObject } from '../../../shared' +import { VideoAbuseInstance } from '../../models/video/video-abuse-interface' +import { getActivityPubUrl } from '../../helpers/activitypub' +import { logger } from '../../helpers/logger' -function sendCreateVideoChannel (videoChannel: VideoChannelInstance, t: Sequelize.Transaction) { +async function sendCreateVideoChannel (videoChannel: VideoChannelInstance, t: Sequelize.Transaction) { const videoChannelObject = videoChannel.toActivityPubObject() - const data = createActivityData(videoChannel.url, videoChannel.Account, videoChannelObject) + const data = await createActivityData(videoChannel.url, videoChannel.Account, videoChannelObject) - return broadcastToFollowers(data, t) + return broadcastToFollowers(data, [ videoChannel.Account ], t) } -function sendUpdateVideoChannel (videoChannel: VideoChannelInstance, t: Sequelize.Transaction) { +async function sendUpdateVideoChannel (videoChannel: VideoChannelInstance, t: Sequelize.Transaction) { const videoChannelObject = videoChannel.toActivityPubObject() - const data = updateActivityData(videoChannel.url, videoChannel.Account, videoChannelObject) + const data = await updateActivityData(videoChannel.url, videoChannel.Account, videoChannelObject) - return broadcastToFollowers(data, t) + const accountsInvolved = await db.VideoChannelShare.loadAccountsByShare(videoChannel.id) + accountsInvolved.push(videoChannel.Account) + + return broadcastToFollowers(data, accountsInvolved, t) } -function sendDeleteVideoChannel (videoChannel: VideoChannelInstance, t: Sequelize.Transaction) { - const videoChannelObject = videoChannel.toActivityPubObject() - const data = deleteActivityData(videoChannel.url, videoChannel.Account, videoChannelObject) +async function sendDeleteVideoChannel (videoChannel: VideoChannelInstance, t: Sequelize.Transaction) { + const data = await deleteActivityData(videoChannel.url, videoChannel.Account) - return broadcastToFollowers(data, t) + const accountsInvolved = await db.VideoChannelShare.loadAccountsByShare(videoChannel.id) + accountsInvolved.push(videoChannel.Account) + + return broadcastToFollowers(data, accountsInvolved, t) } -function sendAddVideo (video: VideoInstance, t: Sequelize.Transaction) { +async function sendAddVideo (video: VideoInstance, t: Sequelize.Transaction) { const videoObject = video.toActivityPubObject() - const data = addActivityData(video.url, video.VideoChannel.Account, video.VideoChannel.url, videoObject) + const data = await addActivityData(video.url, video.VideoChannel.Account, video.VideoChannel.url, videoObject) - return broadcastToFollowers(data, t) + return broadcastToFollowers(data, [ video.VideoChannel.Account ], t) } -function sendUpdateVideo (video: VideoInstance, t: Sequelize.Transaction) { +async function sendUpdateVideo (video: VideoInstance, t: Sequelize.Transaction) { const videoObject = video.toActivityPubObject() - const data = updateActivityData(video.url, video.VideoChannel.Account, videoObject) + const data = await updateActivityData(video.url, video.VideoChannel.Account, videoObject) + + const accountsInvolved = await db.VideoShare.loadAccountsByShare(video.id) + accountsInvolved.push(video.VideoChannel.Account) - return broadcastToFollowers(data, t) + return broadcastToFollowers(data, accountsInvolved, t) } -function sendDeleteVideo (video: VideoInstance, t: Sequelize.Transaction) { - const videoObject = video.toActivityPubObject() - const data = deleteActivityData(video.url, video.VideoChannel.Account, videoObject) +async function sendDeleteVideo (video: VideoInstance, t: Sequelize.Transaction) { + const data = await deleteActivityData(video.url, video.VideoChannel.Account) + + const accountsInvolved = await db.VideoShare.loadAccountsByShare(video.id) + accountsInvolved.push(video.VideoChannel.Account) + + return broadcastToFollowers(data, accountsInvolved, t) +} + +async function sendDeleteAccount (account: AccountInstance, t: Sequelize.Transaction) { + const data = await deleteActivityData(account.url, account) + + return broadcastToFollowers(data, [ account ], t) +} + +async function sendVideoChannelAnnounce (byAccount: AccountInstance, videoChannel: VideoChannelInstance, t: Sequelize.Transaction) { + const url = getActivityPubUrl('videoChannel', videoChannel.uuid) + '#announce' + const announcedActivity = await createActivityData(url, videoChannel.Account, videoChannel.toActivityPubObject(), true) + + const data = await announceActivityData(url, byAccount, announcedActivity) + return broadcastToFollowers(data, [ byAccount ], t) +} + +async function sendVideoAnnounce (byAccount: AccountInstance, video: VideoInstance, t: Sequelize.Transaction) { + const url = getActivityPubUrl('video', video.uuid) + '#announce' + + const videoChannel = video.VideoChannel + const announcedActivity = await addActivityData(url, videoChannel.Account, videoChannel.url, video.toActivityPubObject(), true) - return broadcastToFollowers(data, t) + const data = await announceActivityData(url, byAccount, announcedActivity) + return broadcastToFollowers(data, [ byAccount ], t) +} + +async function sendVideoAbuse ( + fromAccount: AccountInstance, + videoAbuse: VideoAbuseInstance, + video: VideoInstance, + t: Sequelize.Transaction +) { + const url = getActivityPubUrl('videoAbuse', videoAbuse.id.toString()) + const data = await createActivityData(url, fromAccount, videoAbuse.toActivityPubObject()) + + return unicastTo(data, video.VideoChannel.Account.sharedInboxUrl, t) +} + +async function sendAccept (fromAccount: AccountInstance, toAccount: AccountInstance, t: Sequelize.Transaction) { + const data = await acceptActivityData(fromAccount) + + return unicastTo(data, toAccount.inboxUrl, t) +} + +async function sendFollow (fromAccount: AccountInstance, toAccount: AccountInstance, t: Sequelize.Transaction) { + const data = await followActivityData(toAccount.url, fromAccount) + + return unicastTo(data, toAccount.inboxUrl, t) } // --------------------------------------------------------------------------- export { - + sendCreateVideoChannel, + sendUpdateVideoChannel, + sendDeleteVideoChannel, + sendAddVideo, + sendUpdateVideo, + sendDeleteVideo, + sendDeleteAccount, + sendAccept, + sendFollow, + sendVideoAbuse, + sendVideoChannelAnnounce, + sendVideoAnnounce } // --------------------------------------------------------------------------- -function broadcastToFollowers (data: any, t: Sequelize.Transaction) { - return httpRequestJobScheduler.createJob(t, 'http-request', 'httpRequestBroadcastHandler', data) +async function broadcastToFollowers (data: any, toAccountFollowers: AccountInstance[], t: Sequelize.Transaction) { + const toAccountFollowerIds = toAccountFollowers.map(a => a.id) + const result = await db.AccountFollow.listAcceptedFollowerSharedInboxUrls(toAccountFollowerIds) + if (result.data.length === 0) { + logger.info('Not broadcast because of 0 followers for %s.', toAccountFollowerIds.join(', ')) + return + } + + const jobPayload = { + uris: result.data, + body: data + } + + return httpRequestJobScheduler.createJob(t, 'httpRequestBroadcastHandler', jobPayload) +} + +async function unicastTo (data: any, toAccountUrl: string, t: Sequelize.Transaction) { + const jobPayload = { + uris: [ toAccountUrl ], + body: data + } + + return httpRequestJobScheduler.createJob(t, 'httpRequestUnicastHandler', jobPayload) } function buildSignedActivity (byAccount: AccountInstance, data: Object) { @@ -75,7 +169,7 @@ async function getPublicActivityTo (account: AccountInstance) { return inboxUrls.concat('https://www.w3.org/ns/activitystreams#Public') } -async function createActivityData (url: string, byAccount: AccountInstance, object: any) { +async function createActivityData (url: string, byAccount: AccountInstance, object: any, raw = false) { const to = await getPublicActivityTo(byAccount) const base = { type: 'Create', @@ -85,6 +179,8 @@ async function createActivityData (url: string, byAccount: AccountInstance, obje object } + if (raw === true) return base + return buildSignedActivity(byAccount, base) } @@ -101,20 +197,17 @@ async function updateActivityData (url: string, byAccount: AccountInstance, obje return buildSignedActivity(byAccount, base) } -async function deleteActivityData (url: string, byAccount: AccountInstance, object: any) { - const to = await getPublicActivityTo(byAccount) +async function deleteActivityData (url: string, byAccount: AccountInstance) { const base = { - type: 'Update', + type: 'Delete', id: url, - actor: byAccount.url, - to, - object + actor: byAccount.url } return buildSignedActivity(byAccount, base) } -async function addActivityData (url: string, byAccount: AccountInstance, target: string, object: any) { +async function addActivityData (url: string, byAccount: AccountInstance, target: string, object: any, raw = false) { const to = await getPublicActivityTo(byAccount) const base = { type: 'Add', @@ -125,5 +218,39 @@ async function addActivityData (url: string, byAccount: AccountInstance, target: target } + if (raw === true) return base + + return buildSignedActivity(byAccount, base) +} + +async function announceActivityData (url: string, byAccount: AccountInstance, object: any) { + const base = { + type: 'Announce', + id: url, + actor: byAccount.url, + object + } + + return buildSignedActivity(byAccount, base) +} + +async function followActivityData (url: string, byAccount: AccountInstance) { + const base = { + type: 'Follow', + id: byAccount.url, + actor: byAccount.url, + object: url + } + + return buildSignedActivity(byAccount, base) +} + +async function acceptActivityData (byAccount: AccountInstance) { + const base = { + type: 'Accept', + id: byAccount.url, + actor: byAccount.url + } + return buildSignedActivity(byAccount, base) }