mirror of
https://github.com/mattermost/mattermost.git
synced 2025-02-25 18:55:24 -06:00
* Add logic to be able to DM a user by email or username * PLT-6481 update DM url to be in the format https://servername.com/teamname/messages/xxxxxxxx * PLT-6481 Adding logic to get user by full email * PLT-6481 logic for routes /messages/user_id and /messages/id1_id2 to redirect to /messages/@username * PLT-6481 logic for GM route /messages/generated_id
516 lines
14 KiB
JavaScript
516 lines
14 KiB
JavaScript
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
|
// See License.txt for license information.
|
|
|
|
import EventEmitter from 'events';
|
|
|
|
import ChannelStore from 'stores/channel_store.jsx';
|
|
import TeamStore from 'stores/team_store.jsx';
|
|
|
|
import Constants from 'utils/constants.jsx';
|
|
const UserStatuses = Constants.UserStatuses;
|
|
|
|
const CHANGE_EVENT_NOT_IN_CHANNEL = 'change_not_in_channel';
|
|
const CHANGE_EVENT_IN_CHANNEL = 'change_in_channel';
|
|
const CHANGE_EVENT_NOT_IN_TEAM = 'change_not_in_team';
|
|
const CHANGE_EVENT_IN_TEAM = 'change_in_team';
|
|
const CHANGE_EVENT_WITHOUT_TEAM = 'change_without_team';
|
|
const CHANGE_EVENT = 'change';
|
|
const CHANGE_EVENT_SESSIONS = 'change_sessions';
|
|
const CHANGE_EVENT_AUDITS = 'change_audits';
|
|
const CHANGE_EVENT_STATUSES = 'change_statuses';
|
|
|
|
import store from 'stores/redux_store.jsx';
|
|
import * as Selectors from 'mattermost-redux/selectors/entities/users';
|
|
import {UserTypes} from 'mattermost-redux/action_types';
|
|
|
|
var Utils;
|
|
|
|
class UserStoreClass extends EventEmitter {
|
|
constructor() {
|
|
super();
|
|
|
|
this.noAccounts = false;
|
|
this.entities = {};
|
|
|
|
store.subscribe(() => {
|
|
const newEntities = store.getState().entities.users;
|
|
|
|
if (newEntities.profiles !== this.entities.profiles) {
|
|
this.emitChange();
|
|
}
|
|
if (newEntities.profilesInChannel !== this.entities.profilesInChannel) {
|
|
this.emitInChannelChange();
|
|
}
|
|
if (newEntities.profilesNotInChannel !== this.entities.profilesNotInChannel) {
|
|
this.emitNotInChannelChange();
|
|
}
|
|
if (newEntities.profilesInTeam !== this.entities.profilesInTeam) {
|
|
this.emitInTeamChange();
|
|
}
|
|
if (newEntities.profilesNotInTeam !== this.entities.profilesNotInTeam) {
|
|
this.emitNotInTeamChange();
|
|
}
|
|
if (newEntities.profilesWithoutTeam !== this.entities.profilesWithoutTeam) {
|
|
this.emitWithoutTeamChange();
|
|
}
|
|
if (newEntities.statuses !== this.entities.statuses) {
|
|
this.emitStatusesChange();
|
|
}
|
|
if (newEntities.myAudits !== this.entities.myAudits) {
|
|
this.emitAuditsChange();
|
|
}
|
|
if (newEntities.mySessions !== this.entities.mySessions) {
|
|
this.emitSessionsChange();
|
|
}
|
|
|
|
this.entities = newEntities;
|
|
});
|
|
}
|
|
|
|
emitChange(userId) {
|
|
this.emit(CHANGE_EVENT, userId);
|
|
}
|
|
|
|
addChangeListener(callback) {
|
|
this.on(CHANGE_EVENT, callback);
|
|
}
|
|
|
|
removeChangeListener(callback) {
|
|
this.removeListener(CHANGE_EVENT, callback);
|
|
}
|
|
|
|
emitInTeamChange() {
|
|
this.emit(CHANGE_EVENT_IN_TEAM);
|
|
}
|
|
|
|
addInTeamChangeListener(callback) {
|
|
this.on(CHANGE_EVENT_IN_TEAM, callback);
|
|
}
|
|
|
|
removeInTeamChangeListener(callback) {
|
|
this.removeListener(CHANGE_EVENT_IN_TEAM, callback);
|
|
}
|
|
|
|
emitNotInTeamChange() {
|
|
this.emit(CHANGE_EVENT_NOT_IN_TEAM);
|
|
}
|
|
|
|
addNotInTeamChangeListener(callback) {
|
|
this.on(CHANGE_EVENT_NOT_IN_TEAM, callback);
|
|
}
|
|
|
|
removeNotInTeamChangeListener(callback) {
|
|
this.removeListener(CHANGE_EVENT_NOT_IN_TEAM, callback);
|
|
}
|
|
|
|
emitInChannelChange() {
|
|
this.emit(CHANGE_EVENT_IN_CHANNEL);
|
|
}
|
|
|
|
addInChannelChangeListener(callback) {
|
|
this.on(CHANGE_EVENT_IN_CHANNEL, callback);
|
|
}
|
|
|
|
removeInChannelChangeListener(callback) {
|
|
this.removeListener(CHANGE_EVENT_IN_CHANNEL, callback);
|
|
}
|
|
|
|
emitNotInChannelChange() {
|
|
this.emit(CHANGE_EVENT_NOT_IN_CHANNEL);
|
|
}
|
|
|
|
addNotInChannelChangeListener(callback) {
|
|
this.on(CHANGE_EVENT_NOT_IN_CHANNEL, callback);
|
|
}
|
|
|
|
removeNotInChannelChangeListener(callback) {
|
|
this.removeListener(CHANGE_EVENT_NOT_IN_CHANNEL, callback);
|
|
}
|
|
|
|
emitWithoutTeamChange() {
|
|
this.emit(CHANGE_EVENT_WITHOUT_TEAM);
|
|
}
|
|
|
|
addWithoutTeamChangeListener(callback) {
|
|
this.on(CHANGE_EVENT_WITHOUT_TEAM, callback);
|
|
}
|
|
|
|
removeWithoutTeamChangeListener(callback) {
|
|
this.removeListener(CHANGE_EVENT_WITHOUT_TEAM, callback);
|
|
}
|
|
|
|
emitSessionsChange() {
|
|
this.emit(CHANGE_EVENT_SESSIONS);
|
|
}
|
|
|
|
addSessionsChangeListener(callback) {
|
|
this.on(CHANGE_EVENT_SESSIONS, callback);
|
|
}
|
|
|
|
removeSessionsChangeListener(callback) {
|
|
this.removeListener(CHANGE_EVENT_SESSIONS, callback);
|
|
}
|
|
|
|
emitAuditsChange() {
|
|
this.emit(CHANGE_EVENT_AUDITS);
|
|
}
|
|
|
|
addAuditsChangeListener(callback) {
|
|
this.on(CHANGE_EVENT_AUDITS, callback);
|
|
}
|
|
|
|
removeAuditsChangeListener(callback) {
|
|
this.removeListener(CHANGE_EVENT_AUDITS, callback);
|
|
}
|
|
|
|
emitStatusesChange() {
|
|
this.emit(CHANGE_EVENT_STATUSES);
|
|
}
|
|
|
|
addStatusesChangeListener(callback) {
|
|
this.on(CHANGE_EVENT_STATUSES, callback);
|
|
}
|
|
|
|
removeStatusesChangeListener(callback) {
|
|
this.removeListener(CHANGE_EVENT_STATUSES, callback);
|
|
}
|
|
|
|
// General
|
|
|
|
getCurrentUser() {
|
|
return Selectors.getCurrentUser(store.getState());
|
|
}
|
|
|
|
getCurrentId() {
|
|
return Selectors.getCurrentUserId(store.getState());
|
|
}
|
|
|
|
// System-Wide Profiles
|
|
|
|
getProfiles() {
|
|
return Selectors.getUsers(store.getState());
|
|
}
|
|
|
|
getProfile(userId) {
|
|
return Selectors.getUser(store.getState(), userId);
|
|
}
|
|
|
|
getProfileListForIds(userIds, skipCurrent = false, skipInactive = false) {
|
|
const profiles = [];
|
|
const currentId = this.getCurrentId();
|
|
|
|
for (let i = 0; i < userIds.length; i++) {
|
|
const profile = this.getProfile(userIds[i]);
|
|
|
|
if (!profile) {
|
|
continue;
|
|
}
|
|
|
|
if (skipCurrent && profile.id === currentId) {
|
|
continue;
|
|
}
|
|
|
|
if (skipInactive && profile.delete_at > 0) {
|
|
continue;
|
|
}
|
|
|
|
profiles.push(profile);
|
|
}
|
|
|
|
return profiles;
|
|
}
|
|
|
|
hasProfile(userId) {
|
|
return this.getProfiles().hasOwnProperty(userId);
|
|
}
|
|
|
|
getProfileByUsername(username) {
|
|
return this.getProfilesUsernameMap()[username];
|
|
}
|
|
|
|
getProfilesUsernameMap() {
|
|
return Selectors.getUsersByUsername(store.getState());
|
|
}
|
|
|
|
getProfileByEmail(email) {
|
|
return Selectors.getUsersByEmail(store.getState())[email];
|
|
}
|
|
|
|
getActiveOnlyProfiles(skipCurrent) {
|
|
const active = {};
|
|
const profiles = this.getProfiles();
|
|
const currentId = this.getCurrentId();
|
|
|
|
for (var key in profiles) {
|
|
if (!(profiles[key].id === currentId && skipCurrent) && profiles[key].delete_at === 0) {
|
|
active[key] = profiles[key];
|
|
}
|
|
}
|
|
|
|
return active;
|
|
}
|
|
|
|
getActiveOnlyProfileList() {
|
|
const profileMap = this.getActiveOnlyProfiles();
|
|
const profiles = [];
|
|
|
|
for (const id in profileMap) {
|
|
if (profileMap.hasOwnProperty(id)) {
|
|
profiles.push(profileMap[id]);
|
|
}
|
|
}
|
|
|
|
profiles.sort((a, b) => {
|
|
if (a.username < b.username) {
|
|
return -1;
|
|
}
|
|
if (a.username > b.username) {
|
|
return 1;
|
|
}
|
|
return 0;
|
|
});
|
|
|
|
return profiles;
|
|
}
|
|
|
|
getProfileList(skipCurrent = false, allowInactive = false) {
|
|
const profiles = [];
|
|
const currentId = this.getCurrentId();
|
|
const profileMap = this.getProfiles();
|
|
|
|
for (const id in profileMap) {
|
|
if (profileMap.hasOwnProperty(id)) {
|
|
var profile = profileMap[id];
|
|
|
|
if (skipCurrent && id === currentId) {
|
|
continue;
|
|
}
|
|
|
|
if (allowInactive || profile.delete_at === 0) {
|
|
profiles.push(profile);
|
|
}
|
|
}
|
|
}
|
|
|
|
profiles.sort((a, b) => {
|
|
if (a.username < b.username) {
|
|
return -1;
|
|
}
|
|
if (a.username > b.username) {
|
|
return 1;
|
|
}
|
|
return 0;
|
|
});
|
|
|
|
return profiles;
|
|
}
|
|
|
|
saveProfile(profile) {
|
|
store.dispatch({
|
|
type: UserTypes.RECEIVED_PROFILE,
|
|
data: profile
|
|
});
|
|
}
|
|
|
|
// Team-Wide Profiles
|
|
|
|
getProfileListInTeam(teamId = TeamStore.getCurrentId(), skipCurrent = false, skipInactive = false) {
|
|
const userIds = Array.from(Selectors.getUserIdsInTeams(store.getState())[teamId] || []);
|
|
|
|
return this.getProfileListForIds(userIds, skipCurrent, skipInactive);
|
|
}
|
|
|
|
removeProfileFromTeam(teamId, userId) {
|
|
store.dispatch({
|
|
type: UserTypes.RECEIVED_PROFILE_NOT_IN_TEAM,
|
|
data: {user_id: userId},
|
|
id: teamId
|
|
});
|
|
}
|
|
|
|
// Not In Team Profiles
|
|
|
|
getProfileListNotInTeam(teamId = TeamStore.getCurrentId(), skipCurrent = false, skipInactive = false) {
|
|
const userIds = Array.from(Selectors.getUserIdsNotInTeams(store.getState())[teamId] || []);
|
|
const profiles = [];
|
|
const currentId = this.getCurrentId();
|
|
|
|
for (let i = 0; i < userIds.length; i++) {
|
|
const profile = this.getProfile(userIds[i]);
|
|
|
|
if (!profile) {
|
|
continue;
|
|
}
|
|
|
|
if (skipCurrent && profile.id === currentId) {
|
|
continue;
|
|
}
|
|
|
|
if (skipInactive && profile.delete_at > 0) {
|
|
continue;
|
|
}
|
|
|
|
profiles.push(profile);
|
|
}
|
|
|
|
return profiles;
|
|
}
|
|
|
|
removeProfileNotInTeam(teamId, userId) {
|
|
store.dispatch({
|
|
type: UserTypes.RECEIVED_PROFILE_IN_TEAM,
|
|
data: {user_id: userId},
|
|
id: teamId
|
|
});
|
|
}
|
|
|
|
// Channel-Wide Profiles
|
|
|
|
saveProfileInChannel(channelId = ChannelStore.getCurrentId(), profile) {
|
|
store.dispatch({
|
|
type: UserTypes.RECEIVED_PROFILE_IN_CHANNEL,
|
|
data: {user_id: profile.id},
|
|
id: channelId
|
|
});
|
|
}
|
|
|
|
saveUserIdInChannel(channelId = ChannelStore.getCurrentId(), userId) {
|
|
store.dispatch({
|
|
type: UserTypes.RECEIVED_PROFILE_IN_CHANNEL,
|
|
data: {user_id: userId},
|
|
id: channelId
|
|
});
|
|
}
|
|
|
|
removeProfileInChannel(channelId, userId) {
|
|
store.dispatch({
|
|
type: UserTypes.RECEIVED_PROFILE_NOT_IN_CHANNEL,
|
|
data: {user_id: userId},
|
|
id: channelId
|
|
});
|
|
}
|
|
|
|
getProfileListInChannel(channelId = ChannelStore.getCurrentId(), skipCurrent = false) {
|
|
const userIds = Array.from(Selectors.getUserIdsInChannels(store.getState())[channelId] || []);
|
|
|
|
return this.getProfileListForIds(userIds, skipCurrent, false);
|
|
}
|
|
|
|
saveProfileNotInChannel(channelId = ChannelStore.getCurrentId(), profile) {
|
|
store.dispatch({
|
|
type: UserTypes.RECEIVED_PROFILE_NOT_IN_CHANNEL,
|
|
data: {user_id: profile.id},
|
|
id: channelId
|
|
});
|
|
}
|
|
|
|
removeProfileNotInChannel(channelId, userId) {
|
|
store.dispatch({
|
|
type: UserTypes.RECEIVED_PROFILE_IN_CHANNEL,
|
|
data: {user_id: userId},
|
|
id: channelId
|
|
});
|
|
}
|
|
|
|
getProfileListNotInChannel(channelId = ChannelStore.getCurrentId(), skipInactive = false) {
|
|
const userIds = Array.from(Selectors.getUserIdsNotInChannels(store.getState())[channelId] || []);
|
|
|
|
return this.getProfileListForIds(userIds, false, skipInactive);
|
|
}
|
|
|
|
// Profiles without any teams
|
|
|
|
getProfileListWithoutTeam(skipCurrent = false, skipInactive = false) {
|
|
const userIds = Array.from(Selectors.getUserIdsWithoutTeam(store.getState()) || []);
|
|
|
|
return this.getProfileListForIds(userIds, skipCurrent, skipInactive);
|
|
}
|
|
|
|
// Other
|
|
|
|
getSessions() {
|
|
return store.getState().entities.users.mySessions;
|
|
}
|
|
|
|
getAudits() {
|
|
return store.getState().entities.users.myAudits;
|
|
}
|
|
|
|
getCurrentMentionKeys() {
|
|
return this.getMentionKeys(this.getCurrentId());
|
|
}
|
|
|
|
getMentionKeys(id) {
|
|
var user = this.getProfile(id);
|
|
|
|
var keys = [];
|
|
|
|
if (!user || !user.notify_props) {
|
|
return keys;
|
|
}
|
|
|
|
if (user.notify_props.mention_keys) {
|
|
keys = keys.concat(user.notify_props.mention_keys.split(','));
|
|
}
|
|
|
|
if (user.notify_props.first_name === 'true' && user.first_name) {
|
|
keys.push(user.first_name);
|
|
}
|
|
|
|
if (user.notify_props.channel === 'true') {
|
|
keys.push('@channel');
|
|
keys.push('@all');
|
|
}
|
|
|
|
const usernameKey = '@' + user.username;
|
|
if (keys.indexOf(usernameKey) === -1) {
|
|
keys.push(usernameKey);
|
|
}
|
|
|
|
return keys;
|
|
}
|
|
|
|
setStatus(userId, status) {
|
|
const data = [{user_id: userId, status}];
|
|
store.dispatch({
|
|
type: UserTypes.RECEIVED_STATUSES,
|
|
data
|
|
});
|
|
}
|
|
|
|
getStatuses() {
|
|
return store.getState().entities.users.statuses;
|
|
}
|
|
|
|
getStatus(id) {
|
|
return this.getStatuses()[id] || UserStatuses.OFFLINE;
|
|
}
|
|
|
|
getNoAccounts() {
|
|
return global.window.mm_config.NoAccounts === 'true';
|
|
}
|
|
|
|
setNoAccounts(noAccounts) {
|
|
this.noAccounts = noAccounts;
|
|
}
|
|
|
|
isSystemAdminForCurrentUser() {
|
|
if (!Utils) {
|
|
Utils = require('utils/utils.jsx'); //eslint-disable-line global-require
|
|
}
|
|
|
|
var current = this.getCurrentUser();
|
|
|
|
if (current) {
|
|
return Utils.isSystemAdmin(current.roles);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|
|
var UserStore = new UserStoreClass();
|
|
UserStore.setMaxListeners(600);
|
|
|
|
export {UserStore as default};
|