From 0b3fbc962b3787658c82bcd604c459f9ee9dbf31 Mon Sep 17 00:00:00 2001 From: ostjen Date: Mon, 16 Aug 2021 17:40:00 -0300 Subject: [PATCH 01/14] avoid last admin to deactivate itself --- server/methods/setUserActiveStatus.js | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/server/methods/setUserActiveStatus.js b/server/methods/setUserActiveStatus.js index adecec84054b..7e3b21f9ba85 100644 --- a/server/methods/setUserActiveStatus.js +++ b/server/methods/setUserActiveStatus.js @@ -1,6 +1,7 @@ import { Meteor } from 'meteor/meteor'; import { check } from 'meteor/check'; +import { Users } from '../../app/models/server'; import { hasPermission } from '../../app/authorization'; import { setUserActiveStatus } from '../../app/lib/server/functions/setUserActiveStatus'; @@ -21,8 +22,25 @@ Meteor.methods({ }); } - setUserActiveStatus(userId, active, confirmRelenquish); + const userAdmin = Users.findOneAdmin(userId.count); + + if (userAdmin) { + const adminCount = Meteor.users.find({ + roles: { + $in: ['admin'], + }, + active: true, + }).count(); + if (adminCount === 1) { + throw new Meteor.Error('error-action-not-allowed', 'Leaving the app without an active admin is not allowed', { + method: 'removeUserFromRole', + action: 'Remove_last_admin', + }); + } + } + + setUserActiveStatus(userId, active, confirmRelenquish); return true; }, }); From a73fb19faba610aa10cca4e3beb66f9f7d6020e6 Mon Sep 17 00:00:00 2001 From: ostjen Date: Mon, 16 Aug 2021 17:45:49 -0300 Subject: [PATCH 02/14] cleaner code --- server/methods/setUserActiveStatus.js | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/server/methods/setUserActiveStatus.js b/server/methods/setUserActiveStatus.js index 7e3b21f9ba85..70f211c22188 100644 --- a/server/methods/setUserActiveStatus.js +++ b/server/methods/setUserActiveStatus.js @@ -5,6 +5,15 @@ import { Users } from '../../app/models/server'; import { hasPermission } from '../../app/authorization'; import { setUserActiveStatus } from '../../app/lib/server/functions/setUserActiveStatus'; +const getAdminCount = () => { + Meteor.users.find({ + roles: { + $in: ['admin'], + }, + active: true, + }).count(); +}; + Meteor.methods({ setUserActiveStatus(userId, active, confirmRelenquish) { check(userId, String); @@ -25,12 +34,7 @@ Meteor.methods({ const userAdmin = Users.findOneAdmin(userId.count); if (userAdmin) { - const adminCount = Meteor.users.find({ - roles: { - $in: ['admin'], - }, - active: true, - }).count(); + const adminCount = getAdminCount(); if (adminCount === 1) { throw new Meteor.Error('error-action-not-allowed', 'Leaving the app without an active admin is not allowed', { From 23bf06a5081a745e9a3e6bcb226202c1d04a6c46 Mon Sep 17 00:00:00 2001 From: Leonardo Date: Tue, 17 Aug 2021 09:55:22 -0300 Subject: [PATCH 03/14] refact to avoid nesting --- server/methods/setUserActiveStatus.js | 30 ++++++++++++--------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/server/methods/setUserActiveStatus.js b/server/methods/setUserActiveStatus.js index 70f211c22188..b9bfb0792403 100644 --- a/server/methods/setUserActiveStatus.js +++ b/server/methods/setUserActiveStatus.js @@ -6,13 +6,13 @@ import { hasPermission } from '../../app/authorization'; import { setUserActiveStatus } from '../../app/lib/server/functions/setUserActiveStatus'; const getAdminCount = () => { - Meteor.users.find({ - roles: { - $in: ['admin'], - }, - active: true, - }).count(); -}; + return Meteor.users.find({ + roles: { + $in: ['admin'], + }, + active: true, + }).count(); +} Meteor.methods({ setUserActiveStatus(userId, active, confirmRelenquish) { @@ -33,17 +33,13 @@ Meteor.methods({ const userAdmin = Users.findOneAdmin(userId.count); - if (userAdmin) { - const adminCount = getAdminCount(); - - if (adminCount === 1) { - throw new Meteor.Error('error-action-not-allowed', 'Leaving the app without an active admin is not allowed', { - method: 'removeUserFromRole', - action: 'Remove_last_admin', - }); - } + if (userAdmin && getAdminCount() === 1) { + throw new Meteor.Error('error-action-not-allowed', 'Leaving the app without an active admin is not allowed', { + method: 'removeUserFromRole', + action: 'Remove_last_admin', + }); } - + setUserActiveStatus(userId, active, confirmRelenquish); return true; }, From ca309dfa9f8bdaaa7c08b86731376c89be05737a Mon Sep 17 00:00:00 2001 From: ostjen Date: Tue, 17 Aug 2021 12:17:21 -0300 Subject: [PATCH 04/14] lint fix --- server/methods/setUserActiveStatus.js | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/server/methods/setUserActiveStatus.js b/server/methods/setUserActiveStatus.js index b9bfb0792403..cd64eaa8cc25 100644 --- a/server/methods/setUserActiveStatus.js +++ b/server/methods/setUserActiveStatus.js @@ -5,14 +5,12 @@ import { Users } from '../../app/models/server'; import { hasPermission } from '../../app/authorization'; import { setUserActiveStatus } from '../../app/lib/server/functions/setUserActiveStatus'; -const getAdminCount = () => { - return Meteor.users.find({ - roles: { - $in: ['admin'], - }, - active: true, - }).count(); -} +const getAdminCount = () => Meteor.users.find({ + roles: { + $in: ['admin'], + }, + active: true, +}).count(); Meteor.methods({ setUserActiveStatus(userId, active, confirmRelenquish) { @@ -39,7 +37,7 @@ Meteor.methods({ action: 'Remove_last_admin', }); } - + setUserActiveStatus(userId, active, confirmRelenquish); return true; }, From 507ca2d33ea5b36d458285a605ba37a89fec917e Mon Sep 17 00:00:00 2001 From: ostjen Date: Wed, 18 Aug 2021 08:38:57 -0300 Subject: [PATCH 05/14] revert changes --- server/methods/setUserActiveStatus.js | 30 ++++++++++++++++----------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/server/methods/setUserActiveStatus.js b/server/methods/setUserActiveStatus.js index cd64eaa8cc25..1277e5485642 100644 --- a/server/methods/setUserActiveStatus.js +++ b/server/methods/setUserActiveStatus.js @@ -5,12 +5,14 @@ import { Users } from '../../app/models/server'; import { hasPermission } from '../../app/authorization'; import { setUserActiveStatus } from '../../app/lib/server/functions/setUserActiveStatus'; -const getAdminCount = () => Meteor.users.find({ - roles: { - $in: ['admin'], - }, - active: true, -}).count(); +const getAdminCount = () => { + Meteor.users.find({ + roles: { + $in: ['admin'], + }, + active: true, + }).count(); +}; Meteor.methods({ setUserActiveStatus(userId, active, confirmRelenquish) { @@ -31,14 +33,18 @@ Meteor.methods({ const userAdmin = Users.findOneAdmin(userId.count); - if (userAdmin && getAdminCount() === 1) { - throw new Meteor.Error('error-action-not-allowed', 'Leaving the app without an active admin is not allowed', { - method: 'removeUserFromRole', - action: 'Remove_last_admin', - }); + if (userAdmin) { + const adminCount = getAdminCount(); + + if (adminCount === 1) { + throw new Meteor.Error('error-action-not-allowed', 'Leaving the app without an active admin is not allowed', { + method: 'removeUserFromRole', + action: 'Remove_last_admin', + }); + } } setUserActiveStatus(userId, active, confirmRelenquish); return true; }, -}); +}); \ No newline at end of file From f6f8a597bfb494905c3ea15a168575dbdc79a39e Mon Sep 17 00:00:00 2001 From: ostjen Date: Wed, 18 Aug 2021 08:41:02 -0300 Subject: [PATCH 06/14] refact --- server/methods/setUserActiveStatus.js | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/server/methods/setUserActiveStatus.js b/server/methods/setUserActiveStatus.js index 1277e5485642..5945ac9f6271 100644 --- a/server/methods/setUserActiveStatus.js +++ b/server/methods/setUserActiveStatus.js @@ -33,15 +33,11 @@ Meteor.methods({ const userAdmin = Users.findOneAdmin(userId.count); - if (userAdmin) { - const adminCount = getAdminCount(); - - if (adminCount === 1) { - throw new Meteor.Error('error-action-not-allowed', 'Leaving the app without an active admin is not allowed', { - method: 'removeUserFromRole', - action: 'Remove_last_admin', - }); - } + if (userAdmin && getAdminCount() === 1) { + throw new Meteor.Error('error-action-not-allowed', 'Leaving the app without an active admin is not allowed', { + method: 'removeUserFromRole', + action: 'Remove_last_admin', + }); } setUserActiveStatus(userId, active, confirmRelenquish); From 60ae3e990887d9b06ad793a2e38f0ecf01e9ac0a Mon Sep 17 00:00:00 2001 From: ostjen Date: Wed, 18 Aug 2021 08:51:34 -0300 Subject: [PATCH 07/14] lint --- server/methods/setUserActiveStatus.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/methods/setUserActiveStatus.js b/server/methods/setUserActiveStatus.js index 5945ac9f6271..f62421f8912a 100644 --- a/server/methods/setUserActiveStatus.js +++ b/server/methods/setUserActiveStatus.js @@ -43,4 +43,4 @@ Meteor.methods({ setUserActiveStatus(userId, active, confirmRelenquish); return true; }, -}); \ No newline at end of file +}); From dceaafc5f79c11ccea8f88b51c8f289c1c9d037f Mon Sep 17 00:00:00 2001 From: ostjen Date: Thu, 19 Aug 2021 14:54:00 -0300 Subject: [PATCH 08/14] countAdmin refact --- server/methods/setUserActiveStatus.js | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/server/methods/setUserActiveStatus.js b/server/methods/setUserActiveStatus.js index f62421f8912a..2597152ffd59 100644 --- a/server/methods/setUserActiveStatus.js +++ b/server/methods/setUserActiveStatus.js @@ -5,14 +5,6 @@ import { Users } from '../../app/models/server'; import { hasPermission } from '../../app/authorization'; import { setUserActiveStatus } from '../../app/lib/server/functions/setUserActiveStatus'; -const getAdminCount = () => { - Meteor.users.find({ - roles: { - $in: ['admin'], - }, - active: true, - }).count(); -}; Meteor.methods({ setUserActiveStatus(userId, active, confirmRelenquish) { @@ -32,8 +24,9 @@ Meteor.methods({ } const userAdmin = Users.findOneAdmin(userId.count); + const countAdmins = () => Users.findUsersInRoles(['admin']).count(); - if (userAdmin && getAdminCount() === 1) { + if (userAdmin && countAdmins() === 1) { throw new Meteor.Error('error-action-not-allowed', 'Leaving the app without an active admin is not allowed', { method: 'removeUserFromRole', action: 'Remove_last_admin', From 5569bead8cab52d3ba27ae415cff667b35f2d0ac Mon Sep 17 00:00:00 2001 From: ostjen Date: Thu, 19 Aug 2021 16:22:03 -0300 Subject: [PATCH 09/14] created user method + moved code --- app/lib/server/functions/setUserActiveStatus.js | 10 ++++++++++ app/models/client/models/Users.js | 1 + app/models/server/models/Users.js | 11 +++++++++++ server/methods/setUserActiveStatus.js | 11 ----------- 4 files changed, 22 insertions(+), 11 deletions(-) diff --git a/app/lib/server/functions/setUserActiveStatus.js b/app/lib/server/functions/setUserActiveStatus.js index 28d3111d0d2f..1af547832a49 100644 --- a/app/lib/server/functions/setUserActiveStatus.js +++ b/app/lib/server/functions/setUserActiveStatus.js @@ -30,6 +30,7 @@ function reactivateDirectConversations(userId) { } export function setUserActiveStatus(userId, active, confirmRelinquish = false) { + console.log('set user'); check(userId, String); check(active, Boolean); @@ -39,6 +40,15 @@ export function setUserActiveStatus(userId, active, confirmRelinquish = false) { return false; } + const userAdmin = Users.findOneAdmin(userId.count); + const countAdmins = () => Users.findActiveUsersInRoles(['admin']).count(); + if (userAdmin && countAdmins() === 1) { + throw new Meteor.Error('error-action-not-allowed', 'Leaving the app without an active admin is not allowed', { + method: 'removeUserFromRole', + action: 'Remove_last_admin', + }); + } + // Users without username can't do anything, so there is no need to check for owned rooms if (user.username != null && !active) { const subscribedRooms = getSubscribedRoomsForUserWithDetails(userId); diff --git a/app/models/client/models/Users.js b/app/models/client/models/Users.js index 51e71fedf9e0..af1eb8abde9b 100644 --- a/app/models/client/models/Users.js +++ b/app/models/client/models/Users.js @@ -24,6 +24,7 @@ export const Users = { return this.find(query, options); }, + }; // overwrite Meteor.users collection so records on it don't get erased whenever the client reconnects to websocket diff --git a/app/models/server/models/Users.js b/app/models/server/models/Users.js index 1d06be0ad64d..2fcceec625d6 100644 --- a/app/models/server/models/Users.js +++ b/app/models/server/models/Users.js @@ -634,6 +634,17 @@ export class Users extends Base { return this.find(query, options); } + findActiveUsersInRoles(roles, scope, options) { + roles = [].concat(roles); + + const query = { + roles: { $in: roles }, + active: true, + }; + + return this.find(query, options); + } + findOneByAppId(appId, options) { const query = { appId }; diff --git a/server/methods/setUserActiveStatus.js b/server/methods/setUserActiveStatus.js index 2597152ffd59..1fe3731471ac 100644 --- a/server/methods/setUserActiveStatus.js +++ b/server/methods/setUserActiveStatus.js @@ -1,7 +1,6 @@ import { Meteor } from 'meteor/meteor'; import { check } from 'meteor/check'; -import { Users } from '../../app/models/server'; import { hasPermission } from '../../app/authorization'; import { setUserActiveStatus } from '../../app/lib/server/functions/setUserActiveStatus'; @@ -23,16 +22,6 @@ Meteor.methods({ }); } - const userAdmin = Users.findOneAdmin(userId.count); - const countAdmins = () => Users.findUsersInRoles(['admin']).count(); - - if (userAdmin && countAdmins() === 1) { - throw new Meteor.Error('error-action-not-allowed', 'Leaving the app without an active admin is not allowed', { - method: 'removeUserFromRole', - action: 'Remove_last_admin', - }); - } - setUserActiveStatus(userId, active, confirmRelenquish); return true; }, From 63a720ef1690865fa4f67b69c31dd6837c127e6d Mon Sep 17 00:00:00 2001 From: ostjen Date: Thu, 19 Aug 2021 16:26:29 -0300 Subject: [PATCH 10/14] removed useless logs + newlines --- app/lib/server/functions/setUserActiveStatus.js | 1 - app/models/client/models/Users.js | 1 - server/methods/setUserActiveStatus.js | 1 + 3 files changed, 1 insertion(+), 2 deletions(-) diff --git a/app/lib/server/functions/setUserActiveStatus.js b/app/lib/server/functions/setUserActiveStatus.js index 1af547832a49..238699605d56 100644 --- a/app/lib/server/functions/setUserActiveStatus.js +++ b/app/lib/server/functions/setUserActiveStatus.js @@ -30,7 +30,6 @@ function reactivateDirectConversations(userId) { } export function setUserActiveStatus(userId, active, confirmRelinquish = false) { - console.log('set user'); check(userId, String); check(active, Boolean); diff --git a/app/models/client/models/Users.js b/app/models/client/models/Users.js index af1eb8abde9b..51e71fedf9e0 100644 --- a/app/models/client/models/Users.js +++ b/app/models/client/models/Users.js @@ -24,7 +24,6 @@ export const Users = { return this.find(query, options); }, - }; // overwrite Meteor.users collection so records on it don't get erased whenever the client reconnects to websocket diff --git a/server/methods/setUserActiveStatus.js b/server/methods/setUserActiveStatus.js index 1fe3731471ac..6f6e59fc5dd7 100644 --- a/server/methods/setUserActiveStatus.js +++ b/server/methods/setUserActiveStatus.js @@ -23,6 +23,7 @@ Meteor.methods({ } setUserActiveStatus(userId, active, confirmRelenquish); + return true; }, }); From 967342f55772856c6a7f751bccf602482c56eb4d Mon Sep 17 00:00:00 2001 From: ostjen Date: Thu, 19 Aug 2021 16:27:07 -0300 Subject: [PATCH 11/14] removed \n --- server/methods/setUserActiveStatus.js | 1 - 1 file changed, 1 deletion(-) diff --git a/server/methods/setUserActiveStatus.js b/server/methods/setUserActiveStatus.js index 6f6e59fc5dd7..adecec84054b 100644 --- a/server/methods/setUserActiveStatus.js +++ b/server/methods/setUserActiveStatus.js @@ -4,7 +4,6 @@ import { check } from 'meteor/check'; import { hasPermission } from '../../app/authorization'; import { setUserActiveStatus } from '../../app/lib/server/functions/setUserActiveStatus'; - Meteor.methods({ setUserActiveStatus(userId, active, confirmRelenquish) { check(userId, String); From 75573a326fc1ce6e40a645ac2cb7887e7af5f199 Mon Sep 17 00:00:00 2001 From: Leonardo Ostjen Couto Date: Mon, 23 Aug 2021 11:06:37 -0300 Subject: [PATCH 12/14] small changes --- .../server/functions/setUserActiveStatus.js | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/app/lib/server/functions/setUserActiveStatus.js b/app/lib/server/functions/setUserActiveStatus.js index 238699605d56..4b4c97854aff 100644 --- a/app/lib/server/functions/setUserActiveStatus.js +++ b/app/lib/server/functions/setUserActiveStatus.js @@ -39,17 +39,19 @@ export function setUserActiveStatus(userId, active, confirmRelinquish = false) { return false; } - const userAdmin = Users.findOneAdmin(userId.count); - const countAdmins = () => Users.findActiveUsersInRoles(['admin']).count(); - if (userAdmin && countAdmins() === 1) { - throw new Meteor.Error('error-action-not-allowed', 'Leaving the app without an active admin is not allowed', { - method: 'removeUserFromRole', - action: 'Remove_last_admin', - }); - } // Users without username can't do anything, so there is no need to check for owned rooms if (user.username != null && !active) { + + const userAdmin = Users.findOneAdmin(userId.count); + const countAdmins = () => Users.findActiveUsersInRoles(['admin']).count(); + if (userAdmin && countAdmins() === 1) { + throw new Meteor.Error('error-action-not-allowed', 'Leaving the app without an active admin is not allowed', { + method: 'removeUserFromRole', + action: 'Remove_last_admin', + }); + } + const subscribedRooms = getSubscribedRoomsForUserWithDetails(userId); // give omnichannel rooms a special treatment :) const chatSubscribedRooms = subscribedRooms.filter(({ t }) => t !== 'l'); From 9098911c178f8f1f5748014e1c396974d2a86cc9 Mon Sep 17 00:00:00 2001 From: Leonardo Ostjen Couto Date: Mon, 23 Aug 2021 11:18:39 -0300 Subject: [PATCH 13/14] lint --- app/lib/server/functions/setUserActiveStatus.js | 1 - 1 file changed, 1 deletion(-) diff --git a/app/lib/server/functions/setUserActiveStatus.js b/app/lib/server/functions/setUserActiveStatus.js index 4b4c97854aff..2f5d43cbd6fa 100644 --- a/app/lib/server/functions/setUserActiveStatus.js +++ b/app/lib/server/functions/setUserActiveStatus.js @@ -42,7 +42,6 @@ export function setUserActiveStatus(userId, active, confirmRelinquish = false) { // Users without username can't do anything, so there is no need to check for owned rooms if (user.username != null && !active) { - const userAdmin = Users.findOneAdmin(userId.count); const countAdmins = () => Users.findActiveUsersInRoles(['admin']).count(); if (userAdmin && countAdmins() === 1) { From 1cb07ee47bdf34a5ae2546557ac0fa02086fd057 Mon Sep 17 00:00:00 2001 From: Leonardo Ostjen Couto Date: Thu, 14 Oct 2021 15:47:03 -0300 Subject: [PATCH 14/14] Update app/lib/server/functions/setUserActiveStatus.js Co-authored-by: Matheus Barbosa Silva <36537004+matheusbsilva137@users.noreply.github.com> --- app/lib/server/functions/setUserActiveStatus.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/lib/server/functions/setUserActiveStatus.js b/app/lib/server/functions/setUserActiveStatus.js index 7b91f84f0514..8f1207ad898c 100644 --- a/app/lib/server/functions/setUserActiveStatus.js +++ b/app/lib/server/functions/setUserActiveStatus.js @@ -44,8 +44,8 @@ export function setUserActiveStatus(userId, active, confirmRelinquish = false) { // Users without username can't do anything, so there is no need to check for owned rooms if (user.username != null && !active) { const userAdmin = Users.findOneAdmin(userId.count); - const countAdmins = () => Users.findActiveUsersInRoles(['admin']).count(); - if (userAdmin && countAdmins() === 1) { + const adminsCount = Users.findActiveUsersInRoles(['admin']).count(); + if (userAdmin && adminsCount === 1) { throw new Meteor.Error('error-action-not-allowed', 'Leaving the app without an active admin is not allowed', { method: 'removeUserFromRole', action: 'Remove_last_admin',