From b8f4167fb6fa448125aeecff80b201d74e27fe6a Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Thu, 28 Nov 2019 11:37:32 +0100 Subject: Only display accepted followers/followings in about page --- server/controllers/api/server/follows.ts | 35 +++++++++++++---------- server/helpers/custom-validators/follows.ts | 14 +++++++++ server/middlewares/validators/follows.ts | 18 ++++++++++-- server/models/activitypub/actor-follow.ts | 28 ++++++++++++++++-- server/tests/api/check-params/follows.ts | 44 ++++++++++++++++++++++++++++- server/tests/api/server/follows.ts | 26 ++++++++++++++--- 6 files changed, 141 insertions(+), 24 deletions(-) create mode 100644 server/helpers/custom-validators/follows.ts (limited to 'server') diff --git a/server/controllers/api/server/follows.ts b/server/controllers/api/server/follows.ts index 37647622b..e7fd3aabd 100644 --- a/server/controllers/api/server/follows.ts +++ b/server/controllers/api/server/follows.ts @@ -19,7 +19,8 @@ import { followingSortValidator, followValidator, getFollowerValidator, - removeFollowingValidator + removeFollowingValidator, + listFollowsValidator } from '../../../middlewares/validators' import { ActorFollowModel } from '../../../models/activitypub/actor-follow' import { JobQueue } from '../../../lib/job-queue' @@ -29,6 +30,7 @@ import { autoFollowBackIfNeeded } from '../../../lib/activitypub/follow' const serverFollowsRouter = express.Router() serverFollowsRouter.get('/following', + listFollowsValidator, paginationValidator, followingSortValidator, setDefaultSort, @@ -52,6 +54,7 @@ serverFollowsRouter.delete('/following/:host', ) serverFollowsRouter.get('/followers', + listFollowsValidator, paginationValidator, followersSortValidator, setDefaultSort, @@ -92,26 +95,28 @@ export { async function listFollowing (req: express.Request, res: express.Response) { const serverActor = await getServerActor() - const resultList = await ActorFollowModel.listFollowingForApi( - serverActor.id, - req.query.start, - req.query.count, - req.query.sort, - req.query.search - ) + const resultList = await ActorFollowModel.listFollowingForApi({ + id: serverActor.id, + start: req.query.start, + count: req.query.count, + sort: req.query.sort, + search: req.query.search, + state: req.query.state + }) return res.json(getFormattedObjects(resultList.data, resultList.total)) } async function listFollowers (req: express.Request, res: express.Response) { const serverActor = await getServerActor() - const resultList = await ActorFollowModel.listFollowersForApi( - serverActor.id, - req.query.start, - req.query.count, - req.query.sort, - req.query.search - ) + const resultList = await ActorFollowModel.listFollowersForApi({ + actorId: serverActor.id, + start: req.query.start, + count: req.query.count, + sort: req.query.sort, + search: req.query.search, + state: req.query.state + }) return res.json(getFormattedObjects(resultList.data, resultList.total)) } diff --git a/server/helpers/custom-validators/follows.ts b/server/helpers/custom-validators/follows.ts new file mode 100644 index 000000000..fbef7ad87 --- /dev/null +++ b/server/helpers/custom-validators/follows.ts @@ -0,0 +1,14 @@ +import { exists } from './misc' +import { FollowState } from '@shared/models' + +function isFollowStateValid (value: FollowState) { + if (!exists(value)) return false + + return value === 'pending' || value === 'accepted' +} + +// --------------------------------------------------------------------------- + +export { + isFollowStateValid +} diff --git a/server/middlewares/validators/follows.ts b/server/middlewares/validators/follows.ts index 788735663..454f9f2b8 100644 --- a/server/middlewares/validators/follows.ts +++ b/server/middlewares/validators/follows.ts @@ -1,5 +1,5 @@ import * as express from 'express' -import { body, param } from 'express-validator' +import { body, param, query } from 'express-validator' import { isTestInstance } from '../../helpers/core-utils' import { isEachUniqueHostValid, isHostValid } from '../../helpers/custom-validators/servers' import { logger } from '../../helpers/logger' @@ -11,6 +11,19 @@ import { ActorModel } from '../../models/activitypub/actor' import { loadActorUrlOrGetFromWebfinger } from '../../helpers/webfinger' import { isValidActorHandle } from '../../helpers/custom-validators/activitypub/actor' import { MActorFollowActorsDefault } from '@server/typings/models' +import { isFollowStateValid } from '@server/helpers/custom-validators/follows' + +const listFollowsValidator = [ + query('state') + .optional() + .custom(isFollowStateValid).withMessage('Should have a valid follow state'), + + (req: express.Request, res: express.Response, next: express.NextFunction) => { + if (areValidationErrors(req, res)) return + + return next() + } +] const followValidator = [ body('hosts').custom(isEachUniqueHostValid).withMessage('Should have an array of unique hosts'), @@ -110,5 +123,6 @@ export { followValidator, removeFollowingValidator, getFollowerValidator, - acceptOrRejectFollowerValidator + acceptOrRejectFollowerValidator, + listFollowsValidator } diff --git a/server/models/activitypub/actor-follow.ts b/server/models/activitypub/actor-follow.ts index 24272a40e..09bc6853d 100644 --- a/server/models/activitypub/actor-follow.ts +++ b/server/models/activitypub/actor-follow.ts @@ -292,12 +292,24 @@ export class ActorFollowModel extends Model { return ActorFollowModel.findAll(query) } - static listFollowingForApi (id: number, start: number, count: number, sort: string, search?: string) { + static listFollowingForApi (options: { + id: number, + start: number, + count: number, + sort: string, + state?: FollowState, + search?: string + }) { + const { id, start, count, sort, search, state } = options + + const followWhere = state ? { state } : {} + const query = { distinct: true, offset: start, limit: count, order: getSort(sort), + where: followWhere, include: [ { model: ActorModel, @@ -335,12 +347,24 @@ export class ActorFollowModel extends Model { }) } - static listFollowersForApi (actorId: number, start: number, count: number, sort: string, search?: string) { + static listFollowersForApi (options: { + actorId: number, + start: number, + count: number, + sort: string, + state?: FollowState, + search?: string + }) { + const { actorId, start, count, sort, search, state } = options + + const followWhere = state ? { state } : {} + const query = { distinct: true, offset: start, limit: count, order: getSort(sort), + where: followWhere, include: [ { model: ActorModel, diff --git a/server/tests/api/check-params/follows.ts b/server/tests/api/check-params/follows.ts index 2eb54cb0a..488666a75 100644 --- a/server/tests/api/check-params/follows.ts +++ b/server/tests/api/check-params/follows.ts @@ -6,7 +6,7 @@ import { cleanupTests, createUser, flushAndRunServer, - makeDeleteRequest, + makeDeleteRequest, makeGetRequest, makePostBodyRequest, ServerInfo, setAccessTokensToServers, @@ -131,6 +131,27 @@ describe('Test server follows API validators', function () { it('Should fail with an incorrect sort', async function () { await checkBadSortPagination(server.url, path) }) + + it('Should fail with an incorrect state', async function () { + await makeGetRequest({ + url: server.url, + path, + query: { + state: 'blabla' + } + }) + }) + + it('Should fail succeed with the correct params', async function () { + await makeGetRequest({ + url: server.url, + path, + statusCodeExpected: 200, + query: { + state: 'accepted' + } + }) + }) }) describe('When listing followers', function () { @@ -147,6 +168,27 @@ describe('Test server follows API validators', function () { it('Should fail with an incorrect sort', async function () { await checkBadSortPagination(server.url, path) }) + + it('Should fail with an incorrect state', async function () { + await makeGetRequest({ + url: server.url, + path, + query: { + state: 'blabla' + } + }) + }) + + it('Should fail succeed with the correct params', async function () { + await makeGetRequest({ + url: server.url, + path, + statusCodeExpected: 200, + query: { + state: 'accepted' + } + }) + }) }) describe('When removing a follower', function () { diff --git a/server/tests/api/server/follows.ts b/server/tests/api/server/follows.ts index e8d6f5138..36a061926 100644 --- a/server/tests/api/server/follows.ts +++ b/server/tests/api/server/follows.ts @@ -97,14 +97,23 @@ describe('Test follows', function () { expect(server3Follow.state).to.equal('accepted') }) - it('Should search followings on server 1', async function () { + it('Should search/filter followings on server 1', async function () { { - const res = await getFollowingListPaginationAndSort(servers[ 0 ].url, 0, 1, 'createdAt', ':' + servers[1].port) + const search = ':' + servers[1].port + const res = await getFollowingListPaginationAndSort(servers[ 0 ].url, 0, 1, 'createdAt', search) const follows = res.body.data expect(res.body.total).to.equal(1) expect(follows.length).to.equal(1) expect(follows[ 0 ].following.host).to.equal('localhost:' + servers[1].port) + + const res2 = await getFollowingListPaginationAndSort(servers[ 0 ].url, 0, 1, 'createdAt', search, 'accepted') + expect(res2.body.total).to.equal(1) + expect(res2.body.data).to.have.lengthOf(1) + + const res3 = await getFollowingListPaginationAndSort(servers[ 0 ].url, 0, 1, 'createdAt', search, 'pending') + expect(res3.body.total).to.equal(0) + expect(res3.body.data).to.have.lengthOf(0) } { @@ -139,14 +148,23 @@ describe('Test follows', function () { } }) - it('Should search followers on server 2', async function () { + it('Should search/filter followers on server 2', async function () { { - const res = await getFollowersListPaginationAndSort(servers[ 2 ].url, 0, 5, 'createdAt', servers[0].port + '') + const search = servers[0].port + '' + const res = await getFollowersListPaginationAndSort(servers[ 2 ].url, 0, 5, 'createdAt', search) const follows = res.body.data expect(res.body.total).to.equal(1) expect(follows.length).to.equal(1) expect(follows[ 0 ].following.host).to.equal('localhost:' + servers[2].port) + + const res2 = await getFollowersListPaginationAndSort(servers[ 2 ].url, 0, 5, 'createdAt', search, 'accepted') + expect(res2.body.total).to.equal(1) + expect(res2.body.data).to.have.lengthOf(1) + + const res3 = await getFollowersListPaginationAndSort(servers[ 2 ].url, 0, 5, 'createdAt', search, 'pending') + expect(res3.body.total).to.equal(0) + expect(res3.body.data).to.have.lengthOf(0) } { -- cgit v1.2.3