add dialog for change password, shift form from user details view int… (#7450)
This commit is contained in:
committed by
Kenn Jacobsen
parent
ebed80791d
commit
902d4196cf
@@ -405,6 +405,43 @@
|
||||
formattedSaveData),
|
||||
"Failed to save user");
|
||||
}
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name umbraco.resources.usersResource#changePassword
|
||||
* @methodOf umbraco.resources.usersResource
|
||||
*
|
||||
* @description
|
||||
* Changes a user's password
|
||||
*
|
||||
* ##usage
|
||||
* <pre>
|
||||
* usersResource.changePassword(changePasswordModel)
|
||||
* .then(function() {
|
||||
* // password changed
|
||||
* });
|
||||
* </pre>
|
||||
*
|
||||
* @param {Object} model object to save
|
||||
* @returns {Promise} resourcePromise object containing the updated user.
|
||||
*
|
||||
*/
|
||||
function changePassword(changePasswordModel) {
|
||||
if (!changePasswordModel) {
|
||||
throw "password model not specified";
|
||||
}
|
||||
|
||||
//need to convert the password data into the correctly formatted save data - it is *not* the same and we don't want to over-post
|
||||
var formattedPasswordData = umbDataFormatter.formatChangePasswordModel(changePasswordModel);
|
||||
|
||||
return umbRequestHelper.resourcePromise(
|
||||
$http.post(
|
||||
umbRequestHelper.getApiUrl(
|
||||
"userApiBaseUrl",
|
||||
"PostChangePassword"),
|
||||
formattedPasswordData),
|
||||
"Failed to save user");
|
||||
}
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
@@ -447,6 +484,7 @@
|
||||
createUser: createUser,
|
||||
inviteUser: inviteUser,
|
||||
saveUser: saveUser,
|
||||
changePassword: changePassword,
|
||||
deleteNonLoggedInUser: deleteNonLoggedInUser,
|
||||
clearAvatar: clearAvatar
|
||||
};
|
||||
|
||||
@@ -152,8 +152,7 @@
|
||||
formatUserPostData: function (displayModel) {
|
||||
|
||||
//create the save model from the display model
|
||||
var saveModel = _.pick(displayModel, 'id', 'parentId', 'name', 'username', 'culture', 'email', 'startContentIds', 'startMediaIds', 'userGroups', 'message', 'changePassword');
|
||||
saveModel.changePassword = this.formatChangePasswordModel(saveModel.changePassword);
|
||||
var saveModel = _.pick(displayModel, 'id', 'parentId', 'name', 'username', 'culture', 'email', 'startContentIds', 'startMediaIds', 'userGroups', 'message');
|
||||
|
||||
//make sure the userGroups are just a string array
|
||||
var currGroups = saveModel.userGroups;
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
<ng-form name="passwordForm" class="block-form" val-form-manager>
|
||||
|
||||
<change-password password-values="model.changePassword" config="model.config">
|
||||
</change-password>
|
||||
|
||||
</ng-form>
|
||||
@@ -21,7 +21,8 @@
|
||||
//create the initial model for change password
|
||||
vm.changePasswordModel = {
|
||||
config: {},
|
||||
isChanging: false
|
||||
isChanging: false,
|
||||
value: {}
|
||||
};
|
||||
|
||||
vm.goToPage = goToPage;
|
||||
@@ -37,7 +38,8 @@
|
||||
vm.changeAvatar = changeAvatar;
|
||||
vm.clearAvatar = clearAvatar;
|
||||
vm.save = save;
|
||||
|
||||
|
||||
vm.changePassword = changePassword;
|
||||
vm.toggleChangePassword = toggleChangePassword;
|
||||
|
||||
function init() {
|
||||
@@ -125,23 +127,34 @@
|
||||
}
|
||||
|
||||
function toggleChangePassword() {
|
||||
vm.changePasswordModel.isChanging = !vm.changePasswordModel.isChanging;
|
||||
//reset it
|
||||
vm.user.changePassword = null;
|
||||
//reset it
|
||||
vm.user.changePassword = null;
|
||||
|
||||
localizationService.localizeMany(["general_cancel", "general_confirm", "general_changePassword"])
|
||||
.then(function (data) {
|
||||
const overlay = {
|
||||
view: "changepassword",
|
||||
title: data[2],
|
||||
changePassword: vm.user.changePassword,
|
||||
config: vm.changePasswordModel.config,
|
||||
closeButtonLabel: data[0],
|
||||
submitButtonLabel: data[1],
|
||||
submitButtonStyle: 'success',
|
||||
close: () => overlayService.close(),
|
||||
submit: model => {
|
||||
overlayService.close();
|
||||
vm.changePasswordModel.value = model.changePassword;
|
||||
changePassword();
|
||||
}
|
||||
};
|
||||
overlayService.open(overlay);
|
||||
});
|
||||
}
|
||||
|
||||
function save() {
|
||||
|
||||
if (formHelper.submitForm({ scope: $scope })) {
|
||||
|
||||
//anytime a user is changing another user's password, we are in effect resetting it so we need to set that flag here
|
||||
if (vm.user.changePassword) {
|
||||
//NOTE: the check for allowManuallyChangingPassword is due to this legacy user membership provider setting, if that is true, then the current user
|
||||
//can change their own password without entering their current one (this is a legacy setting since that is a security issue but we need to maintain compat).
|
||||
//if allowManuallyChangingPassword=false, then we are using default settings and the user will need to enter their old password to change their own password.
|
||||
vm.user.changePassword.reset = (!vm.user.changePassword.oldPassword && !vm.user.isCurrentUser) || vm.changePasswordModel.config.allowManuallyChangingPassword;
|
||||
}
|
||||
|
||||
vm.page.saveButtonState = "busy";
|
||||
vm.user.resetPasswordValue = null;
|
||||
|
||||
@@ -161,11 +174,7 @@
|
||||
//restore
|
||||
vm.user.navigation = currentNav;
|
||||
setUserDisplayState();
|
||||
formatDatesToLocal(vm.user);
|
||||
|
||||
vm.changePasswordModel.isChanging = false;
|
||||
//the user has a password if they are not states: Invited, NoCredentials
|
||||
vm.changePasswordModel.config.hasPassword = vm.user.userState !== 3 && vm.user.userState !== 4;
|
||||
formatDatesToLocal(vm.user);
|
||||
|
||||
vm.page.saveButtonState = "success";
|
||||
|
||||
@@ -181,6 +190,36 @@
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function changePassword() {
|
||||
//anytime a user is changing another user's password, we are in effect resetting it so we need to set that flag here
|
||||
if (vm.changePasswordModel.value) {
|
||||
//NOTE: the check for allowManuallyChangingPassword is due to this legacy user membership provider setting, if that is true, then the current user
|
||||
//can change their own password without entering their current one (this is a legacy setting since that is a security issue but we need to maintain compat).
|
||||
//if allowManuallyChangingPassword=false, then we are using default settings and the user will need to enter their old password to change their own password.
|
||||
vm.changePasswordModel.value.reset = (!vm.changePasswordModel.value.oldPassword && !vm.user.isCurrentUser) || vm.changePasswordModel.config.allowManuallyChangingPassword;
|
||||
}
|
||||
|
||||
// since we don't send the entire user model, the id is required
|
||||
vm.changePasswordModel.value.id = vm.user.id;
|
||||
|
||||
usersResource.changePassword(vm.changePasswordModel.value)
|
||||
.then(() => {
|
||||
vm.changePasswordModel.isChanging = false;
|
||||
vm.changePasswordModel.value = {};
|
||||
|
||||
//the user has a password if they are not states: Invited, NoCredentials
|
||||
vm.changePasswordModel.config.hasPassword = vm.user.userState !== 3 && vm.user.userState !== 4;
|
||||
}, err => {
|
||||
contentEditingHelper.handleSaveError({
|
||||
err: err,
|
||||
showNotifications: true
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to emit the save event and await any async operations being performed by editor extensions
|
||||
* @param {any} savedUser
|
||||
|
||||
@@ -258,7 +258,7 @@
|
||||
</div>
|
||||
<div>
|
||||
|
||||
<umb-button type="button" ng-if="model.user.userDisplayState.key !== 'Invited' && model.changePasswordModel.isChanging === false"
|
||||
<umb-button type="button" ng-if="model.user.userDisplayState.key !== 'Invited'"
|
||||
button-style="[action,block]"
|
||||
action="model.toggleChangePassword()"
|
||||
label="Change password"
|
||||
@@ -278,21 +278,6 @@
|
||||
</umb-button>
|
||||
</div>
|
||||
|
||||
<ng-form ng-if="model.changePasswordModel.isChanging" name="passwordForm" class="block-form" val-form-manager>
|
||||
|
||||
<change-password password-values="model.user.changePassword"
|
||||
config="model.changePasswordModel.config">
|
||||
</change-password>
|
||||
|
||||
<umb-button type="button"
|
||||
action="model.toggleChangePassword()"
|
||||
label="Cancel"
|
||||
label-key="general_cancel"
|
||||
button-style="cancel">
|
||||
</umb-button>
|
||||
|
||||
</ng-form>
|
||||
|
||||
<div ng-if="model.user.resetPasswordValue">
|
||||
<p><br />Password reset to value: <strong>{{model.user.resetPasswordValue}}</strong></p>
|
||||
</div>
|
||||
|
||||
@@ -737,6 +737,7 @@
|
||||
<key alias="sort">Sort</key>
|
||||
<key alias="status">Status</key>
|
||||
<key alias="submit">Submit</key>
|
||||
<key alias="success">Success</key>
|
||||
<key alias="type">Type</key>
|
||||
<key alias="typeToSearch">Type to search...</key>
|
||||
<key alias="under">under</key>
|
||||
@@ -1843,7 +1844,8 @@ To manage your website, simply open the Umbraco back office and start adding con
|
||||
<key alias="password">Password</key>
|
||||
<key alias="resetPassword">Reset password</key>
|
||||
<key alias="passwordChanged">Your password has been changed!</key>
|
||||
<key alias="passwordConfirm">Please confirm the new password</key>
|
||||
<key alias="passwordChangedGeneric">Password changed</key>
|
||||
<key alias="passwordConfirm">Please confirm the new password</key>
|
||||
<key alias="passwordEnterNew">Enter your new password</key>
|
||||
<key alias="passwordIsBlank">Your new password cannot be blank!</key>
|
||||
<key alias="passwordCurrent">Current password</key>
|
||||
|
||||
@@ -738,6 +738,7 @@
|
||||
<key alias="sort">Sort</key>
|
||||
<key alias="status">Status</key>
|
||||
<key alias="submit">Submit</key>
|
||||
<key alias="success">Success</key>
|
||||
<key alias="type">Type</key>
|
||||
<key alias="typeToSearch">Type to search...</key>
|
||||
<key alias="under">under</key>
|
||||
@@ -1852,6 +1853,7 @@ To manage your website, simply open the Umbraco back office and start adding con
|
||||
<key alias="password">Password</key>
|
||||
<key alias="resetPassword">Reset password</key>
|
||||
<key alias="passwordChanged">Your password has been changed!</key>
|
||||
<key alias="passwordChangedGeneric">Password changed</key>
|
||||
<key alias="passwordConfirm">Please confirm the new password</key>
|
||||
<key alias="passwordEnterNew">Enter your new password</key>
|
||||
<key alias="passwordIsBlank">Your new password cannot be blank!</key>
|
||||
|
||||
@@ -26,6 +26,7 @@ using Umbraco.Core.Persistence.DatabaseModelDefinitions;
|
||||
using Umbraco.Core.Security;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web.Editors.Filters;
|
||||
using Umbraco.Web.Models;
|
||||
using Umbraco.Web.Models.ContentEditing;
|
||||
using Umbraco.Web.Mvc;
|
||||
using Umbraco.Web.WebApi;
|
||||
@@ -549,29 +550,7 @@ namespace Umbraco.Web.Editors
|
||||
if (Current.Configs.Settings().Security.UsernameIsEmail && found.Username == found.Email && userSave.Username != userSave.Email)
|
||||
{
|
||||
userSave.Username = userSave.Email;
|
||||
}
|
||||
|
||||
if (userSave.ChangePassword != null)
|
||||
{
|
||||
var passwordChanger = new PasswordChanger(Logger, Services.UserService, UmbracoContext.HttpContext);
|
||||
|
||||
//this will change the password and raise appropriate events
|
||||
var passwordChangeResult = await passwordChanger.ChangePasswordWithIdentityAsync(Security.CurrentUser, found, userSave.ChangePassword, UserManager);
|
||||
if (passwordChangeResult.Success)
|
||||
{
|
||||
//need to re-get the user
|
||||
found = Services.UserService.GetUserById(intId.Result);
|
||||
}
|
||||
else
|
||||
{
|
||||
hasErrors = true;
|
||||
|
||||
foreach (var memberName in passwordChangeResult.Result.ChangeError.MemberNames)
|
||||
{
|
||||
ModelState.AddModelError(memberName, passwordChangeResult.Result.ChangeError.ErrorMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hasErrors)
|
||||
throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState));
|
||||
@@ -587,6 +566,51 @@ namespace Umbraco.Web.Editors
|
||||
return display;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="changingPasswordModel"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<ModelWithNotifications<string>> PostChangePassword(ChangingPasswordModel changingPasswordModel)
|
||||
{
|
||||
changingPasswordModel = changingPasswordModel ?? throw new ArgumentNullException(nameof(changingPasswordModel));
|
||||
|
||||
if (ModelState.IsValid == false)
|
||||
{
|
||||
throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState));
|
||||
}
|
||||
|
||||
var intId = changingPasswordModel.Id.TryConvertTo<int>();
|
||||
if (intId.Success == false)
|
||||
{
|
||||
throw new HttpResponseException(HttpStatusCode.NotFound);
|
||||
}
|
||||
|
||||
var found = Services.UserService.GetUserById(intId.Result);
|
||||
if (found == null)
|
||||
{
|
||||
throw new HttpResponseException(HttpStatusCode.NotFound);
|
||||
}
|
||||
|
||||
var passwordChanger = new PasswordChanger(Logger, Services.UserService, UmbracoContext.HttpContext);
|
||||
var passwordChangeResult = await passwordChanger.ChangePasswordWithIdentityAsync(Security.CurrentUser, found, changingPasswordModel, UserManager);
|
||||
|
||||
if (passwordChangeResult.Success)
|
||||
{
|
||||
var result = new ModelWithNotifications<string>(passwordChangeResult.Result.ResetPassword);
|
||||
result.AddSuccessNotification(Services.TextService.Localize("general/success"), Services.TextService.Localize("user/passwordChangedGeneric"));
|
||||
return result;
|
||||
}
|
||||
|
||||
foreach (var memberName in passwordChangeResult.Result.ChangeError.MemberNames)
|
||||
{
|
||||
ModelState.AddModelError(memberName, passwordChangeResult.Result.ChangeError.ErrorMessage);
|
||||
}
|
||||
|
||||
throw new HttpResponseException(Request.CreateValidationErrorResponse(ModelState));
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Disables the users with the given user ids
|
||||
/// </summary>
|
||||
|
||||
@@ -49,5 +49,11 @@ namespace Umbraco.Web.Models
|
||||
/// </summary>
|
||||
[DataMember(Name = "generatedPassword")]
|
||||
public string GeneratedPassword { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The id of the user - required to allow changing password without the entire UserSave model
|
||||
/// </summary>
|
||||
[DataMember(Name = "id")]
|
||||
public int Id { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user