Add user adminFlags
[oweals/peertube.git] / server / middlewares / validators / follows.ts
1 import * as express from 'express'
2 import { body, param } from 'express-validator/check'
3 import { isTestInstance } from '../../helpers/core-utils'
4 import { isEachUniqueHostValid, isHostValid } from '../../helpers/custom-validators/servers'
5 import { logger } from '../../helpers/logger'
6 import { getServerActor } from '../../helpers/utils'
7 import { SERVER_ACTOR_NAME, WEBSERVER } from '../../initializers/constants'
8 import { ActorFollowModel } from '../../models/activitypub/actor-follow'
9 import { areValidationErrors } from './utils'
10 import { ActorModel } from '../../models/activitypub/actor'
11 import { loadActorUrlOrGetFromWebfinger } from '../../helpers/webfinger'
12 import { isValidActorHandle } from '../../helpers/custom-validators/activitypub/actor'
13
14 const followValidator = [
15   body('hosts').custom(isEachUniqueHostValid).withMessage('Should have an array of unique hosts'),
16
17   (req: express.Request, res: express.Response, next: express.NextFunction) => {
18     // Force https if the administrator wants to make friends
19     if (isTestInstance() === false && WEBSERVER.SCHEME === 'http') {
20       return res.status(500)
21         .json({
22           error: 'Cannot follow on a non HTTPS web server.'
23         })
24         .end()
25     }
26
27     logger.debug('Checking follow parameters', { parameters: req.body })
28
29     if (areValidationErrors(req, res)) return
30
31     return next()
32   }
33 ]
34
35 const removeFollowingValidator = [
36   param('host').custom(isHostValid).withMessage('Should have a valid host'),
37
38   async (req: express.Request, res: express.Response, next: express.NextFunction) => {
39     logger.debug('Checking unfollowing parameters', { parameters: req.params })
40
41     if (areValidationErrors(req, res)) return
42
43     const serverActor = await getServerActor()
44     const follow = await ActorFollowModel.loadByActorAndTargetNameAndHostForAPI(serverActor.id, SERVER_ACTOR_NAME, req.params.host)
45
46     if (!follow) {
47       return res
48         .status(404)
49         .json({
50           error: `Following ${req.params.host} not found.`
51         })
52         .end()
53     }
54
55     res.locals.follow = follow
56     return next()
57   }
58 ]
59
60 const getFollowerValidator = [
61   param('nameWithHost').custom(isValidActorHandle).withMessage('Should have a valid nameWithHost'),
62
63   async (req: express.Request, res: express.Response, next: express.NextFunction) => {
64     logger.debug('Checking get follower parameters', { parameters: req.params })
65
66     if (areValidationErrors(req, res)) return
67
68     let follow: ActorFollowModel
69     try {
70       const actorUrl = await loadActorUrlOrGetFromWebfinger(req.params.nameWithHost)
71       const actor = await ActorModel.loadByUrl(actorUrl)
72
73       const serverActor = await getServerActor()
74       follow = await ActorFollowModel.loadByActorAndTarget(actor.id, serverActor.id)
75     } catch (err) {
76       logger.warn('Cannot get actor from handle.', { handle: req.params.nameWithHost, err })
77     }
78
79     if (!follow) {
80       return res
81         .status(404)
82         .json({
83           error: `Follower ${req.params.nameWithHost} not found.`
84         })
85         .end()
86     }
87
88     res.locals.follow = follow
89     return next()
90   }
91 ]
92
93 const acceptOrRejectFollowerValidator = [
94   (req: express.Request, res: express.Response, next: express.NextFunction) => {
95     logger.debug('Checking accept/reject follower parameters', { parameters: req.params })
96
97     const follow = res.locals.follow
98     if (follow.state !== 'pending') {
99       return res.status(400).json({ error: 'Follow is not in pending state.' }).end()
100     }
101
102     return next()
103   }
104 ]
105
106 // ---------------------------------------------------------------------------
107
108 export {
109   followValidator,
110   removeFollowingValidator,
111   getFollowerValidator,
112   acceptOrRejectFollowerValidator
113 }