diff --git a/src/database/queries/users.js b/src/database/queries/users.js index 9cd0ee9f2..e3a84b90e 100644 --- a/src/database/queries/users.js +++ b/src/database/queries/users.js @@ -234,3 +234,38 @@ exports.listUsersFromView = async (roleId, organization_id, page, limit, search, throw error } } + +exports.changeOrganization = async (id, currentOrgId, newOrgId, updateBody = {}) => { + const transaction = await Sequelize.transaction() + try { + const existingUserRow = await database.User.findOne({ + where: { id, organization_id: currentOrgId }, + raw: true, + transaction, + }) + + if (!existingUserRow) throw new Error('User not found') + + await database.User.destroy({ + where: { id, organization_id: currentOrgId }, + force: true, + transaction, + }) + + const newUserRow = await database.User.create( + { + ...existingUserRow, + ...updateBody, + organization_id: newOrgId, + id, + }, + { transaction } + ) + + await transaction.commit() + return newUserRow + } catch (error) { + await transaction.rollback() + throw error + } +} diff --git a/src/middlewares/authenticator.js b/src/middlewares/authenticator.js index 193cc6002..f56d84685 100644 --- a/src/middlewares/authenticator.js +++ b/src/middlewares/authenticator.js @@ -22,6 +22,8 @@ module.exports = async function (req, res, next) { common.internalAccessUrls.map(function (path) { if (req.path.includes(path)) { + console.log('REQUEST PATH: ', req.path) + console.log('INTERNAL ACCESS PATH: ', path) if ( req.headers.internal_access_token && process.env.INTERNAL_ACCESS_TOKEN == req.headers.internal_access_token diff --git a/src/services/admin.js b/src/services/admin.js index 9a74b74e6..07c999e1b 100644 --- a/src/services/admin.js +++ b/src/services/admin.js @@ -229,6 +229,7 @@ module.exports = class AdminHelper { responseCode: 'CLIENT_ERROR', }) } + const user = await userQueries.findOne({ id: userCredentials.user_id, organization_id: userCredentials.organization_id, @@ -240,7 +241,7 @@ module.exports = class AdminHelper { responseCode: 'CLIENT_ERROR', }) } - userId = user.id + userId = user.id //un-necessary let organization = await organizationQueries.findByPk(organizationId) if (!organization?.id) { @@ -260,6 +261,9 @@ module.exports = class AdminHelper { }) } + // Create a unique array of organization administrators (orgAdmins) by combining the existing + // organization admins (organization.org_admin) with the userId. The lodash uniq function ensures + // that the resulting array contains only unique values. const orgAdmins = _.uniq([...(organization.org_admin || []), userId]) const orgRowsAffected = await organizationQueries.update( @@ -288,10 +292,6 @@ module.exports = class AdminHelper { const roles = _.uniq([...(user.roles || []), role.id]) - let updateObj = { - roles, - } - if (userOrg.code != process.env.DEFAULT_ORGANISATION_CODE && userOrg.id != organizationId) { return common.failureResponse({ message: 'FAILED_TO_ASSIGN_AS_ADMIN', @@ -300,9 +300,19 @@ module.exports = class AdminHelper { }) } - updateObj.organization_id = organizationId + //update organization + if (userOrg.id != organizationId) { + await userQueries.changeOrganization(userId, userOrg.id, organizationId, { + //organization_id: organizationId, + roles: roles, + }) + } else { + await userQueries.updateUser( + { id: userId, organization_id: userCredentials.organization_id }, + { roles: roles } + ) + } - await userQueries.updateUser({ id: userId, organization_id: userCredentials.organization_id }, updateObj) await UserCredentialQueries.updateUser( { email: userCredentials.email, @@ -322,7 +332,7 @@ module.exports = class AdminHelper { } ) - //update organization in mentoring + // update organization in mentoring eventBroadcaster('updateOrganization', { requestBody: { user_id: userId, diff --git a/src/services/organization.js b/src/services/organization.js index 8a961dfd1..a0d1a2d61 100644 --- a/src/services/organization.js +++ b/src/services/organization.js @@ -99,6 +99,7 @@ module.exports = class OrganizationsHelper { role: common.ORG_ADMIN_ROLE, orgName: bodyData.name, appName: process.env.APP_NAME, + portalURL: process.env.PORTAL_URL, }), }, } diff --git a/src/services/userInvite.js b/src/services/userInvite.js index b4a8f60d0..49367cfdc 100644 --- a/src/services/userInvite.js +++ b/src/services/userInvite.js @@ -155,10 +155,7 @@ module.exports = class UserInviteHelper { static async createUserInvites(csvData, user, fileUploadId) { try { const outputFileName = utils.generateFileName(common.inviteeOutputFile, common.csvExtension) - - // get the role data from db const allRoles = _.uniq(_.map(csvData, 'roles').map((role) => role.toLowerCase())) - const roleList = await roleQueries.findAll({ title: allRoles }) const roleTitlesToIds = {} roleList.forEach((role) => { @@ -167,7 +164,6 @@ module.exports = class UserInviteHelper { //get all existing user const emailArray = _.uniq(_.map(csvData, 'email')) - const userCredentials = await UserCredentialQueries.findAll( { email: { [Op.in]: emailArray } }, { @@ -175,14 +171,12 @@ module.exports = class UserInviteHelper { } ) const userIds = _.map(userCredentials, 'user_id') - const existingUsers = await userQueries.findAll( { id: userIds }, { attributes: ['id', 'email', 'organization_id', 'roles'], } ) - const existingEmailsMap = new Map(existingUsers.map((eachUser) => [eachUser.email, eachUser])) //find default org id @@ -191,6 +185,7 @@ module.exports = class UserInviteHelper { let input = [] let isErrorOccured = false + let isOrgUpdate = false //fetch email template const mentorTemplateCode = process.env.MENTOR_INVITATION_EMAIL_TEMPLATE_CODE || null @@ -237,6 +232,7 @@ module.exports = class UserInviteHelper { //update user details if the user exist and in default org const existingUser = existingEmailsMap.get(invitee.email) + if (existingUser) { invitee.statusOrUserId = 'USER_ALREADY_EXISTS' isErrorOccured = true @@ -246,8 +242,17 @@ module.exports = class UserInviteHelper { existingUser.organization_id === user.organization_id if (isOrganizationMatch) { let userUpdateData = {} + if (existingUser.organization_id != user.organization_id) { - userUpdateData.organization_id = user.organization_id + await userQueries.changeOrganization( + existingUser.id, + existingUser.organization_id, + user.organization_id, + { + organization_id: user.organization_id, + } + ) + isOrgUpdate = true userUpdateData.refresh_tokens = [] } const areAllElementsInArray = _.every(roleTitlesToIds[invitee.roles], (element) => @@ -258,26 +263,26 @@ module.exports = class UserInviteHelper { userUpdateData.refresh_tokens = [] } - if (userUpdateData.organization_id || userUpdateData.roles) { + if (isOrgUpdate || userUpdateData.roles) { const userCredentials = await UserCredentialQueries.findOne({ - email: invitee.email.toLowerCase(), + email: invitee.email, }) await userQueries.updateUser({ id: userCredentials.user_id }, userUpdateData) - await UserCredentialQueries.updateUser( { - email: invitee.email.toLowerCase(), + email: invitee.email, }, - { organization_id: userUpdateData.organization_id } + { organization_id: user.organization_id } ) + const userRoles = await roleQueries.findAll({ id: existingUser.roles }) //call event to update in mentoring if (!userUpdateData?.roles) { eventBroadcaster('updateOrganization', { requestBody: { user_id: existingUser.id, - organization_id: existingUser.organization_id, + organization_id: user.organization_id, roles: _.map(userRoles, 'title'), }, }) @@ -287,7 +292,7 @@ module.exports = class UserInviteHelper { new_roles: [invitee.roles], current_roles: _.map(userRoles, 'title'), } - if (userUpdateData.organization_id) requestBody.organization_id = user.organization_id + if (isOrgUpdate) requestBody.organization_id = user.organization_id eventBroadcaster('roleChange', { requestBody, })