diff --git a/schemas/deactivate.json b/schemas/deactivate.json deleted file mode 100644 index 177cd4830..000000000 --- a/schemas/deactivate.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "$id": "deactivate", - "type": "object", - "required": [ - "username" - ], - "properties": { - "username": { - "type": "string", - "minLength": 1 - }, - "audience": { - "type": "string", - "minLength": 1 - } - } -} diff --git a/src/actions/deactivate.js b/src/actions/deactivate.js deleted file mode 100644 index f296d1757..000000000 --- a/src/actions/deactivate.js +++ /dev/null @@ -1,139 +0,0 @@ -const { ActionTransport } = require('@microfleet/core'); -const { HttpStatusError } = require('common-errors'); -const Promise = require('bluebird'); -const redisKey = require('../utils/key.js'); -const jwt = require('../utils/jwt.js'); -const { getInternalData } = require('../utils/userData'); -const getMetadata = require('../utils/get-metadata'); -const handlePipeline = require('../utils/pipeline-error'); -const setMetadata = require('../utils/update-metadata'); -const { - USERS_INDEX, - USERS_DATA, - USERS_REFERRAL_INDEX, - USERS_PUBLIC_INDEX, - USERS_ACTIVE_FLAG, - USERS_ID_FIELD, - USERS_ALIAS_FIELD, - USERS_REFERRAL_FIELD, - USERS_ACTIVATED_FIELD, -} = require('../constants.js'); - -/** - * Helper to determine if something is true - */ -function throwBasedOnStatus(status) { - if (status === 'true') { - return true; - } - - return false; -} - -/** - * Verifies that account is active - */ -function isAccountActive(username) { - return getInternalData - .call(this, username) - .then((userData) => userData[USERS_ACTIVE_FLAG]) - .then(throwBasedOnStatus); -} - -/** - * Deactivates account after it was verified - * @param {Object} data internal user data - * @return {Promise} - */ -async function deactivateAccount(data, metadata) { - const userId = data[USERS_ID_FIELD]; - const alias = data[USERS_ALIAS_FIELD]; - const referral = metadata[USERS_REFERRAL_FIELD]; - const userKey = redisKey(userId, USERS_DATA); - const { defaultAudience, service } = this; - const { redis } = service; - - // if this goes through, but other async calls fail its ok to repeat that - // adds activation field - await setMetadata.call(service, { - userId, - audience: defaultAudience, - metadata: { - $set: { - [USERS_ACTIVATED_FIELD]: null, - }, - }, - }); - - // WARNING: `persist` is very important, otherwise we will lose user's information in 30 days - // set to active & persist - const pipeline = redis - .pipeline() - .hset(userKey, USERS_ACTIVE_FLAG, 'false') - .persist(userKey) - .sadd(USERS_INDEX, userId); - - if (alias) { - pipeline.sadd(USERS_PUBLIC_INDEX, userId); - } - - if (referral) { - pipeline.sadd(`${USERS_REFERRAL_INDEX}:${referral}`, userId); - } - - handlePipeline(await pipeline.exec()); - - return userId; -} - -/** - * @api {amqp} .deactivate Deactivate User - * @apiVersion 1.0.0 - * @apiName DeactivateUser - * @apiGroup Users - * - * @apiDescription This method allows one to deactivate user - * No verifications will be performed and user will be set - * to inactive. This case is used when admin deactivates a user. - * Success response contains user object. - * - * @apiParam (Payload) {String} username - id of the user - * @apiParam (Payload) {String} [audience] - additional metadata will be pushed there from custom hooks - * - */ -async function deactivateAction({ params }) { - const { username } = params; - const { config } = this; - const { jwt: { defaultAudience } } = config; - const audience = params.audience || defaultAudience; - - // basic context - const context = { - audience, - defaultAudience, - username, - service: this, - erase: config.token.erase, - }; - - const isActive = await isAccountActive.call(this, username); - - if (!isActive) { - throw new HttpStatusError(417, `Account ${username} was already deactivated`); - } - - const userId = await Promise - .bind(context) - .then(() => getInternalData.call(this, username)) - .then((internalData) => Promise.join( - internalData, - getMetadata.call(this, internalData[USERS_ID_FIELD], audience).get(audience) - )) - .spread(deactivateAccount); - - return jwt.reset.call(this, userId); -} - -deactivateAction.transports = [ActionTransport.amqp]; - -module.exports = deactivateAction; diff --git a/src/utils/organization/get-organization-members.js b/src/utils/organization/get-organization-members.js index d2ffe3a1c..3af40d415 100644 --- a/src/utils/organization/get-organization-members.js +++ b/src/utils/organization/get-organization-members.js @@ -1,20 +1,24 @@ const Promise = require('bluebird'); const mapValues = require('lodash/mapValues'); -const { ORGANIZATIONS_MEMBERS } = require('../../constants'); +const { ORGANIZATIONS_MEMBERS, USERS_DATA, USERS_BANNED_FLAG } = require('../../constants'); const redisKey = require('../key'); const JSONParse = (d) => JSON.parse(d); +async function getMemberData(organizationMemberId) { + const [, , userId] = organizationMemberId.split('!'); + const organization = await this.redis.hgetall(organizationMemberId); + const banned = await this.redis.hget(redisKey(userId, USERS_DATA), USERS_BANNED_FLAG); + + return mapValues({ ...organization, banned }, JSONParse); +} + async function getOrganizationMembers(organizationId) { const { redis } = this; - const organizationMembersIds = await redis.zrange(redisKey(organizationId, ORGANIZATIONS_MEMBERS), 0, -1); - let organizationMembersJobs = []; - if (organizationMembersIds) { - organizationMembersJobs = organizationMembersIds.map((organizationMemberId) => redis.hgetall(organizationMemberId)); - } + const organizationMembersIds = await redis.zrange(redisKey(organizationId, ORGANIZATIONS_MEMBERS), 0, -1) || []; + const organizationMembersJobs = organizationMembersIds.map(getMemberData, this); - const members = await Promise.all(organizationMembersJobs); - return members.map((member) => mapValues(member, JSONParse)); + return Promise.all(organizationMembersJobs); } module.exports = getOrganizationMembers; diff --git a/test/suites/actions/activate.js b/test/suites/actions/activate.js index 3376d8289..f96268ecd 100644 --- a/test/suites/actions/activate.js +++ b/test/suites/actions/activate.js @@ -52,11 +52,6 @@ describe('#activate', function activateSuite() { return true; }); }); - - it('must deactivate account', async function test() { - const params = { username: email, audience: 'ok' }; - await this.dispatch('users.deactivate', params); - }); }); describe('activate inactive user', function suite() { @@ -73,16 +68,6 @@ describe('#activate', function activateSuite() { }); }); - it('must reject deactivation when account is already deactivated', async function test() { - const params = { username: email, audience: 'ok' }; - await assert.rejects(this.dispatch('users.deactivate', params), (activation) => { - expect(activation.name).to.be.eq('HttpStatusError'); - expect(activation.message).to.match(new RegExp(`Account ${email} was already deactivated`)); - expect(activation.statusCode).to.be.eq(417); - return true; - }); - }); - it('must activate account when challenge token is correct and not expired', async function test() { await this.dispatch('users.activate', { token: this.token }); });