outbox.ts 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. import * as express from 'express'
  2. import { Activity } from '../../../shared/models/activitypub/activity'
  3. import { VideoPrivacy } from '../../../shared/models/videos'
  4. import { activityPubCollectionPagination, activityPubContextify } from '../../helpers/activitypub'
  5. import { logger } from '../../helpers/logger'
  6. import { buildAnnounceActivity, buildCreateActivity } from '../../lib/activitypub/send'
  7. import { buildAudience } from '../../lib/activitypub/audience'
  8. import { asyncMiddleware, localAccountValidator, localVideoChannelValidator } from '../../middlewares'
  9. import { AccountModel } from '../../models/account/account'
  10. import { ActorModel } from '../../models/activitypub/actor'
  11. import { VideoModel } from '../../models/video/video'
  12. import { activityPubResponse } from './utils'
  13. import { VideoChannelModel } from '../../models/video/video-channel'
  14. const outboxRouter = express.Router()
  15. outboxRouter.get('/accounts/:name/outbox',
  16. localAccountValidator,
  17. asyncMiddleware(outboxController)
  18. )
  19. outboxRouter.get('/video-channels/:name/outbox',
  20. localVideoChannelValidator,
  21. asyncMiddleware(outboxController)
  22. )
  23. // ---------------------------------------------------------------------------
  24. export {
  25. outboxRouter
  26. }
  27. // ---------------------------------------------------------------------------
  28. async function outboxController (req: express.Request, res: express.Response) {
  29. const accountOrVideoChannel = res.locals.account || res.locals.videoChannel
  30. const actor = accountOrVideoChannel.Actor
  31. const actorOutboxUrl = actor.url + '/outbox'
  32. logger.info('Receiving outbox request for %s.', actorOutboxUrl)
  33. const handler = (start: number, count: number) => buildActivities(actor, start, count)
  34. const json = await activityPubCollectionPagination(actorOutboxUrl, handler, req.query.page)
  35. return activityPubResponse(activityPubContextify(json), res)
  36. }
  37. async function buildActivities (actor: ActorModel, start: number, count: number) {
  38. const data = await VideoModel.listAllAndSharedByActorForOutbox(actor.id, start, count)
  39. const activities: Activity[] = []
  40. // Avoid too many SQL requests
  41. const actors = data.data.map(v => v.VideoChannel.Account.Actor)
  42. actors.push(actor)
  43. for (const video of data.data) {
  44. const byActor = video.VideoChannel.Account.Actor
  45. const createActivityAudience = buildAudience([ byActor.followersUrl ], video.privacy === VideoPrivacy.PUBLIC)
  46. // This is a shared video
  47. if (video.VideoShares !== undefined && video.VideoShares.length !== 0) {
  48. const videoShare = video.VideoShares[0]
  49. const announceActivity = buildAnnounceActivity(videoShare.url, actor, video.url, createActivityAudience)
  50. activities.push(announceActivity)
  51. } else {
  52. const videoObject = video.toActivityPubObject()
  53. const createActivity = buildCreateActivity(video.url, byActor, videoObject, createActivityAudience)
  54. activities.push(createActivity)
  55. }
  56. }
  57. return {
  58. data: activities,
  59. total: data.total
  60. }
  61. }