mirror of
https://github.com/Kareadita/Kavita.git
synced 2025-07-09 03:04:19 -04:00
Merge pull request #49 from Kareadita/feature/settings-continued
User Preferences
This commit is contained in:
commit
b30560fdda
@ -1,18 +1,10 @@
|
|||||||
using API.Helpers.Converters;
|
using API.Helpers.Converters;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
using Xunit.Abstractions;
|
|
||||||
|
|
||||||
namespace API.Tests.Converters
|
namespace API.Tests.Converters
|
||||||
{
|
{
|
||||||
public class CronConverterTests
|
public class CronConverterTests
|
||||||
{
|
{
|
||||||
private readonly ITestOutputHelper _testOutputHelper;
|
|
||||||
|
|
||||||
public CronConverterTests(ITestOutputHelper testOutputHelper)
|
|
||||||
{
|
|
||||||
_testOutputHelper = testOutputHelper;
|
|
||||||
}
|
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[InlineData("daily", "0 0 * * *")]
|
[InlineData("daily", "0 0 * * *")]
|
||||||
[InlineData("disabled", "0 0 31 2 *")]
|
[InlineData("disabled", "0 0 31 2 *")]
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using API.Entities;
|
using API.Entities.Enums;
|
||||||
using API.Parser;
|
using API.Parser;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
using static API.Parser.Parser;
|
using static API.Parser.Parser;
|
||||||
@ -109,7 +109,10 @@ namespace API.Tests
|
|||||||
[InlineData("Yumekui-Merry_DKThias_Chapter21.zip", "21")]
|
[InlineData("Yumekui-Merry_DKThias_Chapter21.zip", "21")]
|
||||||
[InlineData("Yumekui_Merry_v01_c01[Bakayarou-Kuu].rar", "1")]
|
[InlineData("Yumekui_Merry_v01_c01[Bakayarou-Kuu].rar", "1")]
|
||||||
[InlineData("Yumekui-Merry_DKThias_Chapter11v2.zip", "11")]
|
[InlineData("Yumekui-Merry_DKThias_Chapter11v2.zip", "11")]
|
||||||
|
[InlineData("Yumekui-Merry DKThiasScanlations Chapter51v2", "51")]
|
||||||
|
[InlineData("Goblin Slayer Side Story - Year One 017.5", "17.5")]
|
||||||
[InlineData("Beelzebub_53[KSH].zip", "53")]
|
[InlineData("Beelzebub_53[KSH].zip", "53")]
|
||||||
|
[InlineData("Black Bullet - v4 c20.5 [batoto]", "20.5")]
|
||||||
//[InlineData("[Tempus Edax Rerum] Epigraph of the Closed Curve - Chapter 6.zip", "6")]
|
//[InlineData("[Tempus Edax Rerum] Epigraph of the Closed Curve - Chapter 6.zip", "6")]
|
||||||
public void ParseChaptersTest(string filename, string expected)
|
public void ParseChaptersTest(string filename, string expected)
|
||||||
{
|
{
|
||||||
|
@ -1,8 +1,4 @@
|
|||||||
using API.Interfaces;
|
using Xunit;
|
||||||
using API.Services;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using NSubstitute;
|
|
||||||
using Xunit;
|
|
||||||
|
|
||||||
namespace API.Tests.Services
|
namespace API.Tests.Services
|
||||||
{
|
{
|
||||||
|
@ -63,6 +63,7 @@ namespace API.Controllers
|
|||||||
}
|
}
|
||||||
|
|
||||||
var user = _mapper.Map<AppUser>(registerDto);
|
var user = _mapper.Map<AppUser>(registerDto);
|
||||||
|
user.UserPreferences ??= new AppUserPreferences();
|
||||||
|
|
||||||
var result = await _userManager.CreateAsync(user, registerDto.Password);
|
var result = await _userManager.CreateAsync(user, registerDto.Password);
|
||||||
|
|
||||||
@ -83,13 +84,14 @@ namespace API.Controllers
|
|||||||
lib.AppUsers ??= new List<AppUser>();
|
lib.AppUsers ??= new List<AppUser>();
|
||||||
lib.AppUsers.Add(user);
|
lib.AppUsers.Add(user);
|
||||||
}
|
}
|
||||||
if (libraries.Any() && !await _unitOfWork.Complete()) _logger.LogInformation("There was an issue granting library access. Please do this manually.");
|
if (libraries.Any() && !await _unitOfWork.Complete()) _logger.LogError("There was an issue granting library access. Please do this manually.");
|
||||||
}
|
}
|
||||||
|
|
||||||
return new UserDto
|
return new UserDto
|
||||||
{
|
{
|
||||||
Username = user.UserName,
|
Username = user.UserName,
|
||||||
Token = await _tokenService.CreateToken(user),
|
Token = await _tokenService.CreateToken(user),
|
||||||
|
Preferences = _mapper.Map<UserPreferencesDto>(user.UserPreferences)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,11 +99,12 @@ namespace API.Controllers
|
|||||||
public async Task<ActionResult<UserDto>> Login(LoginDto loginDto)
|
public async Task<ActionResult<UserDto>> Login(LoginDto loginDto)
|
||||||
{
|
{
|
||||||
var user = await _userManager.Users
|
var user = await _userManager.Users
|
||||||
|
.Include(u => u.UserPreferences)
|
||||||
.SingleOrDefaultAsync(x => x.NormalizedUserName == loginDto.Username.ToUpper());
|
.SingleOrDefaultAsync(x => x.NormalizedUserName == loginDto.Username.ToUpper());
|
||||||
|
|
||||||
var debugUsers = await _userManager.Users.Select(x => x.NormalizedUserName).ToListAsync();
|
var debugUsers = await _userManager.Users.Select(x => x.NormalizedUserName).ToListAsync();
|
||||||
|
|
||||||
_logger.LogInformation($"All Users: {String.Join(",", debugUsers)}");
|
_logger.LogInformation($"All Users: {string.Join(",", debugUsers)}");
|
||||||
|
|
||||||
if (user == null) return Unauthorized("Invalid username");
|
if (user == null) return Unauthorized("Invalid username");
|
||||||
|
|
||||||
@ -112,6 +115,8 @@ namespace API.Controllers
|
|||||||
|
|
||||||
// Update LastActive on account
|
// Update LastActive on account
|
||||||
user.LastActive = DateTime.Now;
|
user.LastActive = DateTime.Now;
|
||||||
|
user.UserPreferences ??= new AppUserPreferences();
|
||||||
|
|
||||||
_unitOfWork.UserRepository.Update(user);
|
_unitOfWork.UserRepository.Update(user);
|
||||||
await _unitOfWork.Complete();
|
await _unitOfWork.Complete();
|
||||||
|
|
||||||
@ -120,7 +125,8 @@ namespace API.Controllers
|
|||||||
return new UserDto
|
return new UserDto
|
||||||
{
|
{
|
||||||
Username = user.UserName,
|
Username = user.UserName,
|
||||||
Token = await _tokenService.CreateToken(user)
|
Token = await _tokenService.CreateToken(user),
|
||||||
|
Preferences = _mapper.Map<UserPreferencesDto>(user.UserPreferences)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
30
API/Controllers/ServerController.cs
Normal file
30
API/Controllers/ServerController.cs
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
using API.Extensions;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.Extensions.Hosting;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
|
namespace API.Controllers
|
||||||
|
{
|
||||||
|
[Authorize(Policy = "RequireAdminRole")]
|
||||||
|
public class ServerController : BaseApiController
|
||||||
|
{
|
||||||
|
private readonly IHostApplicationLifetime _applicationLifetime;
|
||||||
|
private readonly ILogger<ServerController> _logger;
|
||||||
|
|
||||||
|
public ServerController(IHostApplicationLifetime applicationLifetime, ILogger<ServerController> logger)
|
||||||
|
{
|
||||||
|
_applicationLifetime = applicationLifetime;
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost("restart")]
|
||||||
|
public ActionResult RestartServer()
|
||||||
|
{
|
||||||
|
_logger.LogInformation($"{User.GetUsername()} is restarting server from admin dashboard.");
|
||||||
|
|
||||||
|
_applicationLifetime.StopApplication();
|
||||||
|
return Ok();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,8 +1,9 @@
|
|||||||
using System.Collections.Generic;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using API.DTOs;
|
using API.DTOs;
|
||||||
using API.Entities;
|
using API.Entities.Enums;
|
||||||
using API.Extensions;
|
using API.Extensions;
|
||||||
using API.Helpers.Converters;
|
using API.Helpers.Converters;
|
||||||
using API.Interfaces;
|
using API.Interfaces;
|
||||||
@ -62,6 +63,13 @@ namespace API.Controllers
|
|||||||
setting.Value = updateSettingsDto.TaskScan;
|
setting.Value = updateSettingsDto.TaskScan;
|
||||||
_unitOfWork.SettingsRepository.Update(setting);
|
_unitOfWork.SettingsRepository.Update(setting);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (setting.Key == ServerSettingKey.Port && updateSettingsDto.Port + "" != setting.Value)
|
||||||
|
{
|
||||||
|
setting.Value = updateSettingsDto.Port + "";
|
||||||
|
Environment.SetEnvironmentVariable("KAVITA_PORT", setting.Value);
|
||||||
|
_unitOfWork.SettingsRepository.Update(setting);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_unitOfWork.HasChanges() && await _unitOfWork.Complete())
|
if (_unitOfWork.HasChanges() && await _unitOfWork.Complete())
|
||||||
|
@ -44,5 +44,25 @@ namespace API.Controllers
|
|||||||
var libs = await _unitOfWork.LibraryRepository.GetLibraryDtosForUsernameAsync(User.GetUsername());
|
var libs = await _unitOfWork.LibraryRepository.GetLibraryDtosForUsernameAsync(User.GetUsername());
|
||||||
return Ok(libs.Any(x => x.Id == libraryId));
|
return Ok(libs.Any(x => x.Id == libraryId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpPost("update-preferences")]
|
||||||
|
public async Task<ActionResult<UserPreferencesDto>> UpdatePreferences(UserPreferencesDto preferencesDto)
|
||||||
|
{
|
||||||
|
var existingPreferences = await _unitOfWork.UserRepository.GetPreferencesAsync(User.GetUsername());
|
||||||
|
|
||||||
|
existingPreferences.ReadingDirection = preferencesDto.ReadingDirection;
|
||||||
|
existingPreferences.ScalingOption = preferencesDto.ScalingOption;
|
||||||
|
existingPreferences.PageSplitOption = preferencesDto.PageSplitOption;
|
||||||
|
existingPreferences.HideReadOnDetails = preferencesDto.HideReadOnDetails;
|
||||||
|
|
||||||
|
_unitOfWork.UserRepository.Update(existingPreferences);
|
||||||
|
|
||||||
|
if (await _unitOfWork.Complete())
|
||||||
|
{
|
||||||
|
return Ok(preferencesDto);
|
||||||
|
}
|
||||||
|
|
||||||
|
return BadRequest("There was an issue saving preferences.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,6 +1,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using API.Entities;
|
using API.Entities.Enums;
|
||||||
|
|
||||||
namespace API.DTOs
|
namespace API.DTOs
|
||||||
{
|
{
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using API.Entities;
|
using API.Entities.Enums;
|
||||||
|
|
||||||
namespace API.DTOs
|
namespace API.DTOs
|
||||||
{
|
{
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
using API.Entities;
|
using API.Entities.Enums;
|
||||||
|
|
||||||
namespace API.DTOs
|
namespace API.DTOs
|
||||||
{
|
{
|
||||||
|
@ -6,5 +6,6 @@
|
|||||||
public string TaskScan { get; set; }
|
public string TaskScan { get; set; }
|
||||||
public string LoggingLevel { get; set; }
|
public string LoggingLevel { get; set; }
|
||||||
public string TaskBackup { get; set; }
|
public string TaskBackup { get; set; }
|
||||||
|
public int Port { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,8 +1,10 @@
|
|||||||
namespace API.DTOs
|
|
||||||
|
namespace API.DTOs
|
||||||
{
|
{
|
||||||
public class UserDto
|
public class UserDto
|
||||||
{
|
{
|
||||||
public string Username { get; init; }
|
public string Username { get; init; }
|
||||||
public string Token { get; init; }
|
public string Token { get; init; }
|
||||||
|
public UserPreferencesDto Preferences { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
15
API/DTOs/UserPreferencesDto.cs
Normal file
15
API/DTOs/UserPreferencesDto.cs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
using API.Entities.Enums;
|
||||||
|
|
||||||
|
namespace API.DTOs
|
||||||
|
{
|
||||||
|
public class UserPreferencesDto
|
||||||
|
{
|
||||||
|
public ReadingDirection ReadingDirection { get; set; }
|
||||||
|
public ScalingOption ScalingOption { get; set; }
|
||||||
|
public PageSplitOption PageSplitOption { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Whether UI hides read Volumes on Details page
|
||||||
|
/// </summary>
|
||||||
|
public bool HideReadOnDetails { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,5 @@
|
|||||||
|
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace API.DTOs
|
namespace API.DTOs
|
||||||
@ -11,6 +12,9 @@ namespace API.DTOs
|
|||||||
public byte[] CoverImage { get; set; }
|
public byte[] CoverImage { get; set; }
|
||||||
public int Pages { get; set; }
|
public int Pages { get; set; }
|
||||||
public int PagesRead { get; set; }
|
public int PagesRead { get; set; }
|
||||||
|
public DateTime LastModified { get; set; }
|
||||||
|
public DateTime Created { get; set; }
|
||||||
|
public bool IsSpecial { get; set; }
|
||||||
public ICollection<ChapterDto> Chapters { get; set; }
|
public ICollection<ChapterDto> Chapters { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -28,6 +28,7 @@ namespace API.Data
|
|||||||
public DbSet<AppUserProgress> AppUserProgresses { get; set; }
|
public DbSet<AppUserProgress> AppUserProgresses { get; set; }
|
||||||
public DbSet<AppUserRating> AppUserRating { get; set; }
|
public DbSet<AppUserRating> AppUserRating { get; set; }
|
||||||
public DbSet<ServerSetting> ServerSetting { get; set; }
|
public DbSet<ServerSetting> ServerSetting { get; set; }
|
||||||
|
public DbSet<AppUserPreferences> AppUserPreferences { get; set; }
|
||||||
|
|
||||||
protected override void OnModelCreating(ModelBuilder builder)
|
protected override void OnModelCreating(ModelBuilder builder)
|
||||||
{
|
{
|
||||||
|
718
API/Data/Migrations/20210205220227_UserPreferences.Designer.cs
generated
Normal file
718
API/Data/Migrations/20210205220227_UserPreferences.Designer.cs
generated
Normal file
@ -0,0 +1,718 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using API.Data;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
|
||||||
|
namespace API.Data.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(DataContext))]
|
||||||
|
[Migration("20210205220227_UserPreferences")]
|
||||||
|
partial class UserPreferences
|
||||||
|
{
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder
|
||||||
|
.HasAnnotation("ProductVersion", "5.0.1");
|
||||||
|
|
||||||
|
modelBuilder.Entity("API.Entities.AppRole", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("ConcurrencyStamp")
|
||||||
|
.IsConcurrencyToken()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("NormalizedName")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("NormalizedName")
|
||||||
|
.IsUnique()
|
||||||
|
.HasDatabaseName("RoleNameIndex");
|
||||||
|
|
||||||
|
b.ToTable("AspNetRoles");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("API.Entities.AppUser", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("AccessFailedCount")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("ConcurrencyStamp")
|
||||||
|
.IsConcurrencyToken()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime>("Created")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Email")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<bool>("EmailConfirmed")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime>("LastActive")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<bool>("LockoutEnabled")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTimeOffset?>("LockoutEnd")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("NormalizedEmail")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("NormalizedUserName")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("PasswordHash")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("PhoneNumber")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<bool>("PhoneNumberConfirmed")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<uint>("RowVersion")
|
||||||
|
.IsConcurrencyToken()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("SecurityStamp")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<bool>("TwoFactorEnabled")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("UserName")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("NormalizedEmail")
|
||||||
|
.HasDatabaseName("EmailIndex");
|
||||||
|
|
||||||
|
b.HasIndex("NormalizedUserName")
|
||||||
|
.IsUnique()
|
||||||
|
.HasDatabaseName("UserNameIndex");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUsers");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("API.Entities.AppUserPreferences", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("AppUserId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<bool>("HideReadOnDetails")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("PageSplitOption")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("ReadingDirection")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("ScalingOption")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("AppUserId")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.ToTable("AppUserPreferences");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("API.Entities.AppUserProgress", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("AppUserId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("ChapterId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("PagesRead")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("SeriesId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("VolumeId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("AppUserId");
|
||||||
|
|
||||||
|
b.ToTable("AppUserProgresses");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("API.Entities.AppUserRating", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("AppUserId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("Rating")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Review")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("SeriesId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("AppUserId");
|
||||||
|
|
||||||
|
b.ToTable("AppUserRating");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("API.Entities.AppUserRole", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("UserId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("RoleId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("UserId", "RoleId");
|
||||||
|
|
||||||
|
b.HasIndex("RoleId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserRoles");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("API.Entities.Chapter", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<byte[]>("CoverImage")
|
||||||
|
.HasColumnType("BLOB");
|
||||||
|
|
||||||
|
b.Property<DateTime>("Created")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime>("LastModified")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Number")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("Pages")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Range")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("VolumeId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("VolumeId");
|
||||||
|
|
||||||
|
b.ToTable("Chapter");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("API.Entities.FolderPath", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime>("LastScanned")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("LibraryId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Path")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("LibraryId");
|
||||||
|
|
||||||
|
b.ToTable("FolderPath");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("API.Entities.Library", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("CoverImage")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime>("Created")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime>("LastModified")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("Type")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("Library");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("API.Entities.MangaFile", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("ChapterId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("FilePath")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("Format")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("NumberOfPages")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("ChapterId");
|
||||||
|
|
||||||
|
b.ToTable("MangaFile");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("API.Entities.Series", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<byte[]>("CoverImage")
|
||||||
|
.HasColumnType("BLOB");
|
||||||
|
|
||||||
|
b.Property<DateTime>("Created")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime>("LastModified")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("LibraryId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("OriginalName")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("Pages")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("SortName")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Summary")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("LibraryId");
|
||||||
|
|
||||||
|
b.ToTable("Series");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("API.Entities.ServerSetting", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Key")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<uint>("RowVersion")
|
||||||
|
.IsConcurrencyToken()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Value")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Key");
|
||||||
|
|
||||||
|
b.ToTable("ServerSetting");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("API.Entities.Volume", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<byte[]>("CoverImage")
|
||||||
|
.HasColumnType("BLOB");
|
||||||
|
|
||||||
|
b.Property<DateTime>("Created")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<bool>("IsSpecial")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime>("LastModified")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("Number")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("Pages")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("SeriesId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("SeriesId");
|
||||||
|
|
||||||
|
b.ToTable("Volume");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("AppUserLibrary", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("AppUsersId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("LibrariesId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("AppUsersId", "LibrariesId");
|
||||||
|
|
||||||
|
b.HasIndex("LibrariesId");
|
||||||
|
|
||||||
|
b.ToTable("AppUserLibrary");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<int>", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("ClaimType")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("ClaimValue")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("RoleId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("RoleId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetRoleClaims");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<int>", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("ClaimType")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("ClaimValue")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("UserId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserClaims");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<int>", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("LoginProvider")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("ProviderKey")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("ProviderDisplayName")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("UserId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("LoginProvider", "ProviderKey");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserLogins");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<int>", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("UserId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("LoginProvider")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Value")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("UserId", "LoginProvider", "Name");
|
||||||
|
|
||||||
|
b.ToTable("AspNetUserTokens");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("API.Entities.AppUserPreferences", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("API.Entities.AppUser", "AppUser")
|
||||||
|
.WithOne("UserPreferences")
|
||||||
|
.HasForeignKey("API.Entities.AppUserPreferences", "AppUserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("AppUser");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("API.Entities.AppUserProgress", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("API.Entities.AppUser", "AppUser")
|
||||||
|
.WithMany("Progresses")
|
||||||
|
.HasForeignKey("AppUserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("AppUser");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("API.Entities.AppUserRating", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("API.Entities.AppUser", "AppUser")
|
||||||
|
.WithMany("Ratings")
|
||||||
|
.HasForeignKey("AppUserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("AppUser");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("API.Entities.AppUserRole", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("API.Entities.AppRole", "Role")
|
||||||
|
.WithMany("UserRoles")
|
||||||
|
.HasForeignKey("RoleId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("API.Entities.AppUser", "User")
|
||||||
|
.WithMany("UserRoles")
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("Role");
|
||||||
|
|
||||||
|
b.Navigation("User");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("API.Entities.Chapter", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("API.Entities.Volume", "Volume")
|
||||||
|
.WithMany("Chapters")
|
||||||
|
.HasForeignKey("VolumeId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("Volume");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("API.Entities.FolderPath", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("API.Entities.Library", "Library")
|
||||||
|
.WithMany("Folders")
|
||||||
|
.HasForeignKey("LibraryId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("Library");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("API.Entities.MangaFile", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("API.Entities.Chapter", "Chapter")
|
||||||
|
.WithMany("Files")
|
||||||
|
.HasForeignKey("ChapterId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("Chapter");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("API.Entities.Series", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("API.Entities.Library", "Library")
|
||||||
|
.WithMany("Series")
|
||||||
|
.HasForeignKey("LibraryId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("Library");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("API.Entities.Volume", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("API.Entities.Series", "Series")
|
||||||
|
.WithMany("Volumes")
|
||||||
|
.HasForeignKey("SeriesId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("Series");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("AppUserLibrary", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("API.Entities.AppUser", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("AppUsersId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("API.Entities.Library", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("LibrariesId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<int>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("API.Entities.AppRole", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("RoleId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<int>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("API.Entities.AppUser", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<int>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("API.Entities.AppUser", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<int>", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("API.Entities.AppUser", null)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("API.Entities.AppRole", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("UserRoles");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("API.Entities.AppUser", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("Progresses");
|
||||||
|
|
||||||
|
b.Navigation("Ratings");
|
||||||
|
|
||||||
|
b.Navigation("UserPreferences");
|
||||||
|
|
||||||
|
b.Navigation("UserRoles");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("API.Entities.Chapter", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("Files");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("API.Entities.Library", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("Folders");
|
||||||
|
|
||||||
|
b.Navigation("Series");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("API.Entities.Series", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("Volumes");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("API.Entities.Volume", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("Chapters");
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
45
API/Data/Migrations/20210205220227_UserPreferences.cs
Normal file
45
API/Data/Migrations/20210205220227_UserPreferences.cs
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
namespace API.Data.Migrations
|
||||||
|
{
|
||||||
|
public partial class UserPreferences : Migration
|
||||||
|
{
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "AppUserPreferences",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<int>(type: "INTEGER", nullable: false)
|
||||||
|
.Annotation("Sqlite:Autoincrement", true),
|
||||||
|
ReadingDirection = table.Column<int>(type: "INTEGER", nullable: false),
|
||||||
|
ScalingOption = table.Column<int>(type: "INTEGER", nullable: false),
|
||||||
|
PageSplitOption = table.Column<int>(type: "INTEGER", nullable: false),
|
||||||
|
HideReadOnDetails = table.Column<bool>(type: "INTEGER", nullable: false),
|
||||||
|
AppUserId = table.Column<int>(type: "INTEGER", nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_AppUserPreferences", x => x.Id);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_AppUserPreferences_AspNetUsers_AppUserId",
|
||||||
|
column: x => x.AppUserId,
|
||||||
|
principalTable: "AspNetUsers",
|
||||||
|
principalColumn: "Id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_AppUserPreferences_AppUserId",
|
||||||
|
table: "AppUserPreferences",
|
||||||
|
column: "AppUserId",
|
||||||
|
unique: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "AppUserPreferences");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -118,6 +118,35 @@ namespace API.Data.Migrations
|
|||||||
b.ToTable("AspNetUsers");
|
b.ToTable("AspNetUsers");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("API.Entities.AppUserPreferences", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("AppUserId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<bool>("HideReadOnDetails")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("PageSplitOption")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("ReadingDirection")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("ScalingOption")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("AppUserId")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.ToTable("AppUserPreferences");
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("API.Entities.AppUserProgress", b =>
|
modelBuilder.Entity("API.Entities.AppUserProgress", b =>
|
||||||
{
|
{
|
||||||
b.Property<int>("Id")
|
b.Property<int>("Id")
|
||||||
@ -486,6 +515,17 @@ namespace API.Data.Migrations
|
|||||||
b.ToTable("AspNetUserTokens");
|
b.ToTable("AspNetUserTokens");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("API.Entities.AppUserPreferences", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("API.Entities.AppUser", "AppUser")
|
||||||
|
.WithOne("UserPreferences")
|
||||||
|
.HasForeignKey("API.Entities.AppUserPreferences", "AppUserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("AppUser");
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("API.Entities.AppUserProgress", b =>
|
modelBuilder.Entity("API.Entities.AppUserProgress", b =>
|
||||||
{
|
{
|
||||||
b.HasOne("API.Entities.AppUser", "AppUser")
|
b.HasOne("API.Entities.AppUser", "AppUser")
|
||||||
@ -644,6 +684,8 @@ namespace API.Data.Migrations
|
|||||||
|
|
||||||
b.Navigation("Ratings");
|
b.Navigation("Ratings");
|
||||||
|
|
||||||
|
b.Navigation("UserPreferences");
|
||||||
|
|
||||||
b.Navigation("UserRoles");
|
b.Navigation("UserRoles");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ using System.Linq;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using API.Constants;
|
using API.Constants;
|
||||||
using API.Entities;
|
using API.Entities;
|
||||||
|
using API.Entities.Enums;
|
||||||
using API.Services;
|
using API.Services;
|
||||||
using Microsoft.AspNetCore.Identity;
|
using Microsoft.AspNetCore.Identity;
|
||||||
|
|
||||||
@ -30,12 +31,15 @@ namespace API.Data
|
|||||||
|
|
||||||
public static async Task SeedSettings(DataContext context)
|
public static async Task SeedSettings(DataContext context)
|
||||||
{
|
{
|
||||||
context.Database.EnsureCreated();
|
await context.Database.EnsureCreatedAsync();
|
||||||
|
|
||||||
IList<ServerSetting> defaultSettings = new List<ServerSetting>()
|
IList<ServerSetting> defaultSettings = new List<ServerSetting>()
|
||||||
{
|
{
|
||||||
new() {Key = ServerSettingKey.CacheDirectory, Value = CacheService.CacheDirectory},
|
new() {Key = ServerSettingKey.CacheDirectory, Value = CacheService.CacheDirectory},
|
||||||
new () {Key = ServerSettingKey.TaskScan, Value = "daily"}
|
new () {Key = ServerSettingKey.TaskScan, Value = "daily"},
|
||||||
|
//new () {Key = ServerSettingKey.LoggingLevel, Value = "Information"},
|
||||||
|
//new () {Key = ServerSettingKey.TaskBackup, Value = "daily"},
|
||||||
|
new () {Key = ServerSettingKey.Port, Value = "5000"},
|
||||||
};
|
};
|
||||||
|
|
||||||
foreach (var defaultSetting in defaultSettings)
|
foreach (var defaultSetting in defaultSettings)
|
||||||
@ -43,7 +47,7 @@ namespace API.Data
|
|||||||
var existing = context.ServerSetting.FirstOrDefault(s => s.Key == defaultSetting.Key);
|
var existing = context.ServerSetting.FirstOrDefault(s => s.Key == defaultSetting.Key);
|
||||||
if (existing == null)
|
if (existing == null)
|
||||||
{
|
{
|
||||||
context.ServerSetting.Add(defaultSetting);
|
await context.ServerSetting.AddAsync(defaultSetting);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ using System.Linq;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using API.DTOs;
|
using API.DTOs;
|
||||||
using API.Entities;
|
using API.Entities;
|
||||||
|
using API.Entities.Enums;
|
||||||
using API.Interfaces;
|
using API.Interfaces;
|
||||||
using AutoMapper;
|
using AutoMapper;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
@ -25,6 +25,11 @@ namespace API.Data
|
|||||||
{
|
{
|
||||||
_context.Entry(user).State = EntityState.Modified;
|
_context.Entry(user).State = EntityState.Modified;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Update(AppUserPreferences preferences)
|
||||||
|
{
|
||||||
|
_context.Entry(preferences).State = EntityState.Modified;
|
||||||
|
}
|
||||||
|
|
||||||
public void Delete(AppUser user)
|
public void Delete(AppUser user)
|
||||||
{
|
{
|
||||||
@ -59,6 +64,13 @@ namespace API.Data
|
|||||||
_context.AppUserRating.Add(userRating);
|
_context.AppUserRating.Add(userRating);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<AppUserPreferences> GetPreferencesAsync(string username)
|
||||||
|
{
|
||||||
|
return await _context.AppUserPreferences
|
||||||
|
.Include(p => p.AppUser)
|
||||||
|
.SingleOrDefaultAsync(p => p.AppUser.UserName == username);
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<IEnumerable<MemberDto>> GetMembersAsync()
|
public async Task<IEnumerable<MemberDto>> GetMembersAsync()
|
||||||
{
|
{
|
||||||
return await _context.Users
|
return await _context.Users
|
||||||
|
@ -15,6 +15,7 @@ namespace API.Entities
|
|||||||
public ICollection<AppUserRole> UserRoles { get; set; }
|
public ICollection<AppUserRole> UserRoles { get; set; }
|
||||||
public ICollection<AppUserProgress> Progresses { get; set; }
|
public ICollection<AppUserProgress> Progresses { get; set; }
|
||||||
public ICollection<AppUserRating> Ratings { get; set; }
|
public ICollection<AppUserRating> Ratings { get; set; }
|
||||||
|
public AppUserPreferences UserPreferences { get; set; }
|
||||||
|
|
||||||
[ConcurrencyCheck]
|
[ConcurrencyCheck]
|
||||||
public uint RowVersion { get; set; }
|
public uint RowVersion { get; set; }
|
||||||
|
21
API/Entities/AppUserPreferences.cs
Normal file
21
API/Entities/AppUserPreferences.cs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
using API.Entities.Enums;
|
||||||
|
|
||||||
|
namespace API.Entities
|
||||||
|
{
|
||||||
|
public class AppUserPreferences
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
public ReadingDirection ReadingDirection { get; set; } = ReadingDirection.LeftToRight;
|
||||||
|
public ScalingOption ScalingOption { get; set; } = ScalingOption.FitToHeight;
|
||||||
|
public PageSplitOption PageSplitOption { get; set; } = PageSplitOption.SplitRightToLeft;
|
||||||
|
/// <summary>
|
||||||
|
/// Whether UI hides read Volumes on Details page
|
||||||
|
/// </summary>
|
||||||
|
public bool HideReadOnDetails { get; set; } = false;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public AppUser AppUser { get; set; }
|
||||||
|
public int AppUserId { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
|
|
||||||
namespace API.Entities
|
namespace API.Entities.Enums
|
||||||
{
|
{
|
||||||
public enum LibraryType
|
public enum LibraryType
|
||||||
{
|
{
|
@ -1,6 +1,6 @@
|
|||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
|
|
||||||
namespace API.Entities
|
namespace API.Entities.Enums
|
||||||
{
|
{
|
||||||
public enum MangaFormat
|
public enum MangaFormat
|
||||||
{
|
{
|
9
API/Entities/Enums/PageSplitOption.cs
Normal file
9
API/Entities/Enums/PageSplitOption.cs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
namespace API.Entities.Enums
|
||||||
|
{
|
||||||
|
public enum PageSplitOption
|
||||||
|
{
|
||||||
|
SplitLeftToRight = 0,
|
||||||
|
SplitRightToLeft = 1,
|
||||||
|
NoSplit = 2
|
||||||
|
}
|
||||||
|
}
|
8
API/Entities/Enums/ReadingDirection.cs
Normal file
8
API/Entities/Enums/ReadingDirection.cs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
namespace API.Entities.Enums
|
||||||
|
{
|
||||||
|
public enum ReadingDirection
|
||||||
|
{
|
||||||
|
LeftToRight = 0,
|
||||||
|
RightToLeft = 1
|
||||||
|
}
|
||||||
|
}
|
9
API/Entities/Enums/ScalingOption.cs
Normal file
9
API/Entities/Enums/ScalingOption.cs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
namespace API.Entities.Enums
|
||||||
|
{
|
||||||
|
public enum ScalingOption
|
||||||
|
{
|
||||||
|
FitToHeight = 0,
|
||||||
|
FitToWidth = 1,
|
||||||
|
Original = 2
|
||||||
|
}
|
||||||
|
}
|
@ -1,10 +1,11 @@
|
|||||||
namespace API.Entities
|
namespace API.Entities.Enums
|
||||||
{
|
{
|
||||||
public enum ServerSettingKey
|
public enum ServerSettingKey
|
||||||
{
|
{
|
||||||
TaskScan = 0,
|
TaskScan = 0,
|
||||||
CacheDirectory = 1,
|
CacheDirectory = 1,
|
||||||
TaskBackup = 2,
|
TaskBackup = 2,
|
||||||
LoggingLevel = 3
|
LoggingLevel = 3,
|
||||||
|
Port = 4
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using API.Entities.Enums;
|
||||||
using API.Entities.Interfaces;
|
using API.Entities.Interfaces;
|
||||||
|
|
||||||
namespace API.Entities
|
namespace API.Entities
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
|
|
||||||
|
using API.Entities.Enums;
|
||||||
|
|
||||||
namespace API.Entities
|
namespace API.Entities
|
||||||
{
|
{
|
||||||
public class MangaFile
|
public class MangaFile
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using API.Entities.Enums;
|
||||||
using API.Entities.Interfaces;
|
using API.Entities.Interfaces;
|
||||||
|
|
||||||
namespace API.Entities
|
namespace API.Entities
|
||||||
|
@ -21,6 +21,8 @@ namespace API.Helpers
|
|||||||
|
|
||||||
CreateMap<Series, SeriesDto>();
|
CreateMap<Series, SeriesDto>();
|
||||||
|
|
||||||
|
CreateMap<AppUserPreferences, UserPreferencesDto>();
|
||||||
|
|
||||||
CreateMap<Library, LibraryDto>()
|
CreateMap<Library, LibraryDto>()
|
||||||
.ForMember(dest => dest.Folders,
|
.ForMember(dest => dest.Folders,
|
||||||
opt =>
|
opt =>
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using API.DTOs;
|
using API.DTOs;
|
||||||
using API.Entities;
|
using API.Entities;
|
||||||
|
using API.Entities.Enums;
|
||||||
using AutoMapper;
|
using AutoMapper;
|
||||||
|
|
||||||
namespace API.Helpers.Converters
|
namespace API.Helpers.Converters
|
||||||
@ -26,7 +27,9 @@ namespace API.Helpers.Converters
|
|||||||
case ServerSettingKey.TaskBackup:
|
case ServerSettingKey.TaskBackup:
|
||||||
destination.TaskBackup = row.Value;
|
destination.TaskBackup = row.Value;
|
||||||
break;
|
break;
|
||||||
|
case ServerSettingKey.Port:
|
||||||
|
destination.Port = int.Parse(row.Value);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using API.DTOs;
|
using API.DTOs;
|
||||||
using API.Entities;
|
using API.Entities;
|
||||||
|
using API.Entities.Enums;
|
||||||
|
|
||||||
namespace API.Interfaces
|
namespace API.Interfaces
|
||||||
{
|
{
|
||||||
|
@ -8,11 +8,13 @@ namespace API.Interfaces
|
|||||||
public interface IUserRepository
|
public interface IUserRepository
|
||||||
{
|
{
|
||||||
void Update(AppUser user);
|
void Update(AppUser user);
|
||||||
|
void Update(AppUserPreferences preferences);
|
||||||
public void Delete(AppUser user);
|
public void Delete(AppUser user);
|
||||||
Task<AppUser> GetUserByUsernameAsync(string username);
|
Task<AppUser> GetUserByUsernameAsync(string username);
|
||||||
Task<IEnumerable<MemberDto>> GetMembersAsync();
|
Task<IEnumerable<MemberDto>> GetMembersAsync();
|
||||||
Task<IEnumerable<AppUser>> GetAdminUsersAsync();
|
Task<IEnumerable<AppUser>> GetAdminUsersAsync();
|
||||||
Task<AppUserRating> GetUserRating(int seriesId, int userId);
|
Task<AppUserRating> GetUserRating(int seriesId, int userId);
|
||||||
void AddRatingTracking(AppUserRating userRating);
|
void AddRatingTracking(AppUserRating userRating);
|
||||||
|
Task<AppUserPreferences> GetPreferencesAsync(string username);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,9 +1,8 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using API.Entities;
|
using API.Entities.Enums;
|
||||||
|
|
||||||
namespace API.Parser
|
namespace API.Parser
|
||||||
{
|
{
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
|
using API.Entities.Enums;
|
||||||
using API.Entities;
|
|
||||||
|
|
||||||
namespace API.Parser
|
namespace API.Parser
|
||||||
{
|
{
|
||||||
|
@ -13,6 +13,7 @@ namespace API
|
|||||||
{
|
{
|
||||||
public class Program
|
public class Program
|
||||||
{
|
{
|
||||||
|
private static readonly int HttpPort = 5000;
|
||||||
protected Program()
|
protected Program()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -38,7 +39,7 @@ namespace API
|
|||||||
var logger = services.GetRequiredService < ILogger<Program>>();
|
var logger = services.GetRequiredService < ILogger<Program>>();
|
||||||
logger.LogError(ex, "An error occurred during migration");
|
logger.LogError(ex, "An error occurred during migration");
|
||||||
}
|
}
|
||||||
|
|
||||||
await host.RunAsync();
|
await host.RunAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,7 +47,40 @@ namespace API
|
|||||||
Host.CreateDefaultBuilder(args)
|
Host.CreateDefaultBuilder(args)
|
||||||
.ConfigureWebHostDefaults(webBuilder =>
|
.ConfigureWebHostDefaults(webBuilder =>
|
||||||
{
|
{
|
||||||
|
webBuilder.UseKestrel((opts) =>
|
||||||
|
{
|
||||||
|
opts.ListenAnyIP(HttpPort);
|
||||||
|
});
|
||||||
webBuilder.UseStartup<Startup>();
|
webBuilder.UseStartup<Startup>();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// private static void StartNewInstance()
|
||||||
|
// {
|
||||||
|
// //_logger.LogInformation("Starting new instance");
|
||||||
|
//
|
||||||
|
// var module = options.RestartPath;
|
||||||
|
//
|
||||||
|
// if (string.IsNullOrWhiteSpace(module))
|
||||||
|
// {
|
||||||
|
// module = Environment.GetCommandLineArgs()[0];
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // string commandLineArgsString;
|
||||||
|
// // if (options.RestartArgs != null)
|
||||||
|
// // {
|
||||||
|
// // commandLineArgsString = options.RestartArgs ?? string.Empty;
|
||||||
|
// // }
|
||||||
|
// // else
|
||||||
|
// // {
|
||||||
|
// // commandLineArgsString = string.Join(
|
||||||
|
// // ' ',
|
||||||
|
// // Environment.GetCommandLineArgs().Skip(1).Select(NormalizeCommandLineArgument));
|
||||||
|
// // }
|
||||||
|
//
|
||||||
|
// //_logger.LogInformation("Executable: {0}", module);
|
||||||
|
// //_logger.LogInformation("Arguments: {0}", commandLineArgsString);
|
||||||
|
//
|
||||||
|
// Process.Start(module, Array.Empty<string>);
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -129,6 +129,7 @@ namespace API.Services
|
|||||||
try {
|
try {
|
||||||
// TODO: In future, we need to take LibraryType into consideration for what extensions to allow (RAW should allow images)
|
// TODO: In future, we need to take LibraryType into consideration for what extensions to allow (RAW should allow images)
|
||||||
// or we need to move this filtering to another area (Process)
|
// or we need to move this filtering to another area (Process)
|
||||||
|
// or we can get all files and put a check in place during Process to abandon files
|
||||||
files = GetFilesWithCertainExtensions(currentDir, Parser.Parser.MangaFileExtensions)
|
files = GetFilesWithCertainExtensions(currentDir, Parser.Parser.MangaFileExtensions)
|
||||||
.ToArray();
|
.ToArray();
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ using System.IO;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using API.Entities;
|
using API.Entities;
|
||||||
|
using API.Entities.Enums;
|
||||||
using API.Interfaces;
|
using API.Interfaces;
|
||||||
using API.Parser;
|
using API.Parser;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using API.Entities;
|
using API.Entities.Enums;
|
||||||
using API.Helpers.Converters;
|
using API.Helpers.Converters;
|
||||||
using API.Interfaces;
|
using API.Interfaces;
|
||||||
using Hangfire;
|
using Hangfire;
|
||||||
|
@ -3,6 +3,7 @@ using API.Middleware;
|
|||||||
using Hangfire;
|
using Hangfire;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
using Microsoft.AspNetCore.HttpOverrides;
|
||||||
using Microsoft.AspNetCore.StaticFiles;
|
using Microsoft.AspNetCore.StaticFiles;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
@ -26,6 +27,11 @@ namespace API
|
|||||||
|
|
||||||
services.AddApplicationServices(_config);
|
services.AddApplicationServices(_config);
|
||||||
services.AddControllers();
|
services.AddControllers();
|
||||||
|
services.Configure<ForwardedHeadersOptions>(options =>
|
||||||
|
{
|
||||||
|
options.ForwardedHeaders =
|
||||||
|
ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
|
||||||
|
});
|
||||||
services.AddCors();
|
services.AddCors();
|
||||||
services.AddIdentityServices(_config);
|
services.AddIdentityServices(_config);
|
||||||
services.AddSwaggerGen(c =>
|
services.AddSwaggerGen(c =>
|
||||||
@ -45,11 +51,16 @@ namespace API
|
|||||||
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "API v1"));
|
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "API v1"));
|
||||||
app.UseHangfireDashboard();
|
app.UseHangfireDashboard();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
app.UseForwardedHeaders();
|
||||||
|
|
||||||
app.UseRouting();
|
app.UseRouting();
|
||||||
|
|
||||||
// Ordering is important. Cors, authentication, authorization
|
// Ordering is important. Cors, authentication, authorization
|
||||||
app.UseCors(policy => policy.AllowAnyHeader().AllowAnyMethod().WithOrigins("http://localhost:4200"));
|
if (env.IsDevelopment())
|
||||||
|
{
|
||||||
|
app.UseCors(policy => policy.AllowAnyHeader().AllowAnyMethod().WithOrigins("http://localhost:4200"));
|
||||||
|
}
|
||||||
|
|
||||||
app.UseAuthentication();
|
app.UseAuthentication();
|
||||||
|
|
||||||
@ -61,6 +72,7 @@ namespace API
|
|||||||
{
|
{
|
||||||
ContentTypeProvider = new FileExtensionContentTypeProvider() // this is not set by default
|
ContentTypeProvider = new FileExtensionContentTypeProvider() // this is not set by default
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
app.UseEndpoints(endpoints =>
|
app.UseEndpoints(endpoints =>
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user