diff --git a/API/Program.cs b/API/Program.cs index ce123458c..713e2c404 100644 --- a/API/Program.cs +++ b/API/Program.cs @@ -36,7 +36,6 @@ namespace API var isDocker = new OsInfo(Array.Empty()).IsDocker; - // TODO: Figure out a solution for this migration and logger. var directoryService = new DirectoryService(null, new FileSystem()); MigrateConfigFiles.Migrate(isDocker, directoryService); @@ -58,7 +57,7 @@ namespace API try { var context = services.GetRequiredService(); - var roleManager = services.GetRequiredService>(); + if (isDocker && new FileInfo("data/appsettings.json").Exists) { @@ -81,28 +80,27 @@ namespace API requiresCoverImageMigration = false; } - - // Apply all migrations on startup - // If we have pending migrations, make a backup first - var pendingMigrations = await context.Database.GetPendingMigrationsAsync(); - if (pendingMigrations.Any()) - { - var logger = services.GetRequiredService>(); - logger.LogInformation("Performing backup as migrations are needed"); - // var backupService = services.GetRequiredService(); - // await backupService.BackupDatabase(); - } - - await context.Database.MigrateAsync(); - if (requiresCoverImageMigration) { await MigrateCoverImages.UpdateDatabaseWithImages(context, directoryService); } - await Seed.SeedRoles(roleManager); - await Seed.SeedSettings(context, directoryService); - await Seed.SeedUserApiKeys(context); + // // Apply all migrations on startup + // // If we have pending migrations, make a backup first + // var pendingMigrations = await context.Database.GetPendingMigrationsAsync(); + // if (pendingMigrations.Any()) + // { + // var logger = services.GetRequiredService>(); + // logger.LogInformation("Performing backup as migrations are needed"); + // // var backupService = services.GetRequiredService(); + // // await backupService.BackupDatabase(); + // } + // + // await context.Database.MigrateAsync(); + // + // await Seed.SeedRoles(roleManager); + // await Seed.SeedSettings(context, directoryService); + // await Seed.SeedUserApiKeys(context); } catch (Exception ex) { diff --git a/API/Startup.cs b/API/Startup.cs index acb6b615f..b6bd5630e 100644 --- a/API/Startup.cs +++ b/API/Startup.cs @@ -6,10 +6,12 @@ using System.Net; using System.Net.Sockets; using System.Threading.Tasks; using API.Data; +using API.Entities; using API.Extensions; using API.Middleware; using API.Services; using API.Services.HostedServices; +using API.Services.Tasks; using API.SignalR; using Hangfire; using Hangfire.MemoryStorage; @@ -19,8 +21,10 @@ using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.HttpOverrides; +using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.ResponseCompression; using Microsoft.AspNetCore.StaticFiles; +using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; @@ -130,12 +134,45 @@ namespace API // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IBackgroundJobClient backgroundJobs, IWebHostEnvironment env, IHostApplicationLifetime applicationLifetime, IServiceProvider serviceProvider, ICacheService cacheService, - IDirectoryService directoryService, IUnitOfWork unitOfWork) + IDirectoryService directoryService, IUnitOfWork unitOfWork, IBackupService backupService) { // Apply Migrations - Task.Run(async () => await MigrateBookmarks.Migrate(directoryService, unitOfWork, - serviceProvider.GetRequiredService>(), cacheService)).GetAwaiter().GetResult(); + try + { + Task.Run(async () => + { + // Apply all migrations on startup + // If we have pending migrations, make a backup first + var logger = serviceProvider.GetRequiredService>(); + var context = serviceProvider.GetRequiredService(); + var pendingMigrations = await context.Database.GetPendingMigrationsAsync(); + if (pendingMigrations.Any()) + { + logger.LogInformation("Performing backup as migrations are needed"); + await backupService.BackupDatabase(); + } + + await context.Database.MigrateAsync(); + + await MigrateBookmarks.Migrate(directoryService, unitOfWork, + logger, cacheService); + + var roleManager = serviceProvider.GetRequiredService>(); + + await Seed.SeedRoles(roleManager); + await Seed.SeedSettings(context, directoryService); + await Seed.SeedUserApiKeys(context); + + }).GetAwaiter() + .GetResult(); + } + catch (Exception ex) + { + var logger = serviceProvider.GetRequiredService>(); + logger.LogCritical(ex, "An error occurred during migration"); + } + app.UseMiddleware(); diff --git a/UI/Web/src/app/app-routing.module.ts b/UI/Web/src/app/app-routing.module.ts index 636f0052b..7f8bd88f7 100644 --- a/UI/Web/src/app/app-routing.module.ts +++ b/UI/Web/src/app/app-routing.module.ts @@ -10,6 +10,7 @@ import { LibraryAccessGuard } from './_guards/library-access.guard'; import { OnDeckComponent } from './on-deck/on-deck.component'; import { DashboardComponent } from './dashboard/dashboard.component'; import { AllSeriesComponent } from './all-series/all-series.component'; +import { AdminGuard } from './_guards/admin.guard'; // TODO: Once we modularize the components, use this and measure performance impact: https://angular.io/guide/lazy-loading-ngmodules#preloading-modules @@ -17,18 +18,22 @@ const routes: Routes = [ {path: '', component: UserLoginComponent}, { path: 'admin', + canActivate: [AdminGuard], loadChildren: () => import('./admin/admin.module').then(m => m.AdminModule) }, { path: 'collections', + canActivate: [AuthGuard], loadChildren: () => import('./collections/collections.module').then(m => m.CollectionsModule) }, { path: 'preferences', + canActivate: [AuthGuard], loadChildren: () => import('./user-settings/user-settings.module').then(m => m.UserSettingsModule) }, { path: 'lists', + canActivate: [AuthGuard], loadChildren: () => import('./reading-list/reading-list.module').then(m => m.ReadingListModule) }, {