process-follow.ts 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. import { ActivityFollow } from '../../../../shared/models/activitypub'
  2. import { retryTransactionWrapper } from '../../../helpers/database-utils'
  3. import { logger } from '../../../helpers/logger'
  4. import { sequelizeTypescript } from '../../../initializers'
  5. import { ActorModel } from '../../../models/activitypub/actor'
  6. import { ActorFollowModel } from '../../../models/activitypub/actor-follow'
  7. import { sendAccept, sendReject } from '../send'
  8. import { Notifier } from '../../notifier'
  9. import { getAPId } from '../../../helpers/activitypub'
  10. import { getServerActor } from '../../../helpers/utils'
  11. import { CONFIG } from '../../../initializers/config'
  12. async function processFollowActivity (activity: ActivityFollow, byActor: ActorModel) {
  13. const activityObject = getAPId(activity.object)
  14. return retryTransactionWrapper(processFollow, byActor, activityObject)
  15. }
  16. // ---------------------------------------------------------------------------
  17. export {
  18. processFollowActivity
  19. }
  20. // ---------------------------------------------------------------------------
  21. async function processFollow (actor: ActorModel, targetActorURL: string) {
  22. const { actorFollow, created, isFollowingInstance } = await sequelizeTypescript.transaction(async t => {
  23. const targetActor = await ActorModel.loadByUrlAndPopulateAccountAndChannel(targetActorURL, t)
  24. if (!targetActor) throw new Error('Unknown actor')
  25. if (targetActor.isOwned() === false) throw new Error('This is not a local actor.')
  26. const serverActor = await getServerActor()
  27. const isFollowingInstance = targetActor.id === serverActor.id
  28. if (isFollowingInstance && CONFIG.FOLLOWERS.INSTANCE.ENABLED === false) {
  29. logger.info('Rejecting %s because instance followers are disabled.', targetActor.url)
  30. await sendReject(actor, targetActor)
  31. return { actorFollow: undefined }
  32. }
  33. const [ actorFollow, created ] = await ActorFollowModel.findOrCreate({
  34. where: {
  35. actorId: actor.id,
  36. targetActorId: targetActor.id
  37. },
  38. defaults: {
  39. actorId: actor.id,
  40. targetActorId: targetActor.id,
  41. state: CONFIG.FOLLOWERS.INSTANCE.MANUAL_APPROVAL ? 'pending' : 'accepted'
  42. },
  43. transaction: t
  44. })
  45. if (actorFollow.state !== 'accepted' && CONFIG.FOLLOWERS.INSTANCE.MANUAL_APPROVAL === false) {
  46. actorFollow.state = 'accepted'
  47. await actorFollow.save({ transaction: t })
  48. }
  49. actorFollow.ActorFollower = actor
  50. actorFollow.ActorFollowing = targetActor
  51. // Target sends to actor he accepted the follow request
  52. if (actorFollow.state === 'accepted') await sendAccept(actorFollow)
  53. return { actorFollow, created, isFollowingInstance }
  54. })
  55. // Rejected
  56. if (!actorFollow) return
  57. if (created) {
  58. if (isFollowingInstance) Notifier.Instance.notifyOfNewInstanceFollow(actorFollow)
  59. else Notifier.Instance.notifyOfNewUserFollow(actorFollow)
  60. }
  61. logger.info('Actor %s is followed by actor %s.', targetActorURL, actor.url)
  62. }