]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/controllers/activitypub/client.ts
Fix account link in the menu
[github/Chocobozzz/PeerTube.git] / server / controllers / activitypub / client.ts
CommitLineData
e4f97bab
C
1// Intercept ActivityPub client requests
2import * as express from 'express'
2ccaeeb3 3import { VideoPrivacy } from '../../../shared/models/videos'
d6e99e53 4import { activityPubCollectionPagination, activityPubContextify } from '../../helpers/activitypub'
da854ddd 5import { pageToStartAndCount } from '../../helpers/core-utils'
3fd3ab2d 6import { ACTIVITY_PUB, CONFIG } from '../../initializers'
07197db4 7import { buildVideoAnnounce } from '../../lib/activitypub/send'
2ccaeeb3 8import { audiencify, getAudience } from '../../lib/activitypub/send/misc'
296c0905 9import { createActivityData } from '../../lib/activitypub/send/send-create'
3fd3ab2d 10import { asyncMiddleware, executeIfActivityPub, localAccountValidator } from '../../middlewares'
50d6de9c 11import { videoChannelsGetValidator, videosGetValidator, videosShareValidator } from '../../middlewares/validators'
da854ddd 12import { videoCommentGetValidator } from '../../middlewares/validators/video-comments'
3fd3ab2d 13import { AccountModel } from '../../models/account/account'
7006bc63 14import { ActorModel } from '../../models/activitypub/actor'
50d6de9c 15import { ActorFollowModel } from '../../models/activitypub/actor-follow'
3fd3ab2d
C
16import { VideoModel } from '../../models/video/video'
17import { VideoChannelModel } from '../../models/video/video-channel'
da854ddd 18import { VideoCommentModel } from '../../models/video/video-comment'
3fd3ab2d 19import { VideoShareModel } from '../../models/video/video-share'
e4f97bab
C
20
21const activityPubClientRouter = express.Router()
22
108af661 23activityPubClientRouter.get('/accounts?/:name',
a2431b7d 24 executeIfActivityPub(asyncMiddleware(localAccountValidator)),
4e50b6a1 25 executeIfActivityPub(accountController)
e4f97bab 26)
7006bc63 27activityPubClientRouter.get('/accounts?/:name/followers',
a2431b7d 28 executeIfActivityPub(asyncMiddleware(localAccountValidator)),
e4f97bab
C
29 executeIfActivityPub(asyncMiddleware(accountFollowersController))
30)
7006bc63 31activityPubClientRouter.get('/accounts?/:name/following',
a2431b7d 32 executeIfActivityPub(asyncMiddleware(localAccountValidator)),
e4f97bab
C
33 executeIfActivityPub(asyncMiddleware(accountFollowingController))
34)
35
20494f12 36activityPubClientRouter.get('/videos/watch/:id',
a2431b7d 37 executeIfActivityPub(asyncMiddleware(videosGetValidator)),
da854ddd 38 executeIfActivityPub(asyncMiddleware(videoController))
4e50b6a1 39)
296c0905
C
40activityPubClientRouter.get('/videos/watch/:id/activity',
41 executeIfActivityPub(asyncMiddleware(videosGetValidator)),
42 executeIfActivityPub(asyncMiddleware(videoController))
43)
46531a0a
C
44activityPubClientRouter.get('/videos/watch/:id/announces',
45 executeIfActivityPub(asyncMiddleware(videosGetValidator)),
46 executeIfActivityPub(asyncMiddleware(videoAnnouncesController))
47)
4e50b6a1
C
48activityPubClientRouter.get('/videos/watch/:id/announces/:accountId',
49 executeIfActivityPub(asyncMiddleware(videosShareValidator)),
50 executeIfActivityPub(asyncMiddleware(videoAnnounceController))
20494f12 51)
46531a0a
C
52activityPubClientRouter.get('/videos/watch/:id/likes',
53 executeIfActivityPub(asyncMiddleware(videosGetValidator)),
54 executeIfActivityPub(asyncMiddleware(videoLikesController))
55)
56activityPubClientRouter.get('/videos/watch/:id/dislikes',
57 executeIfActivityPub(asyncMiddleware(videosGetValidator)),
58 executeIfActivityPub(asyncMiddleware(videoDislikesController))
59)
60activityPubClientRouter.get('/videos/watch/:id/comments',
61 executeIfActivityPub(asyncMiddleware(videosGetValidator)),
62 executeIfActivityPub(asyncMiddleware(videoCommentsController))
63)
da854ddd
C
64activityPubClientRouter.get('/videos/watch/:videoId/comments/:commentId',
65 executeIfActivityPub(asyncMiddleware(videoCommentGetValidator)),
66 executeIfActivityPub(asyncMiddleware(videoCommentController))
67)
296c0905
C
68activityPubClientRouter.get('/videos/watch/:videoId/comments/:commentId/activity',
69 executeIfActivityPub(asyncMiddleware(videoCommentGetValidator)),
70 executeIfActivityPub(asyncMiddleware(videoCommentController))
71)
da854ddd 72
20494f12 73activityPubClientRouter.get('/video-channels/:id',
a2431b7d 74 executeIfActivityPub(asyncMiddleware(videoChannelsGetValidator)),
20494f12
C
75 executeIfActivityPub(asyncMiddleware(videoChannelController))
76)
7006bc63
C
77activityPubClientRouter.get('/video-channels/:id/followers',
78 executeIfActivityPub(asyncMiddleware(videoChannelsGetValidator)),
79 executeIfActivityPub(asyncMiddleware(videoChannelFollowersController))
80)
81activityPubClientRouter.get('/video-channels/:id/following',
82 executeIfActivityPub(asyncMiddleware(videoChannelsGetValidator)),
83 executeIfActivityPub(asyncMiddleware(videoChannelFollowingController))
84)
20494f12 85
e4f97bab
C
86// ---------------------------------------------------------------------------
87
88export {
89 activityPubClientRouter
90}
91
92// ---------------------------------------------------------------------------
93
4e50b6a1 94function accountController (req: express.Request, res: express.Response, next: express.NextFunction) {
3fd3ab2d 95 const account: AccountModel = res.locals.account
e4f97bab 96
4b8f09fa 97 return activityPubResponse(activityPubContextify(account.toActivityPubObject()), res)
e4f97bab
C
98}
99
100async function accountFollowersController (req: express.Request, res: express.Response, next: express.NextFunction) {
3fd3ab2d 101 const account: AccountModel = res.locals.account
7006bc63 102 const activityPubResult = await actorFollowers(req, account.Actor)
e4f97bab 103
4b8f09fa 104 return activityPubResponse(activityPubContextify(activityPubResult), res)
e4f97bab
C
105}
106
107async function accountFollowingController (req: express.Request, res: express.Response, next: express.NextFunction) {
3fd3ab2d 108 const account: AccountModel = res.locals.account
7006bc63 109 const activityPubResult = await actorFollowing(req, account.Actor)
e4f97bab 110
4b8f09fa 111 return activityPubResponse(activityPubContextify(activityPubResult), res)
e4f97bab 112}
20494f12 113
da854ddd 114async function videoController (req: express.Request, res: express.Response, next: express.NextFunction) {
3fd3ab2d 115 const video: VideoModel = res.locals.video
20494f12 116
da854ddd
C
117 // We need more attributes
118 const videoAll = await VideoModel.loadAndPopulateAll(video.id)
2ccaeeb3 119 const audience = await getAudience(video.VideoChannel.Account.Actor, undefined, video.privacy === VideoPrivacy.PUBLIC)
d6e99e53 120 const videoObject = audiencify(videoAll.toActivityPubObject(), audience)
2ccaeeb3 121
296c0905
C
122 if (req.path.endsWith('/activity')) {
123 const data = await createActivityData(video.url, video.VideoChannel.Account.Actor, videoObject, undefined, audience)
4b8f09fa 124 return activityPubResponse(activityPubContextify(data), res)
296c0905
C
125 }
126
4b8f09fa 127 return activityPubResponse(activityPubContextify(videoObject), res)
20494f12
C
128}
129
4e50b6a1 130async function videoAnnounceController (req: express.Request, res: express.Response, next: express.NextFunction) {
3fd3ab2d 131 const share = res.locals.videoShare as VideoShareModel
07197db4 132 const object = await buildVideoAnnounce(share.Actor, share, res.locals.video, undefined)
4e50b6a1 133
4b8f09fa 134 return activityPubResponse(activityPubContextify(object), res)
4e50b6a1
C
135}
136
46531a0a
C
137async function videoAnnouncesController (req: express.Request, res: express.Response, next: express.NextFunction) {
138 const video: VideoModel = res.locals.video
139
140 // We need more attributes
141 const videoAll = await VideoModel.loadAndPopulateAll(video.id)
142 const object = videoAll.toAnnouncesActivityPubObject()
143
4b8f09fa 144 return activityPubResponse(activityPubContextify(object), res)
46531a0a
C
145}
146
147async function videoLikesController (req: express.Request, res: express.Response, next: express.NextFunction) {
148 const video: VideoModel = res.locals.video
149
150 // We need more attributes
151 const videoAll = await VideoModel.loadAndPopulateAll(video.id)
152 const { likesObject } = videoAll.toRatesActivityPubObjects()
153
4b8f09fa 154 return activityPubResponse(activityPubContextify(likesObject), res)
46531a0a
C
155}
156
157async function videoDislikesController (req: express.Request, res: express.Response, next: express.NextFunction) {
158 const video: VideoModel = res.locals.video
159
160 // We need more attributes
161 const videoAll = await VideoModel.loadAndPopulateAll(video.id)
162 const { dislikesObject } = videoAll.toRatesActivityPubObjects()
163
4b8f09fa 164 return activityPubResponse(activityPubContextify(dislikesObject), res)
46531a0a
C
165}
166
167async function videoCommentsController (req: express.Request, res: express.Response, next: express.NextFunction) {
168 const video: VideoModel = res.locals.video
169
170 // We need more attributes
171 const videoAll = await VideoModel.loadAndPopulateAll(video.id)
172 const commentsObject = videoAll.toCommentsActivityPubObject()
173
4b8f09fa 174 return activityPubResponse(activityPubContextify(commentsObject), res)
46531a0a
C
175}
176
20494f12 177async function videoChannelController (req: express.Request, res: express.Response, next: express.NextFunction) {
3fd3ab2d 178 const videoChannel: VideoChannelModel = res.locals.videoChannel
20494f12 179
4b8f09fa 180 return activityPubResponse(activityPubContextify(videoChannel.toActivityPubObject()), res)
20494f12 181}
da854ddd 182
7006bc63
C
183async function videoChannelFollowersController (req: express.Request, res: express.Response, next: express.NextFunction) {
184 const videoChannel: VideoChannelModel = res.locals.videoChannel
185 const activityPubResult = await actorFollowers(req, videoChannel.Actor)
186
4b8f09fa 187 return activityPubResponse(activityPubContextify(activityPubResult), res)
7006bc63
C
188}
189
190async function videoChannelFollowingController (req: express.Request, res: express.Response, next: express.NextFunction) {
191 const videoChannel: VideoChannelModel = res.locals.videoChannel
192 const activityPubResult = await actorFollowing(req, videoChannel.Actor)
193
4b8f09fa 194 return activityPubResponse(activityPubContextify(activityPubResult), res)
7006bc63
C
195}
196
da854ddd
C
197async function videoCommentController (req: express.Request, res: express.Response, next: express.NextFunction) {
198 const videoComment: VideoCommentModel = res.locals.videoComment
199
d7e70384 200 const threadParentComments = await VideoCommentModel.listThreadParentComments(videoComment, undefined)
d6e99e53
C
201 const isPublic = true // Comments are always public
202 const audience = await getAudience(videoComment.Account.Actor, undefined, isPublic)
203
204 const videoCommentObject = audiencify(videoComment.toActivityPubObject(threadParentComments), audience)
205
296c0905
C
206 if (req.path.endsWith('/activity')) {
207 const data = await createActivityData(videoComment.url, videoComment.Account.Actor, videoCommentObject, undefined, audience)
4b8f09fa 208 return activityPubResponse(activityPubContextify(data), res)
296c0905
C
209 }
210
4b8f09fa 211 return activityPubResponse(activityPubContextify(videoCommentObject), res)
da854ddd 212}
7006bc63
C
213
214// ---------------------------------------------------------------------------
215
216async function actorFollowing (req: express.Request, actor: ActorModel) {
217 const page = req.query.page || 1
218 const { start, count } = pageToStartAndCount(page, ACTIVITY_PUB.COLLECTION_ITEMS_PER_PAGE)
219
220 const result = await ActorFollowModel.listAcceptedFollowingUrlsForApi([ actor.id ], undefined, start, count)
221 return activityPubCollectionPagination(CONFIG.WEBSERVER.URL + req.url, page, result)
222}
223
224async function actorFollowers (req: express.Request, actor: ActorModel) {
225 const page = req.query.page || 1
226 const { start, count } = pageToStartAndCount(page, ACTIVITY_PUB.COLLECTION_ITEMS_PER_PAGE)
227
228 const result = await ActorFollowModel.listAcceptedFollowerUrlsForApi([ actor.id ], undefined, start, count)
229 return activityPubCollectionPagination(CONFIG.WEBSERVER.URL + req.url, page, result)
230}
4b8f09fa
C
231
232function activityPubResponse (data: any, res: express.Response) {
233 return res.type('application/activity+json; charset=utf-8')
234 .json(data)
235 .end()
236}