summaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
Diffstat (limited to 'server')
-rw-r--r--server/src/Data/AppDbContext.cs5
-rw-r--r--server/src/IOL.GreatOffice.Api.csproj5
-rw-r--r--server/src/Migrations/20220616170311_DataProtectionKeys.Designer.cs533
-rw-r--r--server/src/Migrations/20220616170311_DataProtectionKeys.cs33
-rw-r--r--server/src/Migrations/AppDbContextModelSnapshot.cs25
-rw-r--r--server/src/Program.cs3
6 files changed, 598 insertions, 6 deletions
diff --git a/server/src/Data/AppDbContext.cs b/server/src/Data/AppDbContext.cs
index ae34861..a5ef36e 100644
--- a/server/src/Data/AppDbContext.cs
+++ b/server/src/Data/AppDbContext.cs
@@ -1,6 +1,8 @@
+using Microsoft.AspNetCore.DataProtection.EntityFrameworkCore;
+
namespace IOL.GreatOffice.Api.Data;
-public class AppDbContext : DbContext
+public class AppDbContext : DbContext, IDataProtectionKeyContext
{
public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { }
public DbSet<User> Users { get; set; }
@@ -11,6 +13,7 @@ public class AppDbContext : DbContext
public DbSet<GithubUserMapping> GithubUserMappings { get; set; }
public DbSet<ApiAccessToken> AccessTokens { get; set; }
public DbSet<Tenant> Tenants { get; set; }
+ public DbSet<DataProtectionKey> DataProtectionKeys { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder) {
modelBuilder.Entity<User>(e => {
diff --git a/server/src/IOL.GreatOffice.Api.csproj b/server/src/IOL.GreatOffice.Api.csproj
index 44570c0..dde3aaa 100644
--- a/server/src/IOL.GreatOffice.Api.csproj
+++ b/server/src/IOL.GreatOffice.Api.csproj
@@ -15,10 +15,11 @@
<PackageReference Include="Duende.IdentityServer" Version="6.1.0" />
<PackageReference Include="Duende.IdentityServer.EntityFramework.Storage" Version="6.1.0" />
<PackageReference Include="EFCore.NamingConventions" Version="6.0.0" />
- <PackageReference Include="IOL.Helpers" Version="3.0.0" />
+ <PackageReference Include="IOL.Helpers" Version="3.1.0" />
+ <PackageReference Include="Microsoft.AspNetCore.DataProtection.EntityFrameworkCore" Version="6.0.6" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Versioning" Version="5.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer" Version="5.0.0" />
- <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.5">
+ <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.6">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
diff --git a/server/src/Migrations/20220616170311_DataProtectionKeys.Designer.cs b/server/src/Migrations/20220616170311_DataProtectionKeys.Designer.cs
new file mode 100644
index 0000000..b333f23
--- /dev/null
+++ b/server/src/Migrations/20220616170311_DataProtectionKeys.Designer.cs
@@ -0,0 +1,533 @@
+// <auto-generated />
+using System;
+using IOL.GreatOffice.Api.Data;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
+
+#nullable disable
+
+namespace IOL.GreatOffice.Api.Migrations
+{
+ [DbContext(typeof(AppDbContext))]
+ [Migration("20220616170311_DataProtectionKeys")]
+ partial class DataProtectionKeys
+ {
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "6.0.6")
+ .HasAnnotation("Relational:MaxIdentifierLength", 63);
+
+ NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
+
+ modelBuilder.Entity("IOL.GreatOffice.Api.Data.Database.ApiAccessToken", b =>
+ {
+ b.Property<Guid>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid")
+ .HasColumnName("id");
+
+ b.Property<bool>("AllowCreate")
+ .HasColumnType("boolean")
+ .HasColumnName("allow_create");
+
+ b.Property<bool>("AllowDelete")
+ .HasColumnType("boolean")
+ .HasColumnName("allow_delete");
+
+ b.Property<bool>("AllowRead")
+ .HasColumnType("boolean")
+ .HasColumnName("allow_read");
+
+ b.Property<bool>("AllowUpdate")
+ .HasColumnType("boolean")
+ .HasColumnName("allow_update");
+
+ b.Property<DateTime>("CreatedAt")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("created_at");
+
+ b.Property<bool>("Deleted")
+ .HasColumnType("boolean")
+ .HasColumnName("deleted");
+
+ b.Property<DateTime>("ExpiryDate")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("expiry_date");
+
+ b.Property<DateTime?>("ModifiedAt")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("modified_at");
+
+ b.Property<Guid?>("UserId")
+ .HasColumnType("uuid")
+ .HasColumnName("user_id");
+
+ b.HasKey("Id")
+ .HasName("pk_api_access_tokens");
+
+ b.HasIndex("UserId")
+ .HasDatabaseName("ix_api_access_tokens_user_id");
+
+ b.ToTable("api_access_tokens", (string)null);
+ });
+
+ modelBuilder.Entity("IOL.GreatOffice.Api.Data.Database.ForgotPasswordRequest", b =>
+ {
+ b.Property<Guid>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid")
+ .HasColumnName("id");
+
+ b.Property<DateTime>("CreatedAt")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("created_at");
+
+ b.Property<Guid>("UserId")
+ .HasColumnType("uuid")
+ .HasColumnName("user_id");
+
+ b.HasKey("Id")
+ .HasName("pk_forgot_password_requests");
+
+ b.HasIndex("UserId")
+ .HasDatabaseName("ix_forgot_password_requests_user_id");
+
+ b.ToTable("forgot_password_requests", (string)null);
+ });
+
+ modelBuilder.Entity("IOL.GreatOffice.Api.Data.Database.GithubUserMapping", b =>
+ {
+ b.Property<string>("GithubId")
+ .HasColumnType("text")
+ .HasColumnName("github_id");
+
+ b.Property<string>("Email")
+ .HasColumnType("text")
+ .HasColumnName("email");
+
+ b.Property<string>("RefreshToken")
+ .HasColumnType("text")
+ .HasColumnName("refresh_token");
+
+ b.Property<Guid?>("UserId")
+ .HasColumnType("uuid")
+ .HasColumnName("user_id");
+
+ b.HasKey("GithubId")
+ .HasName("pk_github_user_mappings");
+
+ b.HasIndex("UserId")
+ .HasDatabaseName("ix_github_user_mappings_user_id");
+
+ b.ToTable("github_user_mappings", (string)null);
+ });
+
+ modelBuilder.Entity("IOL.GreatOffice.Api.Data.Database.Tenant", b =>
+ {
+ b.Property<Guid>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid")
+ .HasColumnName("id");
+
+ b.Property<string>("ContactEmail")
+ .HasColumnType("text")
+ .HasColumnName("contact_email");
+
+ b.Property<DateTime>("CreatedAt")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("created_at");
+
+ b.Property<Guid?>("CreatedById")
+ .HasColumnType("uuid")
+ .HasColumnName("created_by_id");
+
+ b.Property<bool>("Deleted")
+ .HasColumnType("boolean")
+ .HasColumnName("deleted");
+
+ b.Property<Guid?>("DeletedById")
+ .HasColumnType("uuid")
+ .HasColumnName("deleted_by_id");
+
+ b.Property<string>("Description")
+ .HasColumnType("text")
+ .HasColumnName("description");
+
+ b.Property<Guid>("MasterUserId")
+ .HasColumnType("uuid")
+ .HasColumnName("master_user_id");
+
+ b.Property<string>("MasterUserPassword")
+ .HasColumnType("text")
+ .HasColumnName("master_user_password");
+
+ b.Property<DateTime?>("ModifiedAt")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("modified_at");
+
+ b.Property<Guid?>("ModifiedById")
+ .HasColumnType("uuid")
+ .HasColumnName("modified_by_id");
+
+ b.Property<string>("Name")
+ .HasColumnType("text")
+ .HasColumnName("name");
+
+ b.Property<Guid?>("TenantId")
+ .HasColumnType("uuid")
+ .HasColumnName("tenant_id");
+
+ b.Property<Guid?>("UserId")
+ .HasColumnType("uuid")
+ .HasColumnName("user_id");
+
+ b.HasKey("Id")
+ .HasName("pk_tenants");
+
+ b.ToTable("tenants", (string)null);
+ });
+
+ modelBuilder.Entity("IOL.GreatOffice.Api.Data.Database.TimeCategory", b =>
+ {
+ b.Property<Guid>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid")
+ .HasColumnName("id");
+
+ b.Property<string>("Color")
+ .HasColumnType("text")
+ .HasColumnName("color");
+
+ b.Property<DateTime>("CreatedAt")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("created_at");
+
+ b.Property<Guid?>("CreatedById")
+ .HasColumnType("uuid")
+ .HasColumnName("created_by_id");
+
+ b.Property<bool>("Deleted")
+ .HasColumnType("boolean")
+ .HasColumnName("deleted");
+
+ b.Property<Guid?>("DeletedById")
+ .HasColumnType("uuid")
+ .HasColumnName("deleted_by_id");
+
+ b.Property<DateTime?>("ModifiedAt")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("modified_at");
+
+ b.Property<Guid?>("ModifiedById")
+ .HasColumnType("uuid")
+ .HasColumnName("modified_by_id");
+
+ b.Property<string>("Name")
+ .HasColumnType("text")
+ .HasColumnName("name");
+
+ b.Property<Guid?>("TenantId")
+ .HasColumnType("uuid")
+ .HasColumnName("tenant_id");
+
+ b.Property<Guid?>("UserId")
+ .HasColumnType("uuid")
+ .HasColumnName("user_id");
+
+ b.HasKey("Id")
+ .HasName("pk_time_categories");
+
+ b.ToTable("time_categories", (string)null);
+ });
+
+ modelBuilder.Entity("IOL.GreatOffice.Api.Data.Database.TimeEntry", b =>
+ {
+ b.Property<Guid>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid")
+ .HasColumnName("id");
+
+ b.Property<Guid?>("CategoryId")
+ .HasColumnType("uuid")
+ .HasColumnName("category_id");
+
+ b.Property<DateTime>("CreatedAt")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("created_at");
+
+ b.Property<Guid?>("CreatedById")
+ .HasColumnType("uuid")
+ .HasColumnName("created_by_id");
+
+ b.Property<bool>("Deleted")
+ .HasColumnType("boolean")
+ .HasColumnName("deleted");
+
+ b.Property<Guid?>("DeletedById")
+ .HasColumnType("uuid")
+ .HasColumnName("deleted_by_id");
+
+ b.Property<string>("Description")
+ .HasColumnType("text")
+ .HasColumnName("description");
+
+ b.Property<DateTime?>("ModifiedAt")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("modified_at");
+
+ b.Property<Guid?>("ModifiedById")
+ .HasColumnType("uuid")
+ .HasColumnName("modified_by_id");
+
+ b.Property<DateTime>("Start")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("start");
+
+ b.Property<DateTime>("Stop")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("stop");
+
+ b.Property<Guid?>("TenantId")
+ .HasColumnType("uuid")
+ .HasColumnName("tenant_id");
+
+ b.Property<Guid?>("UserId")
+ .HasColumnType("uuid")
+ .HasColumnName("user_id");
+
+ b.HasKey("Id")
+ .HasName("pk_time_entries");
+
+ b.HasIndex("CategoryId")
+ .HasDatabaseName("ix_time_entries_category_id");
+
+ b.ToTable("time_entries", (string)null);
+ });
+
+ modelBuilder.Entity("IOL.GreatOffice.Api.Data.Database.TimeLabel", b =>
+ {
+ b.Property<Guid>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid")
+ .HasColumnName("id");
+
+ b.Property<string>("Color")
+ .HasColumnType("text")
+ .HasColumnName("color");
+
+ b.Property<DateTime>("CreatedAt")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("created_at");
+
+ b.Property<Guid?>("CreatedById")
+ .HasColumnType("uuid")
+ .HasColumnName("created_by_id");
+
+ b.Property<bool>("Deleted")
+ .HasColumnType("boolean")
+ .HasColumnName("deleted");
+
+ b.Property<Guid?>("DeletedById")
+ .HasColumnType("uuid")
+ .HasColumnName("deleted_by_id");
+
+ b.Property<DateTime?>("ModifiedAt")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("modified_at");
+
+ b.Property<Guid?>("ModifiedById")
+ .HasColumnType("uuid")
+ .HasColumnName("modified_by_id");
+
+ b.Property<string>("Name")
+ .HasColumnType("text")
+ .HasColumnName("name");
+
+ b.Property<Guid?>("TenantId")
+ .HasColumnType("uuid")
+ .HasColumnName("tenant_id");
+
+ b.Property<Guid?>("TimeEntryId")
+ .HasColumnType("uuid")
+ .HasColumnName("time_entry_id");
+
+ b.Property<Guid?>("UserId")
+ .HasColumnType("uuid")
+ .HasColumnName("user_id");
+
+ b.HasKey("Id")
+ .HasName("pk_time_labels");
+
+ b.HasIndex("TimeEntryId")
+ .HasDatabaseName("ix_time_labels_time_entry_id");
+
+ b.ToTable("time_labels", (string)null);
+ });
+
+ modelBuilder.Entity("IOL.GreatOffice.Api.Data.Database.User", b =>
+ {
+ b.Property<Guid>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid")
+ .HasColumnName("id");
+
+ b.Property<DateTime>("CreatedAt")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("created_at");
+
+ b.Property<bool>("Deleted")
+ .HasColumnType("boolean")
+ .HasColumnName("deleted");
+
+ b.Property<string>("Email")
+ .HasColumnType("text")
+ .HasColumnName("email");
+
+ b.Property<string>("FirstName")
+ .HasColumnType("text")
+ .HasColumnName("first_name");
+
+ b.Property<string>("LastName")
+ .HasColumnType("text")
+ .HasColumnName("last_name");
+
+ b.Property<DateTime?>("ModifiedAt")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("modified_at");
+
+ b.Property<string>("Password")
+ .HasColumnType("text")
+ .HasColumnName("password");
+
+ b.Property<string>("Username")
+ .HasColumnType("text")
+ .HasColumnName("username");
+
+ b.HasKey("Id")
+ .HasName("pk_users");
+
+ b.ToTable("users", (string)null);
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.DataProtection.EntityFrameworkCore.DataProtectionKey", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .HasColumnName("id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
+
+ b.Property<string>("FriendlyName")
+ .HasColumnType("text")
+ .HasColumnName("friendly_name");
+
+ b.Property<string>("Xml")
+ .HasColumnType("text")
+ .HasColumnName("xml");
+
+ b.HasKey("Id")
+ .HasName("pk_data_protection_keys");
+
+ b.ToTable("data_protection_keys", (string)null);
+ });
+
+ modelBuilder.Entity("TenantUser", b =>
+ {
+ b.Property<Guid>("TenantsId")
+ .HasColumnType("uuid")
+ .HasColumnName("tenants_id");
+
+ b.Property<Guid>("UsersId")
+ .HasColumnType("uuid")
+ .HasColumnName("users_id");
+
+ b.HasKey("TenantsId", "UsersId")
+ .HasName("pk_tenant_user");
+
+ b.HasIndex("UsersId")
+ .HasDatabaseName("ix_tenant_user_users_id");
+
+ b.ToTable("tenant_user", (string)null);
+ });
+
+ modelBuilder.Entity("IOL.GreatOffice.Api.Data.Database.ApiAccessToken", b =>
+ {
+ b.HasOne("IOL.GreatOffice.Api.Data.Database.User", "User")
+ .WithMany()
+ .HasForeignKey("UserId")
+ .HasConstraintName("fk_api_access_tokens_users_user_id");
+
+ b.Navigation("User");
+ });
+
+ modelBuilder.Entity("IOL.GreatOffice.Api.Data.Database.ForgotPasswordRequest", b =>
+ {
+ b.HasOne("IOL.GreatOffice.Api.Data.Database.User", "User")
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("fk_forgot_password_requests_users_user_id");
+
+ b.Navigation("User");
+ });
+
+ modelBuilder.Entity("IOL.GreatOffice.Api.Data.Database.GithubUserMapping", b =>
+ {
+ b.HasOne("IOL.GreatOffice.Api.Data.Database.User", "User")
+ .WithMany()
+ .HasForeignKey("UserId")
+ .HasConstraintName("fk_github_user_mappings_users_user_id");
+
+ b.Navigation("User");
+ });
+
+ modelBuilder.Entity("IOL.GreatOffice.Api.Data.Database.TimeEntry", b =>
+ {
+ b.HasOne("IOL.GreatOffice.Api.Data.Database.TimeCategory", "Category")
+ .WithMany()
+ .HasForeignKey("CategoryId")
+ .HasConstraintName("fk_time_entries_time_categories_category_id");
+
+ b.Navigation("Category");
+ });
+
+ modelBuilder.Entity("IOL.GreatOffice.Api.Data.Database.TimeLabel", b =>
+ {
+ b.HasOne("IOL.GreatOffice.Api.Data.Database.TimeEntry", null)
+ .WithMany("Labels")
+ .HasForeignKey("TimeEntryId")
+ .HasConstraintName("fk_time_labels_time_entries_time_entry_id");
+ });
+
+ modelBuilder.Entity("TenantUser", b =>
+ {
+ b.HasOne("IOL.GreatOffice.Api.Data.Database.Tenant", null)
+ .WithMany()
+ .HasForeignKey("TenantsId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("fk_tenant_user_tenants_tenants_id");
+
+ b.HasOne("IOL.GreatOffice.Api.Data.Database.User", null)
+ .WithMany()
+ .HasForeignKey("UsersId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("fk_tenant_user_users_users_id");
+ });
+
+ modelBuilder.Entity("IOL.GreatOffice.Api.Data.Database.TimeEntry", b =>
+ {
+ b.Navigation("Labels");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/server/src/Migrations/20220616170311_DataProtectionKeys.cs b/server/src/Migrations/20220616170311_DataProtectionKeys.cs
new file mode 100644
index 0000000..bc3c673
--- /dev/null
+++ b/server/src/Migrations/20220616170311_DataProtectionKeys.cs
@@ -0,0 +1,33 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
+
+#nullable disable
+
+namespace IOL.GreatOffice.Api.Migrations
+{
+ public partial class DataProtectionKeys : Migration
+ {
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.CreateTable(
+ name: "data_protection_keys",
+ columns: table => new
+ {
+ id = table.Column<int>(type: "integer", nullable: false)
+ .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
+ friendly_name = table.Column<string>(type: "text", nullable: true),
+ xml = table.Column<string>(type: "text", nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("pk_data_protection_keys", x => x.id);
+ });
+ }
+
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropTable(
+ name: "data_protection_keys");
+ }
+ }
+}
diff --git a/server/src/Migrations/AppDbContextModelSnapshot.cs b/server/src/Migrations/AppDbContextModelSnapshot.cs
index 70582b5..128d3b6 100644
--- a/server/src/Migrations/AppDbContextModelSnapshot.cs
+++ b/server/src/Migrations/AppDbContextModelSnapshot.cs
@@ -17,7 +17,7 @@ namespace IOL.GreatOffice.Api.Migrations
{
#pragma warning disable 612, 618
modelBuilder
- .HasAnnotation("ProductVersion", "6.0.5")
+ .HasAnnotation("ProductVersion", "6.0.6")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
@@ -412,6 +412,29 @@ namespace IOL.GreatOffice.Api.Migrations
b.ToTable("users", (string)null);
});
+ modelBuilder.Entity("Microsoft.AspNetCore.DataProtection.EntityFrameworkCore.DataProtectionKey", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .HasColumnName("id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
+
+ b.Property<string>("FriendlyName")
+ .HasColumnType("text")
+ .HasColumnName("friendly_name");
+
+ b.Property<string>("Xml")
+ .HasColumnType("text")
+ .HasColumnName("xml");
+
+ b.HasKey("Id")
+ .HasName("pk_data_protection_keys");
+
+ b.ToTable("data_protection_keys", (string)null);
+ });
+
modelBuilder.Entity("TenantUser", b =>
{
b.Property<Guid>("TenantsId")
diff --git a/server/src/Program.cs b/server/src/Program.cs
index 4499b1a..b7e6ce6 100644
--- a/server/src/Program.cs
+++ b/server/src/Program.cs
@@ -89,8 +89,7 @@ public static class Program
});
}
- builder.Services.AddDataProtection().PersistKeysToFileSystem(new DirectoryInfo(AppPaths.DataProtectionKeys.HostPath));
-
+ builder.Services.AddDataProtection().PersistKeysToDbContext<AppDbContext>();
builder.Services.Configure(JsonSettings.Default);
builder.Services.AddQuartz(options => {
options.UsePersistentStore(o => {