Merge branch 'master' of https://github.com/ONLYOFFICE/CommunityServer-AspNetCore
This commit is contained in:
commit
180767c213
@ -173,6 +173,17 @@ namespace ASC.Security.Cryptography
|
||||
checkKeyResult = ValidateEmailKey(Email + Type + (string.IsNullOrEmpty(hash) ? string.Empty : Hasher.Base64Hash(hash)) + UiD, Key, ValidInterval);
|
||||
break;
|
||||
case ConfirmType.Activation:
|
||||
checkKeyResult = ValidateEmailKey(Email + Type + UiD, Key, ValidInterval);
|
||||
break;
|
||||
case ConfirmType.ProfileRemove:
|
||||
// validate UiD
|
||||
if (P == 1)
|
||||
{
|
||||
var user = CoreContext.UserManager.GetUsers(UiD.GetValueOrDefault());
|
||||
if (user == null || user.Status == EmployeeStatus.Terminated || SecurityContext.IsAuthenticated && SecurityContext.CurrentAccount.ID != UiD)
|
||||
return ValidationResult.Invalid;
|
||||
}
|
||||
|
||||
checkKeyResult = ValidateEmailKey(Email + Type + UiD, Key, ValidInterval);
|
||||
break;
|
||||
default:
|
||||
|
@ -28,7 +28,7 @@ import {
|
||||
updateGroup
|
||||
} from "../../../../../store/group/actions";
|
||||
import styled from "styled-components";
|
||||
import { fetchSelectorUsers } from "../../../../../store/people/actions";
|
||||
import { fetchSelectorUsers, fetchPeople, fetchGroups } from "../../../../../store/people/actions";
|
||||
import { GUID_EMPTY } from "../../../../../helpers/constants";
|
||||
import isEqual from "lodash/isEqual";
|
||||
|
||||
@ -110,34 +110,40 @@ class SectionBodyContent extends React.Component {
|
||||
key: 0,
|
||||
label: t("CustomAddEmployee", { typeUser })
|
||||
},
|
||||
groupMembers: group && group.members ? group.members.map(m => {
|
||||
groupMembers:
|
||||
group && group.members
|
||||
? group.members.map(m => {
|
||||
return {
|
||||
key: m.id,
|
||||
label: m.displayName
|
||||
}
|
||||
}) : [],
|
||||
groupManager: group && group.manager ? {
|
||||
};
|
||||
})
|
||||
: [],
|
||||
groupManager:
|
||||
group && group.manager
|
||||
? {
|
||||
key: group.manager.id,
|
||||
label: group.manager.displayName
|
||||
} : {
|
||||
}
|
||||
: {
|
||||
key: GUID_EMPTY,
|
||||
label: t("CustomAddEmployee", { typeUser })
|
||||
}
|
||||
};
|
||||
|
||||
return newState;
|
||||
}
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
const { users, fetchSelectorUsers } = this.props;
|
||||
if(!users || !users.length) {
|
||||
if (!users || !users.length) {
|
||||
fetchSelectorUsers();
|
||||
}
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
//const { users, group } = this.props;
|
||||
if(!isEqual(this.props, prevProps)) {
|
||||
if (!isEqual(this.props, prevProps)) {
|
||||
this.setState(this.mapPropsToState());
|
||||
}
|
||||
}
|
||||
@ -178,14 +184,14 @@ class SectionBodyContent extends React.Component {
|
||||
});
|
||||
};
|
||||
|
||||
onUsersSelectorSearch = (value) => {
|
||||
onUsersSelectorSearch = value => {
|
||||
/*setOptions(
|
||||
options.filter(option => {
|
||||
return option.label.indexOf(value) > -1;
|
||||
})
|
||||
);*/
|
||||
};
|
||||
onUsersSelectorSelect = (selectedOptions) => {
|
||||
onUsersSelectorSelect = selectedOptions => {
|
||||
//console.log("onSelect", selectedOptions);
|
||||
//this.onUsersSelectorClick();
|
||||
this.setState({
|
||||
@ -211,28 +217,33 @@ class SectionBodyContent extends React.Component {
|
||||
});
|
||||
};
|
||||
|
||||
save = (group) => {
|
||||
const { createGroup, updateGroup } = this.props;
|
||||
return group.id
|
||||
? updateGroup(group.id, group.name, group.managerKey, group.members)
|
||||
: createGroup(group.name, group.managerKey, group.members);
|
||||
};
|
||||
|
||||
onSave = () => {
|
||||
const { history, group, createGroup, updateGroup, resetGroup } = this.props;
|
||||
const { group } = this.props;
|
||||
const { groupName, groupManager, groupMembers } = this.state;
|
||||
|
||||
if (!groupName || !groupName.trim().length) return false;
|
||||
|
||||
this.setState({ inLoading: true });
|
||||
|
||||
(group && group.id
|
||||
? updateGroup(
|
||||
group.id,
|
||||
groupName,
|
||||
groupManager.key,
|
||||
groupMembers.map(u => u.key)
|
||||
)
|
||||
: createGroup(groupName, groupManager.key, groupMembers.map(u => u.key))
|
||||
)
|
||||
.then(() => {
|
||||
toastr.success("Success");
|
||||
//this.setState({ inLoading: true });
|
||||
history.goBack();
|
||||
resetGroup();
|
||||
const newGroup = {
|
||||
name: groupName,
|
||||
managerKey: groupManager.key,
|
||||
members: groupMembers.map(u => u.key)
|
||||
};
|
||||
|
||||
if(group && group.id)
|
||||
newGroup.id = group.id;
|
||||
|
||||
this.save(newGroup)
|
||||
.then(group => {
|
||||
toastr.success(`Group '${group.name}' has been saved successfully`);
|
||||
})
|
||||
.catch(error => {
|
||||
toastr.error(error.message);
|
||||
@ -247,11 +258,11 @@ class SectionBodyContent extends React.Component {
|
||||
history.goBack();
|
||||
};
|
||||
|
||||
onSelectedItemClose = (member) => {
|
||||
onSelectedItemClose = member => {
|
||||
this.setState({
|
||||
groupMembers: this.state.groupMembers.filter(g => g.key !== member.key)
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
renderModal = () => {
|
||||
const { groups, modalVisible } = this.state;
|
||||
@ -559,11 +570,11 @@ function mapStateToProps(state) {
|
||||
settings: state.auth.settings,
|
||||
group: state.group.targetGroup,
|
||||
groups: convertGroups(state.people.groups),
|
||||
users: convertUsers(state.people.selector.users) //TODO: replace to api requests with search
|
||||
users: convertUsers(state.people.selector.users), //TODO: replace to api requests with search
|
||||
};
|
||||
}
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
{ resetGroup, createGroup, updateGroup, fetchSelectorUsers }
|
||||
{ resetGroup, createGroup, updateGroup, fetchSelectorUsers, fetchPeople, fetchGroups }
|
||||
)(withRouter(withTranslation()(SectionBodyContent)));
|
||||
|
6
products/ASC.People/Client/src/helpers/utils.js
Normal file
6
products/ASC.People/Client/src/helpers/utils.js
Normal file
@ -0,0 +1,6 @@
|
||||
export function checkResponseError(res) {
|
||||
if (res && res.data && res.data.error) {
|
||||
console.error(res.data.error);
|
||||
throw new Error(res.data.error.message);
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
import * as api from "../services/api";
|
||||
import { setGroups, fetchPeopleAsync } from "../people/actions";
|
||||
import { fetchGroups, fetchPeople } from "../people/actions";
|
||||
import setAuthorizationToken from "../../store/services/setAuthorizationToken";
|
||||
import { getFilterByLocation } from "../../helpers/converters";
|
||||
import config from "../../../package.json";
|
||||
@ -57,9 +57,7 @@ export async function getUserInfo(dispatch) {
|
||||
dispatch(setModules(modules));
|
||||
dispatch(setSettings(newSettings));
|
||||
|
||||
const groupResp = await api.getGroupList();
|
||||
|
||||
dispatch(setGroups(groupResp.data.response));
|
||||
await fetchGroups(dispatch);
|
||||
|
||||
var re = new RegExp(`${config.homepage}((/?)$|/filter)`, "gm");
|
||||
const match = window.location.pathname.match(re);
|
||||
@ -67,7 +65,7 @@ export async function getUserInfo(dispatch) {
|
||||
if (match && match.length > 0)
|
||||
{
|
||||
const newFilter = getFilterByLocation(window.location);
|
||||
await fetchPeopleAsync(dispatch, newFilter);
|
||||
await fetchPeople(newFilter, dispatch);
|
||||
}
|
||||
|
||||
return dispatch(setIsLoaded(true));
|
||||
|
@ -1,5 +1,7 @@
|
||||
import * as api from "../../store/services/api";
|
||||
import { setGroups, fetchPeopleByFilter } from "../people/actions";
|
||||
import { setGroups, fetchPeople, fetchGroups } from "../people/actions";
|
||||
import { checkResponseError } from "../../helpers/utils";
|
||||
import history from "../../history";
|
||||
|
||||
export const SET_GROUP = "SET_GROUP";
|
||||
export const CLEAN_GROUP = "CLEAN_GROUP";
|
||||
@ -17,13 +19,6 @@ export function resetGroup() {
|
||||
};
|
||||
}
|
||||
|
||||
export function checkResponseError(res) {
|
||||
if (res && res.data && res.data.error) {
|
||||
console.error(res.data.error);
|
||||
throw new Error(res.data.error.message);
|
||||
}
|
||||
}
|
||||
|
||||
export function fetchGroup(groupId) {
|
||||
return dispatch => {
|
||||
api.getGroup(groupId).then(res => {
|
||||
@ -36,23 +31,16 @@ export function fetchGroup(groupId) {
|
||||
export function createGroup(groupName, groupManager, members) {
|
||||
return (dispatch, getState) => {
|
||||
const { people } = getState();
|
||||
const { groups, filter } = people;
|
||||
|
||||
let newGroup;
|
||||
const { groups } = people;
|
||||
|
||||
return api
|
||||
.createGroup(groupName, groupManager, members)
|
||||
.then(res => {
|
||||
checkResponseError(res);
|
||||
newGroup = res.data.response;
|
||||
|
||||
//dispatch(setGroup(newGroup));
|
||||
return dispatch(setGroups([...groups, newGroup]));
|
||||
})
|
||||
.then(() => {
|
||||
return fetchPeopleByFilter(dispatch, filter);
|
||||
})
|
||||
.then(() => {
|
||||
history.goBack();
|
||||
const newGroup = res.data.response;
|
||||
dispatch(resetGroup());
|
||||
dispatch(setGroups([...groups, newGroup]));
|
||||
return Promise.resolve(newGroup);
|
||||
});
|
||||
};
|
||||
@ -61,28 +49,19 @@ export function createGroup(groupName, groupManager, members) {
|
||||
export function updateGroup(id, groupName, groupManager, members) {
|
||||
return (dispatch, getState) => {
|
||||
const { people } = getState();
|
||||
const { groups, filter } = people;
|
||||
|
||||
let newGroup;
|
||||
const { groups } = people;
|
||||
|
||||
return api
|
||||
.updateGroup(id, groupName, groupManager, members)
|
||||
.then(res => {
|
||||
checkResponseError(res);
|
||||
newGroup = res.data.response;
|
||||
|
||||
//dispatch(setGroup(newGroup));
|
||||
|
||||
history.goBack();
|
||||
const newGroup = res.data.response;
|
||||
dispatch(resetGroup());
|
||||
const newGroups = groups.map(g =>
|
||||
g.id === newGroup.id ? newGroup : g
|
||||
);
|
||||
|
||||
return dispatch(setGroups(newGroups));
|
||||
})
|
||||
.then(() => {
|
||||
return fetchPeopleByFilter(dispatch, filter);
|
||||
})
|
||||
.then(() => {
|
||||
dispatch(setGroups(newGroups));
|
||||
return Promise.resolve(newGroup);
|
||||
});
|
||||
};
|
||||
@ -101,7 +80,7 @@ export function deleteGroup(id) {
|
||||
})
|
||||
.then(() => {
|
||||
const newFilter = filter.clone(true);
|
||||
return fetchPeopleByFilter(dispatch, newFilter);
|
||||
return fetchPeople(newFilter, dispatch);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ import {
|
||||
PAGE_COUNT,
|
||||
EmployeeStatus
|
||||
} from "../../helpers/constants";
|
||||
import { checkResponseError } from "../../helpers/utils";
|
||||
|
||||
export const SET_GROUPS = "SET_GROUPS";
|
||||
export const SET_USERS = "SET_USERS";
|
||||
@ -69,7 +70,7 @@ export function selectGroup(groupId) {
|
||||
let newFilter = filter.clone();
|
||||
newFilter.group = groupId;
|
||||
|
||||
return fetchPeopleByFilter(dispatch, newFilter);
|
||||
return fetchPeople(newFilter, dispatch);
|
||||
};
|
||||
}
|
||||
|
||||
@ -147,14 +148,38 @@ export function fetchSelectorUsers() {
|
||||
};
|
||||
}
|
||||
|
||||
export function fetchPeople(filter) {
|
||||
return dispatch => {
|
||||
export function fetchGroups(dispatchFunc = null) {
|
||||
return api.getGroupList()
|
||||
.then(res => {
|
||||
checkResponseError(res);
|
||||
return dispatchFunc
|
||||
? dispatchFunc(setGroups(res.data.response))
|
||||
: Promise.resolve(dispatch => dispatch(setGroups(res.data.response)));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
export function fetchPeople(filter, dispatchFunc = null) {
|
||||
return dispatchFunc ? fetchPeopleByFilter(dispatchFunc, filter)
|
||||
: (dispatch, getState) => {
|
||||
if(filter) {
|
||||
return fetchPeopleByFilter(dispatch, filter);
|
||||
}
|
||||
else {
|
||||
const {people} = getState();
|
||||
const {filter} = people;
|
||||
return fetchPeopleByFilter(dispatch, filter);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function fetchPeopleByFilter(dispatch, filter) {
|
||||
let filterData = (filter && filter.clone()) || Filter.getDefault();
|
||||
function fetchPeopleByFilter(dispatch, filter) {
|
||||
let filterData = (filter && filter.clone());
|
||||
|
||||
if(!filterData) {
|
||||
filterData = Filter.getDefault();
|
||||
filterData.employeeStatus = EmployeeStatus.Active;
|
||||
}
|
||||
|
||||
return api.getUserList(filterData).then(res => {
|
||||
filterData.total = res.data.total;
|
||||
@ -167,7 +192,7 @@ export function fetchPeopleByFilter(dispatch, filter) {
|
||||
});
|
||||
}
|
||||
|
||||
export async function fetchPeopleAsync(dispatch, filter = null) {
|
||||
/*export async function fetchPeopleAsync(dispatch, filter = null) {
|
||||
let filterData = (filter && filter.clone());
|
||||
|
||||
if(!filterData) {
|
||||
@ -185,7 +210,7 @@ export async function fetchPeopleAsync(dispatch, filter = null) {
|
||||
groupId: filterData.group
|
||||
});
|
||||
dispatch(setUsers(usersResp.data.response));
|
||||
}
|
||||
}*/
|
||||
|
||||
export function updateUserStatus(status, userIds) {
|
||||
return dispatch => {
|
||||
@ -224,6 +249,6 @@ export function resetFilter() {
|
||||
|
||||
const newFilter = filter.clone(true);
|
||||
|
||||
return fetchPeopleByFilter(dispatch, newFilter);
|
||||
return fetchPeople(newFilter, dispatch);
|
||||
};
|
||||
}
|
||||
|
@ -1,8 +1,9 @@
|
||||
import * as api from "../../store/services/api";
|
||||
import { isMe } from '../auth/selectors';
|
||||
import { getUserByUserName } from '../people/selectors';
|
||||
import { fetchPeopleByFilter } from "../people/actions";
|
||||
import { fetchPeople } from "../people/actions";
|
||||
import { setCurrentUser } from "../auth/actions";
|
||||
import { checkResponseError } from "../../helpers/utils";
|
||||
|
||||
export const SET_PROFILE = 'SET_PROFILE';
|
||||
export const CLEAN_PROFILE = 'CLEAN_PROFILE';
|
||||
@ -20,12 +21,7 @@ export function resetProfile() {
|
||||
};
|
||||
};
|
||||
|
||||
export function checkResponseError(res) {
|
||||
if (res && res.data && res.data.error) {
|
||||
console.error(res.data.error);
|
||||
throw new Error(res.data.error.message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export function employeeWrapperToMemberModel(profile) {
|
||||
const comment = profile.notes;
|
||||
@ -67,7 +63,7 @@ export function createProfile(profile) {
|
||||
result = res.data.response;
|
||||
return dispatch(setProfile(result));
|
||||
}).then(() => {
|
||||
return fetchPeopleByFilter(dispatch, filter);
|
||||
return fetchPeople(filter, dispatch);
|
||||
}).then(() => {
|
||||
return Promise.resolve(result);
|
||||
});
|
||||
@ -86,7 +82,7 @@ export function updateProfile(profile) {
|
||||
result = res.data.response;
|
||||
return Promise.resolve(dispatch(setProfile(result)));
|
||||
}).then(() => {
|
||||
return fetchPeopleByFilter(dispatch, filter);
|
||||
return fetchPeople(filter, dispatch);
|
||||
}).then(() => {
|
||||
return Promise.resolve(result);
|
||||
});
|
||||
|
@ -575,6 +575,50 @@ namespace ASC.Employee.Core.Controllers
|
||||
return new EmployeeWraperFull(user, ApiContext);
|
||||
}
|
||||
|
||||
[Delete("@self")]
|
||||
[Authorize(AuthenticationSchemes = "confirm", Roles = "ProfileRemove")]
|
||||
public EmployeeWraperFull DeleteProfile()
|
||||
{
|
||||
ApiContext.AuthByClaim();
|
||||
|
||||
if (CoreContext.UserManager.IsSystemUser(SecurityContext.CurrentAccount.ID))
|
||||
throw new SecurityException();
|
||||
|
||||
var user = GetUserInfo(SecurityContext.CurrentAccount.ID.ToString());
|
||||
|
||||
if (!CoreContext.UserManager.UserExists(user))
|
||||
throw new Exception(Resource.ErrorUserNotFound);
|
||||
|
||||
if(user.IsLDAP())
|
||||
throw new SecurityException();
|
||||
|
||||
_ = SecurityContext.AuthenticateMe(ASC.Core.Configuration.Constants.CoreSystem);
|
||||
|
||||
user.Status = EmployeeStatus.Terminated;
|
||||
|
||||
CoreContext.UserManager.SaveUserInfo(Tenant, user);
|
||||
|
||||
var userName = user.DisplayUserName(false);
|
||||
MessageService.Send(MessageAction.UsersUpdatedStatus, MessageTarget.Create(user.ID), userName);
|
||||
|
||||
HttpContext.ResetUserCookie(Tenant.TenantId, user.ID);
|
||||
MessageService.Send(MessageAction.CookieSettingsUpdated);
|
||||
|
||||
if (CoreContext.Configuration.Personal)
|
||||
{
|
||||
UserPhotoManager.RemovePhoto(Tenant, user.ID);
|
||||
CoreContext.UserManager.DeleteUser(Tenant, user.ID);
|
||||
MessageService.Send(MessageAction.UserDeleted, MessageTarget.Create(user.ID), userName);
|
||||
}
|
||||
else
|
||||
{
|
||||
//StudioNotifyService.Instance.SendMsgProfileHasDeletedItself(user);
|
||||
//StudioNotifyService.SendMsgProfileDeletion(Tenant.TenantId, user);
|
||||
}
|
||||
|
||||
return new EmployeeWraperFull(user, ApiContext);
|
||||
}
|
||||
|
||||
[Update("{userid}/contacts")]
|
||||
public EmployeeWraperFull UpdateMemberContacts(string userid, UpdateMemberModel memberModel)
|
||||
{
|
||||
|
@ -5,8 +5,8 @@ import styled from 'styled-components';
|
||||
import { welcomePageTitle } from './../../../../helpers/customNames';
|
||||
import PropTypes from 'prop-types';
|
||||
import { withTranslation } from 'react-i18next';
|
||||
import { deleteUser, updateUserStatus } from './../../../../store/services/api'
|
||||
import { EmployeeStatus } from './../../../../helpers/constants';
|
||||
import { deleteSelf } from './../../../../store/services/api';
|
||||
import setAuthorizationToken from './../../../../store/services/setAuthorizationToken';
|
||||
|
||||
const ProfileRemoveContainer = styled.div`
|
||||
display: flex;
|
||||
@ -40,17 +40,13 @@ class ProfileRemove extends React.PureComponent {
|
||||
onDeleteProfile = (e) => {
|
||||
this.setState({ isLoading: true }, function () {
|
||||
const { linkData } = this.props;
|
||||
|
||||
updateUserStatus(EmployeeStatus.Disabled, [linkData.uid], linkData.confirmHeader)
|
||||
.then((res) => {
|
||||
console.log('success update status', res)
|
||||
return deleteUser(linkData.uid);
|
||||
})
|
||||
deleteSelf(linkData.confirmHeader)
|
||||
.then((res) => {
|
||||
this.setState({
|
||||
isLoading: false,
|
||||
isProfileDeleted: true
|
||||
});
|
||||
setAuthorizationToken();
|
||||
console.log('success delete', res)
|
||||
})
|
||||
.catch((e) => {
|
||||
|
@ -85,20 +85,13 @@ export function checkConfirmLink(data) {
|
||||
: axios.post(`${API_URL}/authentication/confirm.json`, data);
|
||||
}
|
||||
|
||||
export function deleteUser(userId) {
|
||||
export function deleteSelf(key) {
|
||||
return IS_FAKE
|
||||
? fakeApi.deleteUser(userId)
|
||||
: axios.delete(`${API_URL}/people/${userId}.json`);
|
||||
}
|
||||
|
||||
export function updateUserStatus(status, userIds, key) {
|
||||
return IS_FAKE
|
||||
? fakeApi.updateUserStatus(status, userIds)
|
||||
: axios.put(`${API_URL}/people/status/${status}`, { userIds }, {
|
||||
? fakeApi.deleteUser(key)
|
||||
: axios.delete(`${API_URL}/people/@self`, {
|
||||
headers: { confirm: key }
|
||||
});
|
||||
}
|
||||
|
||||
export function sendInstructionsToChangePassword(email) {
|
||||
return IS_FAKE
|
||||
? fakeApi.sendInstructionsToChangePassword()
|
||||
|
@ -447,7 +447,7 @@ namespace ASC.Web.Studio.Core.Notify
|
||||
|
||||
public void SendMsgProfileDeletion(int tenantId, UserInfo user)
|
||||
{
|
||||
var confirmationUrl = CommonLinkUtility.GetConfirmationUrl(tenantId, user.Email, ConfirmType.ProfileRemove, null, SecurityContext.CurrentAccount.ID);
|
||||
var confirmationUrl = CommonLinkUtility.GetConfirmationUrl(tenantId, user.Email, ConfirmType.ProfileRemove, SecurityContext.CurrentAccount.ID, SecurityContext.CurrentAccount.ID);
|
||||
|
||||
static string greenButtonText() => CoreContext.Configuration.Personal ? WebstudioNotifyPatternResource.ButtonConfirmTermination : WebstudioNotifyPatternResource.ButtonRemoveProfile;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user