diff --git a/API/Controllers/AccountController.cs b/API/Controllers/AccountController.cs index 576011b91..9d3212389 100644 --- a/API/Controllers/AccountController.cs +++ b/API/Controllers/AccountController.cs @@ -26,6 +26,7 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.RateLimiting; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; +using SharpCompress; namespace API.Controllers; @@ -137,8 +138,7 @@ public class AccountController : BaseApiController if (!result.Succeeded) return BadRequest(result.Errors); // Assign default streams - user.DashboardStreams = Seed.DefaultStreams.ToList(); - user.SideNavStreams = Seed.DefaultSideNavStreams.ToList(); + AddDefaultStreamsToUser(user); var token = await _userManager.GenerateEmailConfirmationTokenAsync(user); if (string.IsNullOrEmpty(token)) return BadRequest(await _localizationService.Get("en", "confirm-token-gen")); @@ -595,7 +595,7 @@ public class AccountController : BaseApiController if (string.IsNullOrEmpty(dto.Email)) return BadRequest(await _localizationService.Translate(userId, "invalid-payload")); - _logger.LogInformation("{User} is inviting {Email} to the server", adminUser.UserName, dto.Email); + _logger.LogInformation("{User} is inviting {Email} to the server", User.GetUsername(), dto.Email); // Check if there is an existing invite var emailValidationErrors = await _accountService.ValidateEmail(dto.Email); @@ -608,7 +608,8 @@ public class AccountController : BaseApiController } // Create a new user - var user = new AppUserBuilder(dto.Email, dto.Email, await _unitOfWork.SiteThemeRepository.GetDefaultTheme()).Build(); + var user = new AppUserBuilder(dto.Email, dto.Email, + await _unitOfWork.SiteThemeRepository.GetDefaultTheme()).Build(); _unitOfWork.UserRepository.Add(user); try { @@ -616,9 +617,7 @@ public class AccountController : BaseApiController if (!result.Succeeded) return BadRequest(result.Errors); // Assign default streams - user.DashboardStreams = Seed.DefaultStreams.ToList(); - user.SideNavStreams = Seed.DefaultSideNavStreams.ToList(); - + AddDefaultStreamsToUser(user); // Assign Roles var roles = dto.Roles; @@ -657,7 +656,6 @@ public class AccountController : BaseApiController user.CreateSideNavFromLibrary(lib); } - _unitOfWork.UserRepository.Update(user); user.AgeRestriction = hasAdminRole ? AgeRating.NotApplicable : dto.AgeRestriction.AgeRating; user.AgeRestrictionIncludeUnknowns = hasAdminRole || dto.AgeRestriction.IncludeUnknowns; @@ -669,6 +667,7 @@ public class AccountController : BaseApiController } user.ConfirmationToken = token; + _unitOfWork.UserRepository.Update(user); await _unitOfWork.CommitAsync(); } catch (Exception ex) @@ -702,7 +701,7 @@ public class AccountController : BaseApiController BackgroundJob.Enqueue(() => _emailService.SendConfirmationEmail(new ConfirmationEmailDto() { EmailAddress = dto.Email, - InvitingUser = adminUser.UserName!, + InvitingUser = User.GetUsername(), ServerConfirmationLink = emailLink })); } @@ -721,6 +720,19 @@ public class AccountController : BaseApiController return BadRequest(await _localizationService.Translate(User.GetUserId(), "generic-invite-user")); } + private void AddDefaultStreamsToUser(AppUser user) + { + foreach (var newStream in Seed.DefaultStreams.Select(stream => _mapper.Map(stream))) + { + user.DashboardStreams.Add(newStream); + } + + foreach (var stream in Seed.DefaultSideNavStreams.Select(stream => _mapper.Map(stream))) + { + user.SideNavStreams.Add(stream); + } + } + /// /// Last step in authentication flow, confirms the email token for email /// diff --git a/API/Data/Seed.cs b/API/Data/Seed.cs index b807e4dcd..c5fe643ea 100644 --- a/API/Data/Seed.cs +++ b/API/Data/Seed.cs @@ -76,48 +76,42 @@ public static class Seed }, }.ToArray()); - public static readonly ImmutableArray DefaultSideNavStreams = ImmutableArray.Create(new[] + public static readonly ImmutableArray DefaultSideNavStreams = ImmutableArray.Create( + new AppUserSideNavStream() { - new AppUserSideNavStream() - { - Name = "want-to-read", - StreamType = SideNavStreamType.WantToRead, - Order = 1, - IsProvided = true, - Visible = true - }, - new AppUserSideNavStream() - { - Name = "collections", - StreamType = SideNavStreamType.Collections, - Order = 2, - IsProvided = true, - Visible = true - }, - new AppUserSideNavStream() - { - Name = "reading-lists", - StreamType = SideNavStreamType.ReadingLists, - Order = 3, - IsProvided = true, - Visible = true - }, - new AppUserSideNavStream() - { - Name = "bookmarks", - StreamType = SideNavStreamType.Bookmarks, - Order = 4, - IsProvided = true, - Visible = true - }, - new AppUserSideNavStream() - { - Name = "all-series", - StreamType = SideNavStreamType.AllSeries, - Order = 5, - IsProvided = true, - Visible = true - } + Name = "want-to-read", + StreamType = SideNavStreamType.WantToRead, + Order = 1, + IsProvided = true, + Visible = true + }, new AppUserSideNavStream() + { + Name = "collections", + StreamType = SideNavStreamType.Collections, + Order = 2, + IsProvided = true, + Visible = true + }, new AppUserSideNavStream() + { + Name = "reading-lists", + StreamType = SideNavStreamType.ReadingLists, + Order = 3, + IsProvided = true, + Visible = true + }, new AppUserSideNavStream() + { + Name = "bookmarks", + StreamType = SideNavStreamType.Bookmarks, + Order = 4, + IsProvided = true, + Visible = true + }, new AppUserSideNavStream() + { + Name = "all-series", + StreamType = SideNavStreamType.AllSeries, + Order = 5, + IsProvided = true, + Visible = true }); diff --git a/API/Helpers/AutoMapperProfiles.cs b/API/Helpers/AutoMapperProfiles.cs index 77ab29396..8d0a4fa43 100644 --- a/API/Helpers/AutoMapperProfiles.cs +++ b/API/Helpers/AutoMapperProfiles.cs @@ -240,9 +240,10 @@ public class AutoMapperProfiles : Profile CreateMap(); CreateMap(); - // CreateMap() - // .ForMember(dest => dest.SmartFilterEncoded, - // opt => opt.MapFrom(src => src.SmartFilter)); + + // This is for cloning to ensure the records don't get overwritten when setting from SeedData + CreateMap(); + CreateMap(); } }