diff options
34 files changed, 278 insertions, 233 deletions
diff --git a/scripts/update-host.ts b/scripts/update-host.ts index d2fb19c76..b030b21c3 100755 --- a/scripts/update-host.ts +++ b/scripts/update-host.ts | |||
@@ -6,11 +6,11 @@ import { ActorFollowModel } from '../server/models/activitypub/actor-follow' | |||
6 | import { VideoModel } from '../server/models/video/video' | 6 | import { VideoModel } from '../server/models/video/video' |
7 | import { ActorModel } from '../server/models/activitypub/actor' | 7 | import { ActorModel } from '../server/models/activitypub/actor' |
8 | import { | 8 | import { |
9 | getAccountActivityPubUrl, | 9 | getLocalAccountActivityPubUrl, |
10 | getVideoActivityPubUrl, | 10 | getLocalVideoActivityPubUrl, |
11 | getVideoAnnounceActivityPubUrl, | 11 | getLocalVideoAnnounceActivityPubUrl, |
12 | getVideoChannelActivityPubUrl, | 12 | getLocalVideoChannelActivityPubUrl, |
13 | getVideoCommentActivityPubUrl | 13 | getLocalVideoCommentActivityPubUrl |
14 | } from '../server/lib/activitypub/url' | 14 | } from '../server/lib/activitypub/url' |
15 | import { VideoShareModel } from '../server/models/video/video-share' | 15 | import { VideoShareModel } from '../server/models/video/video-share' |
16 | import { VideoCommentModel } from '../server/models/video/video-comment' | 16 | import { VideoCommentModel } from '../server/models/video/video-comment' |
@@ -62,8 +62,8 @@ async function run () { | |||
62 | console.log('Updating actor ' + actor.url) | 62 | console.log('Updating actor ' + actor.url) |
63 | 63 | ||
64 | const newUrl = actor.Account | 64 | const newUrl = actor.Account |
65 | ? getAccountActivityPubUrl(actor.preferredUsername) | 65 | ? getLocalAccountActivityPubUrl(actor.preferredUsername) |
66 | : getVideoChannelActivityPubUrl(actor.preferredUsername) | 66 | : getLocalVideoChannelActivityPubUrl(actor.preferredUsername) |
67 | 67 | ||
68 | actor.url = newUrl | 68 | actor.url = newUrl |
69 | actor.inboxUrl = newUrl + '/inbox' | 69 | actor.inboxUrl = newUrl + '/inbox' |
@@ -85,7 +85,7 @@ async function run () { | |||
85 | 85 | ||
86 | console.log('Updating video share ' + videoShare.url) | 86 | console.log('Updating video share ' + videoShare.url) |
87 | 87 | ||
88 | videoShare.url = getVideoAnnounceActivityPubUrl(videoShare.Actor, videoShare.Video) | 88 | videoShare.url = getLocalVideoAnnounceActivityPubUrl(videoShare.Actor, videoShare.Video) |
89 | await videoShare.save() | 89 | await videoShare.save() |
90 | } | 90 | } |
91 | 91 | ||
@@ -110,7 +110,7 @@ async function run () { | |||
110 | 110 | ||
111 | console.log('Updating comment ' + comment.url) | 111 | console.log('Updating comment ' + comment.url) |
112 | 112 | ||
113 | comment.url = getVideoCommentActivityPubUrl(comment.Video, comment) | 113 | comment.url = getLocalVideoCommentActivityPubUrl(comment.Video, comment) |
114 | await comment.save() | 114 | await comment.save() |
115 | } | 115 | } |
116 | 116 | ||
@@ -120,7 +120,7 @@ async function run () { | |||
120 | for (const video of videos) { | 120 | for (const video of videos) { |
121 | console.log('Updating video ' + video.uuid) | 121 | console.log('Updating video ' + video.uuid) |
122 | 122 | ||
123 | video.url = getVideoActivityPubUrl(video) | 123 | video.url = getLocalVideoActivityPubUrl(video) |
124 | await video.save() | 124 | await video.save() |
125 | 125 | ||
126 | for (const file of video.VideoFiles) { | 126 | for (const file of video.VideoFiles) { |
diff --git a/server/controllers/activitypub/client.ts b/server/controllers/activitypub/client.ts index d85d0aa5f..71a5b6232 100644 --- a/server/controllers/activitypub/client.ts +++ b/server/controllers/activitypub/client.ts | |||
@@ -1,8 +1,7 @@ | |||
1 | import * as cors from 'cors' | 1 | import * as cors from 'cors' |
2 | import * as express from 'express' | 2 | import * as express from 'express' |
3 | import { getRateUrl } from '@server/lib/activitypub/video-rates' | ||
4 | import { getServerActor } from '@server/models/application/application' | 3 | import { getServerActor } from '@server/models/application/application' |
5 | import { MAccountId, MActorId, MChannelId, MVideoId } from '@server/types/models' | 4 | import { MAccountId, MActorId, MChannelId, MVideoId, MVideoUrl } from '@server/types/models' |
6 | import { VideoPrivacy, VideoRateType } from '../../../shared/models/videos' | 5 | import { VideoPrivacy, VideoRateType } from '../../../shared/models/videos' |
7 | import { VideoPlaylistPrivacy } from '../../../shared/models/videos/playlist/video-playlist-privacy.model' | 6 | import { VideoPlaylistPrivacy } from '../../../shared/models/videos/playlist/video-playlist-privacy.model' |
8 | import { activityPubCollectionPagination, activityPubContextify } from '../../helpers/activitypub' | 7 | import { activityPubCollectionPagination, activityPubContextify } from '../../helpers/activitypub' |
@@ -12,10 +11,10 @@ import { buildAnnounceWithVideoAudience, buildLikeActivity } from '../../lib/act | |||
12 | import { buildCreateActivity } from '../../lib/activitypub/send/send-create' | 11 | import { buildCreateActivity } from '../../lib/activitypub/send/send-create' |
13 | import { buildDislikeActivity } from '../../lib/activitypub/send/send-dislike' | 12 | import { buildDislikeActivity } from '../../lib/activitypub/send/send-dislike' |
14 | import { | 13 | import { |
15 | getVideoCommentsActivityPubUrl, | 14 | getLocalVideoCommentsActivityPubUrl, |
16 | getVideoDislikesActivityPubUrl, | 15 | getLocalVideoDislikesActivityPubUrl, |
17 | getVideoLikesActivityPubUrl, | 16 | getLocalVideoLikesActivityPubUrl, |
18 | getVideoSharesActivityPubUrl | 17 | getLocalVideoSharesActivityPubUrl |
19 | } from '../../lib/activitypub/url' | 18 | } from '../../lib/activitypub/url' |
20 | import { | 19 | import { |
21 | asyncMiddleware, | 20 | asyncMiddleware, |
@@ -212,10 +211,9 @@ function getAccountVideoRateFactory (rateType: VideoRateType) { | |||
212 | const accountVideoRate = res.locals.accountVideoRate | 211 | const accountVideoRate = res.locals.accountVideoRate |
213 | 212 | ||
214 | const byActor = accountVideoRate.Account.Actor | 213 | const byActor = accountVideoRate.Account.Actor |
215 | const url = getRateUrl(rateType, byActor, accountVideoRate.Video) | ||
216 | const APObject = rateType === 'like' | 214 | const APObject = rateType === 'like' |
217 | ? buildLikeActivity(url, byActor, accountVideoRate.Video) | 215 | ? buildLikeActivity(accountVideoRate.url, byActor, accountVideoRate.Video) |
218 | : buildDislikeActivity(url, byActor, accountVideoRate.Video) | 216 | : buildDislikeActivity(accountVideoRate.url, byActor, accountVideoRate.Video) |
219 | 217 | ||
220 | return activityPubResponse(activityPubContextify(APObject), res) | 218 | return activityPubResponse(activityPubContextify(APObject), res) |
221 | } | 219 | } |
@@ -225,7 +223,7 @@ async function videoController (req: express.Request, res: express.Response) { | |||
225 | // We need more attributes | 223 | // We need more attributes |
226 | const video = await VideoModel.loadAndPopulateAccountAndServerAndTags(res.locals.onlyVideoWithRights.id) | 224 | const video = await VideoModel.loadAndPopulateAccountAndServerAndTags(res.locals.onlyVideoWithRights.id) |
227 | 225 | ||
228 | if (video.url.startsWith(WEBSERVER.URL) === false) return res.redirect(video.url) | 226 | if (redirectIfNotOwned(video.url, res)) return |
229 | 227 | ||
230 | // We need captions to render AP object | 228 | // We need captions to render AP object |
231 | const captions = await VideoCaptionModel.listVideoCaptions(video.id) | 229 | const captions = await VideoCaptionModel.listVideoCaptions(video.id) |
@@ -245,7 +243,7 @@ async function videoController (req: express.Request, res: express.Response) { | |||
245 | async function videoAnnounceController (req: express.Request, res: express.Response) { | 243 | async function videoAnnounceController (req: express.Request, res: express.Response) { |
246 | const share = res.locals.videoShare | 244 | const share = res.locals.videoShare |
247 | 245 | ||
248 | if (share.url.startsWith(WEBSERVER.URL) === false) return res.redirect(share.url) | 246 | if (redirectIfNotOwned(share.url, res)) return |
249 | 247 | ||
250 | const { activity } = await buildAnnounceWithVideoAudience(share.Actor, share, res.locals.videoAll, undefined) | 248 | const { activity } = await buildAnnounceWithVideoAudience(share.Actor, share, res.locals.videoAll, undefined) |
251 | 249 | ||
@@ -255,6 +253,8 @@ async function videoAnnounceController (req: express.Request, res: express.Respo | |||
255 | async function videoAnnouncesController (req: express.Request, res: express.Response) { | 253 | async function videoAnnouncesController (req: express.Request, res: express.Response) { |
256 | const video = res.locals.onlyImmutableVideo | 254 | const video = res.locals.onlyImmutableVideo |
257 | 255 | ||
256 | if (redirectIfNotOwned(video.url, res)) return | ||
257 | |||
258 | const handler = async (start: number, count: number) => { | 258 | const handler = async (start: number, count: number) => { |
259 | const result = await VideoShareModel.listAndCountByVideoId(video.id, start, count) | 259 | const result = await VideoShareModel.listAndCountByVideoId(video.id, start, count) |
260 | return { | 260 | return { |
@@ -262,21 +262,27 @@ async function videoAnnouncesController (req: express.Request, res: express.Resp | |||
262 | data: result.rows.map(r => r.url) | 262 | data: result.rows.map(r => r.url) |
263 | } | 263 | } |
264 | } | 264 | } |
265 | const json = await activityPubCollectionPagination(getVideoSharesActivityPubUrl(video), handler, req.query.page) | 265 | const json = await activityPubCollectionPagination(getLocalVideoSharesActivityPubUrl(video), handler, req.query.page) |
266 | 266 | ||
267 | return activityPubResponse(activityPubContextify(json), res) | 267 | return activityPubResponse(activityPubContextify(json), res) |
268 | } | 268 | } |
269 | 269 | ||
270 | async function videoLikesController (req: express.Request, res: express.Response) { | 270 | async function videoLikesController (req: express.Request, res: express.Response) { |
271 | const video = res.locals.onlyImmutableVideo | 271 | const video = res.locals.onlyImmutableVideo |
272 | const json = await videoRates(req, 'like', video, getVideoLikesActivityPubUrl(video)) | 272 | |
273 | if (redirectIfNotOwned(video.url, res)) return | ||
274 | |||
275 | const json = await videoRates(req, 'like', video, getLocalVideoLikesActivityPubUrl(video)) | ||
273 | 276 | ||
274 | return activityPubResponse(activityPubContextify(json), res) | 277 | return activityPubResponse(activityPubContextify(json), res) |
275 | } | 278 | } |
276 | 279 | ||
277 | async function videoDislikesController (req: express.Request, res: express.Response) { | 280 | async function videoDislikesController (req: express.Request, res: express.Response) { |
278 | const video = res.locals.onlyImmutableVideo | 281 | const video = res.locals.onlyImmutableVideo |
279 | const json = await videoRates(req, 'dislike', video, getVideoDislikesActivityPubUrl(video)) | 282 | |
283 | if (redirectIfNotOwned(video.url, res)) return | ||
284 | |||
285 | const json = await videoRates(req, 'dislike', video, getLocalVideoDislikesActivityPubUrl(video)) | ||
280 | 286 | ||
281 | return activityPubResponse(activityPubContextify(json), res) | 287 | return activityPubResponse(activityPubContextify(json), res) |
282 | } | 288 | } |
@@ -284,6 +290,8 @@ async function videoDislikesController (req: express.Request, res: express.Respo | |||
284 | async function videoCommentsController (req: express.Request, res: express.Response) { | 290 | async function videoCommentsController (req: express.Request, res: express.Response) { |
285 | const video = res.locals.onlyImmutableVideo | 291 | const video = res.locals.onlyImmutableVideo |
286 | 292 | ||
293 | if (redirectIfNotOwned(video.url, res)) return | ||
294 | |||
287 | const handler = async (start: number, count: number) => { | 295 | const handler = async (start: number, count: number) => { |
288 | const result = await VideoCommentModel.listAndCountByVideoForAP(video, start, count) | 296 | const result = await VideoCommentModel.listAndCountByVideoForAP(video, start, count) |
289 | return { | 297 | return { |
@@ -291,7 +299,7 @@ async function videoCommentsController (req: express.Request, res: express.Respo | |||
291 | data: result.rows.map(r => r.url) | 299 | data: result.rows.map(r => r.url) |
292 | } | 300 | } |
293 | } | 301 | } |
294 | const json = await activityPubCollectionPagination(getVideoCommentsActivityPubUrl(video), handler, req.query.page) | 302 | const json = await activityPubCollectionPagination(getLocalVideoCommentsActivityPubUrl(video), handler, req.query.page) |
295 | 303 | ||
296 | return activityPubResponse(activityPubContextify(json), res) | 304 | return activityPubResponse(activityPubContextify(json), res) |
297 | } | 305 | } |
@@ -319,7 +327,7 @@ async function videoChannelFollowingController (req: express.Request, res: expre | |||
319 | async function videoCommentController (req: express.Request, res: express.Response) { | 327 | async function videoCommentController (req: express.Request, res: express.Response) { |
320 | const videoComment = res.locals.videoCommentFull | 328 | const videoComment = res.locals.videoCommentFull |
321 | 329 | ||
322 | if (videoComment.url.startsWith(WEBSERVER.URL) === false) return res.redirect(videoComment.url) | 330 | if (redirectIfNotOwned(videoComment.url, res)) return |
323 | 331 | ||
324 | const threadParentComments = await VideoCommentModel.listThreadParentComments(videoComment, undefined) | 332 | const threadParentComments = await VideoCommentModel.listThreadParentComments(videoComment, undefined) |
325 | const isPublic = true // Comments are always public | 333 | const isPublic = true // Comments are always public |
@@ -340,7 +348,8 @@ async function videoCommentController (req: express.Request, res: express.Respon | |||
340 | 348 | ||
341 | async function videoRedundancyController (req: express.Request, res: express.Response) { | 349 | async function videoRedundancyController (req: express.Request, res: express.Response) { |
342 | const videoRedundancy = res.locals.videoRedundancy | 350 | const videoRedundancy = res.locals.videoRedundancy |
343 | if (videoRedundancy.url.startsWith(WEBSERVER.URL) === false) return res.redirect(videoRedundancy.url) | 351 | |
352 | if (redirectIfNotOwned(videoRedundancy.url, res)) return | ||
344 | 353 | ||
345 | const serverActor = await getServerActor() | 354 | const serverActor = await getServerActor() |
346 | 355 | ||
@@ -358,6 +367,8 @@ async function videoRedundancyController (req: express.Request, res: express.Res | |||
358 | async function videoPlaylistController (req: express.Request, res: express.Response) { | 367 | async function videoPlaylistController (req: express.Request, res: express.Response) { |
359 | const playlist = res.locals.videoPlaylistFull | 368 | const playlist = res.locals.videoPlaylistFull |
360 | 369 | ||
370 | if (redirectIfNotOwned(playlist.url, res)) return | ||
371 | |||
361 | // We need more attributes | 372 | // We need more attributes |
362 | playlist.OwnerAccount = await AccountModel.load(playlist.ownerAccountId) | 373 | playlist.OwnerAccount = await AccountModel.load(playlist.ownerAccountId) |
363 | 374 | ||
@@ -371,6 +382,8 @@ async function videoPlaylistController (req: express.Request, res: express.Respo | |||
371 | function videoPlaylistElementController (req: express.Request, res: express.Response) { | 382 | function videoPlaylistElementController (req: express.Request, res: express.Response) { |
372 | const videoPlaylistElement = res.locals.videoPlaylistElementAP | 383 | const videoPlaylistElement = res.locals.videoPlaylistElementAP |
373 | 384 | ||
385 | if (redirectIfNotOwned(videoPlaylistElement.url, res)) return | ||
386 | |||
374 | const json = videoPlaylistElement.toActivityPubObject() | 387 | const json = videoPlaylistElement.toActivityPubObject() |
375 | return activityPubResponse(activityPubContextify(json), res) | 388 | return activityPubResponse(activityPubContextify(json), res) |
376 | } | 389 | } |
@@ -411,3 +424,12 @@ function videoRates (req: express.Request, rateType: VideoRateType, video: MVide | |||
411 | } | 424 | } |
412 | return activityPubCollectionPagination(url, handler, req.query.page) | 425 | return activityPubCollectionPagination(url, handler, req.query.page) |
413 | } | 426 | } |
427 | |||
428 | function redirectIfNotOwned (url: string, res: express.Response) { | ||
429 | if (url.startsWith(WEBSERVER.URL) === false) { | ||
430 | res.redirect(url) | ||
431 | return true | ||
432 | } | ||
433 | |||
434 | return false | ||
435 | } | ||
diff --git a/server/controllers/api/server/follows.ts b/server/controllers/api/server/follows.ts index 23823c9fb..517d1897e 100644 --- a/server/controllers/api/server/follows.ts +++ b/server/controllers/api/server/follows.ts | |||
@@ -165,7 +165,7 @@ async function removeFollowing (req: express.Request, res: express.Response) { | |||
165 | async function removeOrRejectFollower (req: express.Request, res: express.Response) { | 165 | async function removeOrRejectFollower (req: express.Request, res: express.Response) { |
166 | const follow = res.locals.follow | 166 | const follow = res.locals.follow |
167 | 167 | ||
168 | await sendReject(follow.ActorFollower, follow.ActorFollowing) | 168 | await sendReject(follow.url, follow.ActorFollower, follow.ActorFollowing) |
169 | 169 | ||
170 | await follow.destroy() | 170 | await follow.destroy() |
171 | 171 | ||
diff --git a/server/controllers/api/video-playlist.ts b/server/controllers/api/video-playlist.ts index 41a0e07ff..fb08a63b2 100644 --- a/server/controllers/api/video-playlist.ts +++ b/server/controllers/api/video-playlist.ts | |||
@@ -1,5 +1,24 @@ | |||
1 | import * as express from 'express' | 1 | import * as express from 'express' |
2 | import { join } from 'path' | ||
3 | import { getServerActor } from '@server/models/application/application' | ||
4 | import { MVideoPlaylistFull, MVideoPlaylistThumbnail, MVideoThumbnail } from '@server/types/models' | ||
5 | import { VideoPlaylistCreate } from '../../../shared/models/videos/playlist/video-playlist-create.model' | ||
6 | import { VideoPlaylistElementCreate } from '../../../shared/models/videos/playlist/video-playlist-element-create.model' | ||
7 | import { VideoPlaylistElementUpdate } from '../../../shared/models/videos/playlist/video-playlist-element-update.model' | ||
8 | import { VideoPlaylistPrivacy } from '../../../shared/models/videos/playlist/video-playlist-privacy.model' | ||
9 | import { VideoPlaylistReorder } from '../../../shared/models/videos/playlist/video-playlist-reorder.model' | ||
10 | import { VideoPlaylistUpdate } from '../../../shared/models/videos/playlist/video-playlist-update.model' | ||
11 | import { resetSequelizeInstance } from '../../helpers/database-utils' | ||
12 | import { buildNSFWFilter, createReqFiles } from '../../helpers/express-utils' | ||
13 | import { logger } from '../../helpers/logger' | ||
2 | import { getFormattedObjects } from '../../helpers/utils' | 14 | import { getFormattedObjects } from '../../helpers/utils' |
15 | import { CONFIG } from '../../initializers/config' | ||
16 | import { MIMETYPES, VIDEO_PLAYLIST_PRIVACIES } from '../../initializers/constants' | ||
17 | import { sequelizeTypescript } from '../../initializers/database' | ||
18 | import { sendCreateVideoPlaylist, sendDeleteVideoPlaylist, sendUpdateVideoPlaylist } from '../../lib/activitypub/send' | ||
19 | import { getLocalVideoPlaylistActivityPubUrl, getLocalVideoPlaylistElementActivityPubUrl } from '../../lib/activitypub/url' | ||
20 | import { JobQueue } from '../../lib/job-queue' | ||
21 | import { createPlaylistMiniatureFromExisting } from '../../lib/thumbnail' | ||
3 | import { | 22 | import { |
4 | asyncMiddleware, | 23 | asyncMiddleware, |
5 | asyncRetryTransactionMiddleware, | 24 | asyncRetryTransactionMiddleware, |
@@ -10,11 +29,6 @@ import { | |||
10 | setDefaultSort | 29 | setDefaultSort |
11 | } from '../../middlewares' | 30 | } from '../../middlewares' |
12 | import { videoPlaylistsSortValidator } from '../../middlewares/validators' | 31 | import { videoPlaylistsSortValidator } from '../../middlewares/validators' |
13 | import { buildNSFWFilter, createReqFiles } from '../../helpers/express-utils' | ||
14 | import { MIMETYPES, VIDEO_PLAYLIST_PRIVACIES } from '../../initializers/constants' | ||
15 | import { logger } from '../../helpers/logger' | ||
16 | import { resetSequelizeInstance } from '../../helpers/database-utils' | ||
17 | import { VideoPlaylistModel } from '../../models/video/video-playlist' | ||
18 | import { | 32 | import { |
19 | commonVideoPlaylistFiltersValidator, | 33 | commonVideoPlaylistFiltersValidator, |
20 | videoPlaylistsAddValidator, | 34 | videoPlaylistsAddValidator, |
@@ -25,23 +39,9 @@ import { | |||
25 | videoPlaylistsUpdateOrRemoveVideoValidator, | 39 | videoPlaylistsUpdateOrRemoveVideoValidator, |
26 | videoPlaylistsUpdateValidator | 40 | videoPlaylistsUpdateValidator |
27 | } from '../../middlewares/validators/videos/video-playlists' | 41 | } from '../../middlewares/validators/videos/video-playlists' |
28 | import { VideoPlaylistCreate } from '../../../shared/models/videos/playlist/video-playlist-create.model' | ||
29 | import { VideoPlaylistPrivacy } from '../../../shared/models/videos/playlist/video-playlist-privacy.model' | ||
30 | import { join } from 'path' | ||
31 | import { sendCreateVideoPlaylist, sendDeleteVideoPlaylist, sendUpdateVideoPlaylist } from '../../lib/activitypub/send' | ||
32 | import { getVideoPlaylistActivityPubUrl, getVideoPlaylistElementActivityPubUrl } from '../../lib/activitypub/url' | ||
33 | import { VideoPlaylistUpdate } from '../../../shared/models/videos/playlist/video-playlist-update.model' | ||
34 | import { VideoPlaylistElementModel } from '../../models/video/video-playlist-element' | ||
35 | import { VideoPlaylistElementCreate } from '../../../shared/models/videos/playlist/video-playlist-element-create.model' | ||
36 | import { VideoPlaylistElementUpdate } from '../../../shared/models/videos/playlist/video-playlist-element-update.model' | ||
37 | import { AccountModel } from '../../models/account/account' | 42 | import { AccountModel } from '../../models/account/account' |
38 | import { VideoPlaylistReorder } from '../../../shared/models/videos/playlist/video-playlist-reorder.model' | 43 | import { VideoPlaylistModel } from '../../models/video/video-playlist' |
39 | import { JobQueue } from '../../lib/job-queue' | 44 | import { VideoPlaylistElementModel } from '../../models/video/video-playlist-element' |
40 | import { CONFIG } from '../../initializers/config' | ||
41 | import { sequelizeTypescript } from '../../initializers/database' | ||
42 | import { createPlaylistMiniatureFromExisting } from '../../lib/thumbnail' | ||
43 | import { MVideoPlaylistFull, MVideoPlaylistThumbnail, MVideoThumbnail } from '@server/types/models' | ||
44 | import { getServerActor } from '@server/models/application/application' | ||
45 | 45 | ||
46 | const reqThumbnailFile = createReqFiles([ 'thumbnailfile' ], MIMETYPES.IMAGE.MIMETYPE_EXT, { thumbnailfile: CONFIG.STORAGE.TMP_DIR }) | 46 | const reqThumbnailFile = createReqFiles([ 'thumbnailfile' ], MIMETYPES.IMAGE.MIMETYPE_EXT, { thumbnailfile: CONFIG.STORAGE.TMP_DIR }) |
47 | 47 | ||
@@ -161,7 +161,7 @@ async function addVideoPlaylist (req: express.Request, res: express.Response) { | |||
161 | ownerAccountId: user.Account.id | 161 | ownerAccountId: user.Account.id |
162 | }) as MVideoPlaylistFull | 162 | }) as MVideoPlaylistFull |
163 | 163 | ||
164 | videoPlaylist.url = getVideoPlaylistActivityPubUrl(videoPlaylist) // We use the UUID, so set the URL after building the object | 164 | videoPlaylist.url = getLocalVideoPlaylistActivityPubUrl(videoPlaylist) // We use the UUID, so set the URL after building the object |
165 | 165 | ||
166 | if (videoPlaylistInfo.videoChannelId) { | 166 | if (videoPlaylistInfo.videoChannelId) { |
167 | const videoChannel = res.locals.videoChannel | 167 | const videoChannel = res.locals.videoChannel |
@@ -304,7 +304,7 @@ async function addVideoInPlaylist (req: express.Request, res: express.Response) | |||
304 | videoId: video.id | 304 | videoId: video.id |
305 | }, { transaction: t }) | 305 | }, { transaction: t }) |
306 | 306 | ||
307 | playlistElement.url = getVideoPlaylistElementActivityPubUrl(videoPlaylist, playlistElement) | 307 | playlistElement.url = getLocalVideoPlaylistElementActivityPubUrl(videoPlaylist, playlistElement) |
308 | await playlistElement.save({ transaction: t }) | 308 | await playlistElement.save({ transaction: t }) |
309 | 309 | ||
310 | videoPlaylist.changed('updatedAt', true) | 310 | videoPlaylist.changed('updatedAt', true) |
diff --git a/server/controllers/api/videos/import.ts b/server/controllers/api/videos/import.ts index 5840cd063..bc5fea7aa 100644 --- a/server/controllers/api/videos/import.ts +++ b/server/controllers/api/videos/import.ts | |||
@@ -28,7 +28,7 @@ import { getYoutubeDLInfo, getYoutubeDLSubs, YoutubeDLInfo } from '../../../help | |||
28 | import { CONFIG } from '../../../initializers/config' | 28 | import { CONFIG } from '../../../initializers/config' |
29 | import { MIMETYPES } from '../../../initializers/constants' | 29 | import { MIMETYPES } from '../../../initializers/constants' |
30 | import { sequelizeTypescript } from '../../../initializers/database' | 30 | import { sequelizeTypescript } from '../../../initializers/database' |
31 | import { getVideoActivityPubUrl } from '../../../lib/activitypub/url' | 31 | import { getLocalVideoActivityPubUrl } from '../../../lib/activitypub/url' |
32 | import { JobQueue } from '../../../lib/job-queue/job-queue' | 32 | import { JobQueue } from '../../../lib/job-queue/job-queue' |
33 | import { createVideoMiniatureFromExisting, createVideoMiniatureFromUrl } from '../../../lib/thumbnail' | 33 | import { createVideoMiniatureFromExisting, createVideoMiniatureFromUrl } from '../../../lib/thumbnail' |
34 | import { autoBlacklistVideoIfNeeded } from '../../../lib/video-blacklist' | 34 | import { autoBlacklistVideoIfNeeded } from '../../../lib/video-blacklist' |
@@ -250,7 +250,7 @@ function buildVideo (channelId: number, body: VideoImportCreate, importData: You | |||
250 | originallyPublishedAt: body.originallyPublishedAt || importData.originallyPublishedAt | 250 | originallyPublishedAt: body.originallyPublishedAt || importData.originallyPublishedAt |
251 | } | 251 | } |
252 | const video = new VideoModel(videoData) | 252 | const video = new VideoModel(videoData) |
253 | video.url = getVideoActivityPubUrl(video) | 253 | video.url = getLocalVideoActivityPubUrl(video) |
254 | 254 | ||
255 | return video | 255 | return video |
256 | } | 256 | } |
diff --git a/server/controllers/api/videos/index.ts b/server/controllers/api/videos/index.ts index bfebc54ed..b5ff2e72e 100644 --- a/server/controllers/api/videos/index.ts +++ b/server/controllers/api/videos/index.ts | |||
@@ -5,7 +5,7 @@ import toInt from 'validator/lib/toInt' | |||
5 | import { addOptimizeOrMergeAudioJob } from '@server/helpers/video' | 5 | import { addOptimizeOrMergeAudioJob } from '@server/helpers/video' |
6 | import { createTorrentAndSetInfoHash } from '@server/helpers/webtorrent' | 6 | import { createTorrentAndSetInfoHash } from '@server/helpers/webtorrent' |
7 | import { changeVideoChannelShare } from '@server/lib/activitypub/share' | 7 | import { changeVideoChannelShare } from '@server/lib/activitypub/share' |
8 | import { getVideoActivityPubUrl } from '@server/lib/activitypub/url' | 8 | import { getLocalVideoActivityPubUrl } from '@server/lib/activitypub/url' |
9 | import { LiveManager } from '@server/lib/live-manager' | 9 | import { LiveManager } from '@server/lib/live-manager' |
10 | import { buildLocalVideoFromReq, buildVideoThumbnailsFromReq, setVideoTags } from '@server/lib/video' | 10 | import { buildLocalVideoFromReq, buildVideoThumbnailsFromReq, setVideoTags } from '@server/lib/video' |
11 | import { getVideoFilePath } from '@server/lib/video-paths' | 11 | import { getVideoFilePath } from '@server/lib/video-paths' |
@@ -189,7 +189,7 @@ async function addVideo (req: express.Request, res: express.Response) { | |||
189 | videoData.duration = videoPhysicalFile['duration'] // duration was added by a previous middleware | 189 | videoData.duration = videoPhysicalFile['duration'] // duration was added by a previous middleware |
190 | 190 | ||
191 | const video = new VideoModel(videoData) as MVideoFullLight | 191 | const video = new VideoModel(videoData) as MVideoFullLight |
192 | video.url = getVideoActivityPubUrl(video) // We use the UUID, so set the URL after building the object | 192 | video.url = getLocalVideoActivityPubUrl(video) // We use the UUID, so set the URL after building the object |
193 | 193 | ||
194 | const videoFile = new VideoFileModel({ | 194 | const videoFile = new VideoFileModel({ |
195 | extname: extname(videoPhysicalFile.filename), | 195 | extname: extname(videoPhysicalFile.filename), |
diff --git a/server/controllers/api/videos/live.ts b/server/controllers/api/videos/live.ts index d438b6f3a..a6f00c1bd 100644 --- a/server/controllers/api/videos/live.ts +++ b/server/controllers/api/videos/live.ts | |||
@@ -3,7 +3,7 @@ import { v4 as uuidv4 } from 'uuid' | |||
3 | import { createReqFiles } from '@server/helpers/express-utils' | 3 | import { createReqFiles } from '@server/helpers/express-utils' |
4 | import { CONFIG } from '@server/initializers/config' | 4 | import { CONFIG } from '@server/initializers/config' |
5 | import { ASSETS_PATH, MIMETYPES } from '@server/initializers/constants' | 5 | import { ASSETS_PATH, MIMETYPES } from '@server/initializers/constants' |
6 | import { getVideoActivityPubUrl } from '@server/lib/activitypub/url' | 6 | import { getLocalVideoActivityPubUrl } from '@server/lib/activitypub/url' |
7 | import { federateVideoIfNeeded } from '@server/lib/activitypub/videos' | 7 | import { federateVideoIfNeeded } from '@server/lib/activitypub/videos' |
8 | import { Hooks } from '@server/lib/plugins/hooks' | 8 | import { Hooks } from '@server/lib/plugins/hooks' |
9 | import { buildLocalVideoFromReq, buildVideoThumbnailsFromReq, setVideoTags } from '@server/lib/video' | 9 | import { buildLocalVideoFromReq, buildVideoThumbnailsFromReq, setVideoTags } from '@server/lib/video' |
@@ -86,7 +86,7 @@ async function addLiveVideo (req: express.Request, res: express.Response) { | |||
86 | videoData.duration = 0 | 86 | videoData.duration = 0 |
87 | 87 | ||
88 | const video = new VideoModel(videoData) as MVideoDetails | 88 | const video = new VideoModel(videoData) as MVideoDetails |
89 | video.url = getVideoActivityPubUrl(video) // We use the UUID, so set the URL after building the object | 89 | video.url = getLocalVideoActivityPubUrl(video) // We use the UUID, so set the URL after building the object |
90 | 90 | ||
91 | const videoLive = new VideoLiveModel() | 91 | const videoLive = new VideoLiveModel() |
92 | videoLive.saveReplay = videoInfo.saveReplay || false | 92 | videoLive.saveReplay = videoInfo.saveReplay || false |
diff --git a/server/controllers/api/videos/rate.ts b/server/controllers/api/videos/rate.ts index 3ee365289..df1eddb4f 100644 --- a/server/controllers/api/videos/rate.ts +++ b/server/controllers/api/videos/rate.ts | |||
@@ -2,7 +2,7 @@ import * as express from 'express' | |||
2 | import { UserVideoRateUpdate } from '../../../../shared' | 2 | import { UserVideoRateUpdate } from '../../../../shared' |
3 | import { logger } from '../../../helpers/logger' | 3 | import { logger } from '../../../helpers/logger' |
4 | import { VIDEO_RATE_TYPES } from '../../../initializers/constants' | 4 | import { VIDEO_RATE_TYPES } from '../../../initializers/constants' |
5 | import { getRateUrl, sendVideoRateChange } from '../../../lib/activitypub/video-rates' | 5 | import { getLocalRateUrl, sendVideoRateChange } from '../../../lib/activitypub/video-rates' |
6 | import { asyncMiddleware, asyncRetryTransactionMiddleware, authenticate, videoUpdateRateValidator } from '../../../middlewares' | 6 | import { asyncMiddleware, asyncRetryTransactionMiddleware, authenticate, videoUpdateRateValidator } from '../../../middlewares' |
7 | import { AccountModel } from '../../../models/account/account' | 7 | import { AccountModel } from '../../../models/account/account' |
8 | import { AccountVideoRateModel } from '../../../models/account/account-video-rate' | 8 | import { AccountVideoRateModel } from '../../../models/account/account-video-rate' |
@@ -52,7 +52,7 @@ async function rateVideo (req: express.Request, res: express.Response) { | |||
52 | await previousRate.destroy(sequelizeOptions) | 52 | await previousRate.destroy(sequelizeOptions) |
53 | } else { // Update previous rate | 53 | } else { // Update previous rate |
54 | previousRate.type = rateType | 54 | previousRate.type = rateType |
55 | previousRate.url = getRateUrl(rateType, userAccount.Actor, videoInstance) | 55 | previousRate.url = getLocalRateUrl(rateType, userAccount.Actor, videoInstance) |
56 | await previousRate.save(sequelizeOptions) | 56 | await previousRate.save(sequelizeOptions) |
57 | } | 57 | } |
58 | } else if (rateType !== 'none') { // There was not a previous rate, insert a new one if there is a rate | 58 | } else if (rateType !== 'none') { // There was not a previous rate, insert a new one if there is a rate |
@@ -60,7 +60,7 @@ async function rateVideo (req: express.Request, res: express.Response) { | |||
60 | accountId: accountInstance.id, | 60 | accountId: accountInstance.id, |
61 | videoId: videoInstance.id, | 61 | videoId: videoInstance.id, |
62 | type: rateType, | 62 | type: rateType, |
63 | url: getRateUrl(rateType, userAccount.Actor, videoInstance) | 63 | url: getLocalRateUrl(rateType, userAccount.Actor, videoInstance) |
64 | } | 64 | } |
65 | 65 | ||
66 | await AccountVideoRateModel.create(query, sequelizeOptions) | 66 | await AccountVideoRateModel.create(query, sequelizeOptions) |
diff --git a/server/initializers/migrations/0100-activitypub.ts b/server/initializers/migrations/0100-activitypub.ts index 05fd37406..49309286c 100644 --- a/server/initializers/migrations/0100-activitypub.ts +++ b/server/initializers/migrations/0100-activitypub.ts | |||
@@ -1,7 +1,7 @@ | |||
1 | import * as Sequelize from 'sequelize' | 1 | import * as Sequelize from 'sequelize' |
2 | import { createPrivateAndPublicKeys } from '../../helpers/peertube-crypto' | 2 | import { createPrivateAndPublicKeys } from '../../helpers/peertube-crypto' |
3 | import { shareVideoByServerAndChannel } from '../../lib/activitypub/share' | 3 | import { shareVideoByServerAndChannel } from '../../lib/activitypub/share' |
4 | import { getVideoActivityPubUrl, getVideoChannelActivityPubUrl } from '../../lib/activitypub/url' | 4 | import { getLocalVideoActivityPubUrl, getLocalVideoChannelActivityPubUrl } from '../../lib/activitypub/url' |
5 | import { createLocalAccountWithoutKeys } from '../../lib/user' | 5 | import { createLocalAccountWithoutKeys } from '../../lib/user' |
6 | import { ApplicationModel } from '../../models/application/application' | 6 | import { ApplicationModel } from '../../models/application/application' |
7 | import { SERVER_ACTOR_NAME } from '../constants' | 7 | import { SERVER_ACTOR_NAME } from '../constants' |
@@ -132,7 +132,7 @@ async function up (utils: { | |||
132 | 132 | ||
133 | const videos = await db.Video.findAll() | 133 | const videos = await db.Video.findAll() |
134 | for (const video of videos) { | 134 | for (const video of videos) { |
135 | video.url = getVideoActivityPubUrl(video) | 135 | video.url = getLocalVideoActivityPubUrl(video) |
136 | await video.save() | 136 | await video.save() |
137 | } | 137 | } |
138 | 138 | ||
@@ -151,7 +151,7 @@ async function up (utils: { | |||
151 | 151 | ||
152 | const videoChannels = await db.VideoChannel.findAll() | 152 | const videoChannels = await db.VideoChannel.findAll() |
153 | for (const videoChannel of videoChannels) { | 153 | for (const videoChannel of videoChannels) { |
154 | videoChannel.url = getVideoChannelActivityPubUrl(videoChannel) | 154 | videoChannel.url = getLocalVideoChannelActivityPubUrl(videoChannel) |
155 | await videoChannel.save() | 155 | await videoChannel.save() |
156 | } | 156 | } |
157 | 157 | ||
diff --git a/server/lib/activitypub/process/process-dislike.ts b/server/lib/activitypub/process/process-dislike.ts index 0cd204501..635c8bfcc 100644 --- a/server/lib/activitypub/process/process-dislike.ts +++ b/server/lib/activitypub/process/process-dislike.ts | |||
@@ -3,11 +3,10 @@ import { DislikeObject } from '../../../../shared/models/activitypub/objects' | |||
3 | import { retryTransactionWrapper } from '../../../helpers/database-utils' | 3 | import { retryTransactionWrapper } from '../../../helpers/database-utils' |
4 | import { sequelizeTypescript } from '../../../initializers/database' | 4 | import { sequelizeTypescript } from '../../../initializers/database' |
5 | import { AccountVideoRateModel } from '../../../models/account/account-video-rate' | 5 | import { AccountVideoRateModel } from '../../../models/account/account-video-rate' |
6 | import { getOrCreateVideoAndAccountAndChannel } from '../videos' | ||
7 | import { forwardVideoRelatedActivity } from '../send/utils' | ||
8 | import { getVideoDislikeActivityPubUrl } from '../url' | ||
9 | import { APProcessorOptions } from '../../../types/activitypub-processor.model' | 6 | import { APProcessorOptions } from '../../../types/activitypub-processor.model' |
10 | import { MActorSignature } from '../../../types/models' | 7 | import { MActorSignature } from '../../../types/models' |
8 | import { forwardVideoRelatedActivity } from '../send/utils' | ||
9 | import { getOrCreateVideoAndAccountAndChannel } from '../videos' | ||
11 | 10 | ||
12 | async function processDislikeActivity (options: APProcessorOptions<ActivityCreate | ActivityDislike>) { | 11 | async function processDislikeActivity (options: APProcessorOptions<ActivityCreate | ActivityDislike>) { |
13 | const { activity, byActor } = options | 12 | const { activity, byActor } = options |
@@ -23,7 +22,10 @@ export { | |||
23 | // --------------------------------------------------------------------------- | 22 | // --------------------------------------------------------------------------- |
24 | 23 | ||
25 | async function processDislike (activity: ActivityCreate | ActivityDislike, byActor: MActorSignature) { | 24 | async function processDislike (activity: ActivityCreate | ActivityDislike, byActor: MActorSignature) { |
26 | const dislikeObject = activity.type === 'Dislike' ? activity.object : (activity.object as DislikeObject).object | 25 | const dislikeObject = activity.type === 'Dislike' |
26 | ? activity.object | ||
27 | : (activity.object as DislikeObject).object | ||
28 | |||
27 | const byAccount = byActor.Account | 29 | const byAccount = byActor.Account |
28 | 30 | ||
29 | if (!byAccount) throw new Error('Cannot create dislike with the non account actor ' + byActor.url) | 31 | if (!byAccount) throw new Error('Cannot create dislike with the non account actor ' + byActor.url) |
@@ -31,9 +33,7 @@ async function processDislike (activity: ActivityCreate | ActivityDislike, byAct | |||
31 | const { video } = await getOrCreateVideoAndAccountAndChannel({ videoObject: dislikeObject }) | 33 | const { video } = await getOrCreateVideoAndAccountAndChannel({ videoObject: dislikeObject }) |
32 | 34 | ||
33 | return sequelizeTypescript.transaction(async t => { | 35 | return sequelizeTypescript.transaction(async t => { |
34 | const url = getVideoDislikeActivityPubUrl(byActor, video) | 36 | const existingRate = await AccountVideoRateModel.loadByAccountAndVideoOrUrl(byAccount.id, video.id, activity.id) |
35 | |||
36 | const existingRate = await AccountVideoRateModel.loadByAccountAndVideoOrUrl(byAccount.id, video.id, url) | ||
37 | if (existingRate && existingRate.type === 'dislike') return | 37 | if (existingRate && existingRate.type === 'dislike') return |
38 | 38 | ||
39 | await video.increment('dislikes', { transaction: t }) | 39 | await video.increment('dislikes', { transaction: t }) |
@@ -46,7 +46,7 @@ async function processDislike (activity: ActivityCreate | ActivityDislike, byAct | |||
46 | rate.type = 'dislike' | 46 | rate.type = 'dislike' |
47 | rate.videoId = video.id | 47 | rate.videoId = video.id |
48 | rate.accountId = byAccount.id | 48 | rate.accountId = byAccount.id |
49 | rate.url = url | 49 | rate.url = activity.id |
50 | 50 | ||
51 | await rate.save({ transaction: t }) | 51 | await rate.save({ transaction: t }) |
52 | 52 | ||
diff --git a/server/lib/activitypub/process/process-follow.ts b/server/lib/activitypub/process/process-follow.ts index 7eb7e828d..076ad9cf4 100644 --- a/server/lib/activitypub/process/process-follow.ts +++ b/server/lib/activitypub/process/process-follow.ts | |||
@@ -15,9 +15,11 @@ import { getServerActor } from '@server/models/application/application' | |||
15 | 15 | ||
16 | async function processFollowActivity (options: APProcessorOptions<ActivityFollow>) { | 16 | async function processFollowActivity (options: APProcessorOptions<ActivityFollow>) { |
17 | const { activity, byActor } = options | 17 | const { activity, byActor } = options |
18 | const activityObject = getAPId(activity.object) | ||
19 | 18 | ||
20 | return retryTransactionWrapper(processFollow, byActor, activityObject) | 19 | const activityId = activity.id |
20 | const objectId = getAPId(activity.object) | ||
21 | |||
22 | return retryTransactionWrapper(processFollow, byActor, activityId, objectId) | ||
21 | } | 23 | } |
22 | 24 | ||
23 | // --------------------------------------------------------------------------- | 25 | // --------------------------------------------------------------------------- |
@@ -28,7 +30,7 @@ export { | |||
28 | 30 | ||
29 | // --------------------------------------------------------------------------- | 31 | // --------------------------------------------------------------------------- |
30 | 32 | ||
31 | async function processFollow (byActor: MActorSignature, targetActorURL: string) { | 33 | async function processFollow (byActor: MActorSignature, activityId: string, targetActorURL: string) { |
32 | const { actorFollow, created, isFollowingInstance, targetActor } = await sequelizeTypescript.transaction(async t => { | 34 | const { actorFollow, created, isFollowingInstance, targetActor } = await sequelizeTypescript.transaction(async t => { |
33 | const targetActor = await ActorModel.loadByUrlAndPopulateAccountAndChannel(targetActorURL, t) | 35 | const targetActor = await ActorModel.loadByUrlAndPopulateAccountAndChannel(targetActorURL, t) |
34 | 36 | ||
@@ -41,7 +43,7 @@ async function processFollow (byActor: MActorSignature, targetActorURL: string) | |||
41 | if (isFollowingInstance && CONFIG.FOLLOWERS.INSTANCE.ENABLED === false) { | 43 | if (isFollowingInstance && CONFIG.FOLLOWERS.INSTANCE.ENABLED === false) { |
42 | logger.info('Rejecting %s because instance followers are disabled.', targetActor.url) | 44 | logger.info('Rejecting %s because instance followers are disabled.', targetActor.url) |
43 | 45 | ||
44 | await sendReject(byActor, targetActor) | 46 | await sendReject(activityId, byActor, targetActor) |
45 | 47 | ||
46 | return { actorFollow: undefined as MActorFollowActors } | 48 | return { actorFollow: undefined as MActorFollowActors } |
47 | } | 49 | } |
@@ -54,7 +56,11 @@ async function processFollow (byActor: MActorSignature, targetActorURL: string) | |||
54 | defaults: { | 56 | defaults: { |
55 | actorId: byActor.id, | 57 | actorId: byActor.id, |
56 | targetActorId: targetActor.id, | 58 | targetActorId: targetActor.id, |
57 | state: CONFIG.FOLLOWERS.INSTANCE.MANUAL_APPROVAL ? 'pending' : 'accepted' | 59 | url: activityId, |
60 | |||
61 | state: CONFIG.FOLLOWERS.INSTANCE.MANUAL_APPROVAL | ||
62 | ? 'pending' | ||
63 | : 'accepted' | ||
58 | }, | 64 | }, |
59 | transaction: t | 65 | transaction: t |
60 | }) | 66 | }) |
diff --git a/server/lib/activitypub/process/process-like.ts b/server/lib/activitypub/process/process-like.ts index b800a5618..6acc097b1 100644 --- a/server/lib/activitypub/process/process-like.ts +++ b/server/lib/activitypub/process/process-like.ts | |||
@@ -1,13 +1,12 @@ | |||
1 | import { ActivityLike } from '../../../../shared/models/activitypub' | 1 | import { ActivityLike } from '../../../../shared/models/activitypub' |
2 | import { getAPId } from '../../../helpers/activitypub' | ||
2 | import { retryTransactionWrapper } from '../../../helpers/database-utils' | 3 | import { retryTransactionWrapper } from '../../../helpers/database-utils' |
3 | import { sequelizeTypescript } from '../../../initializers/database' | 4 | import { sequelizeTypescript } from '../../../initializers/database' |
4 | import { AccountVideoRateModel } from '../../../models/account/account-video-rate' | 5 | import { AccountVideoRateModel } from '../../../models/account/account-video-rate' |
5 | import { forwardVideoRelatedActivity } from '../send/utils' | ||
6 | import { getOrCreateVideoAndAccountAndChannel } from '../videos' | ||
7 | import { getVideoLikeActivityPubUrl } from '../url' | ||
8 | import { getAPId } from '../../../helpers/activitypub' | ||
9 | import { APProcessorOptions } from '../../../types/activitypub-processor.model' | 6 | import { APProcessorOptions } from '../../../types/activitypub-processor.model' |
10 | import { MActorSignature } from '../../../types/models' | 7 | import { MActorSignature } from '../../../types/models' |
8 | import { forwardVideoRelatedActivity } from '../send/utils' | ||
9 | import { getOrCreateVideoAndAccountAndChannel } from '../videos' | ||
11 | 10 | ||
12 | async function processLikeActivity (options: APProcessorOptions<ActivityLike>) { | 11 | async function processLikeActivity (options: APProcessorOptions<ActivityLike>) { |
13 | const { activity, byActor } = options | 12 | const { activity, byActor } = options |
@@ -31,9 +30,7 @@ async function processLikeVideo (byActor: MActorSignature, activity: ActivityLik | |||
31 | const { video } = await getOrCreateVideoAndAccountAndChannel({ videoObject: videoUrl }) | 30 | const { video } = await getOrCreateVideoAndAccountAndChannel({ videoObject: videoUrl }) |
32 | 31 | ||
33 | return sequelizeTypescript.transaction(async t => { | 32 | return sequelizeTypescript.transaction(async t => { |
34 | const url = getVideoLikeActivityPubUrl(byActor, video) | 33 | const existingRate = await AccountVideoRateModel.loadByAccountAndVideoOrUrl(byAccount.id, video.id, activity.id) |
35 | |||
36 | const existingRate = await AccountVideoRateModel.loadByAccountAndVideoOrUrl(byAccount.id, video.id, url) | ||
37 | if (existingRate && existingRate.type === 'like') return | 34 | if (existingRate && existingRate.type === 'like') return |
38 | 35 | ||
39 | if (existingRate && existingRate.type === 'dislike') { | 36 | if (existingRate && existingRate.type === 'dislike') { |
@@ -46,7 +43,7 @@ async function processLikeVideo (byActor: MActorSignature, activity: ActivityLik | |||
46 | rate.type = 'like' | 43 | rate.type = 'like' |
47 | rate.videoId = video.id | 44 | rate.videoId = video.id |
48 | rate.accountId = byAccount.id | 45 | rate.accountId = byAccount.id |
49 | rate.url = url | 46 | rate.url = activity.id |
50 | 47 | ||
51 | await rate.save({ transaction: t }) | 48 | await rate.save({ transaction: t }) |
52 | 49 | ||
diff --git a/server/lib/activitypub/send/send-accept.ts b/server/lib/activitypub/send/send-accept.ts index 50e192bdd..bb387e2c0 100644 --- a/server/lib/activitypub/send/send-accept.ts +++ b/server/lib/activitypub/send/send-accept.ts | |||
@@ -1,9 +1,9 @@ | |||
1 | import { ActivityAccept, ActivityFollow } from '../../../../shared/models/activitypub' | 1 | import { ActivityAccept, ActivityFollow } from '../../../../shared/models/activitypub' |
2 | import { getActorFollowAcceptActivityPubUrl, getActorFollowActivityPubUrl } from '../url' | ||
3 | import { unicastTo } from './utils' | ||
4 | import { buildFollowActivity } from './send-follow' | ||
5 | import { logger } from '../../../helpers/logger' | 2 | import { logger } from '../../../helpers/logger' |
6 | import { MActor, MActorFollowActors } from '../../../types/models' | 3 | import { MActor, MActorFollowActors } from '../../../types/models' |
4 | import { getLocalActorFollowAcceptActivityPubUrl } from '../url' | ||
5 | import { buildFollowActivity } from './send-follow' | ||
6 | import { unicastTo } from './utils' | ||
7 | 7 | ||
8 | function sendAccept (actorFollow: MActorFollowActors) { | 8 | function sendAccept (actorFollow: MActorFollowActors) { |
9 | const follower = actorFollow.ActorFollower | 9 | const follower = actorFollow.ActorFollower |
@@ -16,10 +16,9 @@ function sendAccept (actorFollow: MActorFollowActors) { | |||
16 | 16 | ||
17 | logger.info('Creating job to accept follower %s.', follower.url) | 17 | logger.info('Creating job to accept follower %s.', follower.url) |
18 | 18 | ||
19 | const followUrl = getActorFollowActivityPubUrl(follower, me) | 19 | const followData = buildFollowActivity(actorFollow.url, follower, me) |
20 | const followData = buildFollowActivity(followUrl, follower, me) | ||
21 | 20 | ||
22 | const url = getActorFollowAcceptActivityPubUrl(actorFollow) | 21 | const url = getLocalActorFollowAcceptActivityPubUrl(actorFollow) |
23 | const data = buildAcceptActivity(url, me, followData) | 22 | const data = buildAcceptActivity(url, me, followData) |
24 | 23 | ||
25 | return unicastTo(data, me, follower.inboxUrl) | 24 | return unicastTo(data, me, follower.inboxUrl) |
diff --git a/server/lib/activitypub/send/send-dislike.ts b/server/lib/activitypub/send/send-dislike.ts index 1bb7dc937..274230535 100644 --- a/server/lib/activitypub/send/send-dislike.ts +++ b/server/lib/activitypub/send/send-dislike.ts | |||
@@ -1,5 +1,5 @@ | |||
1 | import { Transaction } from 'sequelize' | 1 | import { Transaction } from 'sequelize' |
2 | import { getVideoDislikeActivityPubUrl } from '../url' | 2 | import { getVideoDislikeActivityPubUrlByLocalActor } from '../url' |
3 | import { logger } from '../../../helpers/logger' | 3 | import { logger } from '../../../helpers/logger' |
4 | import { ActivityAudience, ActivityDislike } from '../../../../shared/models/activitypub' | 4 | import { ActivityAudience, ActivityDislike } from '../../../../shared/models/activitypub' |
5 | import { sendVideoRelatedActivity } from './utils' | 5 | import { sendVideoRelatedActivity } from './utils' |
@@ -10,7 +10,7 @@ function sendDislike (byActor: MActor, video: MVideoAccountLight, t: Transaction | |||
10 | logger.info('Creating job to dislike %s.', video.url) | 10 | logger.info('Creating job to dislike %s.', video.url) |
11 | 11 | ||
12 | const activityBuilder = (audience: ActivityAudience) => { | 12 | const activityBuilder = (audience: ActivityAudience) => { |
13 | const url = getVideoDislikeActivityPubUrl(byActor, video) | 13 | const url = getVideoDislikeActivityPubUrlByLocalActor(byActor, video) |
14 | 14 | ||
15 | return buildDislikeActivity(url, byActor, video, audience) | 15 | return buildDislikeActivity(url, byActor, video, audience) |
16 | } | 16 | } |
diff --git a/server/lib/activitypub/send/send-flag.ts b/server/lib/activitypub/send/send-flag.ts index 821637ec8..b0483b5a0 100644 --- a/server/lib/activitypub/send/send-flag.ts +++ b/server/lib/activitypub/send/send-flag.ts | |||
@@ -3,13 +3,13 @@ import { ActivityAudience, ActivityFlag } from '../../../../shared/models/activi | |||
3 | import { logger } from '../../../helpers/logger' | 3 | import { logger } from '../../../helpers/logger' |
4 | import { MAbuseAP, MAccountLight, MActor } from '../../../types/models' | 4 | import { MAbuseAP, MAccountLight, MActor } from '../../../types/models' |
5 | import { audiencify, getAudience } from '../audience' | 5 | import { audiencify, getAudience } from '../audience' |
6 | import { getAbuseActivityPubUrl } from '../url' | 6 | import { getLocalAbuseActivityPubUrl } from '../url' |
7 | import { unicastTo } from './utils' | 7 | import { unicastTo } from './utils' |
8 | 8 | ||
9 | function sendAbuse (byActor: MActor, abuse: MAbuseAP, flaggedAccount: MAccountLight, t: Transaction) { | 9 | function sendAbuse (byActor: MActor, abuse: MAbuseAP, flaggedAccount: MAccountLight, t: Transaction) { |
10 | if (!flaggedAccount.Actor.serverId) return // Local user | 10 | if (!flaggedAccount.Actor.serverId) return // Local user |
11 | 11 | ||
12 | const url = getAbuseActivityPubUrl(abuse) | 12 | const url = getLocalAbuseActivityPubUrl(abuse) |
13 | 13 | ||
14 | logger.info('Creating job to send abuse %s.', url) | 14 | logger.info('Creating job to send abuse %s.', url) |
15 | 15 | ||
diff --git a/server/lib/activitypub/send/send-follow.ts b/server/lib/activitypub/send/send-follow.ts index 08f1d83f9..9219640dd 100644 --- a/server/lib/activitypub/send/send-follow.ts +++ b/server/lib/activitypub/send/send-follow.ts | |||
@@ -1,9 +1,8 @@ | |||
1 | import { Transaction } from 'sequelize' | ||
1 | import { ActivityFollow } from '../../../../shared/models/activitypub' | 2 | import { ActivityFollow } from '../../../../shared/models/activitypub' |
2 | import { getActorFollowActivityPubUrl } from '../url' | ||
3 | import { unicastTo } from './utils' | ||
4 | import { logger } from '../../../helpers/logger' | 3 | import { logger } from '../../../helpers/logger' |
5 | import { Transaction } from 'sequelize' | ||
6 | import { MActor, MActorFollowActors } from '../../../types/models' | 4 | import { MActor, MActorFollowActors } from '../../../types/models' |
5 | import { unicastTo } from './utils' | ||
7 | 6 | ||
8 | function sendFollow (actorFollow: MActorFollowActors, t: Transaction) { | 7 | function sendFollow (actorFollow: MActorFollowActors, t: Transaction) { |
9 | const me = actorFollow.ActorFollower | 8 | const me = actorFollow.ActorFollower |
@@ -14,8 +13,7 @@ function sendFollow (actorFollow: MActorFollowActors, t: Transaction) { | |||
14 | 13 | ||
15 | logger.info('Creating job to send follow request to %s.', following.url) | 14 | logger.info('Creating job to send follow request to %s.', following.url) |
16 | 15 | ||
17 | const url = getActorFollowActivityPubUrl(me, following) | 16 | const data = buildFollowActivity(actorFollow.url, me, following) |
18 | const data = buildFollowActivity(url, me, following) | ||
19 | 17 | ||
20 | t.afterCommit(() => unicastTo(data, me, following.inboxUrl)) | 18 | t.afterCommit(() => unicastTo(data, me, following.inboxUrl)) |
21 | } | 19 | } |
diff --git a/server/lib/activitypub/send/send-like.ts b/server/lib/activitypub/send/send-like.ts index 29fcfc404..ed6dfcf56 100644 --- a/server/lib/activitypub/send/send-like.ts +++ b/server/lib/activitypub/send/send-like.ts | |||
@@ -1,6 +1,6 @@ | |||
1 | import { Transaction } from 'sequelize' | 1 | import { Transaction } from 'sequelize' |
2 | import { ActivityAudience, ActivityLike } from '../../../../shared/models/activitypub' | 2 | import { ActivityAudience, ActivityLike } from '../../../../shared/models/activitypub' |
3 | import { getVideoLikeActivityPubUrl } from '../url' | 3 | import { getVideoLikeActivityPubUrlByLocalActor } from '../url' |
4 | import { sendVideoRelatedActivity } from './utils' | 4 | import { sendVideoRelatedActivity } from './utils' |
5 | import { audiencify, getAudience } from '../audience' | 5 | import { audiencify, getAudience } from '../audience' |
6 | import { logger } from '../../../helpers/logger' | 6 | import { logger } from '../../../helpers/logger' |
@@ -10,7 +10,7 @@ function sendLike (byActor: MActor, video: MVideoAccountLight, t: Transaction) { | |||
10 | logger.info('Creating job to like %s.', video.url) | 10 | logger.info('Creating job to like %s.', video.url) |
11 | 11 | ||
12 | const activityBuilder = (audience: ActivityAudience) => { | 12 | const activityBuilder = (audience: ActivityAudience) => { |
13 | const url = getVideoLikeActivityPubUrl(byActor, video) | 13 | const url = getVideoLikeActivityPubUrlByLocalActor(byActor, video) |
14 | 14 | ||
15 | return buildLikeActivity(url, byActor, video, audience) | 15 | return buildLikeActivity(url, byActor, video, audience) |
16 | } | 16 | } |
diff --git a/server/lib/activitypub/send/send-reject.ts b/server/lib/activitypub/send/send-reject.ts index befbcb8da..8d74a7848 100644 --- a/server/lib/activitypub/send/send-reject.ts +++ b/server/lib/activitypub/send/send-reject.ts | |||
@@ -1,11 +1,11 @@ | |||
1 | import { ActivityFollow, ActivityReject } from '../../../../shared/models/activitypub' | 1 | import { ActivityFollow, ActivityReject } from '../../../../shared/models/activitypub' |
2 | import { getActorFollowActivityPubUrl, getActorFollowRejectActivityPubUrl } from '../url' | ||
3 | import { unicastTo } from './utils' | ||
4 | import { buildFollowActivity } from './send-follow' | ||
5 | import { logger } from '../../../helpers/logger' | 2 | import { logger } from '../../../helpers/logger' |
6 | import { MActor } from '../../../types/models' | 3 | import { MActor } from '../../../types/models' |
4 | import { getLocalActorFollowRejectActivityPubUrl } from '../url' | ||
5 | import { buildFollowActivity } from './send-follow' | ||
6 | import { unicastTo } from './utils' | ||
7 | 7 | ||
8 | function sendReject (follower: MActor, following: MActor) { | 8 | function sendReject (followUrl: string, follower: MActor, following: MActor) { |
9 | if (!follower.serverId) { // This should never happen | 9 | if (!follower.serverId) { // This should never happen |
10 | logger.warn('Do not sending reject to local follower.') | 10 | logger.warn('Do not sending reject to local follower.') |
11 | return | 11 | return |
@@ -13,10 +13,9 @@ function sendReject (follower: MActor, following: MActor) { | |||
13 | 13 | ||
14 | logger.info('Creating job to reject follower %s.', follower.url) | 14 | logger.info('Creating job to reject follower %s.', follower.url) |
15 | 15 | ||
16 | const followUrl = getActorFollowActivityPubUrl(follower, following) | ||
17 | const followData = buildFollowActivity(followUrl, follower, following) | 16 | const followData = buildFollowActivity(followUrl, follower, following) |
18 | 17 | ||
19 | const url = getActorFollowRejectActivityPubUrl(follower, following) | 18 | const url = getLocalActorFollowRejectActivityPubUrl(follower, following) |
20 | const data = buildRejectActivity(url, following, followData) | 19 | const data = buildRejectActivity(url, following, followData) |
21 | 20 | ||
22 | return unicastTo(data, following, follower.inboxUrl) | 21 | return unicastTo(data, following, follower.inboxUrl) |
diff --git a/server/lib/activitypub/send/send-undo.ts b/server/lib/activitypub/send/send-undo.ts index 6ed343300..352c158fd 100644 --- a/server/lib/activitypub/send/send-undo.ts +++ b/server/lib/activitypub/send/send-undo.ts | |||
@@ -8,18 +8,11 @@ import { | |||
8 | ActivityLike, | 8 | ActivityLike, |
9 | ActivityUndo | 9 | ActivityUndo |
10 | } from '../../../../shared/models/activitypub' | 10 | } from '../../../../shared/models/activitypub' |
11 | import { VideoModel } from '../../../models/video/video' | ||
12 | import { getActorFollowActivityPubUrl, getUndoActivityPubUrl, getVideoDislikeActivityPubUrl, getVideoLikeActivityPubUrl } from '../url' | ||
13 | import { broadcastToFollowers, sendVideoRelatedActivity, unicastTo } from './utils' | ||
14 | import { audiencify, getAudience } from '../audience' | ||
15 | import { buildCreateActivity } from './send-create' | ||
16 | import { buildFollowActivity } from './send-follow' | ||
17 | import { buildLikeActivity } from './send-like' | ||
18 | import { buildAnnounceWithVideoAudience } from './send-announce' | ||
19 | import { logger } from '../../../helpers/logger' | 11 | import { logger } from '../../../helpers/logger' |
20 | import { buildDislikeActivity } from './send-dislike' | 12 | import { VideoModel } from '../../../models/video/video' |
21 | import { | 13 | import { |
22 | MActor, MActorAudience, | 14 | MActor, |
15 | MActorAudience, | ||
23 | MActorFollowActors, | 16 | MActorFollowActors, |
24 | MActorLight, | 17 | MActorLight, |
25 | MVideo, | 18 | MVideo, |
@@ -27,6 +20,14 @@ import { | |||
27 | MVideoRedundancyVideo, | 20 | MVideoRedundancyVideo, |
28 | MVideoShare | 21 | MVideoShare |
29 | } from '../../../types/models' | 22 | } from '../../../types/models' |
23 | import { audiencify, getAudience } from '../audience' | ||
24 | import { getUndoActivityPubUrl, getVideoDislikeActivityPubUrlByLocalActor, getVideoLikeActivityPubUrlByLocalActor } from '../url' | ||
25 | import { buildAnnounceWithVideoAudience } from './send-announce' | ||
26 | import { buildCreateActivity } from './send-create' | ||
27 | import { buildDislikeActivity } from './send-dislike' | ||
28 | import { buildFollowActivity } from './send-follow' | ||
29 | import { buildLikeActivity } from './send-like' | ||
30 | import { broadcastToFollowers, sendVideoRelatedActivity, unicastTo } from './utils' | ||
30 | 31 | ||
31 | function sendUndoFollow (actorFollow: MActorFollowActors, t: Transaction) { | 32 | function sendUndoFollow (actorFollow: MActorFollowActors, t: Transaction) { |
32 | const me = actorFollow.ActorFollower | 33 | const me = actorFollow.ActorFollower |
@@ -37,10 +38,9 @@ function sendUndoFollow (actorFollow: MActorFollowActors, t: Transaction) { | |||
37 | 38 | ||
38 | logger.info('Creating job to send an unfollow request to %s.', following.url) | 39 | logger.info('Creating job to send an unfollow request to %s.', following.url) |
39 | 40 | ||
40 | const followUrl = getActorFollowActivityPubUrl(me, following) | 41 | const undoUrl = getUndoActivityPubUrl(actorFollow.url) |
41 | const undoUrl = getUndoActivityPubUrl(followUrl) | ||
42 | 42 | ||
43 | const followActivity = buildFollowActivity(followUrl, me, following) | 43 | const followActivity = buildFollowActivity(actorFollow.url, me, following) |
44 | const undoActivity = undoActivityData(undoUrl, me, followActivity) | 44 | const undoActivity = undoActivityData(undoUrl, me, followActivity) |
45 | 45 | ||
46 | t.afterCommit(() => unicastTo(undoActivity, me, following.inboxUrl)) | 46 | t.afterCommit(() => unicastTo(undoActivity, me, following.inboxUrl)) |
@@ -61,7 +61,7 @@ async function sendUndoAnnounce (byActor: MActorLight, videoShare: MVideoShare, | |||
61 | async function sendUndoLike (byActor: MActor, video: MVideoAccountLight, t: Transaction) { | 61 | async function sendUndoLike (byActor: MActor, video: MVideoAccountLight, t: Transaction) { |
62 | logger.info('Creating job to undo a like of video %s.', video.url) | 62 | logger.info('Creating job to undo a like of video %s.', video.url) |
63 | 63 | ||
64 | const likeUrl = getVideoLikeActivityPubUrl(byActor, video) | 64 | const likeUrl = getVideoLikeActivityPubUrlByLocalActor(byActor, video) |
65 | const likeActivity = buildLikeActivity(likeUrl, byActor, video) | 65 | const likeActivity = buildLikeActivity(likeUrl, byActor, video) |
66 | 66 | ||
67 | return sendUndoVideoRelatedActivity({ byActor, video, url: likeUrl, activity: likeActivity, transaction: t }) | 67 | return sendUndoVideoRelatedActivity({ byActor, video, url: likeUrl, activity: likeActivity, transaction: t }) |
@@ -70,7 +70,7 @@ async function sendUndoLike (byActor: MActor, video: MVideoAccountLight, t: Tran | |||
70 | async function sendUndoDislike (byActor: MActor, video: MVideoAccountLight, t: Transaction) { | 70 | async function sendUndoDislike (byActor: MActor, video: MVideoAccountLight, t: Transaction) { |
71 | logger.info('Creating job to undo a dislike of video %s.', video.url) | 71 | logger.info('Creating job to undo a dislike of video %s.', video.url) |
72 | 72 | ||
73 | const dislikeUrl = getVideoDislikeActivityPubUrl(byActor, video) | 73 | const dislikeUrl = getVideoDislikeActivityPubUrlByLocalActor(byActor, video) |
74 | const dislikeActivity = buildDislikeActivity(dislikeUrl, byActor, video) | 74 | const dislikeActivity = buildDislikeActivity(dislikeUrl, byActor, video) |
75 | 75 | ||
76 | return sendUndoVideoRelatedActivity({ byActor, video, url: dislikeUrl, activity: dislikeActivity, transaction: t }) | 76 | return sendUndoVideoRelatedActivity({ byActor, video, url: dislikeUrl, activity: dislikeActivity, transaction: t }) |
diff --git a/server/lib/activitypub/send/send-view.ts b/server/lib/activitypub/send/send-view.ts index 3358188a2..9254dc7c5 100644 --- a/server/lib/activitypub/send/send-view.ts +++ b/server/lib/activitypub/send/send-view.ts | |||
@@ -1,17 +1,17 @@ | |||
1 | import { Transaction } from 'sequelize' | 1 | import { Transaction } from 'sequelize' |
2 | import { MActorAudience, MVideoImmutable, MVideoUrl } from '@server/types/models' | ||
2 | import { ActivityAudience, ActivityView } from '../../../../shared/models/activitypub' | 3 | import { ActivityAudience, ActivityView } from '../../../../shared/models/activitypub' |
4 | import { logger } from '../../../helpers/logger' | ||
3 | import { ActorModel } from '../../../models/activitypub/actor' | 5 | import { ActorModel } from '../../../models/activitypub/actor' |
4 | import { getVideoLikeActivityPubUrl } from '../url' | ||
5 | import { sendVideoRelatedActivity } from './utils' | ||
6 | import { audiencify, getAudience } from '../audience' | 6 | import { audiencify, getAudience } from '../audience' |
7 | import { logger } from '../../../helpers/logger' | 7 | import { getLocalVideoViewActivityPubUrl } from '../url' |
8 | import { MActorAudience, MVideoImmutable, MVideoUrl } from '@server/types/models' | 8 | import { sendVideoRelatedActivity } from './utils' |
9 | 9 | ||
10 | async function sendView (byActor: ActorModel, video: MVideoImmutable, t: Transaction) { | 10 | async function sendView (byActor: ActorModel, video: MVideoImmutable, t: Transaction) { |
11 | logger.info('Creating job to send view of %s.', video.url) | 11 | logger.info('Creating job to send view of %s.', video.url) |
12 | 12 | ||
13 | const activityBuilder = (audience: ActivityAudience) => { | 13 | const activityBuilder = (audience: ActivityAudience) => { |
14 | const url = getVideoLikeActivityPubUrl(byActor, video) | 14 | const url = getLocalVideoViewActivityPubUrl(byActor, video) |
15 | 15 | ||
16 | return buildViewActivity(url, byActor, video, audience) | 16 | return buildViewActivity(url, byActor, video, audience) |
17 | } | 17 | } |
diff --git a/server/lib/activitypub/share.ts b/server/lib/activitypub/share.ts index 5e426f5db..1f8a8f3c4 100644 --- a/server/lib/activitypub/share.ts +++ b/server/lib/activitypub/share.ts | |||
@@ -1,7 +1,7 @@ | |||
1 | import { Transaction } from 'sequelize' | 1 | import { Transaction } from 'sequelize' |
2 | import { VideoShareModel } from '../../models/video/video-share' | 2 | import { VideoShareModel } from '../../models/video/video-share' |
3 | import { sendUndoAnnounce, sendVideoAnnounce } from './send' | 3 | import { sendUndoAnnounce, sendVideoAnnounce } from './send' |
4 | import { getVideoAnnounceActivityPubUrl } from './url' | 4 | import { getLocalVideoAnnounceActivityPubUrl } from './url' |
5 | import * as Bluebird from 'bluebird' | 5 | import * as Bluebird from 'bluebird' |
6 | import { doRequest } from '../../helpers/requests' | 6 | import { doRequest } from '../../helpers/requests' |
7 | import { getOrCreateActorAndServerAndModel } from './actor' | 7 | import { getOrCreateActorAndServerAndModel } from './actor' |
@@ -74,7 +74,7 @@ export { | |||
74 | async function shareByServer (video: MVideo, t: Transaction) { | 74 | async function shareByServer (video: MVideo, t: Transaction) { |
75 | const serverActor = await getServerActor() | 75 | const serverActor = await getServerActor() |
76 | 76 | ||
77 | const serverShareUrl = getVideoAnnounceActivityPubUrl(serverActor, video) | 77 | const serverShareUrl = getLocalVideoAnnounceActivityPubUrl(serverActor, video) |
78 | const [ serverShare ] = await VideoShareModel.findOrCreate({ | 78 | const [ serverShare ] = await VideoShareModel.findOrCreate({ |
79 | defaults: { | 79 | defaults: { |
80 | actorId: serverActor.id, | 80 | actorId: serverActor.id, |
@@ -91,7 +91,7 @@ async function shareByServer (video: MVideo, t: Transaction) { | |||
91 | } | 91 | } |
92 | 92 | ||
93 | async function shareByVideoChannel (video: MVideoAccountLight, t: Transaction) { | 93 | async function shareByVideoChannel (video: MVideoAccountLight, t: Transaction) { |
94 | const videoChannelShareUrl = getVideoAnnounceActivityPubUrl(video.VideoChannel.Actor, video) | 94 | const videoChannelShareUrl = getLocalVideoAnnounceActivityPubUrl(video.VideoChannel.Actor, video) |
95 | const [ videoChannelShare ] = await VideoShareModel.findOrCreate({ | 95 | const [ videoChannelShare ] = await VideoShareModel.findOrCreate({ |
96 | defaults: { | 96 | defaults: { |
97 | actorId: video.VideoChannel.actorId, | 97 | actorId: video.VideoChannel.actorId, |
diff --git a/server/lib/activitypub/url.ts b/server/lib/activitypub/url.ts index 58030be2c..ad6a1d1fd 100644 --- a/server/lib/activitypub/url.ts +++ b/server/lib/activitypub/url.ts | |||
@@ -1,102 +1,102 @@ | |||
1 | import { WEBSERVER } from '../../initializers/constants' | 1 | import { WEBSERVER } from '../../initializers/constants' |
2 | import { | 2 | import { |
3 | MAbuseId, | ||
3 | MActor, | 4 | MActor, |
4 | MActorFollowActors, | 5 | MActorFollowActors, |
5 | MActorId, | 6 | MActorId, |
6 | MActorUrl, | 7 | MActorUrl, |
7 | MCommentId, | 8 | MCommentId, |
8 | MVideoId, | 9 | MVideoId, |
10 | MVideoPlaylistElement, | ||
9 | MVideoUrl, | 11 | MVideoUrl, |
10 | MVideoUUID, | 12 | MVideoUUID |
11 | MAbuseId, | ||
12 | MVideoPlaylistElement | ||
13 | } from '../../types/models' | 13 | } from '../../types/models' |
14 | import { MVideoPlaylist, MVideoPlaylistUUID } from '../../types/models/video/video-playlist' | ||
15 | import { MVideoFileVideoUUID } from '../../types/models/video/video-file' | 14 | import { MVideoFileVideoUUID } from '../../types/models/video/video-file' |
15 | import { MVideoPlaylist, MVideoPlaylistUUID } from '../../types/models/video/video-playlist' | ||
16 | import { MStreamingPlaylist } from '../../types/models/video/video-streaming-playlist' | 16 | import { MStreamingPlaylist } from '../../types/models/video/video-streaming-playlist' |
17 | 17 | ||
18 | function getVideoActivityPubUrl (video: MVideoUUID) { | 18 | function getLocalVideoActivityPubUrl (video: MVideoUUID) { |
19 | return WEBSERVER.URL + '/videos/watch/' + video.uuid | 19 | return WEBSERVER.URL + '/videos/watch/' + video.uuid |
20 | } | 20 | } |
21 | 21 | ||
22 | function getVideoPlaylistActivityPubUrl (videoPlaylist: MVideoPlaylist) { | 22 | function getLocalVideoPlaylistActivityPubUrl (videoPlaylist: MVideoPlaylist) { |
23 | return WEBSERVER.URL + '/video-playlists/' + videoPlaylist.uuid | 23 | return WEBSERVER.URL + '/video-playlists/' + videoPlaylist.uuid |
24 | } | 24 | } |
25 | 25 | ||
26 | function getVideoPlaylistElementActivityPubUrl (videoPlaylist: MVideoPlaylistUUID, videoPlaylistElement: MVideoPlaylistElement) { | 26 | function getLocalVideoPlaylistElementActivityPubUrl (videoPlaylist: MVideoPlaylistUUID, videoPlaylistElement: MVideoPlaylistElement) { |
27 | return WEBSERVER.URL + '/video-playlists/' + videoPlaylist.uuid + '/videos/' + videoPlaylistElement.id | 27 | return WEBSERVER.URL + '/video-playlists/' + videoPlaylist.uuid + '/videos/' + videoPlaylistElement.id |
28 | } | 28 | } |
29 | 29 | ||
30 | function getVideoCacheFileActivityPubUrl (videoFile: MVideoFileVideoUUID) { | 30 | function getLocalVideoCacheFileActivityPubUrl (videoFile: MVideoFileVideoUUID) { |
31 | const suffixFPS = videoFile.fps && videoFile.fps !== -1 ? '-' + videoFile.fps : '' | 31 | const suffixFPS = videoFile.fps && videoFile.fps !== -1 ? '-' + videoFile.fps : '' |
32 | 32 | ||
33 | return `${WEBSERVER.URL}/redundancy/videos/${videoFile.Video.uuid}/${videoFile.resolution}${suffixFPS}` | 33 | return `${WEBSERVER.URL}/redundancy/videos/${videoFile.Video.uuid}/${videoFile.resolution}${suffixFPS}` |
34 | } | 34 | } |
35 | 35 | ||
36 | function getVideoCacheStreamingPlaylistActivityPubUrl (video: MVideoUUID, playlist: MStreamingPlaylist) { | 36 | function getLocalVideoCacheStreamingPlaylistActivityPubUrl (video: MVideoUUID, playlist: MStreamingPlaylist) { |
37 | return `${WEBSERVER.URL}/redundancy/streaming-playlists/${playlist.getStringType()}/${video.uuid}` | 37 | return `${WEBSERVER.URL}/redundancy/streaming-playlists/${playlist.getStringType()}/${video.uuid}` |
38 | } | 38 | } |
39 | 39 | ||
40 | function getVideoCommentActivityPubUrl (video: MVideoUUID, videoComment: MCommentId) { | 40 | function getLocalVideoCommentActivityPubUrl (video: MVideoUUID, videoComment: MCommentId) { |
41 | return WEBSERVER.URL + '/videos/watch/' + video.uuid + '/comments/' + videoComment.id | 41 | return WEBSERVER.URL + '/videos/watch/' + video.uuid + '/comments/' + videoComment.id |
42 | } | 42 | } |
43 | 43 | ||
44 | function getVideoChannelActivityPubUrl (videoChannelName: string) { | 44 | function getLocalVideoChannelActivityPubUrl (videoChannelName: string) { |
45 | return WEBSERVER.URL + '/video-channels/' + videoChannelName | 45 | return WEBSERVER.URL + '/video-channels/' + videoChannelName |
46 | } | 46 | } |
47 | 47 | ||
48 | function getAccountActivityPubUrl (accountName: string) { | 48 | function getLocalAccountActivityPubUrl (accountName: string) { |
49 | return WEBSERVER.URL + '/accounts/' + accountName | 49 | return WEBSERVER.URL + '/accounts/' + accountName |
50 | } | 50 | } |
51 | 51 | ||
52 | function getAbuseActivityPubUrl (abuse: MAbuseId) { | 52 | function getLocalAbuseActivityPubUrl (abuse: MAbuseId) { |
53 | return WEBSERVER.URL + '/admin/abuses/' + abuse.id | 53 | return WEBSERVER.URL + '/admin/abuses/' + abuse.id |
54 | } | 54 | } |
55 | 55 | ||
56 | function getVideoViewActivityPubUrl (byActor: MActorUrl, video: MVideoId) { | 56 | function getLocalVideoViewActivityPubUrl (byActor: MActorUrl, video: MVideoId) { |
57 | return byActor.url + '/views/videos/' + video.id + '/' + new Date().toISOString() | 57 | return byActor.url + '/views/videos/' + video.id + '/' + new Date().toISOString() |
58 | } | 58 | } |
59 | 59 | ||
60 | function getVideoLikeActivityPubUrl (byActor: MActorUrl, video: MVideoId) { | 60 | function getVideoLikeActivityPubUrlByLocalActor (byActor: MActorUrl, video: MVideoId) { |
61 | return byActor.url + '/likes/' + video.id | 61 | return byActor.url + '/likes/' + video.id |
62 | } | 62 | } |
63 | 63 | ||
64 | function getVideoDislikeActivityPubUrl (byActor: MActorUrl, video: MVideoId) { | 64 | function getVideoDislikeActivityPubUrlByLocalActor (byActor: MActorUrl, video: MVideoId) { |
65 | return byActor.url + '/dislikes/' + video.id | 65 | return byActor.url + '/dislikes/' + video.id |
66 | } | 66 | } |
67 | 67 | ||
68 | function getVideoSharesActivityPubUrl (video: MVideoUrl) { | 68 | function getLocalVideoSharesActivityPubUrl (video: MVideoUrl) { |
69 | return video.url + '/announces' | 69 | return video.url + '/announces' |
70 | } | 70 | } |
71 | 71 | ||
72 | function getVideoCommentsActivityPubUrl (video: MVideoUrl) { | 72 | function getLocalVideoCommentsActivityPubUrl (video: MVideoUrl) { |
73 | return video.url + '/comments' | 73 | return video.url + '/comments' |
74 | } | 74 | } |
75 | 75 | ||
76 | function getVideoLikesActivityPubUrl (video: MVideoUrl) { | 76 | function getLocalVideoLikesActivityPubUrl (video: MVideoUrl) { |
77 | return video.url + '/likes' | 77 | return video.url + '/likes' |
78 | } | 78 | } |
79 | 79 | ||
80 | function getVideoDislikesActivityPubUrl (video: MVideoUrl) { | 80 | function getLocalVideoDislikesActivityPubUrl (video: MVideoUrl) { |
81 | return video.url + '/dislikes' | 81 | return video.url + '/dislikes' |
82 | } | 82 | } |
83 | 83 | ||
84 | function getActorFollowActivityPubUrl (follower: MActor, following: MActorId) { | 84 | function getLocalActorFollowActivityPubUrl (follower: MActor, following: MActorId) { |
85 | return follower.url + '/follows/' + following.id | 85 | return follower.url + '/follows/' + following.id |
86 | } | 86 | } |
87 | 87 | ||
88 | function getActorFollowAcceptActivityPubUrl (actorFollow: MActorFollowActors) { | 88 | function getLocalActorFollowAcceptActivityPubUrl (actorFollow: MActorFollowActors) { |
89 | const follower = actorFollow.ActorFollower | 89 | const follower = actorFollow.ActorFollower |
90 | const me = actorFollow.ActorFollowing | 90 | const me = actorFollow.ActorFollowing |
91 | 91 | ||
92 | return follower.url + '/accepts/follows/' + me.id | 92 | return WEBSERVER.URL + '/accepts/follows/' + follower.id + '/' + me.id |
93 | } | 93 | } |
94 | 94 | ||
95 | function getActorFollowRejectActivityPubUrl (follower: MActorUrl, following: MActorId) { | 95 | function getLocalActorFollowRejectActivityPubUrl (follower: MActorId, following: MActorId) { |
96 | return follower.url + '/rejects/follows/' + following.id | 96 | return WEBSERVER.URL + '/rejects/follows/' + follower.id + '/' + following.id |
97 | } | 97 | } |
98 | 98 | ||
99 | function getVideoAnnounceActivityPubUrl (byActor: MActorId, video: MVideoUrl) { | 99 | function getLocalVideoAnnounceActivityPubUrl (byActor: MActorId, video: MVideoUrl) { |
100 | return video.url + '/announces/' + byActor.id | 100 | return video.url + '/announces/' + byActor.id |
101 | } | 101 | } |
102 | 102 | ||
@@ -113,27 +113,28 @@ function getUndoActivityPubUrl (originalUrl: string) { | |||
113 | } | 113 | } |
114 | 114 | ||
115 | export { | 115 | export { |
116 | getVideoActivityPubUrl, | 116 | getLocalVideoActivityPubUrl, |
117 | getVideoPlaylistElementActivityPubUrl, | 117 | getLocalVideoPlaylistActivityPubUrl, |
118 | getVideoPlaylistActivityPubUrl, | 118 | getLocalVideoPlaylistElementActivityPubUrl, |
119 | getVideoCacheStreamingPlaylistActivityPubUrl, | 119 | getLocalVideoCacheFileActivityPubUrl, |
120 | getVideoChannelActivityPubUrl, | 120 | getLocalVideoCacheStreamingPlaylistActivityPubUrl, |
121 | getAccountActivityPubUrl, | 121 | getLocalVideoCommentActivityPubUrl, |
122 | getAbuseActivityPubUrl, | 122 | getLocalVideoChannelActivityPubUrl, |
123 | getActorFollowActivityPubUrl, | 123 | getLocalAccountActivityPubUrl, |
124 | getActorFollowAcceptActivityPubUrl, | 124 | getLocalAbuseActivityPubUrl, |
125 | getVideoAnnounceActivityPubUrl, | 125 | getLocalActorFollowActivityPubUrl, |
126 | getLocalActorFollowAcceptActivityPubUrl, | ||
127 | getLocalVideoAnnounceActivityPubUrl, | ||
126 | getUpdateActivityPubUrl, | 128 | getUpdateActivityPubUrl, |
127 | getUndoActivityPubUrl, | 129 | getUndoActivityPubUrl, |
128 | getVideoViewActivityPubUrl, | 130 | getVideoLikeActivityPubUrlByLocalActor, |
129 | getVideoLikeActivityPubUrl, | 131 | getLocalVideoViewActivityPubUrl, |
130 | getVideoDislikeActivityPubUrl, | 132 | getVideoDislikeActivityPubUrlByLocalActor, |
131 | getActorFollowRejectActivityPubUrl, | 133 | getLocalActorFollowRejectActivityPubUrl, |
132 | getVideoCommentActivityPubUrl, | ||
133 | getDeleteActivityPubUrl, | 134 | getDeleteActivityPubUrl, |
134 | getVideoSharesActivityPubUrl, | 135 | getLocalVideoSharesActivityPubUrl, |
135 | getVideoCommentsActivityPubUrl, | 136 | getLocalVideoCommentsActivityPubUrl, |
136 | getVideoLikesActivityPubUrl, | 137 | getLocalVideoLikesActivityPubUrl, |
137 | getVideoDislikesActivityPubUrl, | 138 | getLocalVideoDislikesActivityPubUrl, |
138 | getVideoCacheFileActivityPubUrl | 139 | |
139 | } | 140 | } |
diff --git a/server/lib/activitypub/video-rates.ts b/server/lib/activitypub/video-rates.ts index e09e5d9ec..581a2bca1 100644 --- a/server/lib/activitypub/video-rates.ts +++ b/server/lib/activitypub/video-rates.ts | |||
@@ -8,7 +8,7 @@ import { logger } from '../../helpers/logger' | |||
8 | import { CRAWL_REQUEST_CONCURRENCY } from '../../initializers/constants' | 8 | import { CRAWL_REQUEST_CONCURRENCY } from '../../initializers/constants' |
9 | import { doRequest } from '../../helpers/requests' | 9 | import { doRequest } from '../../helpers/requests' |
10 | import { checkUrlsSameHost, getAPId } from '../../helpers/activitypub' | 10 | import { checkUrlsSameHost, getAPId } from '../../helpers/activitypub' |
11 | import { getVideoDislikeActivityPubUrl, getVideoLikeActivityPubUrl } from './url' | 11 | import { getVideoDislikeActivityPubUrlByLocalActor, getVideoLikeActivityPubUrlByLocalActor } from './url' |
12 | import { sendDislike } from './send/send-dislike' | 12 | import { sendDislike } from './send/send-dislike' |
13 | import { MAccountActor, MActorUrl, MVideo, MVideoAccountLight, MVideoId } from '../../types/models' | 13 | import { MAccountActor, MActorUrl, MVideo, MVideoAccountLight, MVideoId } from '../../types/models' |
14 | 14 | ||
@@ -82,14 +82,14 @@ async function sendVideoRateChange ( | |||
82 | if (dislikes > 0) await sendDislike(actor, video, t) | 82 | if (dislikes > 0) await sendDislike(actor, video, t) |
83 | } | 83 | } |
84 | 84 | ||
85 | function getRateUrl (rateType: VideoRateType, actor: MActorUrl, video: MVideoId) { | 85 | function getLocalRateUrl (rateType: VideoRateType, actor: MActorUrl, video: MVideoId) { |
86 | return rateType === 'like' | 86 | return rateType === 'like' |
87 | ? getVideoLikeActivityPubUrl(actor, video) | 87 | ? getVideoLikeActivityPubUrlByLocalActor(actor, video) |
88 | : getVideoDislikeActivityPubUrl(actor, video) | 88 | : getVideoDislikeActivityPubUrlByLocalActor(actor, video) |
89 | } | 89 | } |
90 | 90 | ||
91 | export { | 91 | export { |
92 | getRateUrl, | 92 | getLocalRateUrl, |
93 | createRates, | 93 | createRates, |
94 | sendVideoRateChange | 94 | sendVideoRateChange |
95 | } | 95 | } |
diff --git a/server/lib/job-queue/handlers/activitypub-follow.ts b/server/lib/job-queue/handlers/activitypub-follow.ts index 7a4f85f8b..82c95be80 100644 --- a/server/lib/job-queue/handlers/activitypub-follow.ts +++ b/server/lib/job-queue/handlers/activitypub-follow.ts | |||
@@ -12,6 +12,7 @@ import { Notifier } from '../../notifier' | |||
12 | import { sequelizeTypescript } from '../../../initializers/database' | 12 | import { sequelizeTypescript } from '../../../initializers/database' |
13 | import { MActor, MActorFollowActors, MActorFull } from '../../../types/models' | 13 | import { MActor, MActorFollowActors, MActorFull } from '../../../types/models' |
14 | import { ActivitypubFollowPayload } from '@shared/models' | 14 | import { ActivitypubFollowPayload } from '@shared/models' |
15 | import { getLocalActorFollowActivityPubUrl } from '@server/lib/activitypub/url' | ||
15 | 16 | ||
16 | async function processActivityPubFollow (job: Bull.Job) { | 17 | async function processActivityPubFollow (job: Bull.Job) { |
17 | const payload = job.data as ActivitypubFollowPayload | 18 | const payload = job.data as ActivitypubFollowPayload |
@@ -61,6 +62,7 @@ async function follow (fromActor: MActor, targetActor: MActorFull, isAutoFollow | |||
61 | }, | 62 | }, |
62 | defaults: { | 63 | defaults: { |
63 | state, | 64 | state, |
65 | url: getLocalActorFollowActivityPubUrl(fromActor, targetActor), | ||
64 | actorId: fromActor.id, | 66 | actorId: fromActor.id, |
65 | targetActorId: targetActor.id | 67 | targetActorId: targetActor.id |
66 | }, | 68 | }, |
diff --git a/server/lib/schedulers/videos-redundancy-scheduler.ts b/server/lib/schedulers/videos-redundancy-scheduler.ts index 54d9a9894..82005a2c8 100644 --- a/server/lib/schedulers/videos-redundancy-scheduler.ts +++ b/server/lib/schedulers/videos-redundancy-scheduler.ts | |||
@@ -1,19 +1,10 @@ | |||
1 | import { AbstractScheduler } from './abstract-scheduler' | ||
2 | import { HLS_REDUNDANCY_DIRECTORY, REDUNDANCY, VIDEO_IMPORT_TIMEOUT, WEBSERVER } from '../../initializers/constants' | ||
3 | import { logger } from '../../helpers/logger' | ||
4 | import { VideosRedundancyStrategy } from '../../../shared/models/redundancy' | ||
5 | import { VideoRedundancyModel } from '../../models/redundancy/video-redundancy' | ||
6 | import { downloadWebTorrentVideo, generateMagnetUri } from '../../helpers/webtorrent' | ||
7 | import { join } from 'path' | ||
8 | import { move } from 'fs-extra' | 1 | import { move } from 'fs-extra' |
9 | import { sendCreateCacheFile, sendUpdateCacheFile } from '../activitypub/send' | 2 | import { join } from 'path' |
10 | import { getVideoCacheFileActivityPubUrl, getVideoCacheStreamingPlaylistActivityPubUrl } from '../activitypub/url' | 3 | import { getServerActor } from '@server/models/application/application' |
11 | import { removeVideoRedundancy } from '../redundancy' | 4 | import { VideoModel } from '@server/models/video/video' |
12 | import { getOrCreateVideoAndAccountAndChannel } from '../activitypub/videos' | ||
13 | import { downloadPlaylistSegments } from '../hls' | ||
14 | import { CONFIG } from '../../initializers/config' | ||
15 | import { | 5 | import { |
16 | MStreamingPlaylist, MStreamingPlaylistFiles, | 6 | MStreamingPlaylist, |
7 | MStreamingPlaylistFiles, | ||
17 | MStreamingPlaylistVideo, | 8 | MStreamingPlaylistVideo, |
18 | MVideoAccountLight, | 9 | MVideoAccountLight, |
19 | MVideoFile, | 10 | MVideoFile, |
@@ -23,9 +14,19 @@ import { | |||
23 | MVideoRedundancyVideo, | 14 | MVideoRedundancyVideo, |
24 | MVideoWithAllFiles | 15 | MVideoWithAllFiles |
25 | } from '@server/types/models' | 16 | } from '@server/types/models' |
17 | import { VideosRedundancyStrategy } from '../../../shared/models/redundancy' | ||
18 | import { logger } from '../../helpers/logger' | ||
19 | import { downloadWebTorrentVideo, generateMagnetUri } from '../../helpers/webtorrent' | ||
20 | import { CONFIG } from '../../initializers/config' | ||
21 | import { HLS_REDUNDANCY_DIRECTORY, REDUNDANCY, VIDEO_IMPORT_TIMEOUT, WEBSERVER } from '../../initializers/constants' | ||
22 | import { VideoRedundancyModel } from '../../models/redundancy/video-redundancy' | ||
23 | import { sendCreateCacheFile, sendUpdateCacheFile } from '../activitypub/send' | ||
24 | import { getLocalVideoCacheFileActivityPubUrl, getLocalVideoCacheStreamingPlaylistActivityPubUrl } from '../activitypub/url' | ||
25 | import { getOrCreateVideoAndAccountAndChannel } from '../activitypub/videos' | ||
26 | import { downloadPlaylistSegments } from '../hls' | ||
27 | import { removeVideoRedundancy } from '../redundancy' | ||
26 | import { getVideoFilename } from '../video-paths' | 28 | import { getVideoFilename } from '../video-paths' |
27 | import { VideoModel } from '@server/models/video/video' | 29 | import { AbstractScheduler } from './abstract-scheduler' |
28 | import { getServerActor } from '@server/models/application/application' | ||
29 | 30 | ||
30 | type CandidateToDuplicate = { | 31 | type CandidateToDuplicate = { |
31 | redundancy: VideosRedundancyStrategy | 32 | redundancy: VideosRedundancyStrategy |
@@ -230,7 +231,7 @@ export class VideosRedundancyScheduler extends AbstractScheduler { | |||
230 | 231 | ||
231 | const createdModel: MVideoRedundancyFileVideo = await VideoRedundancyModel.create({ | 232 | const createdModel: MVideoRedundancyFileVideo = await VideoRedundancyModel.create({ |
232 | expiresOn, | 233 | expiresOn, |
233 | url: getVideoCacheFileActivityPubUrl(file), | 234 | url: getLocalVideoCacheFileActivityPubUrl(file), |
234 | fileUrl: video.getVideoRedundancyUrl(file, WEBSERVER.URL), | 235 | fileUrl: video.getVideoRedundancyUrl(file, WEBSERVER.URL), |
235 | strategy, | 236 | strategy, |
236 | videoFileId: file.id, | 237 | videoFileId: file.id, |
@@ -269,7 +270,7 @@ export class VideosRedundancyScheduler extends AbstractScheduler { | |||
269 | 270 | ||
270 | const createdModel: MVideoRedundancyStreamingPlaylistVideo = await VideoRedundancyModel.create({ | 271 | const createdModel: MVideoRedundancyStreamingPlaylistVideo = await VideoRedundancyModel.create({ |
271 | expiresOn, | 272 | expiresOn, |
272 | url: getVideoCacheStreamingPlaylistActivityPubUrl(video, playlist), | 273 | url: getLocalVideoCacheStreamingPlaylistActivityPubUrl(video, playlist), |
273 | fileUrl: playlist.getVideoRedundancyUrl(WEBSERVER.URL), | 274 | fileUrl: playlist.getVideoRedundancyUrl(WEBSERVER.URL), |
274 | strategy, | 275 | strategy, |
275 | videoStreamingPlaylistId: playlist.id, | 276 | videoStreamingPlaylistId: playlist.id, |
diff --git a/server/lib/user.ts b/server/lib/user.ts index 7d6497302..6b0fd9b88 100644 --- a/server/lib/user.ts +++ b/server/lib/user.ts | |||
@@ -11,7 +11,7 @@ import { ActorModel } from '../models/activitypub/actor' | |||
11 | import { MAccountDefault, MActorDefault, MChannelActor } from '../types/models' | 11 | import { MAccountDefault, MActorDefault, MChannelActor } from '../types/models' |
12 | import { MUser, MUserDefault, MUserId } from '../types/models/user' | 12 | import { MUser, MUserDefault, MUserId } from '../types/models/user' |
13 | import { buildActorInstance, setAsyncActorKeys } from './activitypub/actor' | 13 | import { buildActorInstance, setAsyncActorKeys } from './activitypub/actor' |
14 | import { getAccountActivityPubUrl } from './activitypub/url' | 14 | import { getLocalAccountActivityPubUrl } from './activitypub/url' |
15 | import { Emailer } from './emailer' | 15 | import { Emailer } from './emailer' |
16 | import { LiveManager } from './live-manager' | 16 | import { LiveManager } from './live-manager' |
17 | import { Redis } from './redis' | 17 | import { Redis } from './redis' |
@@ -74,7 +74,7 @@ async function createLocalAccountWithoutKeys (parameters: { | |||
74 | type?: ActivityPubActorType | 74 | type?: ActivityPubActorType |
75 | }) { | 75 | }) { |
76 | const { name, displayName, userId, applicationId, t, type = 'Person' } = parameters | 76 | const { name, displayName, userId, applicationId, t, type = 'Person' } = parameters |
77 | const url = getAccountActivityPubUrl(name) | 77 | const url = getLocalAccountActivityPubUrl(name) |
78 | 78 | ||
79 | const actorInstance = buildActorInstance(type, url, name) | 79 | const actorInstance = buildActorInstance(type, url, name) |
80 | const actorInstanceCreated: MActorDefault = await actorInstance.save({ transaction: t }) | 80 | const actorInstanceCreated: MActorDefault = await actorInstance.save({ transaction: t }) |
diff --git a/server/lib/video-channel.ts b/server/lib/video-channel.ts index 8928dda12..49bdf4869 100644 --- a/server/lib/video-channel.ts +++ b/server/lib/video-channel.ts | |||
@@ -1,11 +1,11 @@ | |||
1 | import * as Sequelize from 'sequelize' | 1 | import * as Sequelize from 'sequelize' |
2 | import { v4 as uuidv4 } from 'uuid' | 2 | import { v4 as uuidv4 } from 'uuid' |
3 | import { VideoChannelCreate } from '../../shared/models' | 3 | import { VideoChannelCreate } from '../../shared/models' |
4 | import { VideoChannelModel } from '../models/video/video-channel' | ||
5 | import { buildActorInstance } from './activitypub/actor' | ||
6 | import { VideoModel } from '../models/video/video' | 4 | import { VideoModel } from '../models/video/video' |
5 | import { VideoChannelModel } from '../models/video/video-channel' | ||
7 | import { MAccountId, MChannelDefault, MChannelId } from '../types/models' | 6 | import { MAccountId, MChannelDefault, MChannelId } from '../types/models' |
8 | import { getVideoChannelActivityPubUrl } from './activitypub/url' | 7 | import { buildActorInstance } from './activitypub/actor' |
8 | import { getLocalVideoChannelActivityPubUrl } from './activitypub/url' | ||
9 | import { federateVideoIfNeeded } from './activitypub/videos' | 9 | import { federateVideoIfNeeded } from './activitypub/videos' |
10 | 10 | ||
11 | type CustomVideoChannelModelAccount <T extends MAccountId> = MChannelDefault & { Account?: T } | 11 | type CustomVideoChannelModelAccount <T extends MAccountId> = MChannelDefault & { Account?: T } |
@@ -16,7 +16,7 @@ async function createLocalVideoChannel <T extends MAccountId> ( | |||
16 | t: Sequelize.Transaction | 16 | t: Sequelize.Transaction |
17 | ): Promise<CustomVideoChannelModelAccount<T>> { | 17 | ): Promise<CustomVideoChannelModelAccount<T>> { |
18 | const uuid = uuidv4() | 18 | const uuid = uuidv4() |
19 | const url = getVideoChannelActivityPubUrl(videoChannelInfo.name) | 19 | const url = getLocalVideoChannelActivityPubUrl(videoChannelInfo.name) |
20 | const actorInstance = buildActorInstance('Group', url, videoChannelInfo.name, uuid) | 20 | const actorInstance = buildActorInstance('Group', url, videoChannelInfo.name, uuid) |
21 | 21 | ||
22 | const actorInstanceCreated = await actorInstance.save({ transaction: t }) | 22 | const actorInstanceCreated = await actorInstance.save({ transaction: t }) |
diff --git a/server/lib/video-comment.ts b/server/lib/video-comment.ts index c92a7c43a..736ebb2f8 100644 --- a/server/lib/video-comment.ts +++ b/server/lib/video-comment.ts | |||
@@ -5,9 +5,9 @@ import { sequelizeTypescript } from '@server/initializers/database' | |||
5 | import { ResultList } from '../../shared/models' | 5 | import { ResultList } from '../../shared/models' |
6 | import { VideoCommentThreadTree } from '../../shared/models/videos/video-comment.model' | 6 | import { VideoCommentThreadTree } from '../../shared/models/videos/video-comment.model' |
7 | import { VideoCommentModel } from '../models/video/video-comment' | 7 | import { VideoCommentModel } from '../models/video/video-comment' |
8 | import { MAccountDefault, MComment, MCommentOwnerVideoReply, MVideoFullLight, MCommentOwnerVideo } from '../types/models' | 8 | import { MAccountDefault, MComment, MCommentOwnerVideo, MCommentOwnerVideoReply, MVideoFullLight } from '../types/models' |
9 | import { sendCreateVideoComment, sendDeleteVideoComment } from './activitypub/send' | 9 | import { sendCreateVideoComment, sendDeleteVideoComment } from './activitypub/send' |
10 | import { getVideoCommentActivityPubUrl } from './activitypub/url' | 10 | import { getLocalVideoCommentActivityPubUrl } from './activitypub/url' |
11 | import { Hooks } from './plugins/hooks' | 11 | import { Hooks } from './plugins/hooks' |
12 | 12 | ||
13 | async function removeComment (videoCommentInstance: MCommentOwnerVideo) { | 13 | async function removeComment (videoCommentInstance: MCommentOwnerVideo) { |
@@ -51,7 +51,7 @@ async function createVideoComment (obj: { | |||
51 | url: new Date().toISOString() | 51 | url: new Date().toISOString() |
52 | }, { transaction: t, validate: false }) | 52 | }, { transaction: t, validate: false }) |
53 | 53 | ||
54 | comment.url = getVideoCommentActivityPubUrl(obj.video, comment) | 54 | comment.url = getLocalVideoCommentActivityPubUrl(obj.video, comment) |
55 | 55 | ||
56 | const savedComment: MCommentOwnerVideoReply = await comment.save({ transaction: t }) | 56 | const savedComment: MCommentOwnerVideoReply = await comment.save({ transaction: t }) |
57 | savedComment.InReplyToVideoComment = obj.inReplyToComment | 57 | savedComment.InReplyToVideoComment = obj.inReplyToComment |
diff --git a/server/lib/video-playlist.ts b/server/lib/video-playlist.ts index 6eeb70c8e..a1af2e1af 100644 --- a/server/lib/video-playlist.ts +++ b/server/lib/video-playlist.ts | |||
@@ -1,10 +1,10 @@ | |||
1 | import * as Sequelize from 'sequelize' | 1 | import * as Sequelize from 'sequelize' |
2 | import { VideoPlaylistModel } from '../models/video/video-playlist' | ||
3 | import { VideoPlaylistPrivacy } from '../../shared/models/videos/playlist/video-playlist-privacy.model' | 2 | import { VideoPlaylistPrivacy } from '../../shared/models/videos/playlist/video-playlist-privacy.model' |
4 | import { getVideoPlaylistActivityPubUrl } from './activitypub/url' | ||
5 | import { VideoPlaylistType } from '../../shared/models/videos/playlist/video-playlist-type.model' | 3 | import { VideoPlaylistType } from '../../shared/models/videos/playlist/video-playlist-type.model' |
4 | import { VideoPlaylistModel } from '../models/video/video-playlist' | ||
6 | import { MAccount } from '../types/models' | 5 | import { MAccount } from '../types/models' |
7 | import { MVideoPlaylistOwner } from '../types/models/video/video-playlist' | 6 | import { MVideoPlaylistOwner } from '../types/models/video/video-playlist' |
7 | import { getLocalVideoPlaylistActivityPubUrl } from './activitypub/url' | ||
8 | 8 | ||
9 | async function createWatchLaterPlaylist (account: MAccount, t: Sequelize.Transaction) { | 9 | async function createWatchLaterPlaylist (account: MAccount, t: Sequelize.Transaction) { |
10 | const videoPlaylist: MVideoPlaylistOwner = new VideoPlaylistModel({ | 10 | const videoPlaylist: MVideoPlaylistOwner = new VideoPlaylistModel({ |
@@ -14,7 +14,7 @@ async function createWatchLaterPlaylist (account: MAccount, t: Sequelize.Transac | |||
14 | ownerAccountId: account.id | 14 | ownerAccountId: account.id |
15 | }) | 15 | }) |
16 | 16 | ||
17 | videoPlaylist.url = getVideoPlaylistActivityPubUrl(videoPlaylist) // We use the UUID, so set the URL after building the object | 17 | videoPlaylist.url = getLocalVideoPlaylistActivityPubUrl(videoPlaylist) // We use the UUID, so set the URL after building the object |
18 | 18 | ||
19 | await videoPlaylist.save({ transaction: t }) | 19 | await videoPlaylist.save({ transaction: t }) |
20 | 20 | ||
diff --git a/server/middlewares/validators/videos/video-rates.ts b/server/middlewares/validators/videos/video-rates.ts index cbc144f69..15a8c7983 100644 --- a/server/middlewares/validators/videos/video-rates.ts +++ b/server/middlewares/validators/videos/video-rates.ts | |||
@@ -38,7 +38,6 @@ const getAccountVideoRateValidatorFactory = function (rateType: VideoRateType) { | |||
38 | if (!rate) { | 38 | if (!rate) { |
39 | return res.status(404) | 39 | return res.status(404) |
40 | .json({ error: 'Video rate not found' }) | 40 | .json({ error: 'Video rate not found' }) |
41 | .end() | ||
42 | } | 41 | } |
43 | 42 | ||
44 | res.locals.accountVideoRate = rate | 43 | res.locals.accountVideoRate = rate |
diff --git a/server/models/account/account-video-rate.ts b/server/models/account/account-video-rate.ts index 5064987dc..6955f45ee 100644 --- a/server/models/account/account-video-rate.ts +++ b/server/models/account/account-video-rate.ts | |||
@@ -168,7 +168,8 @@ export class AccountVideoRateModel extends Model<AccountVideoRateModel> { | |||
168 | model: ActorModel.unscoped(), | 168 | model: ActorModel.unscoped(), |
169 | required: true, | 169 | required: true, |
170 | where: { | 170 | where: { |
171 | preferredUsername: accountName | 171 | preferredUsername: accountName, |
172 | serverId: null | ||
172 | } | 173 | } |
173 | } | 174 | } |
174 | ] | 175 | ] |
diff --git a/server/models/activitypub/actor-follow.ts b/server/models/activitypub/actor-follow.ts index 10c13304f..58bc63d34 100644 --- a/server/models/activitypub/actor-follow.ts +++ b/server/models/activitypub/actor-follow.ts | |||
@@ -1,5 +1,6 @@ | |||
1 | import * as Bluebird from 'bluebird' | 1 | import * as Bluebird from 'bluebird' |
2 | import { difference, values } from 'lodash' | 2 | import { difference, values } from 'lodash' |
3 | import { IncludeOptions, Op, QueryTypes, Transaction, WhereOptions } from 'sequelize' | ||
3 | import { | 4 | import { |
4 | AfterCreate, | 5 | AfterCreate, |
5 | AfterDestroy, | 6 | AfterDestroy, |
@@ -11,22 +12,16 @@ import { | |||
11 | DataType, | 12 | DataType, |
12 | Default, | 13 | Default, |
13 | ForeignKey, | 14 | ForeignKey, |
15 | Is, | ||
14 | IsInt, | 16 | IsInt, |
15 | Max, | 17 | Max, |
16 | Model, | 18 | Model, |
17 | Table, | 19 | Table, |
18 | UpdatedAt | 20 | UpdatedAt |
19 | } from 'sequelize-typescript' | 21 | } from 'sequelize-typescript' |
20 | import { FollowState } from '../../../shared/models/actors' | 22 | import { isActivityPubUrlValid } from '@server/helpers/custom-validators/activitypub/misc' |
21 | import { ActorFollow } from '../../../shared/models/actors/follow.model' | 23 | import { getServerActor } from '@server/models/application/application' |
22 | import { logger } from '../../helpers/logger' | 24 | import { VideoModel } from '@server/models/video/video' |
23 | import { ACTOR_FOLLOW_SCORE, FOLLOW_STATES, SERVER_ACTOR_NAME } from '../../initializers/constants' | ||
24 | import { ServerModel } from '../server/server' | ||
25 | import { createSafeIn, getFollowsSort, getSort, searchAttribute } from '../utils' | ||
26 | import { ActorModel, unusedActorAttributesForAPI } from './actor' | ||
27 | import { VideoChannelModel } from '../video/video-channel' | ||
28 | import { AccountModel } from '../account/account' | ||
29 | import { IncludeOptions, Op, QueryTypes, Transaction, WhereOptions } from 'sequelize' | ||
30 | import { | 25 | import { |
31 | MActorFollowActorsDefault, | 26 | MActorFollowActorsDefault, |
32 | MActorFollowActorsDefaultSubscription, | 27 | MActorFollowActorsDefaultSubscription, |
@@ -35,8 +30,15 @@ import { | |||
35 | MActorFollowSubscriptions | 30 | MActorFollowSubscriptions |
36 | } from '@server/types/models' | 31 | } from '@server/types/models' |
37 | import { ActivityPubActorType } from '@shared/models' | 32 | import { ActivityPubActorType } from '@shared/models' |
38 | import { VideoModel } from '@server/models/video/video' | 33 | import { FollowState } from '../../../shared/models/actors' |
39 | import { getServerActor } from '@server/models/application/application' | 34 | import { ActorFollow } from '../../../shared/models/actors/follow.model' |
35 | import { logger } from '../../helpers/logger' | ||
36 | import { ACTOR_FOLLOW_SCORE, CONSTRAINTS_FIELDS, FOLLOW_STATES, SERVER_ACTOR_NAME } from '../../initializers/constants' | ||
37 | import { AccountModel } from '../account/account' | ||
38 | import { ServerModel } from '../server/server' | ||
39 | import { createSafeIn, getFollowsSort, getSort, searchAttribute, throwIfNotValid } from '../utils' | ||
40 | import { VideoChannelModel } from '../video/video-channel' | ||
41 | import { ActorModel, unusedActorAttributesForAPI } from './actor' | ||
40 | 42 | ||
41 | @Table({ | 43 | @Table({ |
42 | tableName: 'actorFollow', | 44 | tableName: 'actorFollow', |
@@ -53,6 +55,10 @@ import { getServerActor } from '@server/models/application/application' | |||
53 | }, | 55 | }, |
54 | { | 56 | { |
55 | fields: [ 'score' ] | 57 | fields: [ 'score' ] |
58 | }, | ||
59 | { | ||
60 | fields: [ 'url' ], | ||
61 | unique: true | ||
56 | } | 62 | } |
57 | ] | 63 | ] |
58 | }) | 64 | }) |
@@ -69,6 +75,12 @@ export class ActorFollowModel extends Model<ActorFollowModel> { | |||
69 | @Column | 75 | @Column |
70 | score: number | 76 | score: number |
71 | 77 | ||
78 | // Allow null because we added this column in PeerTube v3, and don't want to generate fake URLs of remote follows | ||
79 | @AllowNull(true) | ||
80 | @Is('ActorFollowUrl', value => throwIfNotValid(value, isActivityPubUrlValid, 'url')) | ||
81 | @Column(DataType.STRING(CONSTRAINTS_FIELDS.COMMONS.URL.max)) | ||
82 | url: string | ||
83 | |||
72 | @CreatedAt | 84 | @CreatedAt |
73 | createdAt: Date | 85 | createdAt: Date |
74 | 86 | ||
diff --git a/server/models/video/video-format-utils.ts b/server/models/video/video-format-utils.ts index d4b213686..b1adbcb86 100644 --- a/server/models/video/video-format-utils.ts +++ b/server/models/video/video-format-utils.ts | |||
@@ -4,10 +4,10 @@ import { ActivityTagObject, ActivityUrlObject, VideoObject } from '../../../shar | |||
4 | import { MIMETYPES, WEBSERVER } from '../../initializers/constants' | 4 | import { MIMETYPES, WEBSERVER } from '../../initializers/constants' |
5 | import { VideoCaptionModel } from './video-caption' | 5 | import { VideoCaptionModel } from './video-caption' |
6 | import { | 6 | import { |
7 | getVideoCommentsActivityPubUrl, | 7 | getLocalVideoCommentsActivityPubUrl, |
8 | getVideoDislikesActivityPubUrl, | 8 | getLocalVideoDislikesActivityPubUrl, |
9 | getVideoLikesActivityPubUrl, | 9 | getLocalVideoLikesActivityPubUrl, |
10 | getVideoSharesActivityPubUrl | 10 | getLocalVideoSharesActivityPubUrl |
11 | } from '../../lib/activitypub/url' | 11 | } from '../../lib/activitypub/url' |
12 | import { isArray } from '../../helpers/custom-validators/misc' | 12 | import { isArray } from '../../helpers/custom-validators/misc' |
13 | import { VideoStreamingPlaylist } from '../../../shared/models/videos/video-streaming-playlist.model' | 13 | import { VideoStreamingPlaylist } from '../../../shared/models/videos/video-streaming-playlist.model' |
@@ -382,10 +382,10 @@ function videoModelToActivityPubObject (video: MVideoAP): VideoObject { | |||
382 | height: i.height | 382 | height: i.height |
383 | })), | 383 | })), |
384 | url, | 384 | url, |
385 | likes: getVideoLikesActivityPubUrl(video), | 385 | likes: getLocalVideoLikesActivityPubUrl(video), |
386 | dislikes: getVideoDislikesActivityPubUrl(video), | 386 | dislikes: getLocalVideoDislikesActivityPubUrl(video), |
387 | shares: getVideoSharesActivityPubUrl(video), | 387 | shares: getLocalVideoSharesActivityPubUrl(video), |
388 | comments: getVideoCommentsActivityPubUrl(video), | 388 | comments: getLocalVideoCommentsActivityPubUrl(video), |
389 | attributedTo: [ | 389 | attributedTo: [ |
390 | { | 390 | { |
391 | type: 'Person', | 391 | type: 'Person', |
diff --git a/server/tests/api/server/follows-moderation.ts b/server/tests/api/server/follows-moderation.ts index cee85cc4b..73c212a32 100644 --- a/server/tests/api/server/follows-moderation.ts +++ b/server/tests/api/server/follows-moderation.ts | |||
@@ -81,6 +81,8 @@ describe('Test follows moderation', function () { | |||
81 | }) | 81 | }) |
82 | 82 | ||
83 | it('Should remove follower on server 2', async function () { | 83 | it('Should remove follower on server 2', async function () { |
84 | this.timeout(10000) | ||
85 | |||
84 | await removeFollower(servers[1].url, servers[1].accessToken, servers[0]) | 86 | await removeFollower(servers[1].url, servers[1].accessToken, servers[0]) |
85 | 87 | ||
86 | await waitJobs(servers) | 88 | await waitJobs(servers) |
@@ -91,6 +93,8 @@ describe('Test follows moderation', function () { | |||
91 | }) | 93 | }) |
92 | 94 | ||
93 | it('Should disable followers on server 2', async function () { | 95 | it('Should disable followers on server 2', async function () { |
96 | this.timeout(10000) | ||
97 | |||
94 | const subConfig = { | 98 | const subConfig = { |
95 | followers: { | 99 | followers: { |
96 | instance: { | 100 | instance: { |
@@ -109,6 +113,8 @@ describe('Test follows moderation', function () { | |||
109 | }) | 113 | }) |
110 | 114 | ||
111 | it('Should re enable followers on server 2', async function () { | 115 | it('Should re enable followers on server 2', async function () { |
116 | this.timeout(10000) | ||
117 | |||
112 | const subConfig = { | 118 | const subConfig = { |
113 | followers: { | 119 | followers: { |
114 | instance: { | 120 | instance: { |
@@ -151,6 +157,8 @@ describe('Test follows moderation', function () { | |||
151 | }) | 157 | }) |
152 | 158 | ||
153 | it('Should accept a follower', async function () { | 159 | it('Should accept a follower', async function () { |
160 | this.timeout(10000) | ||
161 | |||
154 | await acceptFollower(servers[1].url, servers[1].accessToken, 'peertube@localhost:' + servers[0].port) | 162 | await acceptFollower(servers[1].url, servers[1].accessToken, 'peertube@localhost:' + servers[0].port) |
155 | await waitJobs(servers) | 163 | await waitJobs(servers) |
156 | 164 | ||