diff --git a/src/actions/remove.js b/src/actions/remove.js index 8fbe9e446..ed0b4b659 100644 --- a/src/actions/remove.js +++ b/src/actions/remove.js @@ -27,6 +27,7 @@ const { USERS_ACTION_REGISTER, THROTTLE_PREFIX, SSO_PROVIDERS, + ORGANIZATIONS_MEMBERS, } = require('../constants'); // intersection of priority users @@ -42,6 +43,25 @@ function addMetadata(userData) { .then((metadata) => [userData, metadata]); } +async function removeOrganizationUser(userId) { + const { redis, config } = this; + const { audience } = config.organizations; + + const userOrganizationsKey = key(userId, USERS_METADATA, audience); + const userOrganizations = await redis.hgetall(userOrganizationsKey); + + if (userOrganizations) { + const pipeline = redis.pipeline(); + + for (const organizationId of Object.keys(userOrganizations)) { + const memberKey = key(organizationId, ORGANIZATIONS_MEMBERS, userId); + pipeline.zrem(key(organizationId, ORGANIZATIONS_MEMBERS), memberKey); + } + + await pipeline.exec().then(handlePipeline); + } +} + /** * @api {amqp} .remove Remove User * @apiVersion 1.0.0 @@ -110,6 +130,9 @@ async function removeUser({ params }) { .exec() .then(handlePipeline); + // remove user from organizations + await removeOrganizationUser.call(this, userId); + // clear cache const now = Date.now(); await Promise.all([redis.fsortBust(USERS_INDEX, now), redis.fsortBust(USERS_PUBLIC_INDEX, now)]); diff --git a/src/utils/challenges/email/generate.js b/src/utils/challenges/email/generate.js index 1ebf2cde9..73cf499bf 100644 --- a/src/utils/challenges/email/generate.js +++ b/src/utils/challenges/email/generate.js @@ -40,22 +40,20 @@ function generate(email, type, ctx = {}, opts = {}, nodemailer = {}) { context.qs = `?q=${context.token.secret}`; context.link = generateLink(server, paths[type]); break; + case USERS_ACTION_ORGANIZATION_REGISTER: + context.qs = `?${stringify({ + password: ctx.password, + login: ctx.email, + })}`; + context.link = generateLink(server, paths[USERS_ACTION_ORGANIZATION_REGISTER]); + break; case USERS_ACTION_ORGANIZATION_INVITE: - // generate secret - if (ctx.password) { - context.qs = `?${stringify({ - password: ctx.password, - login: ctx.email, - })}`; - context.link = generateLink(server, paths[USERS_ACTION_ORGANIZATION_REGISTER]); - } else { - context.qs = `?${stringify({ - q: context.token.secret, - organizationId: ctx.organizationId, - username: ctx.email, - })}`; - context.link = generateLink(server, paths[USERS_ACTION_ORGANIZATION_INVITE]); - } + context.qs = `?${stringify({ + q: context.token.secret, + organizationId: ctx.organizationId, + username: ctx.email, + })}`; + context.link = generateLink(server, paths[USERS_ACTION_ORGANIZATION_INVITE]); break; case USERS_ACTION_PASSWORD: diff --git a/src/utils/organization/send-invite-email.js b/src/utils/organization/send-invite-email.js index c03709695..2d4256e5a 100644 --- a/src/utils/organization/send-invite-email.js +++ b/src/utils/organization/send-invite-email.js @@ -5,6 +5,7 @@ const { TOKEN_METADATA_FIELD_CONTEXT, TOKEN_METADATA_FIELD_SENDED_AT, USERS_ACTION_ORGANIZATION_INVITE, + USERS_ACTION_ORGANIZATION_REGISTER, TOKEN_METADATA_FIELD_METADATA, } = require('../../constants.js'); @@ -25,7 +26,8 @@ module.exports = async function sendInviteMail(params) { }, }); - const res = await generateEmail.call(this, email, USERS_ACTION_ORGANIZATION_INVITE, { ...ctx, token }, { wait: true, send: true }); + const emailType = ctx.password ? USERS_ACTION_ORGANIZATION_REGISTER : USERS_ACTION_ORGANIZATION_INVITE; + const res = await generateEmail.call(this, email, emailType, { ...ctx, token }, { wait: true, send: true }); if (res.err) { this.log.error(res, 'send invite mail result');