diff --git a/features/api/usersettings/blacklist.feature b/features/api/usersettings/blacklist.feature deleted file mode 100644 index 290fc34..0000000 --- a/features/api/usersettings/blacklist.feature +++ /dev/null @@ -1,43 +0,0 @@ -Feature: Individual Blacklist - As a user - I want to click on a button to blacklist certain user profiles - In order to stop seeing user content of this account, because I don't like them - - Background: - Given this is your user account: - | email | password | isVerified | - | user@example.com | 1234 | true | - And these user accounts exist: - | name | email | isVerified | - | Troll | troll@example.com | true | - | Legit | legit@example.com | true | - And you are authenticated - - - Scenario: Blacklist a user - When you create your user settings via POST request to "/usersettings" with: - """ - { - "blacklist": ["5b5863e8d47c14323165718b"] - } - """ - Then you will stop seeing posts of the user with id "5b5863e8d47c14323165718b" - - Scenario: Filter out contributions of a blacklisted user - Given you blacklisted the user "Troll" before - When this user publishes a post - And you read your current news feed - Then this post is not included - - Scenario: Show but conceal comments of a blacklisted user - Given you blacklisted the user "Troll" before - And there is a post "Hello World" by user "Legit" - And the blacklisted user wrote a comment on that post: - """ - I hate you - """ - When you read through the comments of that post - Then you will see a hint instead of a comment: - """ - Comments of this blacklisted user are not visible. - """ diff --git a/features/step_definitions/steps.js b/features/step_definitions/steps.js index fd8c237..3dd582c 100644 --- a/features/step_definitions/steps.js +++ b/features/step_definitions/steps.js @@ -12,7 +12,6 @@ let currentUserPassword; let httpResponse; let currentUserAccessToken; let lastPost; -let blacklistedUser; function authenticate(email, plainTextPassword) { const formData = { @@ -131,34 +130,6 @@ When('you create your user settings via POST request to {string} with:', functio postRequest(route, JSON.stringify(jsonBody), callback); }); -Then('you will stop seeing posts of the user with id {string}', function (blacklistedUserId) { - return this.app.service('usersettings').find({userId: currentUser._id.toString()}).then((settings) => { - expect(settings.total).to.eq(1); - expect(settings.data[0].blacklist).to.be.an('array').that.does.include(blacklistedUserId); - }); -}); - -Given('you blacklisted the user {string} before', async function (blacklistedUserName) { - const res = await this.app.service('users').find({query: {name: blacklistedUserName}}); - blacklistedUser = res.data[0]; - const params = { - userId: currentUser._id, - blacklist: [blacklistedUser._id] - }; - return this.app.service('usersettings').create(params); -}); - -When('this user publishes a post', function () { - const params = { - title: 'Awful title', - content: 'disgusting content', - language: 'en', - type: 'post', - userId: blacklistedUser._id - }; - return this.app.service('contributions').create(params); -}); - When('you read your current news feed', function (callback) { getRequest('/contributions', callback); }); @@ -181,15 +152,6 @@ Given('there is a post {string} by user {string}', async function (postTitle, us return lastPost; }); -Given('the blacklisted user wrote a comment on that post:', function (comment) { - const commentParams = { - userId: blacklistedUser._id, - content: comment, - contributionId: lastPost._id - }; - return this.app.service('comments').create(commentParams); -}); - When('you read through the comments of that post', function (callback) { getRequest('/comments', callback); }); diff --git a/server/hooks/conceal-blacklisted-data.js b/server/hooks/conceal-blacklisted-data.js deleted file mode 100644 index baaf394..0000000 --- a/server/hooks/conceal-blacklisted-data.js +++ /dev/null @@ -1,40 +0,0 @@ -const alterItems = require('../helper/alter-items'); - -const defaults = { - blacklist: [], - data: { - content: 'You have blacklisted this user' - } -}; - -const handleItem = options => item => { - if (options.blacklist){ - let found = options.blacklist.find((userId) => { - return String(userId) === item.userId; - }); - if (found){ - item = {...item, ...options.data}; - } - } - return item; -}; - -module.exports = function concealBlacklistedData(options = defaults) { - return async function(hook){ - if (hook.method === 'find' || hook.id === null) { - const authenticatedUser = hook.params.user; - if (!authenticatedUser){ - return hook; - } - const usersettings = await hook.app.service('usersettings').find({query: {userId: authenticatedUser._id}}); - if (usersettings.total <= 0){ - return hook; - } - options.blacklist = usersettings.data[0].blacklist; - return alterItems(handleItem(options))(hook); - } - - return hook; - }; -}; - diff --git a/server/hooks/exclude-blacklisted.js b/server/hooks/exclude-blacklisted.js deleted file mode 100644 index ea068db..0000000 --- a/server/hooks/exclude-blacklisted.js +++ /dev/null @@ -1,27 +0,0 @@ -module.exports = function excludeBlacklisted() { - return async function (hook) { - if (hook.type !== 'before') { - throw new Error('The \'excludeBlacklisted\' hook should only be used as a \'before\' hook.'); - } - - if (hook.method === 'find' || hook.id === null) { - const authenticatedUser = hook.params.user; - if (!authenticatedUser){ - return hook; - } - const usersettings = await hook.app.service('usersettings').find({query: {userId: authenticatedUser._id}}); - if (usersettings.total <= 0){ - return hook; - } - const { blacklist } = usersettings.data[0]; - if (blacklist) { - let { query } = hook.params; - query.userId = query.userId || {}; - query.userId.$nin = blacklist; - } - return hook; - } - - return hook; - }; -}; diff --git a/server/models/usersettings.model.js b/server/models/usersettings.model.js index 93c17e3..98eed52 100644 --- a/server/models/usersettings.model.js +++ b/server/models/usersettings.model.js @@ -7,7 +7,6 @@ module.exports = function (app) { const mongooseClient = app.get('mongooseClient'); const usersettings = new mongooseClient.Schema({ userId: {type: String, required: true, unique: true}, - blacklist: {type: Array, default: []}, uiLanguage: {type: String, required: true}, contentLanguages: {type: Array, default: []}, filter: { diff --git a/server/services/comments/comments.hooks.js b/server/services/comments/comments.hooks.js index a6fdc5d..1821f66 100644 --- a/server/services/comments/comments.hooks.js +++ b/server/services/comments/comments.hooks.js @@ -10,7 +10,6 @@ const { const { isVerified } = require('feathers-authentication-management').hooks; const createExcerpt = require('../../hooks/create-excerpt'); const patchDeletedData = require('../../hooks/patch-deleted-data'); -const concealBlacklistedData = require('../../hooks/conceal-blacklisted-data'); const keepDeletedDataFields = require('../../hooks/keep-deleted-data-fields'); const createNotifications = require('./hooks/create-notifications'); const createMentionNotifications = require('./hooks/create-mention-notifications'); @@ -119,24 +118,10 @@ module.exports = { ], find: [ populate({ schema: userSchema }), - protect('content', 'badgeIds'), - concealBlacklistedData({ - data: { - content: 'Comments of this blacklisted user are not visible.', - contentExcerpt: 'Comments of this blacklisted user are not visible.', - hasMore: false - } - }) + protect('content', 'badgeIds') ], get: [ - populate({ schema: userSchema }), - concealBlacklistedData({ - data: { - content: 'Comments of this blacklisted user are not visible.', - contentExcerpt: 'Comments of this blacklisted user are not visible.', - hasMore: false - } - }) + populate({ schema: userSchema }) ], create: [ populate({ schema: userSchema }), diff --git a/server/services/contributions/contributions.hooks.js b/server/services/contributions/contributions.hooks.js index 03f2cc8..ff5e73d 100644 --- a/server/services/contributions/contributions.hooks.js +++ b/server/services/contributions/contributions.hooks.js @@ -17,7 +17,6 @@ const search = require('feathers-mongodb-fuzzy-search'); const thumbnails = require('../../hooks/thumbnails'); const isModerator = require('../../hooks/is-moderator-boolean'); const excludeDisabled = require('../../hooks/exclude-disabled'); -const excludeBlacklisted = require('../../hooks/exclude-blacklisted'); const getAssociatedCanDos = require('./hooks/get-associated-can-dos'); const createMentionNotifications = require('./hooks/create-mention-notifications'); const notifyFollowers = require('./hooks/notify-followers'); @@ -114,7 +113,6 @@ module.exports = { unless(isModerator(), excludeDisabled() ), - excludeBlacklisted(), when(isProvider('server'), includeAll() ), diff --git a/server/services/usersettings/hooks/validate-blacklist.js b/server/services/usersettings/hooks/validate-blacklist.js deleted file mode 100644 index 039fa53..0000000 --- a/server/services/usersettings/hooks/validate-blacklist.js +++ /dev/null @@ -1,24 +0,0 @@ -const { BadRequest } = require('@feathersjs/errors'); - -const validateBlacklist = () => { - return async (hook) => { - const { data } = hook; - const blacklist = data.blacklist; - if (!blacklist) return hook; - const userId = data.userId; - - if(blacklist && blacklist.includes(userId)) { - throw new BadRequest('You can not blacklist yourself.'); - } - - const users = await hook.app.service('users').find({query: {_id: {$in: blacklist}}}); - const unblacklistable = users.data.find((user) => { - return (user.role === 'admin') || (user.role === 'moderator'); - }); - if (unblacklistable){ - throw new BadRequest('You can not blacklist admin users or moderators.'); - } - return hook; - }; -}; -module.exports = validateBlacklist; diff --git a/server/services/usersettings/usersettings.hooks.js b/server/services/usersettings/usersettings.hooks.js index 6fad29f..71fa9fe 100644 --- a/server/services/usersettings/usersettings.hooks.js +++ b/server/services/usersettings/usersettings.hooks.js @@ -1,6 +1,5 @@ const { restrictToOwner } = require('feathers-authentication-hooks'); const mapCreateToUpsert = require('../../hooks/map-create-to-upsert'); -const validateBlacklist = require('./hooks/validate-blacklist'); const { authenticate } = require('@feathersjs/authentication').hooks; module.exports = { @@ -10,7 +9,6 @@ module.exports = { get: [], create: [ authenticate('jwt'), - validateBlacklist(), mapCreateToUpsert(context => { const { data } = context; return { userId: data.userId }; @@ -18,17 +16,14 @@ module.exports = { ], update: [ authenticate('jwt'), - validateBlacklist(), restrictToOwner() ], patch: [ authenticate('jwt'), - validateBlacklist(), restrictToOwner() ], remove: [ authenticate('jwt'), - validateBlacklist(), restrictToOwner() ] }, diff --git a/test/hooks/exclude-blacklisted.test.js b/test/hooks/exclude-blacklisted.test.js deleted file mode 100644 index b6faeaa..0000000 --- a/test/hooks/exclude-blacklisted.test.js +++ /dev/null @@ -1,66 +0,0 @@ -const assert = require('assert'); -const feathers = require('@feathersjs/feathers'); -const excludeBlacklisted = require('../../server/hooks/exclude-blacklisted'); - -let app; -let usersettings = {}; -beforeEach(() => { - // Create a new plain Feathers application - app = feathers(); - - // Register a dummy custom service that just return the - // message data back - app.use('/usersettings', { - async find() { - return { - data: [usersettings] - }; - } - }); -}); - -describe('\'exclude-blacklisted\' hook', () => { - context('given a blacklist', () => { - let mock; - beforeEach(() => { - usersettings = { blacklist: ['4711'] }; - mock = { - type: 'before', - method: 'find', - params: { - user: { _id: 'whatever' } - }, - app - }; - }); - - context('query param `userId` is an object', () => { - it('adds one key', () => { - mock.params.query = { - userId: { $ne: 'user id' } - }; - - const hook = excludeBlacklisted(); - return hook(mock).then(result => { - assert.deepEqual(result.params.query.userId, { - $ne: 'user id', - $nin: ['4711'] - }); - }); - }); - }); - - context('query param `userId` is set to an exact id', () => { - it('has no effect', () => { - mock.params.query = { - userId: 'exact user id' - }; - - const hook = excludeBlacklisted(); - return hook(mock).then(result => { - assert.deepEqual(result.params.query.userId, 'exact user id' ); - }); - }); - }); - }); -}); diff --git a/test/services/comments.test.js b/test/services/comments.test.js index cb442fc..f1214ba 100644 --- a/test/services/comments.test.js +++ b/test/services/comments.test.js @@ -97,52 +97,27 @@ describe('\'comments\' service', () => { await service.create(data); }); - context('who is not blacklisted', () => { - it('is visible', async () => { - const comments = await service.find(params); - const comment = comments.data[1]; - assert.equal(comment.content, 'Original content'); - assert.equal(comment.contentExcerpt, 'Original content'); - }); - - context('usersettings exist, but without blacklist', () => { - beforeEach(async() => { - await usersettingsService.create({ - userId: user._id - }); - }); - - it('is visible', async () => { - const comments = await service.find(params); - const comment = comments.data[1]; - assert.equal(comment.content, 'Original content'); - assert.equal(comment.contentExcerpt, 'Original content'); - }); - }); + it('is visible', async () => { + const comments = await service.find(params); + const comment = comments.data[1]; + assert.equal(comment.content, 'Original content'); + assert.equal(comment.contentExcerpt, 'Original content'); }); - context('who is blacklisted', () => { + context('usersettings exist', () => { + // we had a blacklist once, the test below was checking if certain + // attributes are unaltered beforeEach(async() => { await usersettingsService.create({ - userId: user._id, - blacklist: [author._id] + userId: user._id }); }); - it('is concealed', async () => { + it('is visible', async () => { const comments = await service.find(params); const comment = comments.data[1]; - assert.equal(comment.content, 'Comments of this blacklisted user are not visible.'); - assert.equal(comment.contentExcerpt, 'Comments of this blacklisted user are not visible.'); - }); - - context('but if user is not authenticated', () => { - it('is visible', async () => { - const comments = await service.find(); - const comment = comments.data[1]; - assert.equal(comment.content, 'Original content'); - assert.equal(comment.contentExcerpt, 'Original content'); - }); + assert.equal(comment.content, 'Original content'); + assert.equal(comment.contentExcerpt, 'Original content'); }); }); }); diff --git a/test/services/contributions.test.js b/test/services/contributions.test.js index 4bb08b2..b70dbb8 100644 --- a/test/services/contributions.test.js +++ b/test/services/contributions.test.js @@ -4,7 +4,6 @@ const service = app.service('contributions'); const userService = app.service('users'); const notificationService = app.service('notifications'); const categoryService = app.service('categories'); -const usersettingsService = app.service('usersettings'); const { userData, adminData } = require('../assets/users'); const { contributionData, @@ -191,27 +190,6 @@ describe('\'contributions\' service', () => { assert.equal(contributions.total, 2); }); }); - - context('who is blacklisted', () => { - beforeEach(async() => { - await usersettingsService.create({ - userId: user._id, - blacklist: [author._id] - }); - }); - - it('is filtered', async () => { - const contributions = await service.find(params); - assert.equal(contributions.total, 1); - }); - - context('but if user is not authenticated', () => { - it('is not filtered', async () => { - const contributions = await service.find(); - assert.equal(contributions.total, 2); - }); - }); - }); }); }); diff --git a/test/services/usersettings.test.js b/test/services/usersettings.test.js index bf42dd8..1c16041 100644 --- a/test/services/usersettings.test.js +++ b/test/services/usersettings.test.js @@ -39,73 +39,6 @@ describe('\'usersettings\' service', () => { const usersettings = await service.create(data); assert.ok(usersettings); }); - - describe('blacklist', () => { - const testSetup = async (blacklistedUserData) => { - let blacklistedUser = await userService.create({ - ...userData, - ...blacklistedUserData, - email: 'someoneelse@test.de', - name: 'Someone' - }); - let data = { - userId: user._id, - blacklist: [blacklistedUser._id] - }; - const usersettings = await service.create(data); - return usersettings[0].blacklist; - }; - - context('ordinary account', () => { - it('succeeds', async () => { - const blacklist = await testSetup({}); - assert.equal(blacklist.length, 1); - }); - }); - - context('own account', () => { - it('rejects', async () => { - try { - let data = { - userId: user._id, - blacklist: [user._id] - }; - await service.create(data); - } catch(BadRequest) { - const usersettings = await service.find({userId: user._id}); - assert.equal(usersettings.total, 0); - return; - } - assert.fail('Blacklisting yourself was not rejected'); - }); - }); - - context('moderator account', () => { - it('rejects', async () => { - try { - await testSetup({role: 'moderator'}); - } catch(BadRequest){ - const usersettings = await service.find({userId: user._id}); - assert.equal(usersettings.total, 0); - return; - } - assert.fail('Blacklisting a moderator was not rejected'); - }); - }); - - context('admin account', () => { - it('rejects', async () => { - try { - await testSetup({role: 'admin'}); - } catch(BadRequest){ - const usersettings = await service.find({userId: user._id}); - assert.equal(usersettings.total, 0); - return; - } - assert.fail('Blacklisting an admin user was not rejected'); - }); - }); - }); }); }); });