Files
mostlymatter/webapp/actions/user_actions.jsx
Joram Wilander 30a10d35a8 PLT-4767 Implement MFA Enforcement (#4662)
* Create MFA setup page and remove MFA setup from account settings modal

* Add enforce MFA to system console and force redirect

* Lockdown mfa required API routes, add localization, other changes

* Minor fixes

* Fix typo

* Fix some unit tests

* Fix more unit tests

* Minor fix

* Updating UI for MFA screen (#4670)

* Updating UI for MFA screen

* Updating styles for MFA page

* Add the ability to switch between email/sso with MFA enabled

* Added mfa change email

* Minor UI updates for MFA enforcement

* Fix unit test

* Fix client unit test

* Allow switching email to ldap and back when MFA is enabled

* Fix unit test

* Revert config.json
2016-12-12 10:16:10 -03:00

435 строки
11 KiB
JavaScript

// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import AppDispatcher from 'dispatcher/app_dispatcher.jsx';
import PreferenceStore from 'stores/preference_store.jsx';
import TeamStore from 'stores/team_store.jsx';
import UserStore from 'stores/user_store.jsx';
import ChannelStore from 'stores/channel_store.jsx';
import {loadStatusesForProfilesList, loadStatusesForProfilesMap} from 'actions/status_actions.jsx';
import {getDirectChannelName} from 'utils/utils.jsx';
import * as AsyncClient from 'utils/async_client.jsx';
import Client from 'client/web_client.jsx';
import {ActionTypes, Preferences} from 'utils/constants.jsx';
export function switchFromLdapToEmail(email, password, token, ldapPassword, onSuccess, onError) {
Client.ldapToEmail(
email,
password,
token,
ldapPassword,
(data) => {
if (data.follow_link) {
window.location.href = data.follow_link;
}
if (onSuccess) {
onSuccess(data);
}
},
onError
);
}
export function loadProfilesAndTeamMembers(offset, limit, teamId = TeamStore.getCurrentId(), success, error) {
Client.getProfilesInTeam(
teamId,
offset,
limit,
(data) => {
AppDispatcher.handleServerAction({
type: ActionTypes.RECEIVED_PROFILES_IN_TEAM,
profiles: data,
team_id: teamId,
offset,
count: Object.keys(data).length
});
loadTeamMembersForProfilesMap(data, teamId, success, error);
loadStatusesForProfilesMap(data);
},
(err) => {
AsyncClient.dispatchError(err, 'getProfilesInTeam');
}
);
}
export function loadTeamMembersForProfilesMap(profiles, teamId = TeamStore.getCurrentId(), success, error) {
const membersToLoad = {};
for (const pid in profiles) {
if (!profiles.hasOwnProperty(pid)) {
continue;
}
if (!TeamStore.hasActiveMemberInTeam(teamId, pid)) {
membersToLoad[pid] = true;
}
}
const list = Object.keys(membersToLoad);
if (list.length === 0) {
if (success) {
success({});
}
return;
}
loadTeamMembersForProfiles(list, teamId, success, error);
}
export function loadTeamMembersForProfilesList(profiles, teamId = TeamStore.getCurrentId(), success, error) {
const membersToLoad = {};
for (let i = 0; i < profiles.length; i++) {
const pid = profiles[i].id;
if (!TeamStore.hasActiveMemberInTeam(teamId, pid)) {
membersToLoad[pid] = true;
}
}
const list = Object.keys(membersToLoad);
if (list.length === 0) {
if (success) {
success({});
}
return;
}
loadTeamMembersForProfiles(list, teamId, success, error);
}
function loadTeamMembersForProfiles(userIds, teamId, success, error) {
Client.getTeamMembersByIds(
teamId,
userIds,
(data) => {
const memberMap = {};
for (let i = 0; i < data.length; i++) {
memberMap[data[i].user_id] = data[i];
}
AppDispatcher.handleServerAction({
type: ActionTypes.RECEIVED_MEMBERS_IN_TEAM,
team_id: teamId,
team_members: memberMap
});
if (success) {
success(data);
}
},
(err) => {
AsyncClient.dispatchError(err, 'getTeamMembersByIds');
if (error) {
error(err);
}
}
);
}
function populateDMChannelsWithProfiles(userIds) {
const currentUserId = UserStore.getCurrentId();
for (let i = 0; i < userIds.length; i++) {
// TODO There's a race condition here for DM channels if those channels aren't loaded yet
const channelName = getDirectChannelName(currentUserId, userIds[i]);
const channel = ChannelStore.getByName(channelName);
if (channel) {
UserStore.saveUserIdInChannel(channel.id, userIds[i]);
}
}
}
export function loadProfilesAndTeamMembersForDMSidebar() {
const dmPrefs = PreferenceStore.getCategory(Preferences.CATEGORY_DIRECT_CHANNEL_SHOW);
const teamId = TeamStore.getCurrentId();
const profilesToLoad = [];
const membersToLoad = [];
for (const [key, value] of dmPrefs) {
if (value === 'true') {
if (!UserStore.hasProfile(key)) {
profilesToLoad.push(key);
}
membersToLoad.push(key);
}
}
if (profilesToLoad.length > 0) {
Client.getProfilesByIds(
profilesToLoad,
(data) => {
AppDispatcher.handleServerAction({
type: ActionTypes.RECEIVED_PROFILES,
profiles: data
});
// Use membersToLoad so we get all the DM profiles even if they were already loaded
populateDMChannelsWithProfiles(membersToLoad);
},
(err) => {
AsyncClient.dispatchError(err, 'getProfilesByIds');
}
);
} else {
populateDMChannelsWithProfiles(membersToLoad);
}
if (membersToLoad.length > 0) {
Client.getTeamMembersByIds(
teamId,
membersToLoad,
(data) => {
const memberMap = {};
for (let i = 0; i < data.length; i++) {
memberMap[data[i].user_id] = data[i];
}
const nonMembersMap = {};
for (let i = 0; i < membersToLoad.length; i++) {
if (!memberMap[membersToLoad[i]]) {
nonMembersMap[membersToLoad[i]] = true;
}
}
AppDispatcher.handleServerAction({
type: ActionTypes.RECEIVED_MEMBERS_IN_TEAM,
team_id: teamId,
team_members: memberMap,
non_team_members: nonMembersMap
});
},
(err) => {
AsyncClient.dispatchError(err, 'getTeamMembersByIds');
}
);
}
}
export function saveTheme(teamId, theme, onSuccess, onError) {
AsyncClient.savePreference(
Preferences.CATEGORY_THEME,
teamId,
JSON.stringify(theme),
() => {
onThemeSaved(teamId, theme, onSuccess);
},
(err) => {
onError(err);
}
);
}
function onThemeSaved(teamId, theme, onSuccess) {
const themePreferences = PreferenceStore.getCategory(Preferences.CATEGORY_THEME);
if (teamId !== '' && themePreferences.size > 1) {
// no extra handling to be done to delete team-specific themes
onSuccess();
return;
}
const toDelete = [];
for (const [name] of themePreferences) {
if (name === '' || name === teamId) {
continue;
}
toDelete.push({
user_id: UserStore.getCurrentId(),
category: Preferences.CATEGORY_THEME,
name
});
}
if (toDelete.length > 0) {
// we're saving a new global theme so delete any team-specific ones
AsyncClient.deletePreferences(toDelete);
// delete them locally before we hear from the server so that the UI flow is smoother
AppDispatcher.handleServerAction({
type: ActionTypes.DELETED_PREFERENCES,
preferences: toDelete
});
}
onSuccess();
}
export function searchUsers(term, teamId = TeamStore.getCurrentId(), options = {}, success, error) {
Client.searchUsers(
term,
teamId,
options,
(data) => {
loadStatusesForProfilesList(data);
if (success) {
success(data);
}
},
(err) => {
AsyncClient.dispatchError(err, 'searchUsers');
if (error) {
error(err);
}
}
);
}
export function autocompleteUsersInChannel(username, channelId, success, error) {
Client.autocompleteUsersInChannel(
username,
channelId,
(data) => {
if (success) {
success(data);
}
},
(err) => {
AsyncClient.dispatchError(err, 'autocompleteUsersInChannel');
if (error) {
error(err);
}
}
);
}
export function autocompleteUsersInTeam(username, success, error) {
Client.autocompleteUsersInTeam(
username,
(data) => {
if (success) {
success(data);
}
},
(err) => {
AsyncClient.dispatchError(err, 'autocompleteUsersInTeam');
if (error) {
error(err);
}
}
);
}
export function autocompleteUsers(username, success, error) {
Client.autocompleteUsers(
username,
(data) => {
if (success) {
success(data);
}
},
(err) => {
AsyncClient.dispatchError(err, 'autocompleteUsers');
if (error) {
error(err);
}
}
);
}
export function updateUser(username, success, error) {
Client.updateUser(
username,
(data) => {
if (success) {
success(data);
}
},
(err) => {
AsyncClient.dispatchError(err, 'updateUser');
if (error) {
error(err);
}
}
);
}
export function generateMfaSecret(success, error) {
Client.generateMfaSecret(
(data) => {
if (success) {
success(data);
}
},
(err) => {
AsyncClient.dispatchError(err, 'generateMfaSecret');
if (error) {
error(err);
}
}
);
}
export function updateUserRoles(userId, newRoles, success, error) {
Client.updateUserRoles(
userId,
newRoles,
() => {
AsyncClient.getUser(userId);
if (success) {
success();
}
},
(err) => {
if (error) {
error(err);
}
}
);
}
export function activateMfa(code, success, error) {
Client.updateMfa(
code,
true,
() => {
AsyncClient.getMe();
if (success) {
success();
}
},
(err) => {
if (error) {
error(err);
}
}
);
}
export function checkMfa(loginId, success, error) {
if (global.window.mm_config.EnableMultifactorAuthentication !== 'true') {
success(false);
return;
}
Client.checkMfa(
loginId,
(data) => {
if (success) {
success(data.mfa_required === 'true');
}
},
(err) => {
if (error) {
error(err);
}
}
);
}