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.
This commit is contained in:
parent
5098098d96
commit
7226e90fdc
|
@ -37,6 +37,6 @@ async function bulkRemoveCommentsOf (req: express.Request, res: express.Response
|
||||||
res.status(HttpStatusCode.NO_CONTENT_204).end()
|
res.status(HttpStatusCode.NO_CONTENT_204).end()
|
||||||
|
|
||||||
for (const comment of comments) {
|
for (const comment of comments) {
|
||||||
await removeComment(comment)
|
await removeComment(comment, req, res)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -212,7 +212,7 @@ async function createUser (req: express.Request, res: express.Response) {
|
||||||
await Emailer.Instance.addPasswordCreateEmailJob(userToCreate.username, user.email, url)
|
await Emailer.Instance.addPasswordCreateEmailJob(userToCreate.username, user.email, url)
|
||||||
}
|
}
|
||||||
|
|
||||||
Hooks.runAction('action:api.user.created', { body, user, account, videoChannel })
|
Hooks.runAction('action:api.user.created', { body, user, account, videoChannel, req, res })
|
||||||
|
|
||||||
return res.json({
|
return res.json({
|
||||||
user: {
|
user: {
|
||||||
|
@ -254,7 +254,7 @@ async function registerUser (req: express.Request, res: express.Response) {
|
||||||
|
|
||||||
Notifier.Instance.notifyOnNewUserRegistration(user)
|
Notifier.Instance.notifyOnNewUserRegistration(user)
|
||||||
|
|
||||||
Hooks.runAction('action:api.user.registered', { body, user, account, videoChannel })
|
Hooks.runAction('action:api.user.registered', { body, user, account, videoChannel, req, res })
|
||||||
|
|
||||||
return res.type('json').status(HttpStatusCode.NO_CONTENT_204).end()
|
return res.type('json').status(HttpStatusCode.NO_CONTENT_204).end()
|
||||||
}
|
}
|
||||||
|
@ -264,7 +264,7 @@ async function unblockUser (req: express.Request, res: express.Response) {
|
||||||
|
|
||||||
await changeUserBlock(res, user, false)
|
await changeUserBlock(res, user, false)
|
||||||
|
|
||||||
Hooks.runAction('action:api.user.unblocked', { user })
|
Hooks.runAction('action:api.user.unblocked', { user, req, res })
|
||||||
|
|
||||||
return res.status(HttpStatusCode.NO_CONTENT_204).end()
|
return res.status(HttpStatusCode.NO_CONTENT_204).end()
|
||||||
}
|
}
|
||||||
|
@ -275,7 +275,7 @@ async function blockUser (req: express.Request, res: express.Response) {
|
||||||
|
|
||||||
await changeUserBlock(res, user, true, reason)
|
await changeUserBlock(res, user, true, reason)
|
||||||
|
|
||||||
Hooks.runAction('action:api.user.blocked', { user })
|
Hooks.runAction('action:api.user.blocked', { user, req, res })
|
||||||
|
|
||||||
return res.status(HttpStatusCode.NO_CONTENT_204).end()
|
return res.status(HttpStatusCode.NO_CONTENT_204).end()
|
||||||
}
|
}
|
||||||
|
@ -312,7 +312,7 @@ async function removeUser (req: express.Request, res: express.Response) {
|
||||||
await user.destroy({ transaction: t })
|
await user.destroy({ transaction: t })
|
||||||
})
|
})
|
||||||
|
|
||||||
Hooks.runAction('action:api.user.deleted', { user })
|
Hooks.runAction('action:api.user.deleted', { user, req, res })
|
||||||
|
|
||||||
return res.status(HttpStatusCode.NO_CONTENT_204).end()
|
return res.status(HttpStatusCode.NO_CONTENT_204).end()
|
||||||
}
|
}
|
||||||
|
@ -345,7 +345,7 @@ async function updateUser (req: express.Request, res: express.Response) {
|
||||||
|
|
||||||
auditLogger.update(getAuditIdFromRes(res), new UserAuditView(user.toFormattedJSON()), oldUserAuditView)
|
auditLogger.update(getAuditIdFromRes(res), new UserAuditView(user.toFormattedJSON()), oldUserAuditView)
|
||||||
|
|
||||||
Hooks.runAction('action:api.user.updated', { user })
|
Hooks.runAction('action:api.user.updated', { user, req, res })
|
||||||
|
|
||||||
// Don't need to send this update to followers, these attributes are not federated
|
// Don't need to send this update to followers, these attributes are not federated
|
||||||
|
|
||||||
|
|
|
@ -66,7 +66,7 @@ async function handleToken (req: express.Request, res: express.Response, next: e
|
||||||
res.set('Cache-Control', 'no-store')
|
res.set('Cache-Control', 'no-store')
|
||||||
res.set('Pragma', 'no-cache')
|
res.set('Pragma', 'no-cache')
|
||||||
|
|
||||||
Hooks.runAction('action:api.user.oauth2-got-token', { username: token.user.username, ip: req.ip })
|
Hooks.runAction('action:api.user.oauth2-got-token', { username: token.user.username, ip: req.ip, req, res })
|
||||||
|
|
||||||
return res.json({
|
return res.json({
|
||||||
token_type: 'Bearer',
|
token_type: 'Bearer',
|
||||||
|
|
|
@ -334,7 +334,7 @@ async function addVideoInPlaylist (req: express.Request, res: express.Response)
|
||||||
|
|
||||||
logger.info('Video added in playlist %s at position %d.', videoPlaylist.uuid, playlistElement.position)
|
logger.info('Video added in playlist %s at position %d.', videoPlaylist.uuid, playlistElement.position)
|
||||||
|
|
||||||
Hooks.runAction('action:api.video-playlist-element.created', { playlistElement })
|
Hooks.runAction('action:api.video-playlist-element.created', { playlistElement, req, res })
|
||||||
|
|
||||||
return res.json({
|
return res.json({
|
||||||
videoPlaylistElement: {
|
videoPlaylistElement: {
|
||||||
|
|
|
@ -192,7 +192,7 @@ async function addVideoCommentThread (req: express.Request, res: express.Respons
|
||||||
Notifier.Instance.notifyOnNewComment(comment)
|
Notifier.Instance.notifyOnNewComment(comment)
|
||||||
auditLogger.create(getAuditIdFromRes(res), new CommentAuditView(comment.toFormattedJSON()))
|
auditLogger.create(getAuditIdFromRes(res), new CommentAuditView(comment.toFormattedJSON()))
|
||||||
|
|
||||||
Hooks.runAction('action:api.video-thread.created', { comment })
|
Hooks.runAction('action:api.video-thread.created', { comment, req, res })
|
||||||
|
|
||||||
return res.json({ comment: comment.toFormattedJSON() })
|
return res.json({ comment: comment.toFormattedJSON() })
|
||||||
}
|
}
|
||||||
|
@ -214,7 +214,7 @@ async function addVideoCommentReply (req: express.Request, res: express.Response
|
||||||
Notifier.Instance.notifyOnNewComment(comment)
|
Notifier.Instance.notifyOnNewComment(comment)
|
||||||
auditLogger.create(getAuditIdFromRes(res), new CommentAuditView(comment.toFormattedJSON()))
|
auditLogger.create(getAuditIdFromRes(res), new CommentAuditView(comment.toFormattedJSON()))
|
||||||
|
|
||||||
Hooks.runAction('action:api.video-comment-reply.created', { comment })
|
Hooks.runAction('action:api.video-comment-reply.created', { comment, req, res })
|
||||||
|
|
||||||
return res.json({ comment: comment.toFormattedJSON() })
|
return res.json({ comment: comment.toFormattedJSON() })
|
||||||
}
|
}
|
||||||
|
@ -222,7 +222,7 @@ async function addVideoCommentReply (req: express.Request, res: express.Response
|
||||||
async function removeVideoComment (req: express.Request, res: express.Response) {
|
async function removeVideoComment (req: express.Request, res: express.Response) {
|
||||||
const videoCommentInstance = res.locals.videoCommentFull
|
const videoCommentInstance = res.locals.videoCommentFull
|
||||||
|
|
||||||
await removeComment(videoCommentInstance)
|
await removeComment(videoCommentInstance, req, res)
|
||||||
|
|
||||||
auditLogger.delete(getAuditIdFromRes(res), new CommentAuditView(videoCommentInstance.toFormattedJSON()))
|
auditLogger.delete(getAuditIdFromRes(res), new CommentAuditView(videoCommentInstance.toFormattedJSON()))
|
||||||
|
|
||||||
|
|
|
@ -158,7 +158,7 @@ async function viewVideo (req: express.Request, res: express.Response) {
|
||||||
const serverActor = await getServerActor()
|
const serverActor = await getServerActor()
|
||||||
await sendView(serverActor, video, undefined)
|
await sendView(serverActor, video, undefined)
|
||||||
|
|
||||||
Hooks.runAction('action:api.video.viewed', { video: video, ip })
|
Hooks.runAction('action:api.video.viewed', { video: video, ip, req, res })
|
||||||
}
|
}
|
||||||
|
|
||||||
return res.status(HttpStatusCode.NO_CONTENT_204).end()
|
return res.status(HttpStatusCode.NO_CONTENT_204).end()
|
||||||
|
@ -201,7 +201,7 @@ async function listVideos (req: express.Request, res: express.Response) {
|
||||||
return res.json(getFormattedObjects(resultList.data, resultList.total, guessAdditionalAttributesFromQuery(query)))
|
return res.json(getFormattedObjects(resultList.data, resultList.total, guessAdditionalAttributesFromQuery(query)))
|
||||||
}
|
}
|
||||||
|
|
||||||
async function removeVideo (_req: express.Request, res: express.Response) {
|
async function removeVideo (req: express.Request, res: express.Response) {
|
||||||
const videoInstance = res.locals.videoAll
|
const videoInstance = res.locals.videoAll
|
||||||
|
|
||||||
await sequelizeTypescript.transaction(async t => {
|
await sequelizeTypescript.transaction(async t => {
|
||||||
|
@ -211,7 +211,7 @@ async function removeVideo (_req: express.Request, res: express.Response) {
|
||||||
auditLogger.delete(getAuditIdFromRes(res), new VideoAuditView(videoInstance.toFormattedDetailsJSON()))
|
auditLogger.delete(getAuditIdFromRes(res), new VideoAuditView(videoInstance.toFormattedDetailsJSON()))
|
||||||
logger.info('Video with name %s and uuid %s deleted.', videoInstance.name, videoInstance.uuid)
|
logger.info('Video with name %s and uuid %s deleted.', videoInstance.name, videoInstance.uuid)
|
||||||
|
|
||||||
Hooks.runAction('action:api.video.deleted', { video: videoInstance })
|
Hooks.runAction('action:api.video.deleted', { video: videoInstance, req, res })
|
||||||
|
|
||||||
return res.type('json')
|
return res.type('json')
|
||||||
.status(HttpStatusCode.NO_CONTENT_204)
|
.status(HttpStatusCode.NO_CONTENT_204)
|
||||||
|
|
|
@ -133,7 +133,7 @@ async function addLiveVideo (req: express.Request, res: express.Response) {
|
||||||
return { videoCreated }
|
return { videoCreated }
|
||||||
})
|
})
|
||||||
|
|
||||||
Hooks.runAction('action:api.live-video.created', { video: videoCreated })
|
Hooks.runAction('action:api.live-video.created', { video: videoCreated, req, res })
|
||||||
|
|
||||||
return res.json({
|
return res.json({
|
||||||
video: {
|
video: {
|
||||||
|
|
|
@ -153,7 +153,7 @@ async function updateVideo (req: express.Request, res: express.Response) {
|
||||||
Notifier.Instance.notifyOnNewVideoIfNeeded(videoInstanceUpdated)
|
Notifier.Instance.notifyOnNewVideoIfNeeded(videoInstanceUpdated)
|
||||||
}
|
}
|
||||||
|
|
||||||
Hooks.runAction('action:api.video.updated', { video: videoInstanceUpdated, body: req.body })
|
Hooks.runAction('action:api.video.updated', { video: videoInstanceUpdated, body: req.body, req, res })
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// Force fields we want to update
|
// Force fields we want to update
|
||||||
// If the transaction is retried, sequelize will think the object has not changed
|
// If the transaction is retried, sequelize will think the object has not changed
|
||||||
|
|
|
@ -129,7 +129,7 @@ async function addVideoLegacy (req: express.Request, res: express.Response) {
|
||||||
const videoInfo: VideoCreate = req.body
|
const videoInfo: VideoCreate = req.body
|
||||||
const files = req.files
|
const files = req.files
|
||||||
|
|
||||||
const response = await addVideo({ res, videoPhysicalFile, videoInfo, files })
|
const response = await addVideo({ req, res, videoPhysicalFile, videoInfo, files })
|
||||||
|
|
||||||
return res.json(response)
|
return res.json(response)
|
||||||
}
|
}
|
||||||
|
@ -139,19 +139,20 @@ async function addVideoResumable (req: express.Request, res: express.Response) {
|
||||||
const videoInfo = videoPhysicalFile.metadata
|
const videoInfo = videoPhysicalFile.metadata
|
||||||
const files = { previewfile: videoInfo.previewfile }
|
const files = { previewfile: videoInfo.previewfile }
|
||||||
|
|
||||||
const response = await addVideo({ res, videoPhysicalFile, videoInfo, files })
|
const response = await addVideo({ req, res, videoPhysicalFile, videoInfo, files })
|
||||||
await Redis.Instance.setUploadSession(req.query.upload_id, response)
|
await Redis.Instance.setUploadSession(req.query.upload_id, response)
|
||||||
|
|
||||||
return res.json(response)
|
return res.json(response)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function addVideo (options: {
|
async function addVideo (options: {
|
||||||
|
req: express.Request
|
||||||
res: express.Response
|
res: express.Response
|
||||||
videoPhysicalFile: express.VideoUploadFile
|
videoPhysicalFile: express.VideoUploadFile
|
||||||
videoInfo: VideoCreate
|
videoInfo: VideoCreate
|
||||||
files: express.UploadFiles
|
files: express.UploadFiles
|
||||||
}) {
|
}) {
|
||||||
const { res, videoPhysicalFile, videoInfo, files } = options
|
const { req, res, videoPhysicalFile, videoInfo, files } = options
|
||||||
const videoChannel = res.locals.videoChannel
|
const videoChannel = res.locals.videoChannel
|
||||||
const user = res.locals.oauth.token.User
|
const user = res.locals.oauth.token.User
|
||||||
|
|
||||||
|
@ -235,7 +236,7 @@ async function addVideo (options: {
|
||||||
})
|
})
|
||||||
.catch(err => logger.error('Cannot add optimize/merge audio job for %s.', videoCreated.uuid, { err, ...lTags(videoCreated.uuid) }))
|
.catch(err => logger.error('Cannot add optimize/merge audio job for %s.', videoCreated.uuid, { err, ...lTags(videoCreated.uuid) }))
|
||||||
|
|
||||||
Hooks.runAction('action:api.video.uploaded', { video: videoCreated })
|
Hooks.runAction('action:api.video.uploaded', { video: videoCreated, req, res })
|
||||||
|
|
||||||
return {
|
return {
|
||||||
video: {
|
video: {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { cloneDeep } from 'lodash'
|
import { cloneDeep } from 'lodash'
|
||||||
import * as Sequelize from 'sequelize'
|
import * as Sequelize from 'sequelize'
|
||||||
|
import express from 'express'
|
||||||
import { logger } from '@server/helpers/logger'
|
import { logger } from '@server/helpers/logger'
|
||||||
import { sequelizeTypescript } from '@server/initializers/database'
|
import { sequelizeTypescript } from '@server/initializers/database'
|
||||||
import { ResultList } from '../../shared/models'
|
import { ResultList } from '../../shared/models'
|
||||||
|
@ -10,7 +11,7 @@ import { sendCreateVideoComment, sendDeleteVideoComment } from './activitypub/se
|
||||||
import { getLocalVideoCommentActivityPubUrl } from './activitypub/url'
|
import { getLocalVideoCommentActivityPubUrl } from './activitypub/url'
|
||||||
import { Hooks } from './plugins/hooks'
|
import { Hooks } from './plugins/hooks'
|
||||||
|
|
||||||
async function removeComment (videoCommentInstance: MCommentOwnerVideo) {
|
async function removeComment (videoCommentInstance: MCommentOwnerVideo, req: express.Request, res: express.Response) {
|
||||||
const videoCommentInstanceBefore = cloneDeep(videoCommentInstance)
|
const videoCommentInstanceBefore = cloneDeep(videoCommentInstance)
|
||||||
|
|
||||||
await sequelizeTypescript.transaction(async t => {
|
await sequelizeTypescript.transaction(async t => {
|
||||||
|
@ -25,7 +26,7 @@ async function removeComment (videoCommentInstance: MCommentOwnerVideo) {
|
||||||
|
|
||||||
logger.info('Video comment %d deleted.', videoCommentInstance.id)
|
logger.info('Video comment %d deleted.', videoCommentInstance.id)
|
||||||
|
|
||||||
Hooks.runAction('action:api.video-comment.deleted', { comment: videoCommentInstanceBefore })
|
Hooks.runAction('action:api.video-comment.deleted', { comment: videoCommentInstanceBefore, req, res })
|
||||||
}
|
}
|
||||||
|
|
||||||
async function createVideoComment (obj: {
|
async function createVideoComment (obj: {
|
||||||
|
|
|
@ -85,6 +85,8 @@ export const serverActionHookObject = {
|
||||||
// Fired when the application has been loaded and is listening HTTP requests
|
// Fired when the application has been loaded and is listening HTTP requests
|
||||||
'action:application.listening': true,
|
'action:application.listening': true,
|
||||||
|
|
||||||
|
// API actions hooks give access to the original express `req` and `res` parameters
|
||||||
|
|
||||||
// Fired when a local video is updated
|
// Fired when a local video is updated
|
||||||
'action:api.video.updated': true,
|
'action:api.video.updated': true,
|
||||||
// Fired when a local video is deleted
|
// Fired when a local video is deleted
|
||||||
|
|
|
@ -108,6 +108,20 @@ async function register ({
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
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):
|
||||||
|
|
||||||
|
```js
|
||||||
|
async function register ({
|
||||||
|
registerHook,
|
||||||
|
peertubeHelpers: { logger }
|
||||||
|
}) {
|
||||||
|
registerHook({
|
||||||
|
target: 'action:api.video.updated',
|
||||||
|
handler: ({ req, res }) => logger.debug('original request parameters', { params: req.params })
|
||||||
|
})
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
On client side, these hooks are registered by the `clientScripts` files defined in `package.json`.
|
On client side, these hooks are registered by the `clientScripts` files defined in `package.json`.
|
||||||
All client scripts have scopes so PeerTube client only loads scripts it needs:
|
All client scripts have scopes so PeerTube client only loads scripts it needs:
|
||||||
|
|
Loading…
Reference in New Issue