PeerTube/server/core/controllers/api/server/follows.ts

211 lines
6.0 KiB
TypeScript
Raw Normal View History

2021-08-27 07:32:44 -05:00
import express from 'express'
import { HttpStatusCode, ServerFollowCreate, UserRight } from '@peertube/peertube-models'
import { getServerActor } from '@server/models/application/application.js'
import { logger } from '../../../helpers/logger.js'
import { getFormattedObjects } from '../../../helpers/utils.js'
import { sequelizeTypescript } from '../../../initializers/database.js'
import { autoFollowBackIfNeeded } from '../../../lib/activitypub/follow.js'
import { sendAccept, sendReject, sendUndoFollow } from '../../../lib/activitypub/send/index.js'
import { JobQueue } from '../../../lib/job-queue/index.js'
import { removeRedundanciesOfServer } from '../../../lib/redundancy.js'
2017-12-12 10:53:50 -06:00
import {
asyncMiddleware,
authenticate,
ensureUserHasRight,
paginationValidator,
setBodyHostsPort,
setDefaultPagination,
setDefaultSort
} from '../../../middlewares/index.js'
import {
acceptFollowerValidator,
followValidator,
getFollowerValidator,
instanceFollowersSortValidator,
instanceFollowingSortValidator,
2021-05-11 04:15:29 -05:00
listFollowsValidator,
rejectFollowerValidator,
2021-05-11 04:15:29 -05:00
removeFollowingValidator
} from '../../../middlewares/validators/index.js'
import { ActorFollowModel } from '../../../models/actor/actor-follow.js'
2017-11-16 10:16:42 -06:00
const serverFollowsRouter = express.Router()
serverFollowsRouter.get('/following',
listFollowsValidator,
paginationValidator,
2021-10-19 02:10:01 -05:00
instanceFollowingSortValidator,
2018-01-17 03:50:33 -06:00
setDefaultSort,
setDefaultPagination,
2017-11-13 10:39:41 -06:00
asyncMiddleware(listFollowing)
)
2017-11-17 08:20:42 -06:00
serverFollowsRouter.post('/following',
2017-11-14 02:11:43 -06:00
authenticate,
2017-11-16 10:16:42 -06:00
ensureUserHasRight(UserRight.MANAGE_SERVER_FOLLOW),
2017-11-13 11:48:28 -06:00
followValidator,
setBodyHostsPort,
asyncMiddleware(addFollow)
2017-11-13 11:48:28 -06:00
)
serverFollowsRouter.delete('/following/:hostOrHandle',
2017-11-20 02:43:39 -06:00
authenticate,
ensureUserHasRight(UserRight.MANAGE_SERVER_FOLLOW),
2017-11-27 10:30:46 -06:00
asyncMiddleware(removeFollowingValidator),
asyncMiddleware(removeFollowing)
2017-11-20 02:43:39 -06:00
)
2017-11-16 10:16:42 -06:00
serverFollowsRouter.get('/followers',
listFollowsValidator,
2017-11-13 10:39:41 -06:00
paginationValidator,
2021-10-19 02:10:01 -05:00
instanceFollowersSortValidator,
2018-01-17 03:50:33 -06:00
setDefaultSort,
setDefaultPagination,
2017-11-13 10:39:41 -06:00
asyncMiddleware(listFollowers)
2017-05-15 15:22:03 -05:00
)
serverFollowsRouter.delete('/followers/:nameWithHost',
authenticate,
ensureUserHasRight(UserRight.MANAGE_SERVER_FOLLOW),
asyncMiddleware(getFollowerValidator),
asyncMiddleware(removeFollower)
)
serverFollowsRouter.post('/followers/:nameWithHost/reject',
authenticate,
ensureUserHasRight(UserRight.MANAGE_SERVER_FOLLOW),
asyncMiddleware(getFollowerValidator),
rejectFollowerValidator,
asyncMiddleware(rejectFollower)
)
serverFollowsRouter.post('/followers/:nameWithHost/accept',
authenticate,
ensureUserHasRight(UserRight.MANAGE_SERVER_FOLLOW),
asyncMiddleware(getFollowerValidator),
acceptFollowerValidator,
asyncMiddleware(acceptFollower)
)
2017-05-15 15:22:03 -05:00
// ---------------------------------------------------------------------------
export {
2017-11-16 10:16:42 -06:00
serverFollowsRouter
2017-05-15 15:22:03 -05:00
}
// ---------------------------------------------------------------------------
2019-03-19 04:35:15 -05:00
async function listFollowing (req: express.Request, res: express.Response) {
2017-12-14 10:38:41 -06:00
const serverActor = await getServerActor()
2021-10-19 02:44:43 -05:00
const resultList = await ActorFollowModel.listInstanceFollowingForApi({
followerId: serverActor.id,
start: req.query.start,
count: req.query.count,
sort: req.query.sort,
search: req.query.search,
actorType: req.query.actorType,
state: req.query.state
})
2017-11-13 10:39:41 -06:00
return res.json(getFormattedObjects(resultList.data, resultList.total))
}
2019-03-19 04:35:15 -05:00
async function listFollowers (req: express.Request, res: express.Response) {
2017-12-14 10:38:41 -06:00
const serverActor = await getServerActor()
const resultList = await ActorFollowModel.listFollowersForApi({
2021-10-19 02:44:43 -05:00
actorIds: [ serverActor.id ],
start: req.query.start,
count: req.query.count,
sort: req.query.sort,
search: req.query.search,
actorType: req.query.actorType,
state: req.query.state
})
2017-10-25 04:55:06 -05:00
return res.json(getFormattedObjects(resultList.data, resultList.total))
2017-05-15 15:22:03 -05:00
}
2017-11-13 11:48:28 -06:00
async function addFollow (req: express.Request, res: express.Response) {
const { hosts, handles } = req.body as ServerFollowCreate
const follower = await getServerActor()
2017-11-14 10:31:26 -06:00
2017-11-13 11:48:28 -06:00
for (const host of hosts) {
const payload = {
host,
followerActorId: follower.id
}
2022-08-08 08:48:17 -05:00
JobQueue.Instance.createJobAsync({ type: 'activitypub-follow', payload })
2017-11-13 11:48:28 -06:00
}
for (const handle of handles) {
const [ name, host ] = handle.split('@')
const payload = {
host,
name,
followerActorId: follower.id
}
2022-08-08 08:48:17 -05:00
JobQueue.Instance.createJobAsync({ type: 'activitypub-follow', payload })
}
return res.status(HttpStatusCode.NO_CONTENT_204).end()
2017-11-13 11:48:28 -06:00
}
2017-11-14 10:31:26 -06:00
async function removeFollowing (req: express.Request, res: express.Response) {
2019-03-19 04:35:15 -05:00
const follow = res.locals.follow
2017-11-20 02:43:39 -06:00
2017-12-12 10:53:50 -06:00
await sequelizeTypescript.transaction(async t => {
if (follow.state === 'accepted') sendUndoFollow(follow, t)
2017-11-22 09:25:03 -06:00
2018-09-11 09:27:07 -05:00
// Disable redundancy on unfollowed instances
const server = follow.ActorFollowing.Server
server.redundancyAllowed = false
await server.save({ transaction: t })
// Async, could be long
2020-01-10 03:11:28 -06:00
removeRedundanciesOfServer(server.id)
2022-07-18 04:55:13 -05:00
.catch(err => logger.error('Cannot remove redundancy of %s.', server.host, { err }))
2017-11-21 06:43:29 -06:00
await follow.destroy({ transaction: t })
2017-11-20 02:43:39 -06:00
})
return res.status(HttpStatusCode.NO_CONTENT_204).end()
2017-11-20 02:43:39 -06:00
}
async function rejectFollower (req: express.Request, res: express.Response) {
const follow = res.locals.follow
follow.state = 'rejected'
await follow.save()
sendReject(follow.url, follow.ActorFollower, follow.ActorFollowing)
return res.status(HttpStatusCode.NO_CONTENT_204).end()
}
async function removeFollower (req: express.Request, res: express.Response) {
const follow = res.locals.follow
if (follow.state === 'accepted' || follow.state === 'pending') {
sendReject(follow.url, follow.ActorFollower, follow.ActorFollowing)
}
await follow.destroy()
return res.status(HttpStatusCode.NO_CONTENT_204).end()
}
async function acceptFollower (req: express.Request, res: express.Response) {
const follow = res.locals.follow
2021-06-15 02:17:19 -05:00
sendAccept(follow)
follow.state = 'accepted'
await follow.save()
await autoFollowBackIfNeeded(follow)
return res.status(HttpStatusCode.NO_CONTENT_204).end()
}