diff options
author | lutangar <johan.dufour@gmail.com> | 2021-11-24 14:33:14 +0100 |
---|---|---|
committer | Chocobozzz <chocobozzz@cpy.re> | 2021-11-25 09:54:22 +0100 |
commit | 7226e90fdc61a3c6cad5ccab18b6707d55cf0992 (patch) | |
tree | 0bdd7304352b1af2d9ae87439486a138e02d46e8 | |
parent | 5098098d96164c93f84ec8419e98fbd83ba8dc71 (diff) | |
download | PeerTube-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.ts | 2 | ||||
-rw-r--r-- | server/controllers/api/users/index.ts | 12 | ||||
-rw-r--r-- | server/controllers/api/users/token.ts | 2 | ||||
-rw-r--r-- | server/controllers/api/video-playlist.ts | 2 | ||||
-rw-r--r-- | server/controllers/api/videos/comment.ts | 6 | ||||
-rw-r--r-- | server/controllers/api/videos/index.ts | 6 | ||||
-rw-r--r-- | server/controllers/api/videos/live.ts | 2 | ||||
-rw-r--r-- | server/controllers/api/videos/update.ts | 2 | ||||
-rw-r--r-- | server/controllers/api/videos/upload.ts | 9 | ||||
-rw-r--r-- | server/lib/video-comment.ts | 5 | ||||
-rw-r--r-- | shared/models/plugins/server/server-hook.model.ts | 2 | ||||
-rw-r--r-- | support/doc/plugins/guide.md | 14 |
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 | |||
222 | async function removeVideoComment (req: express.Request, res: express.Response) { | 222 | async 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 | ||
204 | async function removeVideo (_req: express.Request, res: express.Response) { | 204 | async 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 | ||
148 | async function addVideo (options: { | 148 | async 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 @@ | |||
1 | import { cloneDeep } from 'lodash' | 1 | import { cloneDeep } from 'lodash' |
2 | import * as Sequelize from 'sequelize' | 2 | import * as Sequelize from 'sequelize' |
3 | import express from 'express' | ||
3 | import { logger } from '@server/helpers/logger' | 4 | import { logger } from '@server/helpers/logger' |
4 | import { sequelizeTypescript } from '@server/initializers/database' | 5 | import { sequelizeTypescript } from '@server/initializers/database' |
5 | import { ResultList } from '../../shared/models' | 6 | import { ResultList } from '../../shared/models' |
@@ -10,7 +11,7 @@ import { sendCreateVideoComment, sendDeleteVideoComment } from './activitypub/se | |||
10 | import { getLocalVideoCommentActivityPubUrl } from './activitypub/url' | 11 | import { getLocalVideoCommentActivityPubUrl } from './activitypub/url' |
11 | import { Hooks } from './plugins/hooks' | 12 | import { Hooks } from './plugins/hooks' |
12 | 13 | ||
13 | async function removeComment (videoCommentInstance: MCommentOwnerVideo) { | 14 | async 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 | ||
31 | async function createVideoComment (obj: { | 32 | async 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 | ||
111 | Hooks 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 | ||
114 | async 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 | ||
112 | On client side, these hooks are registered by the `clientScripts` files defined in `package.json`. | 126 | On client side, these hooks are registered by the `clientScripts` files defined in `package.json`. |
113 | All client scripts have scopes so PeerTube client only loads scripts it needs: | 127 | All client scripts have scopes so PeerTube client only loads scripts it needs: |