1 import * as express from 'express'
2 import { createAccountAbuse, createVideoAbuse, createVideoCommentAbuse } from '@server/lib/moderation'
3 import { AbuseModel } from '@server/models/abuse/abuse'
4 import { AbuseMessageModel } from '@server/models/abuse/abuse-message'
5 import { getServerActor } from '@server/models/application/application'
6 import { AbuseCreate, abusePredefinedReasonsMap, AbuseState, UserRight } from '../../../shared'
7 import { getFormattedObjects } from '../../helpers/utils'
8 import { sequelizeTypescript } from '../../initializers/database'
11 abuseListForAdminsValidator,
15 addAbuseMessageValidator,
17 asyncRetryTransactionMiddleware,
19 checkAbuseValidForMessagesValidator,
20 deleteAbuseMessageValidator,
26 } from '../../middlewares'
27 import { AccountModel } from '../../models/account/account'
29 const abuseRouter = express.Router()
33 ensureUserHasRight(UserRight.MANAGE_ABUSES),
38 abuseListForAdminsValidator,
39 asyncMiddleware(listAbusesForAdmins)
41 abuseRouter.put('/:id',
43 ensureUserHasRight(UserRight.MANAGE_ABUSES),
44 asyncMiddleware(abuseUpdateValidator),
45 asyncRetryTransactionMiddleware(updateAbuse)
49 asyncMiddleware(abuseReportValidator),
50 asyncRetryTransactionMiddleware(reportAbuse)
52 abuseRouter.delete('/:id',
54 ensureUserHasRight(UserRight.MANAGE_ABUSES),
55 asyncMiddleware(abuseGetValidator),
56 asyncRetryTransactionMiddleware(deleteAbuse)
59 abuseRouter.get('/:id/messages',
61 asyncMiddleware(getAbuseValidator),
62 checkAbuseValidForMessagesValidator,
63 asyncRetryTransactionMiddleware(listAbuseMessages)
66 abuseRouter.post('/:id/messages',
68 asyncMiddleware(getAbuseValidator),
69 checkAbuseValidForMessagesValidator,
70 addAbuseMessageValidator,
71 asyncRetryTransactionMiddleware(addAbuseMessage)
74 abuseRouter.delete('/:id/messages/:messageId',
76 asyncMiddleware(getAbuseValidator),
77 checkAbuseValidForMessagesValidator,
78 asyncMiddleware(deleteAbuseMessageValidator),
79 asyncRetryTransactionMiddleware(deleteAbuseMessage)
82 // ---------------------------------------------------------------------------
87 // FIXME: deprecated in 2.3. Remove these exports
94 // ---------------------------------------------------------------------------
96 async function listAbusesForAdmins (req: express.Request, res: express.Response) {
97 const user = res.locals.oauth.token.user
98 const serverActor = await getServerActor()
100 const resultList = await AbuseModel.listForAdminApi({
101 start: req.query.start,
102 count: req.query.count,
103 sort: req.query.sort,
105 filter: req.query.filter,
106 predefinedReason: req.query.predefinedReason,
107 search: req.query.search,
108 state: req.query.state,
109 videoIs: req.query.videoIs,
110 searchReporter: req.query.searchReporter,
111 searchReportee: req.query.searchReportee,
112 searchVideo: req.query.searchVideo,
113 searchVideoChannel: req.query.searchVideoChannel,
114 serverAccountId: serverActor.Account.id,
119 total: resultList.total,
120 data: resultList.data.map(d => d.toFormattedAdminJSON())
124 async function updateAbuse (req: express.Request, res: express.Response) {
125 const abuse = res.locals.abuse
127 if (req.body.moderationComment !== undefined) abuse.moderationComment = req.body.moderationComment
128 if (req.body.state !== undefined) abuse.state = req.body.state
130 await sequelizeTypescript.transaction(t => {
131 return abuse.save({ transaction: t })
134 // TODO: Notification
136 // Do not send the delete to other instances, we updated OUR copy of this abuse
138 return res.type('json').status(204).end()
141 async function deleteAbuse (req: express.Request, res: express.Response) {
142 const abuse = res.locals.abuse
144 await sequelizeTypescript.transaction(t => {
145 return abuse.destroy({ transaction: t })
148 // Do not send the delete to other instances, we delete OUR copy of this abuse
150 return res.type('json').status(204).end()
153 async function reportAbuse (req: express.Request, res: express.Response) {
154 const videoInstance = res.locals.videoAll
155 const commentInstance = res.locals.videoCommentFull
156 const accountInstance = res.locals.account
158 const body: AbuseCreate = req.body
160 const { id } = await sequelizeTypescript.transaction(async t => {
161 const reporterAccount = await AccountModel.load(res.locals.oauth.token.User.Account.id, t)
162 const predefinedReasons = body.predefinedReasons?.map(r => abusePredefinedReasonsMap[r])
165 reporterAccountId: reporterAccount.id,
167 state: AbuseState.PENDING,
172 return createVideoAbuse({
177 startAt: body.video.startAt,
178 endAt: body.video.endAt
183 return createVideoCommentAbuse({
192 return createAccountAbuse({
200 return res.json({ abuse: { id } })
203 async function listAbuseMessages (req: express.Request, res: express.Response) {
204 const abuse = res.locals.abuse
206 const resultList = await AbuseMessageModel.listForApi(abuse.id)
208 return res.json(getFormattedObjects(resultList.data, resultList.total))
211 async function addAbuseMessage (req: express.Request, res: express.Response) {
212 const abuse = res.locals.abuse
213 const user = res.locals.oauth.token.user
215 const abuseMessage = await AbuseMessageModel.create({
216 message: req.body.message,
217 byModerator: abuse.reporterAccountId !== user.Account.id,
218 accountId: user.Account.id,
222 // TODO: Notification
231 async function deleteAbuseMessage (req: express.Request, res: express.Response) {
232 const abuseMessage = res.locals.abuseMessage
234 await sequelizeTypescript.transaction(t => {
235 return abuseMessage.destroy({ transaction: t })
238 return res.sendStatus(204)