-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/zero.Web.UI/App/pages/settings/user.vue b/zero.Web.UI/App/pages/settings/user.vue
index ceca6a1a..e33fb951 100644
--- a/zero.Web.UI/App/pages/settings/user.vue
+++ b/zero.Web.UI/App/pages/settings/user.vue
@@ -4,7 +4,6 @@
-
@@ -29,6 +28,7 @@
+
+
\ No newline at end of file
diff --git a/zero.Web.UI/app/core/editor-field.ts b/zero.Web.UI/app/core/editor-field.ts
index f881cd69..a27990f4 100644
--- a/zero.Web.UI/app/core/editor-field.ts
+++ b/zero.Web.UI/app/core/editor-field.ts
@@ -201,6 +201,17 @@ class EditorField
}
+ /**
+ * Render a password hash field
+ * @param {number} [maxLength] - Maximum length of the password
+ * @returns {EditorField}
+ */
+ passwordHash(maxLength)
+ {
+ return this._setComponent(() => import('../editor/fields/password-hash.vue'), { maxLength });
+ }
+
+
/**
* Render a currency input field
* @param {string|function} [placeholder] - Placeholder text (can be a translation) or function
diff --git a/zero.Web.UI/app/editor/fields/password-hash.vue b/zero.Web.UI/app/editor/fields/password-hash.vue
new file mode 100644
index 00000000..ef7f9c00
--- /dev/null
+++ b/zero.Web.UI/app/editor/fields/password-hash.vue
@@ -0,0 +1,54 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/zero.Web.UI/app/renderers/editors/password.js b/zero.Web.UI/app/renderers/editors/password.js
new file mode 100644
index 00000000..6b7a4196
--- /dev/null
+++ b/zero.Web.UI/app/renderers/editors/password.js
@@ -0,0 +1,10 @@
+
+import Editor from 'zero/core/editor.ts';
+
+const editor = new Editor('media', '@changepasswordoverlay.fields.');
+
+editor.field('currentPassword').password().required();
+editor.field('newPassword').password().required();
+editor.field('confirmNewPassword').password().required();
+
+export default editor;
\ No newline at end of file
diff --git a/zero.Web/Controllers/UsersController.cs b/zero.Web/Controllers/UsersController.cs
index 0a29435d..622e9922 100644
--- a/zero.Web/Controllers/UsersController.cs
+++ b/zero.Web/Controllers/UsersController.cs
@@ -77,6 +77,14 @@ namespace zero.Web.Controllers
}
+ [ZeroAuthorize]
+ public async Task> HashPassword([FromBody] UserPasswordEditModel model)
+ {
+ BackofficeUser user = await Api.GetUserById(model.UserId);
+ return await Api.HashPassword(user, model.CurrentPassword, model.NewPassword, model.ConfirmNewPassword);
+ }
+
+
[ZeroAuthorize(Permissions.Settings.Users, PermissionsValue.Update)]
public async Task> Disable([FromBody] BackofficeUser model)
{
diff --git a/zero.Web/Models/UserPasswordEditModel.cs b/zero.Web/Models/UserPasswordEditModel.cs
index 665c02f6..296bbc66 100644
--- a/zero.Web/Models/UserPasswordEditModel.cs
+++ b/zero.Web/Models/UserPasswordEditModel.cs
@@ -2,6 +2,8 @@
{
public class UserPasswordEditModel
{
+ public string UserId { get; set; }
+
public string CurrentPassword { get; set; }
public string NewPassword { get; set; }
diff --git a/zero.Web/Resources/Localization/zero.en-us.json b/zero.Web/Resources/Localization/zero.en-us.json
index a7fefddf..678a7877 100644
--- a/zero.Web/Resources/Localization/zero.en-us.json
+++ b/zero.Web/Resources/Localization/zero.en-us.json
@@ -195,7 +195,8 @@
"changepassword": {
"emptyfields": "Please fill out all fields",
"nouser": "User is invalid",
- "newpasswordsnotmatching": "The new password does not match the confirmation"
+ "newpasswordsnotmatching": "The new password does not match the confirmation",
+ "passwordincorrect": "The current password for this user is wrong"
},
"preview": {
"notfound": "Not found",
@@ -328,6 +329,8 @@
"email": "Email",
"email_text": "Also used as login username",
"email_placeholder": "Enter your email address",
+ "passwordHash": "Password",
+ "passwordHash_text": "Password used for login",
"avatarId": "Avatar",
"avatarId_text": "Upload a user image",
"languageId": "Language",