Misc Fixes + Enhancements (#1875)

* Moved Collapse Series with relationships into a user preference rather than library setting.

* Fixed bookmarks not converting to webp after initial save

* Fixed a bug where when merging we'd print out a duplicate series error when we shouldn't have

* Fixed a bug where clicking on a genre or tag from server stats wouldn't load all-series page in a filtered state.

* Implemented the ability to have Login role and thus disable accounts.

* Ensure first time flow gets the Login role

* Refactored user management screen so that pending users can be edited or deleted before the end user accepts the invite. A side effect is old legacy users that were here before email was required can now be deleted.

* Show a progress bar under the main series image on larger viewports to show whole series progress.

* Removed code no longer needed

* Cleanup tags, people, collections without connections after editing series metadata.

* Moved the Entity Builders to the main project
This commit is contained in:
Joe Milazzo 2023-03-10 19:09:38 -06:00 committed by GitHub
parent c62e594792
commit bd19b282d5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
63 changed files with 2186 additions and 239 deletions

View file

@ -144,6 +144,7 @@ public class AccountController : BaseApiController
var roleResult = await _userManager.AddToRoleAsync(user, PolicyConstants.AdminRole);
if (!roleResult.Succeeded) return BadRequest(result.Errors);
await _userManager.AddToRoleAsync(user, PolicyConstants.LoginRole);
return new UserDto
{
@ -182,6 +183,8 @@ public class AccountController : BaseApiController
.SingleOrDefaultAsync(x => x.NormalizedUserName == loginDto.Username.ToUpper());
if (user == null) return Unauthorized("Your credentials are not correct");
var roles = await _userManager.GetRolesAsync(user);
if (!roles.Contains(PolicyConstants.LoginRole)) return Unauthorized("Your account is disabled. Contact the server admin.");
var result = await _signInManager
.CheckPasswordSignInAsync(user, loginDto.Password, true);

View file

@ -338,7 +338,6 @@ public class LibraryController : BaseApiController
library.IncludeInRecommended = dto.IncludeInRecommended;
library.IncludeInSearch = dto.IncludeInSearch;
library.ManageCollections = dto.ManageCollections;
library.CollapseSeriesRelationships = dto.CollapseSeriesRelationships;
_unitOfWork.LibraryRepository.Update(library);

View file

@ -31,6 +31,7 @@ public class MetadataController : BaseApiController
/// <param name="libraryIds">String separated libraryIds or null for all genres</param>
/// <returns></returns>
[HttpGet("genres")]
[ResponseCache(CacheProfileName = ResponseCacheProfiles.Instant, VaryByQueryKeys = new []{"libraryIds"})]
public async Task<ActionResult<IList<GenreTagDto>>> GetAllGenres(string? libraryIds)
{
var userId = await _unitOfWork.UserRepository.GetUserIdByUsernameAsync(User.GetUsername());
@ -51,6 +52,7 @@ public class MetadataController : BaseApiController
/// <param name="libraryIds">String separated libraryIds or null for all people</param>
/// <returns></returns>
[HttpGet("people")]
[ResponseCache(CacheProfileName = ResponseCacheProfiles.Instant, VaryByQueryKeys = new []{"libraryIds"})]
public async Task<ActionResult<IList<PersonDto>>> GetAllPeople(string? libraryIds)
{
var userId = await _unitOfWork.UserRepository.GetUserIdByUsernameAsync(User.GetUsername());
@ -68,6 +70,7 @@ public class MetadataController : BaseApiController
/// <param name="libraryIds">String separated libraryIds or null for all tags</param>
/// <returns></returns>
[HttpGet("tags")]
[ResponseCache(CacheProfileName = ResponseCacheProfiles.Instant, VaryByQueryKeys = new []{"libraryIds"})]
public async Task<ActionResult<IList<TagDto>>> GetAllTags(string? libraryIds)
{
var userId = await _unitOfWork.UserRepository.GetUserIdByUsernameAsync(User.GetUsername());
@ -132,6 +135,7 @@ public class MetadataController : BaseApiController
/// <param name="libraryIds">String separated libraryIds or null for all ratings</param>
/// <returns></returns>
[HttpGet("languages")]
[ResponseCache(CacheProfileName = ResponseCacheProfiles.Instant, VaryByQueryKeys = new []{"libraryIds"})]
public async Task<ActionResult<IList<LanguageDto>>> GetAllLanguages(string? libraryIds)
{
var ids = libraryIds?.Split(",").Select(int.Parse).ToList();
@ -145,6 +149,7 @@ public class MetadataController : BaseApiController
}
[HttpGet("all-languages")]
[ResponseCache(CacheProfileName = ResponseCacheProfiles.Hour)]
public IEnumerable<LanguageDto> GetAllValidLanguages()
{
return CultureInfo.GetCultures(CultureTypes.AllCultures).Select(c =>

View file

@ -38,18 +38,16 @@ public class UsersController : BaseApiController
return BadRequest("Could not delete the user.");
}
/// <summary>
/// Returns all users of this server
/// </summary>
/// <param name="includePending">This will include pending members</param>
/// <returns></returns>
[Authorize(Policy = "RequireAdminRole")]
[HttpGet]
public async Task<ActionResult<IEnumerable<MemberDto>>> GetUsers()
public async Task<ActionResult<IEnumerable<MemberDto>>> GetUsers(bool includePending = false)
{
return Ok(await _unitOfWork.UserRepository.GetEmailConfirmedMemberDtosAsync());
}
[Authorize(Policy = "RequireAdminRole")]
[HttpGet("pending")]
public async Task<ActionResult<IEnumerable<MemberDto>>> GetPendingUsers()
{
return Ok(await _unitOfWork.UserRepository.GetPendingMemberDtosAsync());
return Ok(await _unitOfWork.UserRepository.GetEmailConfirmedMemberDtosAsync(!includePending));
}
[HttpGet("myself")]
@ -110,6 +108,7 @@ public class UsersController : BaseApiController
existingPreferences.PromptForDownloadSize = preferencesDto.PromptForDownloadSize;
existingPreferences.NoTransitions = preferencesDto.NoTransitions;
existingPreferences.SwipeToPaginate = preferencesDto.SwipeToPaginate;
existingPreferences.CollapseSeriesRelationships = preferencesDto.CollapseSeriesRelationships;
_unitOfWork.UserRepository.Update(existingPreferences);