diff --git a/HISTORY.md b/HISTORY.md
index d47b699a3ce4..1d3d8139d3d1 100644
--- a/HISTORY.md
+++ b/HISTORY.md
@@ -8,6 +8,7 @@
- [FIX] Incoming integrations would break when trying to use the `Store` feature.
- [FIX] Outgoing webhooks which have an error and they're retrying would still retry even if the integration was disabled. (#4835)
- [FIX] Removed Deprecated Package rocketchat:sharedsecret.
+- [BREAK] `getUsersOfRoom` API to return array of objects with user and username, instead of array of strings
## 0.54.2 - 2017-Mar-24
diff --git a/packages/rocketchat-cas/cas_server.js b/packages/rocketchat-cas/cas_server.js
index 6a8516cd1809..77c5bab6e9b2 100644
--- a/packages/rocketchat-cas/cas_server.js
+++ b/packages/rocketchat-cas/cas_server.js
@@ -188,7 +188,7 @@ Accounts.registerLoginHandler(function(options) {
logger.debug('Syncing user attributes');
// Update name
if (int_attrs.name) {
- Meteor.users.update(user, { $set: { name: int_attrs.name }});
+ RocketChat._setRealName(user._id, int_attrs.name);
}
// Update email
diff --git a/packages/rocketchat-crowd/server/crowd.js b/packages/rocketchat-crowd/server/crowd.js
index 0ca60d4548a4..234fd09eca39 100644
--- a/packages/rocketchat-crowd/server/crowd.js
+++ b/packages/rocketchat-crowd/server/crowd.js
@@ -85,7 +85,6 @@ const CROWD = class CROWD {
syncDataToUser(crowdUser, id) {
const user = {
- name: crowdUser.displayname,
username: crowdUser.username,
emails: [{
address : crowdUser.email,
@@ -95,6 +94,10 @@ const CROWD = class CROWD {
active: crowdUser.active
};
+ if (crowdUser.displayname) {
+ RocketChat._setRealName(id, crowdUser.displayname);
+ }
+
Meteor.users.update(id, {
$set: user
});
diff --git a/packages/rocketchat-i18n/i18n/en.i18n.json b/packages/rocketchat-i18n/i18n/en.i18n.json
index 6057e02758c1..3df551cb89d8 100644
--- a/packages/rocketchat-i18n/i18n/en.i18n.json
+++ b/packages/rocketchat-i18n/i18n/en.i18n.json
@@ -1522,6 +1522,7 @@
"UI_DisplayRoles": "Display Roles",
"UI_Merge_Channels_Groups": "Merge private groups with channels",
"UI_Use_Name_Avatar": "Use full name initials to generate default avatar",
+ "UI_Use_Real_Name" : "Use Real Name",
"Unarchive": "Unarchive",
"Unblock_User": "Unblock User",
"Unmute_someone_in_room": "Unmute someone in the room",
diff --git a/packages/rocketchat-importer-hipchat/server.coffee b/packages/rocketchat-importer-hipchat/server.coffee
index c84a6413b8f1..19a4cbced951 100644
--- a/packages/rocketchat-importer-hipchat/server.coffee
+++ b/packages/rocketchat-importer-hipchat/server.coffee
@@ -221,7 +221,7 @@ Importer.HipChat = class Importer.HipChat extends Importer.Base
getRocketUser: (hipchatId) =>
for user in @users.users when user.user_id is hipchatId
- return RocketChat.models.Users.findOneById user.rocketId, { fields: { username: 1 }}
+ return RocketChat.models.Users.findOneById user.rocketId, { fields: { username: 1, name: 1 }}
convertHipChatMessageToRocketChat: (message) =>
if message?
diff --git a/packages/rocketchat-importer-slack/server.coffee b/packages/rocketchat-importer-slack/server.coffee
index 04ca574ac1a1..bbfa2a050474 100644
--- a/packages/rocketchat-importer-slack/server.coffee
+++ b/packages/rocketchat-importer-slack/server.coffee
@@ -342,7 +342,7 @@ Importer.Slack = class Importer.Slack extends Importer.Base
getRocketUser: (slackId) =>
for user in @users.users when user.id is slackId
- return RocketChat.models.Users.findOneById user.rocketId, { fields: { username: 1 }}
+ return RocketChat.models.Users.findOneById user.rocketId, { fields: { username: 1, name: 1 }}
convertSlackMessageToRocketChat: (message) =>
if message?
diff --git a/packages/rocketchat-ldap/server/sync.js b/packages/rocketchat-ldap/server/sync.js
index 0b0b218d24eb..df3ec4bf828b 100644
--- a/packages/rocketchat-ldap/server/sync.js
+++ b/packages/rocketchat-ldap/server/sync.js
@@ -122,9 +122,13 @@ syncUserData = function syncUserData(user, ldapUser) {
const userData = getDataToSyncUserData(ldapUser, user);
if (user && user._id && userData) {
+ logger.debug('setting', JSON.stringify(userData, null, 2));
+ if (userData.name) {
+ RocketChat._setRealName(user._id, userData.name);
+ delete userData.name;
+ }
Meteor.users.update(user._id, { $set: userData });
user = Meteor.users.findOne({_id: user._id});
- logger.debug('setting', JSON.stringify(userData, null, 2));
}
if (RocketChat.settings.get('LDAP_Username_Field') !== '') {
diff --git a/packages/rocketchat-lib/package.js b/packages/rocketchat-lib/package.js
index 03e88cded081..dbb17c2bda9b 100644
--- a/packages/rocketchat-lib/package.js
+++ b/packages/rocketchat-lib/package.js
@@ -87,6 +87,7 @@ Package.onUse(function(api) {
api.addFiles('server/functions/settings.coffee', 'server');
api.addFiles('server/functions/setUserAvatar.js', 'server');
api.addFiles('server/functions/setUsername.coffee', 'server');
+ api.addFiles('server/functions/setRealName.js', 'server');
api.addFiles('server/functions/setEmail.js', 'server');
api.addFiles('server/functions/unarchiveRoom.js', 'server');
api.addFiles('server/functions/updateMessage.js', 'server');
diff --git a/packages/rocketchat-lib/server/functions/addUserToRoom.js b/packages/rocketchat-lib/server/functions/addUserToRoom.js
index 47ae76aeaabe..b27acb1f6791 100644
--- a/packages/rocketchat-lib/server/functions/addUserToRoom.js
+++ b/packages/rocketchat-lib/server/functions/addUserToRoom.js
@@ -27,7 +27,8 @@ RocketChat.addUserToRoom = function(rid, user, inviter, silenced) {
ts: now,
u: {
_id: inviter._id,
- username: inviter.username
+ username: inviter.username,
+ name: inviter.name
}
});
} else {
diff --git a/packages/rocketchat-lib/server/functions/saveUser.js b/packages/rocketchat-lib/server/functions/saveUser.js
index ac9c31abc142..540479df0afb 100644
--- a/packages/rocketchat-lib/server/functions/saveUser.js
+++ b/packages/rocketchat-lib/server/functions/saveUser.js
@@ -140,6 +140,10 @@ RocketChat.saveUser = function(userId, userData) {
RocketChat.setUsername(userData._id, userData.username);
}
+ if (userData.name) {
+ RocketChat.setRealName(userData._id, userData.name);
+ }
+
if (userData.email) {
RocketChat.setEmail(userData._id, userData.email);
}
@@ -152,10 +156,6 @@ RocketChat.saveUser = function(userId, userData) {
$set: {}
};
- if (userData.name) {
- updateUser.$set.name = userData.name;
- }
-
if (userData.roles) {
updateUser.$set.roles = userData.roles;
}
diff --git a/packages/rocketchat-lib/server/functions/sendMessage.coffee b/packages/rocketchat-lib/server/functions/sendMessage.coffee
index bdce87faba4d..e25bf08cb8dc 100644
--- a/packages/rocketchat-lib/server/functions/sendMessage.coffee
+++ b/packages/rocketchat-lib/server/functions/sendMessage.coffee
@@ -5,7 +5,7 @@ RocketChat.sendMessage = (user, message, room, upsert = false) ->
unless message.ts?
message.ts = new Date()
- message.u = _.pick user, ['_id','username']
+ message.u = _.pick user, ['_id','username', 'name']
if not Match.test(message.msg, String)
message.msg = ''
diff --git a/packages/rocketchat-lib/server/functions/setRealName.js b/packages/rocketchat-lib/server/functions/setRealName.js
new file mode 100644
index 000000000000..93d7545e7796
--- /dev/null
+++ b/packages/rocketchat-lib/server/functions/setRealName.js
@@ -0,0 +1,29 @@
+RocketChat._setRealName = function(userId, name) {
+ name = s.trim(name);
+ if (!userId || !name) {
+ return false;
+ }
+
+ const user = RocketChat.models.Users.findOneById(userId);
+
+ // User already has desired name, return
+ if (user.name === name) {
+ return user;
+ }
+
+ const previousName = user.name;
+
+ if (previousName) {
+ RocketChat.models.Messages.updateAllNamesByUserId(user._id, name);
+ RocketChat.models.Subscriptions.setRealNameForDirectRoomsWithUsername(user.username, name);
+ }
+
+ // Set new name
+ RocketChat.models.Users.setName(user._id, name);
+ user.name = name;
+ return user;
+};
+
+RocketChat.setRealName = RocketChat.RateLimiter.limitFunction(RocketChat._setRealName, 1, 60000, {
+ 0() { return !Meteor.userId() || !RocketChat.authz.hasPermission(Meteor.userId(), 'edit-other-user-info'); } // Administrators have permission to change others names, so don't limit those
+});
diff --git a/packages/rocketchat-lib/server/lib/sendNotificationsOnMessage.js b/packages/rocketchat-lib/server/lib/sendNotificationsOnMessage.js
index 735ac1340dea..85ab61fb1119 100644
--- a/packages/rocketchat-lib/server/lib/sendNotificationsOnMessage.js
+++ b/packages/rocketchat-lib/server/lib/sendNotificationsOnMessage.js
@@ -128,7 +128,7 @@ RocketChat.callbacks.add('afterSaveMessage', function(message, room) {
}
if ((userOfMention != null) && canBeNotified(userOfMentionId, 'mobile')) {
RocketChat.Notifications.notifyUser(userOfMention._id, 'notification', {
- title: `@${ user.username }`,
+ title: RocketChat.settings.get('UI_Use_Real_Name') ? user.name : `@${ user.username }`,
text: message.msg,
duration: settings.desktopNotificationDurations[userOfMention._id],
payload: {
diff --git a/packages/rocketchat-lib/server/methods/setRealName.js b/packages/rocketchat-lib/server/methods/setRealName.js
index 16f7068f9ea6..467bb979822e 100644
--- a/packages/rocketchat-lib/server/methods/setRealName.js
+++ b/packages/rocketchat-lib/server/methods/setRealName.js
@@ -17,10 +17,14 @@ Meteor.methods({
name = _.trim(name);
}
- if (!RocketChat.models.Users.setName(Meteor.userId(), name)) {
+ if (!RocketChat.setRealName(Meteor.userId(), name)) {
throw new Meteor.Error('error-could-not-change-name', 'Could not change name', { method: 'setRealName' });
}
return name;
}
});
+
+RocketChat.RateLimiter.limitMethod('setRealName', 1, 1000, {
+ userId: () => true
+});
diff --git a/packages/rocketchat-lib/server/models/Messages.coffee b/packages/rocketchat-lib/server/models/Messages.coffee
index 8ac7b4efcd7b..524133ae7b0e 100644
--- a/packages/rocketchat-lib/server/models/Messages.coffee
+++ b/packages/rocketchat-lib/server/models/Messages.coffee
@@ -320,6 +320,16 @@ RocketChat.models.Messages = new class extends RocketChat.models._Base
return @update query, update
+ updateAllNamesByUserId: (userId, name) ->
+ query =
+ 'u._id': userId
+
+ update =
+ $set:
+ "u.name": name
+
+ return @update query, update, { multi: true }
+
updateUserStarById: (_id, userId, starred) ->
query =
_id: _id
@@ -380,6 +390,7 @@ RocketChat.models.Messages = new class extends RocketChat.models._Base
u:
_id: user._id
username: user.username
+ name: user.name
groupable: false
_.extend record, extraData
diff --git a/packages/rocketchat-lib/server/models/Subscriptions.coffee b/packages/rocketchat-lib/server/models/Subscriptions.coffee
index 4ae7500ffef5..7b9aa80e605a 100644
--- a/packages/rocketchat-lib/server/models/Subscriptions.coffee
+++ b/packages/rocketchat-lib/server/models/Subscriptions.coffee
@@ -242,6 +242,17 @@ class ModelSubscriptions extends RocketChat.models._Base
return @update query, update, { multi: true }
+ setRealNameForDirectRoomsWithUsername: (username, name) ->
+ query =
+ name: username
+ t: "d"
+
+ update =
+ $set:
+ fname: name
+
+ return @update query, update, { multi: true }
+
setNameForDirectRoomsWithOldName: (oldName, name) ->
query =
name: oldName
diff --git a/packages/rocketchat-lib/server/models/Users.coffee b/packages/rocketchat-lib/server/models/Users.coffee
index f5c6a201f3c1..8eef5f4ab515 100644
--- a/packages/rocketchat-lib/server/models/Users.coffee
+++ b/packages/rocketchat-lib/server/models/Users.coffee
@@ -109,7 +109,7 @@ class ModelUsers extends RocketChat.models._Base
return @find query, options
- findByActiveUsersUsernameExcept: (searchTerm, exceptions = [], options = {}) ->
+ findByActiveUsersExcept: (searchTerm, exceptions = [], options = {}) ->
if not _.isArray exceptions
exceptions = [ exceptions ]
@@ -118,7 +118,14 @@ class ModelUsers extends RocketChat.models._Base
$and: [
{
active: true
- username: termRegex
+ $or: [
+ {
+ username: termRegex
+ }
+ {
+ name: termRegex
+ }
+ ]
}
{
username: { $nin: exceptions }
diff --git a/packages/rocketchat-lib/server/startup/settings.coffee b/packages/rocketchat-lib/server/startup/settings.coffee
index 76d858f7b4a7..4c817e5c012f 100644
--- a/packages/rocketchat-lib/server/startup/settings.coffee
+++ b/packages/rocketchat-lib/server/startup/settings.coffee
@@ -263,6 +263,7 @@ RocketChat.settings.addGroup 'Layout', ->
@add 'UI_DisplayRoles', true, { type: 'boolean', public: true }
@add 'UI_Merge_Channels_Groups', true, { type: 'boolean', public: true }
@add 'UI_Use_Name_Avatar', false, { type: 'boolean', public: true }
+ @add 'UI_Use_Real_Name', false, { type: 'boolean', public: true }
RocketChat.settings.addGroup 'Logs', ->
diff --git a/packages/rocketchat-lib/startup/defaultRoomTypes.js b/packages/rocketchat-lib/startup/defaultRoomTypes.js
index 2826e4a99c48..400c31fc6924 100644
--- a/packages/rocketchat-lib/startup/defaultRoomTypes.js
+++ b/packages/rocketchat-lib/startup/defaultRoomTypes.js
@@ -25,7 +25,7 @@ RocketChat.roomTypes.add('c', 10, {
},
roomName(roomData) {
- return roomData.name;
+ return { name: roomData.name };
},
condition() {
@@ -64,8 +64,7 @@ RocketChat.roomTypes.add('d', 20, {
},
roomName(roomData) {
- const room = ChatSubscription.findOne({ rid: roomData._id }, { fields: { name: 1 } });
- return room && room.name;
+ return ChatSubscription.findOne({ rid: roomData._id }, { fields: { name: 1, fname: 1 } });
},
condition() {
@@ -100,7 +99,7 @@ RocketChat.roomTypes.add('p', 30, {
},
roomName(roomData) {
- return roomData.name;
+ return { name: roomData.name };
},
condition() {
diff --git a/packages/rocketchat-livechat/server/lib/Livechat.js b/packages/rocketchat-livechat/server/lib/Livechat.js
index d5801811af2e..aa9200a1ac9c 100644
--- a/packages/rocketchat-livechat/server/lib/Livechat.js
+++ b/packages/rocketchat-livechat/server/lib/Livechat.js
@@ -116,7 +116,6 @@ RocketChat.Livechat = {
userId = existingUser._id;
} else {
- updateUser.$set.name = name;
const userData = {
username,
@@ -156,6 +155,10 @@ RocketChat.Livechat = {
];
}
+ if (name) {
+ RocketChat._setRealName(userId, name);
+ }
+
Meteor.users.update(userId, updateUser);
return userId;
diff --git a/packages/rocketchat-theme/client/imports/base.less b/packages/rocketchat-theme/client/imports/base.less
index 334cd74107da..2210ab1f2102 100644
--- a/packages/rocketchat-theme/client/imports/base.less
+++ b/packages/rocketchat-theme/client/imports/base.less
@@ -2515,6 +2515,11 @@ label.required::after {
display: inline-block;
}
}
+
+ .secondary-name {
+ color: #666666;
+ font-size: 15px;
+ }
}
.message-popup-position {
diff --git a/packages/rocketchat-ui-flextab/client/tabs/membersList.html b/packages/rocketchat-ui-flextab/client/tabs/membersList.html
index 4f1675dead84..1c455ab3700d 100644
--- a/packages/rocketchat-ui-flextab/client/tabs/membersList.html
+++ b/packages/rocketchat-ui-flextab/client/tabs/membersList.html
@@ -30,9 +30,9 @@
{{_ "Members_List"}}
{{else}}
{{#each users}}
-