Put activity pub sends inside transactions
authorChocobozzz <florian.bigard@gmail.com>
Thu, 30 Nov 2017 10:31:15 +0000 (11:31 +0100)
committerChocobozzz <florian.bigard@gmail.com>
Thu, 30 Nov 2017 10:31:15 +0000 (11:31 +0100)
21 files changed:
server/controllers/api/videos/rate.ts
server/lib/activitypub/process/process-update.ts
server/lib/activitypub/send/misc.ts
server/lib/activitypub/send/send-accept.ts
server/lib/activitypub/send/send-add.ts
server/lib/activitypub/send/send-announce.ts
server/lib/activitypub/send/send-create.ts
server/lib/activitypub/send/send-delete.ts
server/lib/activitypub/send/send-follow.ts
server/lib/activitypub/send/send-like.ts
server/lib/activitypub/send/send-undo.ts
server/lib/activitypub/send/send-update.ts
server/models/account/account-follow-interface.ts
server/models/account/account-follow.ts
server/models/account/account-interface.ts
server/models/account/account-video-rate.ts
server/models/account/account.ts
server/models/video/video-channel-share-interface.ts
server/models/video/video-channel-share.ts
server/models/video/video-share-interface.ts
server/models/video/video-share.ts

index 0c6a988cfbdb0b69118cd4da662df7c7c301c009..c27c611161dcb2fcb332da8ecb11901931b4aaca 100644 (file)
@@ -58,11 +58,11 @@ async function rateVideo (req: express.Request, res: express.Response) {
       else if (previousRate.type === VIDEO_RATE_TYPES.DISLIKE) dislikesToIncrement--
 
       if (rateType === 'none') { // Destroy previous rate
-        await previousRate.destroy()
+        await previousRate.destroy({ transaction: t })
       } else { // Update previous rate
         previousRate.type = rateType
 
-        await previousRate.save()
+        await previousRate.save({ transaction: t })
       }
     } else if (rateType !== 'none') { // There was not a previous rate, insert a new one if there is a rate
       const query = {
index 84a62de9ff140d6e71901c8b1a74b458cf1f61aa..11c6de8f56bc5f6f99e5ccbd0ca2189b1aa15def 100644 (file)
@@ -1,3 +1,4 @@
+import * as Bluebird from 'bluebird'
 import { VideoChannelObject, VideoTorrentObject } from '../../../../shared'
 import { ActivityUpdate } from '../../../../shared/models/activitypub/activity'
 import { retryTransactionWrapper } from '../../../helpers/database-utils'
@@ -6,9 +7,8 @@ import { resetSequelizeInstance } from '../../../helpers/utils'
 import { database as db } from '../../../initializers'
 import { AccountInstance } from '../../../models/account/account-interface'
 import { VideoInstance } from '../../../models/video/video-interface'
-import { videoActivityObjectToDBAttributes, videoFileActivityUrlToDBAttributes } from './misc'
-import Bluebird = require('bluebird')
 import { getOrCreateAccountAndServer } from '../account'
+import { videoActivityObjectToDBAttributes, videoFileActivityUrlToDBAttributes } from './misc'
 
 async function processUpdateActivity (activity: ActivityUpdate) {
   const account = await getOrCreateAccountAndServer(activity.actor)
index fd1add68eaceedb0efde9f4c7303af8e7b7ff6c9..999def70168a4fef7866169d9ce348c42f7c4a1e 100644 (file)
@@ -25,8 +25,8 @@ async function forwardActivity (
     }
   }
 
-  const toAccountFollowers = await db.Account.listByFollowersUrls(followersUrls)
-  const uris = await computeFollowerUris(toAccountFollowers, followersException)
+  const toAccountFollowers = await db.Account.listByFollowersUrls(followersUrls, t)
+  const uris = await computeFollowerUris(toAccountFollowers, followersException, t)
 
   if (uris.length === 0) {
     logger.info('0 followers for %s, no forwarding.', toAccountFollowers.map(a => a.id).join(', '))
@@ -50,7 +50,7 @@ async function broadcastToFollowers (
   t: Transaction,
   followersException: AccountInstance[] = []
 ) {
-  const uris = await computeFollowerUris(toAccountFollowers, followersException)
+  const uris = await computeFollowerUris(toAccountFollowers, followersException, t)
   if (uris.length === 0) {
     logger.info('0 followers for %s, no broadcasting.', toAccountFollowers.map(a => a.id).join(', '))
     return undefined
@@ -100,22 +100,22 @@ function getObjectFollowersAudience (accountsInvolvedInObject: AccountInstance[]
   }
 }
 
-async function getAccountsInvolvedInVideo (video: VideoInstance) {
-  const accountsToForwardView = await db.VideoShare.loadAccountsByShare(video.id)
+async function getAccountsInvolvedInVideo (video: VideoInstance, t: Transaction) {
+  const accountsToForwardView = await db.VideoShare.loadAccountsByShare(video.id, t)
   accountsToForwardView.push(video.VideoChannel.Account)
 
   return accountsToForwardView
 }
 
-async function getAccountsInvolvedInVideoChannel (videoChannel: VideoChannelInstance) {
-  const accountsToForwardView = await db.VideoChannelShare.loadAccountsByShare(videoChannel.id)
+async function getAccountsInvolvedInVideoChannel (videoChannel: VideoChannelInstance, t: Transaction) {
+  const accountsToForwardView = await db.VideoChannelShare.loadAccountsByShare(videoChannel.id, t)
   accountsToForwardView.push(videoChannel.Account)
 
   return accountsToForwardView
 }
 
-async function getAudience (accountSender: AccountInstance, isPublic = true) {
-  const followerInboxUrls = await accountSender.getFollowerSharedInboxUrls()
+async function getAudience (accountSender: AccountInstance, t: Transaction, isPublic = true) {
+  const followerInboxUrls = await accountSender.getFollowerSharedInboxUrls(t)
 
   // Thanks Mastodon: https://github.com/tootsuite/mastodon/blob/master/app/lib/activitypub/tag_manager.rb#L47
   let to = []
@@ -132,10 +132,10 @@ async function getAudience (accountSender: AccountInstance, isPublic = true) {
   return { to, cc }
 }
 
-async function computeFollowerUris (toAccountFollower: AccountInstance[], followersException: AccountInstance[]) {
+async function computeFollowerUris (toAccountFollower: AccountInstance[], followersException: AccountInstance[], t: Transaction) {
   const toAccountFollowerIds = toAccountFollower.map(a => a.id)
 
-  const result = await db.AccountFollow.listAcceptedFollowerSharedInboxUrls(toAccountFollowerIds)
+  const result = await db.AccountFollow.listAcceptedFollowerSharedInboxUrls(toAccountFollowerIds, t)
   const followersSharedInboxException = followersException.map(f => f.sharedInboxUrl)
   const uris = result.data.filter(sharedInbox => followersSharedInboxException.indexOf(sharedInbox) === -1)
 
index eeab19ed01c59c94384bfa4751c35444dfe83207..d3f8fbe38475dced9725849aeeaff49306f756b2 100644 (file)
@@ -10,7 +10,7 @@ async function sendAccept (accountFollow: AccountFollowInstance, t: Transaction)
   const me = accountFollow.AccountFollowing
 
   const url = getAccountFollowAcceptActivityPubUrl(accountFollow)
-  const data = await acceptActivityData(url, me)
+  const data = acceptActivityData(url, me)
 
   return unicastTo(data, me, follower.inboxUrl, t)
 }
@@ -23,7 +23,7 @@ export {
 
 // ---------------------------------------------------------------------------
 
-async function acceptActivityData (url: string, byAccount: AccountInstance) {
+function acceptActivityData (url: string, byAccount: AccountInstance) {
   const activity: ActivityAccept = {
     type: 'Accept',
     id: url,
index 3012b75333c18f6aab700f1fdafa08ed2434eecc..d8ac2853eb4579a4ce299ebcbeb5b2f0b6cca73b 100644 (file)
@@ -8,15 +8,22 @@ async function sendAddVideo (video: VideoInstance, t: Transaction) {
   const byAccount = video.VideoChannel.Account
 
   const videoObject = video.toActivityPubObject()
-  const data = await addActivityData(video.url, byAccount, video, video.VideoChannel.url, videoObject)
+  const data = await addActivityData(video.url, byAccount, video, video.VideoChannel.url, videoObject, t)
 
   return broadcastToFollowers(data, byAccount, [ byAccount ], t)
 }
 
-async function addActivityData (url: string, byAccount: AccountInstance, video: VideoInstance, target: string, object: any) {
+async function addActivityData (
+  url: string,
+  byAccount: AccountInstance,
+  video: VideoInstance,
+  target: string,
+  object: any,
+  t: Transaction
+) {
   const videoPublic = video.privacy === VideoPrivacy.PUBLIC
 
-  const { to, cc } = await getAudience(byAccount, videoPublic)
+  const { to, cc } = await getAudience(byAccount, t, videoPublic)
   const activity: ActivityAdd = {
     type: 'Add',
     id: url,
index efc23af46dd80590c5f354dcd06eb669989d3d96..3acf604cd947e2f08b470a37286a706ceb8bca59 100644 (file)
@@ -21,11 +21,11 @@ async function buildVideoAnnounceToFollowers (byAccount: AccountInstance, video:
   const url = getAnnounceActivityPubUrl(video.url, byAccount)
 
   const videoChannel = video.VideoChannel
-  const announcedActivity = await addActivityData(url, videoChannel.Account, video, videoChannel.url, video.toActivityPubObject())
+  const announcedActivity = await addActivityData(url, videoChannel.Account, video, videoChannel.url, video.toActivityPubObject(), t)
 
-  const accountsToForwardView = await getAccountsInvolvedInVideo(video)
+  const accountsToForwardView = await getAccountsInvolvedInVideo(video, t)
   const audience = getObjectFollowersAudience(accountsToForwardView)
-  const data = await announceActivityData(url, byAccount, announcedActivity, audience)
+  const data = await announceActivityData(url, byAccount, announcedActivity, t, audience)
 
   return data
 }
@@ -40,22 +40,22 @@ async function sendVideoAnnounceToOrigin (byAccount: AccountInstance, video: Vid
   const url = getAnnounceActivityPubUrl(video.url, byAccount)
 
   const videoChannel = video.VideoChannel
-  const announcedActivity = await addActivityData(url, videoChannel.Account, video, videoChannel.url, video.toActivityPubObject())
+  const announcedActivity = await addActivityData(url, videoChannel.Account, video, videoChannel.url, video.toActivityPubObject(), t)
 
-  const accountsInvolvedInVideo = await getAccountsInvolvedInVideo(video)
+  const accountsInvolvedInVideo = await getAccountsInvolvedInVideo(video, t)
   const audience = getOriginVideoAudience(video, accountsInvolvedInVideo)
-  const data = await createActivityData(url, byAccount, announcedActivity, audience)
+  const data = await createActivityData(url, byAccount, announcedActivity, t, audience)
 
   return unicastTo(data, byAccount, videoChannel.Account.sharedInboxUrl, t)
 }
 
 async function buildVideoChannelAnnounceToFollowers (byAccount: AccountInstance, videoChannel: VideoChannelInstance, t: Transaction) {
   const url = getAnnounceActivityPubUrl(videoChannel.url, byAccount)
-  const announcedActivity = await createActivityData(url, videoChannel.Account, videoChannel.toActivityPubObject())
+  const announcedActivity = await createActivityData(url, videoChannel.Account, videoChannel.toActivityPubObject(), t)
 
-  const accountsToForwardView = await getAccountsInvolvedInVideoChannel(videoChannel)
+  const accountsToForwardView = await getAccountsInvolvedInVideoChannel(videoChannel, t)
   const audience = getObjectFollowersAudience(accountsToForwardView)
-  const data = await announceActivityData(url, byAccount, announcedActivity, audience)
+  const data = await announceActivityData(url, byAccount, announcedActivity, t, audience)
 
   return data
 }
@@ -68,11 +68,11 @@ async function sendVideoChannelAnnounceToFollowers (byAccount: AccountInstance,
 
 async function sendVideoChannelAnnounceToOrigin (byAccount: AccountInstance, videoChannel: VideoChannelInstance, t: Transaction) {
   const url = getAnnounceActivityPubUrl(videoChannel.url, byAccount)
-  const announcedActivity = await createActivityData(url, videoChannel.Account, videoChannel.toActivityPubObject())
+  const announcedActivity = await createActivityData(url, videoChannel.Account, videoChannel.toActivityPubObject(), t)
 
-  const accountsInvolvedInVideo = await getAccountsInvolvedInVideoChannel(videoChannel)
+  const accountsInvolvedInVideo = await getAccountsInvolvedInVideoChannel(videoChannel, t)
   const audience = getOriginVideoChannelAudience(videoChannel, accountsInvolvedInVideo)
-  const data = await createActivityData(url, byAccount, announcedActivity, audience)
+  const data = await createActivityData(url, byAccount, announcedActivity, t, audience)
 
   return unicastTo(data, byAccount, videoChannel.Account.sharedInboxUrl, t)
 }
@@ -81,10 +81,11 @@ async function announceActivityData (
   url: string,
   byAccount: AccountInstance,
   object: ActivityCreate | ActivityAdd,
+  t: Transaction,
   audience?: ActivityAudience
 ) {
   if (!audience) {
-    audience = await getAudience(byAccount)
+    audience = await getAudience(byAccount, t)
   }
 
   const activity: ActivityAnnounce = {
index bf66606c13426805a7138b362a4b0a729b08d7ce..a34d3776caa9ec8160b2359a1f5fcea81a5b6cc7 100644 (file)
@@ -8,8 +8,8 @@ import {
   broadcastToFollowers,
   getAccountsInvolvedInVideo,
   getAudience,
-  getOriginVideoAudience,
   getObjectFollowersAudience,
+  getOriginVideoAudience,
   unicastTo
 } from './misc'
 
@@ -17,7 +17,7 @@ async function sendCreateVideoChannel (videoChannel: VideoChannelInstance, t: Tr
   const byAccount = videoChannel.Account
 
   const videoChannelObject = videoChannel.toActivityPubObject()
-  const data = await createActivityData(videoChannel.url, byAccount, videoChannelObject)
+  const data = await createActivityData(videoChannel.url, byAccount, videoChannelObject, t)
 
   return broadcastToFollowers(data, byAccount, [ byAccount ], t)
 }
@@ -26,7 +26,7 @@ async function sendVideoAbuse (byAccount: AccountInstance, videoAbuse: VideoAbus
   const url = getVideoAbuseActivityPubUrl(videoAbuse)
 
   const audience = { to: [ video.VideoChannel.Account.url ], cc: [] }
-  const data = await createActivityData(url, byAccount, videoAbuse.toActivityPubObject(), audience)
+  const data = await createActivityData(url, byAccount, videoAbuse.toActivityPubObject(), t, audience)
 
   return unicastTo(data, byAccount, video.VideoChannel.Account.sharedInboxUrl, t)
 }
@@ -35,9 +35,9 @@ async function sendCreateViewToOrigin (byAccount: AccountInstance, video: VideoI
   const url = getVideoViewActivityPubUrl(byAccount, video)
   const viewActivity = createViewActivityData(byAccount, video)
 
-  const accountsInvolvedInVideo = await getAccountsInvolvedInVideo(video)
+  const accountsInvolvedInVideo = await getAccountsInvolvedInVideo(video, t)
   const audience = getOriginVideoAudience(video, accountsInvolvedInVideo)
-  const data = await createActivityData(url, byAccount, viewActivity, audience)
+  const data = await createActivityData(url, byAccount, viewActivity, t, audience)
 
   return unicastTo(data, byAccount, video.VideoChannel.Account.sharedInboxUrl, t)
 }
@@ -46,9 +46,9 @@ async function sendCreateViewToVideoFollowers (byAccount: AccountInstance, video
   const url = getVideoViewActivityPubUrl(byAccount, video)
   const viewActivity = createViewActivityData(byAccount, video)
 
-  const accountsToForwardView = await getAccountsInvolvedInVideo(video)
+  const accountsToForwardView = await getAccountsInvolvedInVideo(video, t)
   const audience = getObjectFollowersAudience(accountsToForwardView)
-  const data = await createActivityData(url, byAccount, viewActivity, audience)
+  const data = await createActivityData(url, byAccount, viewActivity, t, audience)
 
   // Use the server account to send the view, because it could be an unregistered account
   const serverAccount = await getServerAccount()
@@ -60,9 +60,9 @@ async function sendCreateDislikeToOrigin (byAccount: AccountInstance, video: Vid
   const url = getVideoDislikeActivityPubUrl(byAccount, video)
   const dislikeActivity = createDislikeActivityData(byAccount, video)
 
-  const accountsInvolvedInVideo = await getAccountsInvolvedInVideo(video)
+  const accountsInvolvedInVideo = await getAccountsInvolvedInVideo(video, t)
   const audience = getOriginVideoAudience(video, accountsInvolvedInVideo)
-  const data = await createActivityData(url, byAccount, dislikeActivity, audience)
+  const data = await createActivityData(url, byAccount, dislikeActivity, t, audience)
 
   return unicastTo(data, byAccount, video.VideoChannel.Account.sharedInboxUrl, t)
 }
@@ -71,17 +71,17 @@ async function sendCreateDislikeToVideoFollowers (byAccount: AccountInstance, vi
   const url = getVideoDislikeActivityPubUrl(byAccount, video)
   const dislikeActivity = createDislikeActivityData(byAccount, video)
 
-  const accountsToForwardView = await getAccountsInvolvedInVideo(video)
+  const accountsToForwardView = await getAccountsInvolvedInVideo(video, t)
   const audience = getObjectFollowersAudience(accountsToForwardView)
-  const data = await createActivityData(url, byAccount, dislikeActivity, audience)
+  const data = await createActivityData(url, byAccount, dislikeActivity, t, audience)
 
   const followersException = [ byAccount ]
   return broadcastToFollowers(data, byAccount, accountsToForwardView, t, followersException)
 }
 
-async function createActivityData (url: string, byAccount: AccountInstance, object: any, audience?: ActivityAudience) {
+async function createActivityData (url: string, byAccount: AccountInstance, object: any, t: Transaction, audience?: ActivityAudience) {
   if (!audience) {
-    audience = await getAudience(byAccount)
+    audience = await getAudience(byAccount, t)
   }
 
   const activity: ActivityCreate = {
index 5be0e2d247568a5c9f3a736045221483aae8bbb8..c49cda04f905f6da7e39614e7a145bfcfab5b3d4 100644 (file)
@@ -7,9 +7,9 @@ import { broadcastToFollowers } from './misc'
 async function sendDeleteVideoChannel (videoChannel: VideoChannelInstance, t: Transaction) {
   const byAccount = videoChannel.Account
 
-  const data = await deleteActivityData(videoChannel.url, byAccount)
+  const data = deleteActivityData(videoChannel.url, byAccount)
 
-  const accountsInvolved = await db.VideoChannelShare.loadAccountsByShare(videoChannel.id)
+  const accountsInvolved = await db.VideoChannelShare.loadAccountsByShare(videoChannel.id, t)
   accountsInvolved.push(byAccount)
 
   return broadcastToFollowers(data, byAccount, accountsInvolved, t)
@@ -18,9 +18,9 @@ async function sendDeleteVideoChannel (videoChannel: VideoChannelInstance, t: Tr
 async function sendDeleteVideo (video: VideoInstance, t: Transaction) {
   const byAccount = video.VideoChannel.Account
 
-  const data = await deleteActivityData(video.url, byAccount)
+  const data = deleteActivityData(video.url, byAccount)
 
-  const accountsInvolved = await db.VideoShare.loadAccountsByShare(video.id)
+  const accountsInvolved = await db.VideoShare.loadAccountsByShare(video.id, t)
   accountsInvolved.push(byAccount)
 
   return broadcastToFollowers(data, byAccount, accountsInvolved, t)
@@ -42,7 +42,7 @@ export {
 
 // ---------------------------------------------------------------------------
 
-async function deleteActivityData (url: string, byAccount: AccountInstance) {
+function deleteActivityData (url: string, byAccount: AccountInstance) {
   const activity: ActivityDelete = {
     type: 'Delete',
     id: url,
index 3c01fb77c378cc71462c277b7fa0091c45444b7f..8fba1b6b57661ca765714091bc2055f36512d19a 100644 (file)
@@ -5,17 +5,17 @@ import { AccountFollowInstance } from '../../../models/account/account-follow-in
 import { getAccountFollowActivityPubUrl } from '../url'
 import { unicastTo } from './misc'
 
-async function sendFollow (accountFollow: AccountFollowInstance, t: Transaction) {
+function sendFollow (accountFollow: AccountFollowInstance, t: Transaction) {
   const me = accountFollow.AccountFollower
   const following = accountFollow.AccountFollowing
 
   const url = getAccountFollowActivityPubUrl(accountFollow)
-  const data = await followActivityData(url, me, following)
+  const data = followActivityData(url, me, following)
 
   return unicastTo(data, me, following.inboxUrl, t)
 }
 
-async function followActivityData (url: string, byAccount: AccountInstance, targetAccount: AccountInstance) {
+function followActivityData (url: string, byAccount: AccountInstance, targetAccount: AccountInstance) {
   const activity: ActivityFollow = {
     type: 'Follow',
     id: url,
index 41b879b8ac6f59768d46e01842ebeb8d465b5650..0c464b2d3f401c6c185632abb945359e12caf0f1 100644 (file)
@@ -1,5 +1,5 @@
 import { Transaction } from 'sequelize'
-import { ActivityLike } from '../../../../shared/models/activitypub/activity'
+import { ActivityAudience, ActivityLike } from '../../../../shared/models/activitypub/activity'
 import { AccountInstance, VideoInstance } from '../../../models'
 import { getVideoLikeActivityPubUrl } from '../url'
 import {
@@ -14,9 +14,9 @@ import {
 async function sendLikeToOrigin (byAccount: AccountInstance, video: VideoInstance, t: Transaction) {
   const url = getVideoLikeActivityPubUrl(byAccount, video)
 
-  const accountsInvolvedInVideo = await getAccountsInvolvedInVideo(video)
+  const accountsInvolvedInVideo = await getAccountsInvolvedInVideo(video, t)
   const audience = getOriginVideoAudience(video, accountsInvolvedInVideo)
-  const data = await likeActivityData(url, byAccount, video, audience)
+  const data = await likeActivityData(url, byAccount, video, t, audience)
 
   return unicastTo(data, byAccount, video.VideoChannel.Account.sharedInboxUrl, t)
 }
@@ -24,19 +24,23 @@ async function sendLikeToOrigin (byAccount: AccountInstance, video: VideoInstanc
 async function sendLikeToVideoFollowers (byAccount: AccountInstance, video: VideoInstance, t: Transaction) {
   const url = getVideoLikeActivityPubUrl(byAccount, video)
 
-  const accountsInvolvedInVideo = await getAccountsInvolvedInVideo(video)
+  const accountsInvolvedInVideo = await getAccountsInvolvedInVideo(video, t)
   const audience = getObjectFollowersAudience(accountsInvolvedInVideo)
-  const data = await likeActivityData(url, byAccount, video, audience)
-
-  const toAccountsFollowers = await getAccountsInvolvedInVideo(video)
+  const data = await likeActivityData(url, byAccount, video, t, audience)
 
   const followersException = [ byAccount ]
-  return broadcastToFollowers(data, byAccount, toAccountsFollowers, t, followersException)
+  return broadcastToFollowers(data, byAccount, accountsInvolvedInVideo, t, followersException)
 }
 
-async function likeActivityData (url: string, byAccount: AccountInstance, video: VideoInstance, audience?: { to: string[], cc: string[] }) {
+async function likeActivityData (
+  url: string,
+  byAccount: AccountInstance,
+  video: VideoInstance,
+  t: Transaction,
+  audience?: ActivityAudience
+) {
   if (!audience) {
-    audience = await getAudience(byAccount)
+    audience = await getAudience(byAccount, t)
   }
 
   const activity: ActivityLike = {
index 878acd21e3ff5eb8e4b5ad6184dfb6f8a5a953ad..2f5e6998e194d906340d37710b93a911fde3c06c 100644 (file)
@@ -29,8 +29,8 @@ async function sendUndoFollow (accountFollow: AccountFollowInstance, t: Transact
   const followUrl = getAccountFollowActivityPubUrl(accountFollow)
   const undoUrl = getUndoActivityPubUrl(followUrl)
 
-  const object = await followActivityData(followUrl, me, following)
-  const data = await undoActivityData(undoUrl, me, object)
+  const object = followActivityData(followUrl, me, following)
+  const data = await undoActivityData(undoUrl, me, object, t)
 
   return unicastTo(data, me, following.inboxUrl, t)
 }
@@ -39,10 +39,10 @@ async function sendUndoLikeToOrigin (byAccount: AccountInstance, video: VideoIns
   const likeUrl = getVideoLikeActivityPubUrl(byAccount, video)
   const undoUrl = getUndoActivityPubUrl(likeUrl)
 
-  const accountsInvolvedInVideo = await getAccountsInvolvedInVideo(video)
+  const accountsInvolvedInVideo = await getAccountsInvolvedInVideo(video, t)
   const audience = getOriginVideoAudience(video, accountsInvolvedInVideo)
-  const object = await likeActivityData(likeUrl, byAccount, video)
-  const data = await undoActivityData(undoUrl, byAccount, object, audience)
+  const object = await likeActivityData(likeUrl, byAccount, video, t)
+  const data = await undoActivityData(undoUrl, byAccount, object, t, audience)
 
   return unicastTo(data, byAccount, video.VideoChannel.Account.sharedInboxUrl, t)
 }
@@ -51,10 +51,10 @@ async function sendUndoLikeToVideoFollowers (byAccount: AccountInstance, video:
   const likeUrl = getVideoLikeActivityPubUrl(byAccount, video)
   const undoUrl = getUndoActivityPubUrl(likeUrl)
 
-  const toAccountsFollowers = await getAccountsInvolvedInVideo(video)
+  const toAccountsFollowers = await getAccountsInvolvedInVideo(video, t)
   const audience = getObjectFollowersAudience(toAccountsFollowers)
-  const object = await likeActivityData(likeUrl, byAccount, video)
-  const data = await undoActivityData(undoUrl, byAccount, object, audience)
+  const object = await likeActivityData(likeUrl, byAccount, video, t)
+  const data = await undoActivityData(undoUrl, byAccount, object, t, audience)
 
   const followersException = [ byAccount ]
   return broadcastToFollowers(data, byAccount, toAccountsFollowers, t, followersException)
@@ -64,12 +64,12 @@ async function sendUndoDislikeToOrigin (byAccount: AccountInstance, video: Video
   const dislikeUrl = getVideoDislikeActivityPubUrl(byAccount, video)
   const undoUrl = getUndoActivityPubUrl(dislikeUrl)
 
-  const accountsInvolvedInVideo = await getAccountsInvolvedInVideo(video)
+  const accountsInvolvedInVideo = await getAccountsInvolvedInVideo(video, t)
   const audience = getOriginVideoAudience(video, accountsInvolvedInVideo)
   const dislikeActivity = createDislikeActivityData(byAccount, video)
-  const object = await createActivityData(undoUrl, byAccount, dislikeActivity, audience)
+  const object = await createActivityData(undoUrl, byAccount, dislikeActivity, t, audience)
 
-  const data = await undoActivityData(undoUrl, byAccount, object)
+  const data = await undoActivityData(undoUrl, byAccount, object, t)
 
   return unicastTo(data, byAccount, video.VideoChannel.Account.sharedInboxUrl, t)
 }
@@ -79,11 +79,11 @@ async function sendUndoDislikeToVideoFollowers (byAccount: AccountInstance, vide
   const undoUrl = getUndoActivityPubUrl(dislikeUrl)
 
   const dislikeActivity = createDislikeActivityData(byAccount, video)
-  const object = await createActivityData(undoUrl, byAccount, dislikeActivity)
+  const object = await createActivityData(undoUrl, byAccount, dislikeActivity, t)
 
-  const data = await undoActivityData(undoUrl, byAccount, object)
+  const data = await undoActivityData(undoUrl, byAccount, object, t)
 
-  const toAccountsFollowers = await getAccountsInvolvedInVideo(video)
+  const toAccountsFollowers = await getAccountsInvolvedInVideo(video, t)
 
   const followersException = [ byAccount ]
   return broadcastToFollowers(data, byAccount, toAccountsFollowers, t, followersException)
@@ -105,10 +105,11 @@ async function undoActivityData (
   url: string,
   byAccount: AccountInstance,
   object: ActivityFollow | ActivityLike | ActivityCreate,
+  t: Transaction,
   audience?: ActivityAudience
 ) {
   if (!audience) {
-    audience = await getAudience(byAccount)
+    audience = await getAudience(byAccount, t)
   }
 
   const activity: ActivityUndo = {
index 32cada06e3fb691a112dfc1ce46bcee74e6c999e..59524e523738b636dc36d0eae3f46f5e570f5e94 100644 (file)
@@ -10,9 +10,9 @@ async function sendUpdateVideoChannel (videoChannel: VideoChannelInstance, t: Tr
 
   const url = getUpdateActivityPubUrl(videoChannel.url, videoChannel.updatedAt.toISOString())
   const videoChannelObject = videoChannel.toActivityPubObject()
-  const data = await updateActivityData(url, byAccount, videoChannelObject)
+  const data = await updateActivityData(url, byAccount, videoChannelObject, t)
 
-  const accountsInvolved = await db.VideoChannelShare.loadAccountsByShare(videoChannel.id)
+  const accountsInvolved = await db.VideoChannelShare.loadAccountsByShare(videoChannel.id, t)
   accountsInvolved.push(byAccount)
 
   return broadcastToFollowers(data, byAccount, accountsInvolved, t)
@@ -23,9 +23,9 @@ async function sendUpdateVideo (video: VideoInstance, t: Transaction) {
 
   const url = getUpdateActivityPubUrl(video.url, video.updatedAt.toISOString())
   const videoObject = video.toActivityPubObject()
-  const data = await updateActivityData(url, byAccount, videoObject)
+  const data = await updateActivityData(url, byAccount, videoObject, t)
 
-  const accountsInvolved = await db.VideoShare.loadAccountsByShare(video.id)
+  const accountsInvolved = await db.VideoShare.loadAccountsByShare(video.id, t)
   accountsInvolved.push(byAccount)
 
   return broadcastToFollowers(data, byAccount, accountsInvolved, t)
@@ -40,8 +40,8 @@ export {
 
 // ---------------------------------------------------------------------------
 
-async function updateActivityData (url: string, byAccount: AccountInstance, object: any) {
-  const { to, cc } = await getAudience(byAccount)
+async function updateActivityData (url: string, byAccount: AccountInstance, object: any, t: Transaction) {
+  const { to, cc } = await getAudience(byAccount, t)
   const activity: ActivityUpdate = {
     type: 'Update',
     id: url,
index a0d620dd0b20cd504453828aa62d22cf33c06282..7975a46f32f47b6be10442e877091e8293851c96 100644 (file)
@@ -14,9 +14,19 @@ export namespace AccountFollowMethods {
   export type ListFollowingForApi = (id: number, start: number, count: number, sort: string) => Bluebird< ResultList<AccountFollowInstance>>
   export type ListFollowersForApi = (id: number, start: number, count: number, sort: string) => Bluebird< ResultList<AccountFollowInstance>>
 
-  export type ListAcceptedFollowerUrlsForApi = (accountId: number[], start?: number, count?: number) => Promise< ResultList<string> >
-  export type ListAcceptedFollowingUrlsForApi = (accountId: number[], start?: number, count?: number) => Promise< ResultList<string> >
-  export type ListAcceptedFollowerSharedInboxUrls = (accountId: number[]) => Promise< ResultList<string> >
+  export type ListAcceptedFollowerUrlsForApi = (
+    accountId: number[],
+    t: Sequelize.Transaction,
+    start?: number,
+    count?: number
+  ) => Promise< ResultList<string> >
+  export type ListAcceptedFollowingUrlsForApi = (
+    accountId: number[],
+    t: Sequelize.Transaction,
+    start?: number,
+    count?: number
+  ) => Promise< ResultList<string> >
+  export type ListAcceptedFollowerSharedInboxUrls = (accountId: number[], t: Sequelize.Transaction) => Promise< ResultList<string> >
   export type ToFormattedJSON = (this: AccountFollowInstance) => AccountFollow
 }
 
index 8e35c7d207fde9e800a1c0838016cde5bfa02ccf..724f37baa6b6038815611ab1d8f5cf652f70e8b0 100644 (file)
@@ -181,16 +181,16 @@ listFollowersForApi = function (id: number, start: number, count: number, sort:
   })
 }
 
-listAcceptedFollowerUrlsForApi = function (accountIds: number[], start?: number, count?: number) {
-  return createListAcceptedFollowForApiQuery('followers', accountIds, start, count)
+listAcceptedFollowerUrlsForApi = function (accountIds: number[], t: Sequelize.Transaction, start?: number, count?: number) {
+  return createListAcceptedFollowForApiQuery('followers', accountIds, t, start, count)
 }
 
-listAcceptedFollowerSharedInboxUrls = function (accountIds: number[]) {
-  return createListAcceptedFollowForApiQuery('followers', accountIds, undefined, undefined, 'sharedInboxUrl')
+listAcceptedFollowerSharedInboxUrls = function (accountIds: number[], t: Sequelize.Transaction) {
+  return createListAcceptedFollowForApiQuery('followers', accountIds, t, undefined, undefined, 'sharedInboxUrl')
 }
 
-listAcceptedFollowingUrlsForApi = function (accountIds: number[], start?: number, count?: number) {
-  return createListAcceptedFollowForApiQuery('following', accountIds, start, count)
+listAcceptedFollowingUrlsForApi = function (accountIds: number[], t: Sequelize.Transaction, start?: number, count?: number) {
+  return createListAcceptedFollowForApiQuery('following', accountIds, t, start, count)
 }
 
 // ------------------------------ UTILS ------------------------------
@@ -198,6 +198,7 @@ listAcceptedFollowingUrlsForApi = function (accountIds: number[], start?: number
 async function createListAcceptedFollowForApiQuery (
   type: 'followers' | 'following',
   accountIds: number[],
+  t: Sequelize.Transaction,
   start?: number,
   count?: number,
   columnUrl = 'url'
@@ -227,7 +228,8 @@ async function createListAcceptedFollowForApiQuery (
 
     const options = {
       bind: { accountIds },
-      type: Sequelize.QueryTypes.SELECT
+      type: Sequelize.QueryTypes.SELECT,
+      transaction: t
     }
     tasks.push(AccountFollow['sequelize'].query(query, options))
   }
index 6fc98ba45c4b4112dc19d987f23fc4fc15575767..b369766dc4d6b6ecd399715eded4163684c972c8 100644 (file)
@@ -12,12 +12,12 @@ export namespace AccountMethods {
   export type LoadByUrl = (url: string, transaction?: Sequelize.Transaction) => Bluebird<AccountInstance>
   export type LoadLocalByName = (name: string) => Bluebird<AccountInstance>
   export type LoadByNameAndHost = (name: string, host: string) => Bluebird<AccountInstance>
-  export type ListByFollowersUrls = (followerUrls: string[], transaction?: Sequelize.Transaction) => Bluebird<AccountInstance[]>
+  export type ListByFollowersUrls = (followerUrls: string[], transaction: Sequelize.Transaction) => Bluebird<AccountInstance[]>
 
   export type ToActivityPubObject = (this: AccountInstance) => ActivityPubActor
   export type ToFormattedJSON = (this: AccountInstance) => FormattedAccount
   export type IsOwned = (this: AccountInstance) => boolean
-  export type GetFollowerSharedInboxUrls = (this: AccountInstance) => Bluebird<string[]>
+  export type GetFollowerSharedInboxUrls = (this: AccountInstance, t: Sequelize.Transaction) => Bluebird<string[]>
   export type GetFollowingUrl = (this: AccountInstance) => string
   export type GetFollowersUrl = (this: AccountInstance) => string
   export type GetPublicKeyUrl = (this: AccountInstance) => string
index 7f7c976068a39f2c5b64625dbdd714f904bc434e..d92834bbbd24152ef7b495dbf973e37ee23bc68c 100644 (file)
@@ -28,7 +28,7 @@ export default function (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.Da
     {
       indexes: [
         {
-          fields: [ 'videoId', 'accountId', 'type' ],
+          fields: [ 'videoId', 'accountId' ],
           unique: true
         }
       ]
index c721656cbe26ce1885ebfacc42941604ba58f15f..61a88524c2d39662557d9ba524450f01b0566981 100644 (file)
@@ -10,7 +10,6 @@ import {
 import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc'
 import { CONFIG, CONSTRAINTS_FIELDS } from '../../initializers/constants'
 import { sendDeleteAccount } from '../../lib/activitypub/send/send-delete'
-
 import { addMethodsToModel } from '../utils'
 import { AccountAttributes, AccountInstance, AccountMethods } from './account-interface'
 
@@ -315,7 +314,7 @@ isOwned = function (this: AccountInstance) {
   return this.serverId === null
 }
 
-getFollowerSharedInboxUrls = function (this: AccountInstance) {
+getFollowerSharedInboxUrls = function (this: AccountInstance, t: Sequelize.Transaction) {
   const query: Sequelize.FindOptions<AccountAttributes> = {
     attributes: [ 'sharedInboxUrl' ],
     include: [
@@ -327,7 +326,8 @@ getFollowerSharedInboxUrls = function (this: AccountInstance) {
           targetAccountId: this.id
         }
       }
-    ]
+    ],
+    transaction: t
   }
 
   return Account.findAll(query)
index bcb3a0e246db48aa6683bd4a2aa359d140da8e61..0482e82971f78b209721b298f494c658ef8101ff 100644 (file)
@@ -1,11 +1,12 @@
 import * as Bluebird from 'bluebird'
 import * as Sequelize from 'sequelize'
+import { Transaction } from 'sequelize'
 import { AccountInstance } from '../account/account-interface'
 import { VideoChannelInstance } from './video-channel-interface'
 
 export namespace VideoChannelShareMethods {
-  export type LoadAccountsByShare = (videoChannelId: number) => Bluebird<AccountInstance[]>
-  export type Load = (accountId: number, videoId: number) => Bluebird<VideoChannelShareInstance>
+  export type LoadAccountsByShare = (videoChannelId: number, t: Transaction) => Bluebird<AccountInstance[]>
+  export type Load = (accountId: number, videoId: number, t: Transaction) => Bluebird<VideoChannelShareInstance>
 }
 
 export interface VideoChannelShareClass {
index e47c0dae7b7e26d2bafc609b3db65b7c720b0047..2e9b658a39574e0a6d5e39d630cda12be65517f2 100644 (file)
@@ -52,7 +52,7 @@ function associate (models) {
   })
 }
 
-load = function (accountId: number, videoChannelId: number) {
+load = function (accountId: number, videoChannelId: number, t: Sequelize.Transaction) {
   return VideoChannelShare.findOne({
     where: {
       accountId,
@@ -61,11 +61,12 @@ load = function (accountId: number, videoChannelId: number) {
     include: [
       VideoChannelShare['sequelize'].models.Account,
       VideoChannelShare['sequelize'].models.VideoChannel
-    ]
+    ],
+    transaction: t
   })
 }
 
-loadAccountsByShare = function (videoChannelId: number) {
+loadAccountsByShare = function (videoChannelId: number, t: Sequelize.Transaction) {
   const query = {
     where: {
       videoChannelId
@@ -75,7 +76,8 @@ loadAccountsByShare = function (videoChannelId: number) {
         model: VideoChannelShare['sequelize'].models.Account,
         required: true
       }
-    ]
+    ],
+    transaction: t
   }
 
   return VideoChannelShare.findAll(query)
index ad23444b617560f0eec82d60e334471c216aeda4..8ad10e095b6ed9a3ab27b2cce309b3260bb23b99 100644 (file)
@@ -1,11 +1,12 @@
 import * as Bluebird from 'bluebird'
 import * as Sequelize from 'sequelize'
+import { Transaction } from 'sequelize'
 import { AccountInstance } from '../account/account-interface'
 import { VideoInstance } from './video-interface'
 
 export namespace VideoShareMethods {
-  export type LoadAccountsByShare = (videoId: number) => Bluebird<AccountInstance[]>
-  export type Load = (accountId: number, videoId: number) => Bluebird<VideoShareInstance>
+  export type LoadAccountsByShare = (videoId: number, t: Transaction) => Bluebird<AccountInstance[]>
+  export type Load = (accountId: number, videoId: number, t: Transaction) => Bluebird<VideoShareInstance>
 }
 
 export interface VideoShareClass {
index fe5d56d42b16b4e151a465bc847320fdb70838e0..37e405fa9810dd519dbcd02ea5d1d31961cf9fc7 100644 (file)
@@ -52,7 +52,7 @@ function associate (models) {
   })
 }
 
-load = function (accountId: number, videoId: number) {
+load = function (accountId: number, videoId: number, t: Sequelize.Transaction) {
   return VideoShare.findOne({
     where: {
       accountId,
@@ -60,11 +60,12 @@ load = function (accountId: number, videoId: number) {
     },
     include: [
       VideoShare['sequelize'].models.Account
-    ]
+    ],
+    transaction: t
   })
 }
 
-loadAccountsByShare = function (videoId: number) {
+loadAccountsByShare = function (videoId: number, t: Sequelize.Transaction) {
   const query = {
     where: {
       videoId
@@ -74,7 +75,8 @@ loadAccountsByShare = function (videoId: number) {
         model: VideoShare['sequelize'].models.Account,
         required: true
       }
-    ]
+    ],
+    transaction: t
   }
 
   return VideoShare.findAll(query)