Re-send of invitation from user profile.
Allow delete of users that haven't logged in from user profile. Prevent disable/enable and change password options from user profile for invited users.
This commit is contained in:
@@ -280,7 +280,7 @@
|
||||
* });
|
||||
* </pre>
|
||||
*
|
||||
* @param {Array} id user id.
|
||||
* @param {Int} userId user id.
|
||||
* @returns {Promise} resourcePromise object containing the user.
|
||||
*
|
||||
*/
|
||||
@@ -406,6 +406,36 @@
|
||||
"Failed to save user");
|
||||
}
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name umbraco.resources.usersResource#deleteNonLoggedInUser
|
||||
* @methodOf umbraco.resources.usersResource
|
||||
*
|
||||
* @description
|
||||
* Deletes a user that hasn't already logged in (and hence we know has made no content updates that would create related records)
|
||||
*
|
||||
* ##usage
|
||||
* <pre>
|
||||
* usersResource.deleteNonLoggedInUser(1)
|
||||
* .then(function() {
|
||||
* alert("user was deleted");
|
||||
* });
|
||||
* </pre>
|
||||
*
|
||||
* @param {Int} userId user id.
|
||||
* @returns {Promise} resourcePromise object.
|
||||
*
|
||||
*/
|
||||
function deleteNonLoggedInUser(userId) {
|
||||
|
||||
return umbRequestHelper.resourcePromise(
|
||||
$http.post(
|
||||
umbRequestHelper.getApiUrl(
|
||||
"userApiBaseUrl",
|
||||
"PostDeleteNonLoggedInUser", { id: userId })),
|
||||
'Failed to delete the user ' + userId);
|
||||
}
|
||||
|
||||
|
||||
var resource = {
|
||||
disableUsers: disableUsers,
|
||||
@@ -417,6 +447,7 @@
|
||||
createUser: createUser,
|
||||
inviteUser: inviteUser,
|
||||
saveUser: saveUser,
|
||||
deleteNonLoggedInUser: deleteNonLoggedInUser,
|
||||
clearAvatar: clearAvatar
|
||||
};
|
||||
|
||||
|
||||
@@ -31,6 +31,8 @@
|
||||
vm.disableUser = disableUser;
|
||||
vm.enableUser = enableUser;
|
||||
vm.unlockUser = unlockUser;
|
||||
vm.resendInvite = resendInvite;
|
||||
vm.deleteNonLoggedInUser = deleteNonLoggedInUser;
|
||||
vm.changeAvatar = changeAvatar;
|
||||
vm.clearAvatar = clearAvatar;
|
||||
vm.save = save;
|
||||
@@ -49,7 +51,9 @@
|
||||
"sections_users",
|
||||
"content_contentRoot",
|
||||
"media_mediaRoot",
|
||||
"user_noStartNodes"
|
||||
"user_noStartNodes",
|
||||
"user_defaultInvitationMessage",
|
||||
"user_deleteUserConfirmation"
|
||||
];
|
||||
|
||||
localizationService.localizeMany(labelKeys).then(function (values) {
|
||||
@@ -61,6 +65,8 @@
|
||||
vm.labels.contentRoot = values[5];
|
||||
vm.labels.mediaRoot = values[6];
|
||||
vm.labels.noStartNodes = values[7];
|
||||
vm.labels.defaultInvitationMessage = values[8];
|
||||
vm.labels.deleteUserConfirmation = values[9];
|
||||
});
|
||||
|
||||
// get user
|
||||
@@ -350,6 +356,44 @@
|
||||
});
|
||||
}
|
||||
|
||||
function resendInvite() {
|
||||
vm.resendInviteButtonState = "busy";
|
||||
|
||||
if (vm.resendInviteMessage) {
|
||||
vm.user.message = vm.resendInviteMessage;
|
||||
}
|
||||
else {
|
||||
vm.user.message = vm.labels.defaultInvitationMessage;
|
||||
}
|
||||
|
||||
usersResource.inviteUser(vm.user).then(function (data) {
|
||||
vm.resendInviteButtonState = "success";
|
||||
vm.resendInviteMessage = "";
|
||||
formHelper.showNotifications(data);
|
||||
}, function (error) {
|
||||
vm.resendInviteButtonState = "error";
|
||||
formHelper.showNotifications(error.data);
|
||||
});
|
||||
}
|
||||
|
||||
function deleteNonLoggedInUser() {
|
||||
vm.deleteNotLoggedInUserButtonState = "busy";
|
||||
|
||||
var confirmationMessage = vm.labels.deleteUserConfirmation;
|
||||
if (!confirm(confirmationMessage)) {
|
||||
vm.deleteNotLoggedInUserButtonState = "danger";
|
||||
return;
|
||||
}
|
||||
|
||||
usersResource.deleteNonLoggedInUser(vm.user.id).then(function (data) {
|
||||
formHelper.showNotifications(data);
|
||||
goToPage(vm.breadcrumbs[0]);
|
||||
}, function (error) {
|
||||
vm.deleteNotLoggedInUserButtonState = "error";
|
||||
formHelper.showNotifications(error.data);
|
||||
});
|
||||
}
|
||||
|
||||
function clearAvatar() {
|
||||
// get user
|
||||
usersResource.clearAvatar(vm.user.id).then(function (data) {
|
||||
|
||||
@@ -239,7 +239,7 @@
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 10px;">
|
||||
<umb-button ng-if="model.user.userDisplayState.key !== 'Disabled' && !model.user.isCurrentUser"
|
||||
<umb-button ng-if="model.user.userDisplayState.key !== 'Disabled' && model.user.userDisplayState.key !== 'Invited' && !model.user.isCurrentUser"
|
||||
type="button"
|
||||
button-style="[info,block]"
|
||||
action="model.disableUser()"
|
||||
@@ -250,7 +250,7 @@
|
||||
</umb-button>
|
||||
</div>
|
||||
|
||||
<umb-button type="button"
|
||||
<umb-button type="button" ng-if="model.user.userDisplayState.key !== 'Invited'"
|
||||
button-style="[info,block]"
|
||||
action="model.toggleChangePassword()"
|
||||
label="Change password"
|
||||
@@ -260,6 +260,15 @@
|
||||
size="s">
|
||||
</umb-button>
|
||||
|
||||
<umb-button type="button" ng-if="!model.user.lastLoginDate"
|
||||
button-style="[danger,block]"
|
||||
action="model.deleteNonLoggedInUser()"
|
||||
label="Delete"
|
||||
label-key="user_deleteUser"
|
||||
state="deleteNotLoggedInUserButtonState"
|
||||
size="s">
|
||||
</umb-button>
|
||||
|
||||
<ng-form ng-if="model.changePasswordModel.isChanging" name="passwordForm" class="block-form" val-form-manager>
|
||||
|
||||
<change-password password-values="model.user.changePassword"
|
||||
@@ -293,6 +302,25 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 10px;" ng-if="model.user.userDisplayState.key === 'Invited' && !model.user.isCurrentUser">
|
||||
<textarea name="resendInviteMessage"
|
||||
type="text"
|
||||
class="input-block-level"
|
||||
localize="placeholder"
|
||||
placeholder="@placeholders_enterMessage"
|
||||
ng-model="model.resendInviteMessage"
|
||||
rows="4">
|
||||
</textarea>
|
||||
<umb-button type="button"
|
||||
button-style="[info,block]"
|
||||
action="model.resendInvite()"
|
||||
state="model.resendInviteButtonState"
|
||||
label="Resend Invite"
|
||||
label-key="actions_resendInvite"
|
||||
size="s">
|
||||
</umb-button>
|
||||
</div>
|
||||
|
||||
<div class="umb-package-details__information-item">
|
||||
<div class="umb-package-details__information-item-label">
|
||||
<localize key="user_lastLogin">Last login</localize>:
|
||||
@@ -358,4 +386,4 @@
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
<key alias="setPermissions">Set permissions</key>
|
||||
<key alias="unlock">Unlock</key>
|
||||
<key alias="createblueprint">Create Content Template</key>
|
||||
<key alias="resendInvite">Resend Invitation</key>
|
||||
</area>
|
||||
<area alias="actionCategories">
|
||||
<key alias="content">Content</key>
|
||||
@@ -1419,6 +1420,9 @@ To manage your website, simply open the Umbraco back office and start adding con
|
||||
<key alias="unlockUserError">An error occurred while unlocking the user</key>
|
||||
<key alias="memberExportedSuccess">Member was exported to file</key>
|
||||
<key alias="memberExportedError">An error occurred while exporting the member</key>
|
||||
<key alias="deleteUserSuccess">User %0% was deleted</key>
|
||||
<key alias="resendInviteHeader">Invite user</key>
|
||||
<key alias="resendInviteSuccess">Invitation has been re-sent to %0%</key>
|
||||
</area>
|
||||
<area alias="stylesheet">
|
||||
<key alias="aliasHelp">Uses CSS syntax ex: h1, .redHeader, .blueTex</key>
|
||||
@@ -1996,6 +2000,9 @@ To manage your website, simply open the Umbraco back office and start adding con
|
||||
</html>]]>
|
||||
</key>
|
||||
<key alias="invite">Invite</key>
|
||||
<key alias="defaultInvitationMessage">Resending invitation...</key>
|
||||
<key alias="deleteUser">Delete User</key>
|
||||
<key alias="deleteUserConfirmation">Are you sure you wish to delete this user account?</key>
|
||||
</area>
|
||||
|
||||
<area alias="validation">
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
<key alias="setPermissions">Set permissions</key>
|
||||
<key alias="unlock">Unlock</key>
|
||||
<key alias="createblueprint">Create Content Template</key>
|
||||
<key alias="resendInvite">Resend Invitation</key>
|
||||
</area>
|
||||
<area alias="actionCategories">
|
||||
<key alias="content">Content</key>
|
||||
@@ -1416,6 +1417,9 @@ To manage your website, simply open the Umbraco back office and start adding con
|
||||
<key alias="unlockUserError">An error occurred while unlocking the user</key>
|
||||
<key alias="memberExportedSuccess">Member was exported to file</key>
|
||||
<key alias="memberExportedError">An error occurred while exporting the member</key>
|
||||
<key alias="deleteUserSuccess">User %0% was deleted</key>
|
||||
<key alias="resendInviteHeader">Invite user</key>
|
||||
<key alias="resendInviteSuccess">Invitation has been re-sent to %0%</key>
|
||||
</area>
|
||||
<area alias="stylesheet">
|
||||
<key alias="aliasHelp">Uses CSS syntax ex: h1, .redHeader, .blueTex</key>
|
||||
@@ -1988,6 +1992,9 @@ To manage your website, simply open the Umbraco back office and start adding con
|
||||
</html>]]>
|
||||
</key>
|
||||
<key alias="invite">Invite</key>
|
||||
<key alias="defaultInvitationMessage">Resending invitation...</key>
|
||||
<key alias="deleteUser">Delete User</key>
|
||||
<key alias="deleteUserConfirmation">Are you sure you wish to delete this user account?</key>
|
||||
</area>
|
||||
<area alias="validation">
|
||||
<key alias="validation">Validation</key>
|
||||
|
||||
@@ -412,6 +412,8 @@ namespace Umbraco.Web.Editors
|
||||
|
||||
await SendUserInviteEmailAsync(display, Security.CurrentUser.Name, Security.CurrentUser.Email, user, userSave.Message);
|
||||
|
||||
display.AddSuccessNotification(Services.TextService.Localize("speechBubbles/resendInviteHeader"), Services.TextService.Localize("speechBubbles/resendInviteSuccess", new[] { user.Name }));
|
||||
|
||||
return display;
|
||||
}
|
||||
|
||||
@@ -699,6 +701,36 @@ namespace Umbraco.Web.Editors
|
||||
Services.TextService.Localize("speechBubbles/setUserGroupOnUsersSuccess"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes the non-logged in user provided id
|
||||
/// </summary>
|
||||
/// <param name="id">User Id</param>
|
||||
/// <remarks>
|
||||
/// Limited to users that haven't logged in to avoid issues with related records constrained
|
||||
/// with a foreign key on the user Id
|
||||
/// </remarks>
|
||||
public async Task<HttpResponseMessage> PostDeleteNonLoggedInUser(int id)
|
||||
{
|
||||
var user = Services.UserService.GetUserById(id);
|
||||
if (user == null)
|
||||
{
|
||||
throw new HttpResponseException(HttpStatusCode.NotFound);
|
||||
}
|
||||
|
||||
// Check user hasn't logged in. If they have they may have made content changes which will mean
|
||||
// the Id is associated with audit trails, versions etc. and can't be removed.
|
||||
if (user.LastLoginDate != default(DateTime))
|
||||
{
|
||||
throw new HttpResponseException(HttpStatusCode.BadRequest);
|
||||
}
|
||||
|
||||
var userName = user.Name;
|
||||
Services.UserService.Delete(user, true);
|
||||
|
||||
return Request.CreateNotificationSuccessResponse(
|
||||
Services.TextService.Localize("speechBubbles/deleteUserSuccess", new[] { userName }));
|
||||
}
|
||||
|
||||
public class PagedUserResult : PagedResult<UserBasic>
|
||||
{
|
||||
public PagedUserResult(long totalItems, long pageNumber, long pageSize) : base(totalItems, pageNumber, pageSize)
|
||||
|
||||
Reference in New Issue
Block a user