aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorlutangar <johan.dufour@gmail.com>2021-11-24 14:33:14 +0100
committerChocobozzz <chocobozzz@cpy.re>2021-11-25 09:54:22 +0100
commit7226e90fdc61a3c6cad5ccab18b6707d55cf0992 (patch)
tree0bdd7304352b1af2d9ae87439486a138e02d46e8
parent5098098d96164c93f84ec8419e98fbd83ba8dc71 (diff)
downloadPeerTube-7226e90fdc61a3c6cad5ccab18b6707d55cf0992.tar.gz
PeerTube-7226e90fdc61a3c6cad5ccab18b6707d55cf0992.tar.zst
PeerTube-7226e90fdc61a3c6cad5ccab18b6707d55cf0992.zip
Add `req` and `res` as controllers hooks parameters
Hooks prefixed by `action:api` now give access the original express req and res. Checkout guide.md for possible usage.
-rw-r--r--server/controllers/api/bulk.ts2
-rw-r--r--server/controllers/api/users/index.ts12
-rw-r--r--server/controllers/api/users/token.ts2
-rw-r--r--server/controllers/api/video-playlist.ts2
-rw-r--r--server/controllers/api/videos/comment.ts6
-rw-r--r--server/controllers/api/videos/index.ts6
-rw-r--r--server/controllers/api/videos/live.ts2
-rw-r--r--server/controllers/api/videos/update.ts2
-rw-r--r--server/controllers/api/videos/upload.ts9
-rw-r--r--server/lib/video-comment.ts5
-rw-r--r--shared/models/plugins/server/server-hook.model.ts2
-rw-r--r--support/doc/plugins/guide.md14
12 files changed, 41 insertions, 23 deletions
diff --git a/server/controllers/api/bulk.ts b/server/controllers/api/bulk.ts
index d27c3c73e..51292175b 100644
--- a/server/controllers/api/bulk.ts
+++ b/server/controllers/api/bulk.ts
@@ -37,6 +37,6 @@ async function bulkRemoveCommentsOf (req: express.Request, res: express.Response
37 res.status(HttpStatusCode.NO_CONTENT_204).end() 37 res.status(HttpStatusCode.NO_CONTENT_204).end()
38 38
39 for (const comment of comments) { 39 for (const comment of comments) {
40 await removeComment(comment) 40 await removeComment(comment, req, res)
41 } 41 }
42} 42}
diff --git a/server/controllers/api/users/index.ts b/server/controllers/api/users/index.ts
index bc47e5fec..11d3525e4 100644
--- a/server/controllers/api/users/index.ts
+++ b/server/controllers/api/users/index.ts
@@ -212,7 +212,7 @@ async function createUser (req: express.Request, res: express.Response) {
212 await Emailer.Instance.addPasswordCreateEmailJob(userToCreate.username, user.email, url) 212 await Emailer.Instance.addPasswordCreateEmailJob(userToCreate.username, user.email, url)
213 } 213 }
214 214
215 Hooks.runAction('action:api.user.created', { body, user, account, videoChannel }) 215 Hooks.runAction('action:api.user.created', { body, user, account, videoChannel, req, res })
216 216
217 return res.json({ 217 return res.json({
218 user: { 218 user: {
@@ -254,7 +254,7 @@ async function registerUser (req: express.Request, res: express.Response) {
254 254
255 Notifier.Instance.notifyOnNewUserRegistration(user) 255 Notifier.Instance.notifyOnNewUserRegistration(user)
256 256
257 Hooks.runAction('action:api.user.registered', { body, user, account, videoChannel }) 257 Hooks.runAction('action:api.user.registered', { body, user, account, videoChannel, req, res })
258 258
259 return res.type('json').status(HttpStatusCode.NO_CONTENT_204).end() 259 return res.type('json').status(HttpStatusCode.NO_CONTENT_204).end()
260} 260}
@@ -264,7 +264,7 @@ async function unblockUser (req: express.Request, res: express.Response) {
264 264
265 await changeUserBlock(res, user, false) 265 await changeUserBlock(res, user, false)
266 266
267 Hooks.runAction('action:api.user.unblocked', { user }) 267 Hooks.runAction('action:api.user.unblocked', { user, req, res })
268 268
269 return res.status(HttpStatusCode.NO_CONTENT_204).end() 269 return res.status(HttpStatusCode.NO_CONTENT_204).end()
270} 270}
@@ -275,7 +275,7 @@ async function blockUser (req: express.Request, res: express.Response) {
275 275
276 await changeUserBlock(res, user, true, reason) 276 await changeUserBlock(res, user, true, reason)
277 277
278 Hooks.runAction('action:api.user.blocked', { user }) 278 Hooks.runAction('action:api.user.blocked', { user, req, res })
279 279
280 return res.status(HttpStatusCode.NO_CONTENT_204).end() 280 return res.status(HttpStatusCode.NO_CONTENT_204).end()
281} 281}
@@ -312,7 +312,7 @@ async function removeUser (req: express.Request, res: express.Response) {
312 await user.destroy({ transaction: t }) 312 await user.destroy({ transaction: t })
313 }) 313 })
314 314
315 Hooks.runAction('action:api.user.deleted', { user }) 315 Hooks.runAction('action:api.user.deleted', { user, req, res })
316 316
317 return res.status(HttpStatusCode.NO_CONTENT_204).end() 317 return res.status(HttpStatusCode.NO_CONTENT_204).end()
318} 318}
@@ -345,7 +345,7 @@ async function updateUser (req: express.Request, res: express.Response) {
345 345
346 auditLogger.update(getAuditIdFromRes(res), new UserAuditView(user.toFormattedJSON()), oldUserAuditView) 346 auditLogger.update(getAuditIdFromRes(res), new UserAuditView(user.toFormattedJSON()), oldUserAuditView)
347 347
348 Hooks.runAction('action:api.user.updated', { user }) 348 Hooks.runAction('action:api.user.updated', { user, req, res })
349 349
350 // Don't need to send this update to followers, these attributes are not federated 350 // Don't need to send this update to followers, these attributes are not federated
351 351
diff --git a/server/controllers/api/users/token.ts b/server/controllers/api/users/token.ts
index d5dbe921c..1d4004ce0 100644
--- a/server/controllers/api/users/token.ts
+++ b/server/controllers/api/users/token.ts
@@ -66,7 +66,7 @@ async function handleToken (req: express.Request, res: express.Response, next: e
66 res.set('Cache-Control', 'no-store') 66 res.set('Cache-Control', 'no-store')
67 res.set('Pragma', 'no-cache') 67 res.set('Pragma', 'no-cache')
68 68
69 Hooks.runAction('action:api.user.oauth2-got-token', { username: token.user.username, ip: req.ip }) 69 Hooks.runAction('action:api.user.oauth2-got-token', { username: token.user.username, ip: req.ip, req, res })
70 70
71 return res.json({ 71 return res.json({
72 token_type: 'Bearer', 72 token_type: 'Bearer',
diff --git a/server/controllers/api/video-playlist.ts b/server/controllers/api/video-playlist.ts
index 2347e18d2..8b7a76718 100644
--- a/server/controllers/api/video-playlist.ts
+++ b/server/controllers/api/video-playlist.ts
@@ -334,7 +334,7 @@ async function addVideoInPlaylist (req: express.Request, res: express.Response)
334 334
335 logger.info('Video added in playlist %s at position %d.', videoPlaylist.uuid, playlistElement.position) 335 logger.info('Video added in playlist %s at position %d.', videoPlaylist.uuid, playlistElement.position)
336 336
337 Hooks.runAction('action:api.video-playlist-element.created', { playlistElement }) 337 Hooks.runAction('action:api.video-playlist-element.created', { playlistElement, req, res })
338 338
339 return res.json({ 339 return res.json({
340 videoPlaylistElement: { 340 videoPlaylistElement: {
diff --git a/server/controllers/api/videos/comment.ts b/server/controllers/api/videos/comment.ts
index 23bba9089..47fa2f2e2 100644
--- a/server/controllers/api/videos/comment.ts
+++ b/server/controllers/api/videos/comment.ts
@@ -192,7 +192,7 @@ async function addVideoCommentThread (req: express.Request, res: express.Respons
192 Notifier.Instance.notifyOnNewComment(comment) 192 Notifier.Instance.notifyOnNewComment(comment)
193 auditLogger.create(getAuditIdFromRes(res), new CommentAuditView(comment.toFormattedJSON())) 193 auditLogger.create(getAuditIdFromRes(res), new CommentAuditView(comment.toFormattedJSON()))
194 194
195 Hooks.runAction('action:api.video-thread.created', { comment }) 195 Hooks.runAction('action:api.video-thread.created', { comment, req, res })
196 196
197 return res.json({ comment: comment.toFormattedJSON() }) 197 return res.json({ comment: comment.toFormattedJSON() })
198} 198}
@@ -214,7 +214,7 @@ async function addVideoCommentReply (req: express.Request, res: express.Response
214 Notifier.Instance.notifyOnNewComment(comment) 214 Notifier.Instance.notifyOnNewComment(comment)
215 auditLogger.create(getAuditIdFromRes(res), new CommentAuditView(comment.toFormattedJSON())) 215 auditLogger.create(getAuditIdFromRes(res), new CommentAuditView(comment.toFormattedJSON()))
216 216
217 Hooks.runAction('action:api.video-comment-reply.created', { comment }) 217 Hooks.runAction('action:api.video-comment-reply.created', { comment, req, res })
218 218
219 return res.json({ comment: comment.toFormattedJSON() }) 219 return res.json({ comment: comment.toFormattedJSON() })
220} 220}
@@ -222,7 +222,7 @@ async function addVideoCommentReply (req: express.Request, res: express.Response
222async function removeVideoComment (req: express.Request, res: express.Response) { 222async function removeVideoComment (req: express.Request, res: express.Response) {
223 const videoCommentInstance = res.locals.videoCommentFull 223 const videoCommentInstance = res.locals.videoCommentFull
224 224
225 await removeComment(videoCommentInstance) 225 await removeComment(videoCommentInstance, req, res)
226 226
227 auditLogger.delete(getAuditIdFromRes(res), new CommentAuditView(videoCommentInstance.toFormattedJSON())) 227 auditLogger.delete(getAuditIdFromRes(res), new CommentAuditView(videoCommentInstance.toFormattedJSON()))
228 228
diff --git a/server/controllers/api/videos/index.ts b/server/controllers/api/videos/index.ts
index fc1bcc73d..61a030ba1 100644
--- a/server/controllers/api/videos/index.ts
+++ b/server/controllers/api/videos/index.ts
@@ -158,7 +158,7 @@ async function viewVideo (req: express.Request, res: express.Response) {
158 const serverActor = await getServerActor() 158 const serverActor = await getServerActor()
159 await sendView(serverActor, video, undefined) 159 await sendView(serverActor, video, undefined)
160 160
161 Hooks.runAction('action:api.video.viewed', { video: video, ip }) 161 Hooks.runAction('action:api.video.viewed', { video: video, ip, req, res })
162 } 162 }
163 163
164 return res.status(HttpStatusCode.NO_CONTENT_204).end() 164 return res.status(HttpStatusCode.NO_CONTENT_204).end()
@@ -201,7 +201,7 @@ async function listVideos (req: express.Request, res: express.Response) {
201 return res.json(getFormattedObjects(resultList.data, resultList.total, guessAdditionalAttributesFromQuery(query))) 201 return res.json(getFormattedObjects(resultList.data, resultList.total, guessAdditionalAttributesFromQuery(query)))
202} 202}
203 203
204async function removeVideo (_req: express.Request, res: express.Response) { 204async function removeVideo (req: express.Request, res: express.Response) {
205 const videoInstance = res.locals.videoAll 205 const videoInstance = res.locals.videoAll
206 206
207 await sequelizeTypescript.transaction(async t => { 207 await sequelizeTypescript.transaction(async t => {
@@ -211,7 +211,7 @@ async function removeVideo (_req: express.Request, res: express.Response) {
211 auditLogger.delete(getAuditIdFromRes(res), new VideoAuditView(videoInstance.toFormattedDetailsJSON())) 211 auditLogger.delete(getAuditIdFromRes(res), new VideoAuditView(videoInstance.toFormattedDetailsJSON()))
212 logger.info('Video with name %s and uuid %s deleted.', videoInstance.name, videoInstance.uuid) 212 logger.info('Video with name %s and uuid %s deleted.', videoInstance.name, videoInstance.uuid)
213 213
214 Hooks.runAction('action:api.video.deleted', { video: videoInstance }) 214 Hooks.runAction('action:api.video.deleted', { video: videoInstance, req, res })
215 215
216 return res.type('json') 216 return res.type('json')
217 .status(HttpStatusCode.NO_CONTENT_204) 217 .status(HttpStatusCode.NO_CONTENT_204)
diff --git a/server/controllers/api/videos/live.ts b/server/controllers/api/videos/live.ts
index efafe64e9..e29615ff5 100644
--- a/server/controllers/api/videos/live.ts
+++ b/server/controllers/api/videos/live.ts
@@ -133,7 +133,7 @@ async function addLiveVideo (req: express.Request, res: express.Response) {
133 return { videoCreated } 133 return { videoCreated }
134 }) 134 })
135 135
136 Hooks.runAction('action:api.live-video.created', { video: videoCreated }) 136 Hooks.runAction('action:api.live-video.created', { video: videoCreated, req, res })
137 137
138 return res.json({ 138 return res.json({
139 video: { 139 video: {
diff --git a/server/controllers/api/videos/update.ts b/server/controllers/api/videos/update.ts
index de5d94d55..3fcff3e86 100644
--- a/server/controllers/api/videos/update.ts
+++ b/server/controllers/api/videos/update.ts
@@ -153,7 +153,7 @@ async function updateVideo (req: express.Request, res: express.Response) {
153 Notifier.Instance.notifyOnNewVideoIfNeeded(videoInstanceUpdated) 153 Notifier.Instance.notifyOnNewVideoIfNeeded(videoInstanceUpdated)
154 } 154 }
155 155
156 Hooks.runAction('action:api.video.updated', { video: videoInstanceUpdated, body: req.body }) 156 Hooks.runAction('action:api.video.updated', { video: videoInstanceUpdated, body: req.body, req, res })
157 } catch (err) { 157 } catch (err) {
158 // Force fields we want to update 158 // Force fields we want to update
159 // If the transaction is retried, sequelize will think the object has not changed 159 // If the transaction is retried, sequelize will think the object has not changed
diff --git a/server/controllers/api/videos/upload.ts b/server/controllers/api/videos/upload.ts
index 3e9979330..6773b500f 100644
--- a/server/controllers/api/videos/upload.ts
+++ b/server/controllers/api/videos/upload.ts
@@ -129,7 +129,7 @@ async function addVideoLegacy (req: express.Request, res: express.Response) {
129 const videoInfo: VideoCreate = req.body 129 const videoInfo: VideoCreate = req.body
130 const files = req.files 130 const files = req.files
131 131
132 const response = await addVideo({ res, videoPhysicalFile, videoInfo, files }) 132 const response = await addVideo({ req, res, videoPhysicalFile, videoInfo, files })
133 133
134 return res.json(response) 134 return res.json(response)
135} 135}
@@ -139,19 +139,20 @@ async function addVideoResumable (req: express.Request, res: express.Response) {
139 const videoInfo = videoPhysicalFile.metadata 139 const videoInfo = videoPhysicalFile.metadata
140 const files = { previewfile: videoInfo.previewfile } 140 const files = { previewfile: videoInfo.previewfile }
141 141
142 const response = await addVideo({ res, videoPhysicalFile, videoInfo, files }) 142 const response = await addVideo({ req, res, videoPhysicalFile, videoInfo, files })
143 await Redis.Instance.setUploadSession(req.query.upload_id, response) 143 await Redis.Instance.setUploadSession(req.query.upload_id, response)
144 144
145 return res.json(response) 145 return res.json(response)
146} 146}
147 147
148async function addVideo (options: { 148async function addVideo (options: {
149 req: express.Request
149 res: express.Response 150 res: express.Response
150 videoPhysicalFile: express.VideoUploadFile 151 videoPhysicalFile: express.VideoUploadFile
151 videoInfo: VideoCreate 152 videoInfo: VideoCreate
152 files: express.UploadFiles 153 files: express.UploadFiles
153}) { 154}) {
154 const { res, videoPhysicalFile, videoInfo, files } = options 155 const { req, res, videoPhysicalFile, videoInfo, files } = options
155 const videoChannel = res.locals.videoChannel 156 const videoChannel = res.locals.videoChannel
156 const user = res.locals.oauth.token.User 157 const user = res.locals.oauth.token.User
157 158
@@ -235,7 +236,7 @@ async function addVideo (options: {
235 }) 236 })
236 .catch(err => logger.error('Cannot add optimize/merge audio job for %s.', videoCreated.uuid, { err, ...lTags(videoCreated.uuid) })) 237 .catch(err => logger.error('Cannot add optimize/merge audio job for %s.', videoCreated.uuid, { err, ...lTags(videoCreated.uuid) }))
237 238
238 Hooks.runAction('action:api.video.uploaded', { video: videoCreated }) 239 Hooks.runAction('action:api.video.uploaded', { video: videoCreated, req, res })
239 240
240 return { 241 return {
241 video: { 242 video: {
diff --git a/server/lib/video-comment.ts b/server/lib/video-comment.ts
index c76570a5d..02f160fe8 100644
--- a/server/lib/video-comment.ts
+++ b/server/lib/video-comment.ts
@@ -1,5 +1,6 @@
1import { cloneDeep } from 'lodash' 1import { cloneDeep } from 'lodash'
2import * as Sequelize from 'sequelize' 2import * as Sequelize from 'sequelize'
3import express from 'express'
3import { logger } from '@server/helpers/logger' 4import { logger } from '@server/helpers/logger'
4import { sequelizeTypescript } from '@server/initializers/database' 5import { sequelizeTypescript } from '@server/initializers/database'
5import { ResultList } from '../../shared/models' 6import { ResultList } from '../../shared/models'
@@ -10,7 +11,7 @@ import { sendCreateVideoComment, sendDeleteVideoComment } from './activitypub/se
10import { getLocalVideoCommentActivityPubUrl } from './activitypub/url' 11import { getLocalVideoCommentActivityPubUrl } from './activitypub/url'
11import { Hooks } from './plugins/hooks' 12import { Hooks } from './plugins/hooks'
12 13
13async function removeComment (videoCommentInstance: MCommentOwnerVideo) { 14async function removeComment (videoCommentInstance: MCommentOwnerVideo, req: express.Request, res: express.Response) {
14 const videoCommentInstanceBefore = cloneDeep(videoCommentInstance) 15 const videoCommentInstanceBefore = cloneDeep(videoCommentInstance)
15 16
16 await sequelizeTypescript.transaction(async t => { 17 await sequelizeTypescript.transaction(async t => {
@@ -25,7 +26,7 @@ async function removeComment (videoCommentInstance: MCommentOwnerVideo) {
25 26
26 logger.info('Video comment %d deleted.', videoCommentInstance.id) 27 logger.info('Video comment %d deleted.', videoCommentInstance.id)
27 28
28 Hooks.runAction('action:api.video-comment.deleted', { comment: videoCommentInstanceBefore }) 29 Hooks.runAction('action:api.video-comment.deleted', { comment: videoCommentInstanceBefore, req, res })
29} 30}
30 31
31async function createVideoComment (obj: { 32async function createVideoComment (obj: {
diff --git a/shared/models/plugins/server/server-hook.model.ts b/shared/models/plugins/server/server-hook.model.ts
index 562c6eb12..3ab910197 100644
--- a/shared/models/plugins/server/server-hook.model.ts
+++ b/shared/models/plugins/server/server-hook.model.ts
@@ -85,6 +85,8 @@ export const serverActionHookObject = {
85 // Fired when the application has been loaded and is listening HTTP requests 85 // Fired when the application has been loaded and is listening HTTP requests
86 'action:application.listening': true, 86 'action:application.listening': true,
87 87
88 // API actions hooks give access to the original express `req` and `res` parameters
89
88 // Fired when a local video is updated 90 // Fired when a local video is updated
89 'action:api.video.updated': true, 91 'action:api.video.updated': true,
90 // Fired when a local video is deleted 92 // Fired when a local video is deleted
diff --git a/support/doc/plugins/guide.md b/support/doc/plugins/guide.md
index 072c7c6ca..acf4718e4 100644
--- a/support/doc/plugins/guide.md
+++ b/support/doc/plugins/guide.md
@@ -108,6 +108,20 @@ async function register ({
108} 108}
109``` 109```
110 110
111Hooks prefixed by `action:api` also give access the original **express** [Request](http://expressjs.com/en/api.html#req) and [Response](http://expressjs.com/en/api.html#res):
112
113```js
114async function register ({
115 registerHook,
116 peertubeHelpers: { logger }
117}) {
118 registerHook({
119 target: 'action:api.video.updated',
120 handler: ({ req, res }) => logger.debug('original request parameters', { params: req.params })
121 })
122}
123```
124
111 125
112On client side, these hooks are registered by the `clientScripts` files defined in `package.json`. 126On client side, these hooks are registered by the `clientScripts` files defined in `package.json`.
113All client scripts have scopes so PeerTube client only loads scripts it needs: 127All client scripts have scopes so PeerTube client only loads scripts it needs: