fix: `afterCreateUser` callback being called before setting user's roles (#30309)

Co-authored-by: Murtaza Patrawala <34130764+murtaza98@users.noreply.github.com>
pull/32286/head^2
Kevin Aleman 2 years ago committed by GitHub
parent 1e772e4201
commit d79ddf10fb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 5
      .changeset/tame-ducks-turn.md
  2. 15
      apps/meteor/app/authentication/server/startup/index.js
  3. 3
      apps/meteor/app/lib/server/functions/saveUser.js
  4. 2
      apps/meteor/lib/callbacks.ts
  5. 18
      apps/meteor/tests/end-to-end/api/livechat/19-business-hours.ts

@ -0,0 +1,5 @@
---
"@rocket.chat/meteor": patch
---
Fixed a problem that caused `afterCreateUser` callback to be called without new user's roles inside. This caused Omnichannel Business Hour manager to ignore these users from assigning open business hours until the manager restarted or the business hour restarted.

@ -265,10 +265,14 @@ Accounts.onCreateUser(function (...args) {
const { insertUserDoc } = Accounts;
const insertUserDocAsync = async function (options, user) {
const globalRoles = [];
const globalRoles = new Set();
if (Match.test(options.globalRoles, [String]) && options.globalRoles.length > 0) {
options.globalRoles.map((role) => globalRoles.add(role));
}
if (Match.test(user.globalRoles, [String]) && user.globalRoles.length > 0) {
globalRoles.push(...user.globalRoles);
user.globalRoles.map((role) => globalRoles.add(role));
}
delete user.globalRoles;
@ -277,11 +281,12 @@ const insertUserDocAsync = async function (options, user) {
const defaultAuthServiceRoles = parseCSV(settings.get('Accounts_Registration_AuthenticationServices_Default_Roles') || '');
if (defaultAuthServiceRoles.length > 0) {
globalRoles.push(...defaultAuthServiceRoles);
defaultAuthServiceRoles.map((role) => globalRoles.add(role));
}
}
const roles = getNewUserRoles(globalRoles);
const arrayGlobalRoles = [...globalRoles];
const roles = options.skipNewUserRolesSetting ? arrayGlobalRoles : getNewUserRoles(arrayGlobalRoles);
if (!user.type) {
user.type = 'user';
@ -326,7 +331,7 @@ const insertUserDocAsync = async function (options, user) {
await addUserRolesAsync(_id, roles);
// Make user's roles to be present on callback
user = await Users.findOneById(_id, { projection: { username: 1, type: 1 } });
user = await Users.findOneById(_id, { projection: { username: 1, type: 1, roles: 1 } });
if (user.username) {
if (options.joinDefaultChannels !== false) {

@ -276,6 +276,8 @@ const saveNewUser = async function (userData, sendPassword) {
password: userData.password,
joinDefaultChannels: userData.joinDefaultChannels,
isGuest,
globalRoles: roles,
skipNewUserRolesSetting: true,
};
if (userData.email) {
createUser.email = userData.email;
@ -285,7 +287,6 @@ const saveNewUser = async function (userData, sendPassword) {
const updateUser = {
$set: {
roles,
...(typeof userData.name !== 'undefined' && { name: userData.name }),
settings: userData.settings || {},
},

@ -124,7 +124,7 @@ type ChainedCallbackSignatures = {
'livechat.onLoadConfigApi': (config: { room: IOmnichannelRoom }) => Record<string, unknown>;
'afterCreateUser': (user: IUser) => IUser;
'afterCreateUser': (user: AtLeast<IUser, '_id' | 'username' | 'roles'>) => IUser;
'afterDeleteRoom': (rid: IRoom['_id']) => IRoom['_id'];
'livechat:afterOnHold': (room: Pick<IOmnichannelRoom, '_id'>) => Pick<IOmnichannelRoom, '_id'>;
'livechat:afterOnHoldChatResumed': (room: Pick<IOmnichannelRoom, '_id'>) => Pick<IOmnichannelRoom, '_id'>;

@ -838,6 +838,24 @@ describe('LIVECHAT - business hours', function () {
expect(latestAgent.statusLivechat).to.be.undefined;
});
describe('Special Case - Agent created, BH already enabled', () => {
let newAgent: ILivechatAgent;
let newAgentCredentials: IUserCredentialsHeader;
before(async () => {
newAgent = await createUser({ roles: ['user', 'livechat-agent'] });
newAgentCredentials = await login(newAgent.username, password);
});
after(async () => {
await deleteUser(newAgent);
});
it('should verify a newly created agent to be assigned to the default business hour', async () => {
const latestAgent: ILivechatAgent = await getMe(newAgentCredentials as any);
expect(latestAgent).to.be.an('object');
expect(latestAgent.openBusinessHours).to.be.an('array').of.length(1);
expect(latestAgent?.openBusinessHours?.[0]).to.be.equal(defaultBH._id);
});
});
after(async () => {
await deleteUser(agent._id);
});

Loading…
Cancel
Save