diff --git a/src/Umbraco.Core/Models/ContentEditing/MemberBasic.cs b/src/Umbraco.Core/Models/ContentEditing/MemberBasic.cs index 7ef1ce5f72..49eaf51eb5 100644 --- a/src/Umbraco.Core/Models/ContentEditing/MemberBasic.cs +++ b/src/Umbraco.Core/Models/ContentEditing/MemberBasic.cs @@ -13,6 +13,24 @@ public class MemberBasic : ContentItemBasic [DataMember(Name = "email")] public string? Email { get; set; } + [DataMember(Name = "failedPasswordAttempts")] + public int FailedPasswordAttempts { get; set; } + + [DataMember(Name = "approved")] + public bool Approved { get; set; } + + [DataMember(Name = "lockedOut")] + public bool LockedOut { get; set; } + + [DataMember(Name = "lastLockoutDate")] + public DateTime? LastLockoutDate { get; set; } + + [DataMember(Name = "lastLoginDate")] + public DateTime? LastLoginDate { get; set; } + + [DataMember(Name = "lastPasswordChangeDate")] + public DateTime? LastPasswordChangeDate { get; set; } + [DataMember(Name = "properties")] public override IEnumerable Properties { diff --git a/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/MemberRepository.cs b/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/MemberRepository.cs index 200af7ad70..c89344716f 100644 --- a/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/MemberRepository.cs +++ b/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/MemberRepository.cs @@ -280,6 +280,36 @@ public class MemberRepository : ContentRepositoryBase(x => x.Alias); } + if (ordering.OrderBy.InvariantEquals("failedPasswordAttempts")) + { + return SqlSyntax.GetFieldName(x => x.FailedPasswordAttempts); + } + + if (ordering.OrderBy.InvariantEquals("approved")) + { + return SqlSyntax.GetFieldName(x => x.IsApproved); + } + + if (ordering.OrderBy.InvariantEquals("lockedOut")) + { + return SqlSyntax.GetFieldName(x => x.IsLockedOut); + } + + if (ordering.OrderBy.InvariantEquals("lastLockoutDate")) + { + return SqlSyntax.GetFieldName(x => x.LastLockoutDate); + } + + if (ordering.OrderBy.InvariantEquals("lastLoginDate")) + { + return SqlSyntax.GetFieldName(x => x.LastLoginDate); + } + + if (ordering.OrderBy.InvariantEquals("lastPasswordChangeDate")) + { + return SqlSyntax.GetFieldName(x => x.LastPasswordChangeDate); + } + return base.ApplySystemOrdering(ref sql, ordering); } diff --git a/src/Umbraco.Web.BackOffice/Mapping/MemberMapDefinition.cs b/src/Umbraco.Web.BackOffice/Mapping/MemberMapDefinition.cs index 541c6f2710..7164974878 100644 --- a/src/Umbraco.Web.BackOffice/Mapping/MemberMapDefinition.cs +++ b/src/Umbraco.Web.BackOffice/Mapping/MemberMapDefinition.cs @@ -88,6 +88,12 @@ public class MemberMapDefinition : IMapDefinition target.Udi = Udi.Create(Constants.UdiEntityType.Member, source.Key); target.UpdateDate = source.UpdateDate; target.Username = source.Username; + target.FailedPasswordAttempts = source.FailedPasswordAttempts; + target.Approved = source.IsApproved; + target.LockedOut = source.IsLockedOut; + target.LastLockoutDate = source.LastLockoutDate; + target.LastLoginDate = source.LastLoginDate; + target.LastPasswordChangeDate = source.LastPasswordChangeDate; } // Umbraco.Code.MapAll -Icon -Trashed -ParentId -Alias diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/includeproperties.prevalues.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/includeproperties.prevalues.controller.js index 2eced1f660..d3399a35e1 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/includeproperties.prevalues.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/includeproperties.prevalues.controller.js @@ -10,42 +10,26 @@ function includePropsPreValsController($rootScope, $scope, localizationService, $scope.propertyAliases = []; $scope.selectedField = null; $scope.systemFields = [ - { value: "sortOrder" }, - { value: "updateDate" }, - { value: "updater" }, - { value: "createDate" }, - { value: "owner" }, - { value: "published"}, - { value: "contentTypeAlias" }, - { value: "email" }, - { value: "username" } + { value: "sortOrder", localizedKey: "general_sort" }, + { value: "updateDate", localizedKey: "content_updateDate" }, + { value: "updater", localizedKey: "content_updatedBy" }, + { value: "createDate", localizedKey: "content_createDate" }, + { value: "owner", localizedKey: "content_createBy" }, + { value: "published", localizedKey: "content_isPublished" }, + { value: "contentTypeAlias", localizedKey: "content_documentType" }, + { value: "email", localizedKey: "general_email" }, + { value: "username", localizedKey: "general_username" }, + { value: "failedPasswordAttempts", localizedKey: "user_failedPasswordAttempts" }, + { value: "approved", localizedKey: "user_stateApproved" }, + { value: "lockedOut", localizedKey: "user_stateLockedOut" }, + { value: "lastLockoutDate", localizedKey: "user_lastLockoutDate" }, + { value: "lastLoginDate", localizedKey: "user_lastLogin" }, + { value: "lastPasswordChangeDate", localizedKey: "user_lastPasswordChangeDate" } ]; - $scope.getLocalizedKey = function(alias) { - switch (alias) { - case "name": - return "general_name"; - case "sortOrder": - return "general_sort"; - case "updateDate": - return "content_updateDate"; - case "updater": - return "content_updatedBy"; - case "createDate": - return "content_createDate"; - case "owner": - return "content_createBy"; - case "published": - return "content_isPublished"; - case "contentTypeAlias": - //NOTE: This will just be 'Document' type even if it's for media/members since this is just a pre-val editor and we don't have a key for 'Content Type Alias' - return "content_documentType"; - case "email": - return "general_email"; - case "username": - return "general_username"; - } - return alias; + $scope.getLocalizedKey = function (alias) { + const translationKey = $scope.systemFields.find(x => x.value === alias)?.localizedKey; + return translationKey !== undefined ? translationKey : alias; } $scope.changeField = function () { @@ -65,16 +49,18 @@ function includePropsPreValsController($rootScope, $scope, localizationService, e.name = v; switch (e.value) { + case "published": case "updater": e.name += " (Content only)"; break; - case "published": - e.name += " (Content only)"; - break; - case "email": - e.name += " (Members only)"; - break; case "username": + case "email": + case "failedPasswordAttempts": + case "approved": + case "lockedOut": + case "lastLockoutDate": + case "lastLoginDate": + case "lastPasswordChangeDate": e.name += " (Members only)"; break; } @@ -174,4 +160,4 @@ function includePropsPreValsController($rootScope, $scope, localizationService, } -angular.module("umbraco").controller("Umbraco.PrevalueEditors.IncludePropertiesListViewController", includePropsPreValsController); \ No newline at end of file +angular.module("umbraco").controller("Umbraco.PrevalueEditors.IncludePropertiesListViewController", includePropsPreValsController); diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.controller.js index 98de0c4bfc..68075cb999 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.controller.js @@ -213,7 +213,13 @@ function listViewController($scope, $interpolate, $routeParams, $injector, $time e.alias === "email" || e.alias === "updateDate" || e.alias === "createDate" || - e.alias === "contentTypeAlias"; + e.alias === "contentTypeAlias" || + e.alias === "failedPasswordAttempts" || + e.alias === "approved" || + e.alias === "lockedOut" || + e.alias === "lastLockoutDate" || + e.alias === "lastLoginDate" || + e.alias === "lastPasswordChangeDate"; } if (e.isSystem) { @@ -815,6 +821,18 @@ function listViewController($scope, $interpolate, $routeParams, $injector, $time return "general_email"; case "username": return "general_username"; + case "failedPasswordAttempts": + return "user_failedPasswordAttempts"; + case "approved": + return "user_stateApproved"; + case "lockedOut": + return "user_stateLockedOut"; + case "lastLockoutDate": + return "user_lastLockoutDate"; + case "lastLoginDate": + return "user_lastLogin"; + case "lastPasswordChangeDate": + return "user_lastPasswordChangeDate"; } return alias; } diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/sortby.prevalues.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/sortby.prevalues.controller.js index 0a81bb40e2..dcc4a8ebec 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/sortby.prevalues.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/sortby.prevalues.controller.js @@ -53,7 +53,13 @@ function sortByPreValsController($rootScope, $scope, localizationService, editor { value: "ContentTypeAlias", key: "content_documentType" }, { value: "Published", key: "content_isPublished" }, { value: "Email", key: "general_email" }, - { value: "Username", key: "general_username" } + { value: "Username", key: "general_username" }, + { value: "failedPasswordAttempts", key: "user_failedPasswordAttempts" }, + { value: "approved", key: "user_stateApproved" }, + { value: "lockedOut", key: "user_stateLockedOut" }, + { value: "lastLockoutDate", key: "user_lastLockoutDate" }, + { value: "lastLoginDate", key: "user_lastLogin" }, + { value: "lastPasswordChangeDate", key: "user_lastPasswordChangeDate" } ]; _.each(systemFields, function (e) { localizationService.localize(e.key).then(function (v) {