< Summary - Heimdall API

Line coverage
100%
Covered lines: 1051
Uncovered lines: 0
Coverable lines: 1051
Total lines: 1183
Line coverage: 100%
Branch coverage
N/A
Covered branches: 0
Total branches: 0
Branch coverage: N/A
Method coverage
100%
Covered methods: 3
Fully covered methods: 3
Total methods: 3
Method coverage: 100%
Full method coverage: 100%

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
File 1: Up(...)100%11100%
File 1: Down(...)100%11100%
File 2: BuildTargetModel(...)100%11100%

File(s)

/home/ci/agent/workspace/heimdall-api-docs_main/app/src/Infrastructure/ArturRios.Heimdall.Data/Migrations/20260814232813_HashSingleUseTokens.cs

#LineLine coverage
 1using Microsoft.EntityFrameworkCore.Migrations;
 2
 3#nullable disable
 4
 5namespace ArturRios.Heimdall.Data.Migrations
 6{
 7    /// <summary>
 8    ///     Replaces the plaintext password-reset and email-verification tokens with their SHA-256
 9    ///     digests (Threat Model TH-14).
 10    /// </summary>
 11    /// <remarks>
 12    ///     <para>
 13    ///         Hand-written rather than left as scaffolded. The generated version dropped the token
 14    ///         column and added <c>token_hash</c> with an empty-array default, which would have given
 15    ///         every existing row the same value and failed the unique index the moment a table held
 16    ///         more than one row — and silently invalidated every live token on a table that held
 17    ///         exactly one.
 18    ///     </para>
 19    ///     <para>
 20    ///         Instead the digest is computed from the column being replaced, in place, so links
 21    ///         already sitting in people's inboxes keep working. A verification token lives for a day
 22    ///         by default, so dropping them would have meant a day of failed verifications for
 23    ///         everybody mid-flow.
 24    ///     </para>
 25    ///     <para>
 26    ///         <c>sha256(bytea)</c> is core PostgreSQL from version 11 and needs no extension. It must
 27    ///         agree exactly with <c>SingleUseTokenHash.Of</c>, which is SHA-256 over the token's
 28    ///         UTF-8 bytes rendered as lowercase hex — hence <c>convert_to(token, 'UTF8')</c> rather
 29    ///         than a cast, and <c>encode(..., 'hex')</c>, which PostgreSQL emits in lower case.
 30    ///     </para>
 31    /// </remarks>
 32    public partial class HashSingleUseTokens : Migration
 33    {
 34        /// <inheritdoc />
 35        protected override void Up(MigrationBuilder migrationBuilder)
 36        {
 37            // Nullable first, so existing rows can be filled before the constraint applies.
 1938            migrationBuilder.AddColumn<string>(
 1939                name: "token_hash",
 1940                schema: "heimdall",
 1941                table: "password_reset_token",
 1942                type: "character varying(64)",
 1943                maxLength: 64,
 1944                nullable: true);
 45
 1946            migrationBuilder.AddColumn<string>(
 1947                name: "token_hash",
 1948                schema: "heimdall",
 1949                table: "email_verification_token",
 1950                type: "character varying(64)",
 1951                maxLength: 64,
 1952                nullable: true);
 53
 1954            migrationBuilder.Sql(
 1955                """
 1956                UPDATE heimdall.password_reset_token
 1957                SET token_hash = encode(sha256(convert_to(token, 'UTF8')), 'hex');
 1958                """);
 59
 1960            migrationBuilder.Sql(
 1961                """
 1962                UPDATE heimdall.email_verification_token
 1963                SET token_hash = encode(sha256(convert_to(token, 'UTF8')), 'hex');
 1964                """);
 65
 1966            migrationBuilder.DropIndex(
 1967                name: "ix_password_reset_token_token",
 1968                schema: "heimdall",
 1969                table: "password_reset_token");
 70
 1971            migrationBuilder.DropIndex(
 1972                name: "ix_email_verification_token_token",
 1973                schema: "heimdall",
 1974                table: "email_verification_token");
 75
 76            // The plaintext leaves the database here, which is the whole point of the migration.
 1977            migrationBuilder.DropColumn(
 1978                name: "token",
 1979                schema: "heimdall",
 1980                table: "password_reset_token");
 81
 1982            migrationBuilder.DropColumn(
 1983                name: "token",
 1984                schema: "heimdall",
 1985                table: "email_verification_token");
 86
 87            // Raw SQL rather than AlterColumn, and not by preference. AlterColumn compares against
 88            // the model the migration started from, where token_hash did not exist at all, so it
 89            // emitted nothing whatsoever — no error, just a column left nullable while the entity
 90            // and the snapshot both declared it required. Verified by reading the generated script
 91            // and the resulting table; the scaffolded call looked correct and did nothing.
 1992            migrationBuilder.Sql(
 1993                "ALTER TABLE heimdall.password_reset_token ALTER COLUMN token_hash SET NOT NULL;");
 94
 1995            migrationBuilder.Sql(
 1996                "ALTER TABLE heimdall.email_verification_token ALTER COLUMN token_hash SET NOT NULL;");
 97
 1998            migrationBuilder.CreateIndex(
 1999                name: "ix_password_reset_token_token_hash",
 19100                schema: "heimdall",
 19101                table: "password_reset_token",
 19102                column: "token_hash",
 19103                unique: true);
 104
 19105            migrationBuilder.CreateIndex(
 19106                name: "ix_email_verification_token_token_hash",
 19107                schema: "heimdall",
 19108                table: "email_verification_token",
 19109                column: "token_hash",
 19110                unique: true);
 19111        }
 112
 113        /// <summary>
 114        ///     Restores the plaintext columns, and discards every token row to do it.
 115        /// </summary>
 116        /// <remarks>
 117        ///     A hash cannot be inverted, so there is no honest way to put back what Up removed. The
 118        ///     alternatives were to leave the rows with an empty token — which the unique index would
 119        ///     reject for the second row, and which would silently accept an empty string as a valid
 120        ///     token for the first — or to delete them. Deleting is the one that fails safe: a person
 121        ///     mid-reset requests another email, and the rows were expiring within the day anyway.
 122        /// </remarks>
 123        protected override void Down(MigrationBuilder migrationBuilder)
 124        {
 1125            migrationBuilder.Sql("DELETE FROM heimdall.password_reset_token;");
 1126            migrationBuilder.Sql("DELETE FROM heimdall.email_verification_token;");
 127
 1128            migrationBuilder.DropIndex(
 1129                name: "ix_password_reset_token_token_hash",
 1130                schema: "heimdall",
 1131                table: "password_reset_token");
 132
 1133            migrationBuilder.DropIndex(
 1134                name: "ix_email_verification_token_token_hash",
 1135                schema: "heimdall",
 1136                table: "email_verification_token");
 137
 1138            migrationBuilder.DropColumn(
 1139                name: "token_hash",
 1140                schema: "heimdall",
 1141                table: "password_reset_token");
 142
 1143            migrationBuilder.DropColumn(
 1144                name: "token_hash",
 1145                schema: "heimdall",
 1146                table: "email_verification_token");
 147
 1148            migrationBuilder.AddColumn<string>(
 1149                name: "token",
 1150                schema: "heimdall",
 1151                table: "password_reset_token",
 1152                type: "character varying(256)",
 1153                maxLength: 256,
 1154                nullable: false,
 1155                defaultValue: "");
 156
 1157            migrationBuilder.AddColumn<string>(
 1158                name: "token",
 1159                schema: "heimdall",
 1160                table: "email_verification_token",
 1161                type: "character varying(256)",
 1162                maxLength: 256,
 1163                nullable: false,
 1164                defaultValue: "");
 165
 1166            migrationBuilder.CreateIndex(
 1167                name: "ix_password_reset_token_token",
 1168                schema: "heimdall",
 1169                table: "password_reset_token",
 1170                column: "token",
 1171                unique: true);
 172
 1173            migrationBuilder.CreateIndex(
 1174                name: "ix_email_verification_token_token",
 1175                schema: "heimdall",
 1176                table: "email_verification_token",
 1177                column: "token",
 1178                unique: true);
 1179        }
 180    }
 181}

/home/ci/agent/workspace/heimdall-api-docs_main/app/src/Infrastructure/ArturRios.Heimdall.Data/Migrations/20260814232813_HashSingleUseTokens.Designer.cs

#LineLine coverage
 1// <auto-generated />
 2using System;
 3using ArturRios.Heimdall.Data.Configuration;
 4using Microsoft.EntityFrameworkCore;
 5using Microsoft.EntityFrameworkCore.Infrastructure;
 6using Microsoft.EntityFrameworkCore.Migrations;
 7using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
 8using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
 9
 10#nullable disable
 11
 12namespace ArturRios.Heimdall.Data.Migrations
 13{
 14    [DbContext(typeof(AppDbContext))]
 15    [Migration("20260814232813_HashSingleUseTokens")]
 16    partial class HashSingleUseTokens
 17    {
 18        /// <inheritdoc />
 19        protected override void BuildTargetModel(ModelBuilder modelBuilder)
 20        {
 21#pragma warning disable 612, 618
 1022            modelBuilder
 1023                .HasDefaultSchema("heimdall")
 1024                .HasAnnotation("ProductVersion", "10.0.11")
 1025                .HasAnnotation("Relational:MaxIdentifierLength", 63);
 26
 1027            NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
 28
 1029            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.Application", b =>
 1030                {
 1031                    b.Property<long>("Id")
 1032                        .ValueGeneratedOnAdd()
 1033                        .HasColumnType("bigint")
 1034                        .HasColumnName("id")
 1035                        .HasColumnOrder(1);
 1036
 1037                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
 1038
 1039                    b.Property<DateTime>("CreatedAt")
 1040                        .ValueGeneratedOnAdd()
 1041                        .HasColumnType("timestamp with time zone")
 1042                        .HasColumnName("created_at")
 1043                        .HasDefaultValueSql("now()");
 1044
 1045                    b.Property<bool>("IsDeleted")
 1046                        .ValueGeneratedOnAdd()
 1047                        .HasColumnType("boolean")
 1048                        .HasDefaultValue(false)
 1049                        .HasColumnName("is_deleted");
 1050
 1051                    b.Property<string>("Name")
 1052                        .IsRequired()
 1053                        .HasMaxLength(200)
 1054                        .HasColumnType("character varying(200)")
 1055                        .HasColumnName("name");
 1056
 1057                    b.Property<long>("OwnerId")
 1058                        .HasColumnType("bigint")
 1059                        .HasColumnName("owner_id");
 1060
 1061                    b.Property<Guid>("PublicId")
 1062                        .HasColumnType("uuid")
 1063                        .HasColumnName("public_id");
 1064
 1065                    b.Property<long>("ScopeId")
 1066                        .HasColumnType("bigint")
 1067                        .HasColumnName("scope_id");
 1068
 1069                    b.Property<DateTime>("UpdatedAt")
 1070                        .ValueGeneratedOnAdd()
 1071                        .HasColumnType("timestamp with time zone")
 1072                        .HasColumnName("updated_at")
 1073                        .HasDefaultValueSql("now()");
 1074
 1075                    b.HasKey("Id")
 1076                        .HasName("pk_application");
 1077
 1078                    b.HasIndex("OwnerId")
 1079                        .HasDatabaseName("ix_application_owner_id");
 1080
 1081                    b.HasIndex("PublicId")
 1082                        .IsUnique()
 1083                        .HasDatabaseName("ix_application_public_id");
 1084
 1085                    b.HasIndex("ScopeId")
 1086                        .HasDatabaseName("ix_application_scope_id");
 1087
 1088                    b.ToTable("application", "heimdall");
 2089                });
 90
 1091            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.AuditLog", b =>
 1092                {
 1093                    b.Property<long>("Id")
 1094                        .ValueGeneratedOnAdd()
 1095                        .HasColumnType("bigint")
 1096                        .HasColumnName("id")
 1097                        .HasColumnOrder(1);
 1098
 1099                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
 10100
 10101                    b.Property<string>("Action")
 10102                        .IsRequired()
 10103                        .HasMaxLength(200)
 10104                        .HasColumnType("character varying(200)")
 10105                        .HasColumnName("action");
 10106
 10107                    b.Property<Guid?>("ActorPersonId")
 10108                        .HasColumnType("uuid")
 10109                        .HasColumnName("actor_person_id");
 10110
 10111                    b.Property<int?>("ActorRole")
 10112                        .HasColumnType("integer")
 10113                        .HasColumnName("actor_role");
 10114
 10115                    b.Property<DateTime>("CreatedAt")
 10116                        .ValueGeneratedOnAdd()
 10117                        .HasColumnType("timestamp with time zone")
 10118                        .HasColumnName("created_at")
 10119                        .HasDefaultValueSql("now()");
 10120
 10121                    b.Property<string>("FailureReason")
 10122                        .HasMaxLength(500)
 10123                        .HasColumnType("character varying(500)")
 10124                        .HasColumnName("failure_reason");
 10125
 10126                    b.Property<Guid>("PublicId")
 10127                        .HasColumnType("uuid")
 10128                        .HasColumnName("public_id");
 10129
 10130                    b.Property<bool>("Succeeded")
 10131                        .HasColumnType("boolean")
 10132                        .HasColumnName("succeeded");
 10133
 10134                    b.Property<Guid?>("TargetId")
 10135                        .HasColumnType("uuid")
 10136                        .HasColumnName("target_id");
 10137
 10138                    b.HasKey("Id")
 10139                        .HasName("pk_audit_log");
 10140
 10141                    b.HasIndex("ActorPersonId")
 10142                        .HasDatabaseName("ix_audit_log_actor_person_id");
 10143
 10144                    b.HasIndex("CreatedAt")
 10145                        .HasDatabaseName("ix_audit_log_created_at");
 10146
 10147                    b.HasIndex("PublicId")
 10148                        .IsUnique()
 10149                        .HasDatabaseName("ix_audit_log_public_id");
 10150
 10151                    b.ToTable("audit_log", "heimdall");
 20152                });
 153
 10154            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.EmailVerificationToken", b =>
 10155                {
 10156                    b.Property<long>("Id")
 10157                        .ValueGeneratedOnAdd()
 10158                        .HasColumnType("bigint")
 10159                        .HasColumnName("id")
 10160                        .HasColumnOrder(1);
 10161
 10162                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
 10163
 10164                    b.Property<DateTime>("ExpiresAt")
 10165                        .HasColumnType("timestamp with time zone")
 10166                        .HasColumnName("expires_at");
 10167
 10168                    b.Property<long>("PersonId")
 10169                        .HasColumnType("bigint")
 10170                        .HasColumnName("person_id");
 10171
 10172                    b.Property<string>("TokenHash")
 10173                        .IsRequired()
 10174                        .HasMaxLength(64)
 10175                        .HasColumnType("character varying(64)")
 10176                        .HasColumnName("token_hash");
 10177
 10178                    b.Property<bool>("Used")
 10179                        .ValueGeneratedOnAdd()
 10180                        .HasColumnType("boolean")
 10181                        .HasDefaultValue(false)
 10182                        .HasColumnName("used");
 10183
 10184                    b.HasKey("Id")
 10185                        .HasName("pk_email_verification_token");
 10186
 10187                    b.HasIndex("PersonId")
 10188                        .HasDatabaseName("ix_email_verification_token_person_id");
 10189
 10190                    b.HasIndex("TokenHash")
 10191                        .IsUnique()
 10192                        .HasDatabaseName("ix_email_verification_token_token_hash");
 10193
 10194                    b.ToTable("email_verification_token", "heimdall");
 20195                });
 196
 10197            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.GoogleUser", b =>
 10198                {
 10199                    b.Property<long>("Id")
 10200                        .ValueGeneratedOnAdd()
 10201                        .HasColumnType("bigint")
 10202                        .HasColumnName("id")
 10203                        .HasColumnOrder(1);
 10204
 10205                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
 10206
 10207                    b.Property<DateTime>("CreatedAt")
 10208                        .ValueGeneratedOnAdd()
 10209                        .HasColumnType("timestamp with time zone")
 10210                        .HasColumnName("created_at")
 10211                        .HasDefaultValueSql("now()");
 10212
 10213                    b.Property<string>("Email")
 10214                        .IsRequired()
 10215                        .HasMaxLength(256)
 10216                        .HasColumnType("character varying(256)")
 10217                        .HasColumnName("email");
 10218
 10219                    b.Property<bool>("EmailVerified")
 10220                        .ValueGeneratedOnAdd()
 10221                        .HasColumnType("boolean")
 10222                        .HasDefaultValue(false)
 10223                        .HasColumnName("email_verified");
 10224
 10225                    b.Property<string>("GoogleId")
 10226                        .IsRequired()
 10227                        .HasMaxLength(255)
 10228                        .HasColumnType("character varying(255)")
 10229                        .HasColumnName("google_id");
 10230
 10231                    b.Property<bool>("IsDeleted")
 10232                        .ValueGeneratedOnAdd()
 10233                        .HasColumnType("boolean")
 10234                        .HasDefaultValue(false)
 10235                        .HasColumnName("is_deleted");
 10236
 10237                    b.Property<string>("Name")
 10238                        .IsRequired()
 10239                        .HasMaxLength(200)
 10240                        .HasColumnType("character varying(200)")
 10241                        .HasColumnName("name");
 10242
 10243                    b.Property<string>("ProfilePictureUrl")
 10244                        .HasMaxLength(2048)
 10245                        .HasColumnType("character varying(2048)")
 10246                        .HasColumnName("profile_picture_url");
 10247
 10248                    b.Property<Guid>("PublicId")
 10249                        .HasColumnType("uuid")
 10250                        .HasColumnName("public_id");
 10251
 10252                    b.Property<long>("ScopeId")
 10253                        .HasColumnType("bigint")
 10254                        .HasColumnName("scope_id");
 10255
 10256                    b.Property<DateTime>("UpdatedAt")
 10257                        .ValueGeneratedOnAdd()
 10258                        .HasColumnType("timestamp with time zone")
 10259                        .HasColumnName("updated_at")
 10260                        .HasDefaultValueSql("now()");
 10261
 10262                    b.HasKey("Id")
 10263                        .HasName("pk_google_user");
 10264
 10265                    b.HasIndex("PublicId")
 10266                        .IsUnique()
 10267                        .HasDatabaseName("ix_google_user_public_id");
 10268
 10269                    b.HasIndex("ScopeId", "Email")
 10270                        .IsUnique()
 10271                        .HasDatabaseName("ix_google_user_scope_id_email");
 10272
 10273                    b.HasIndex("ScopeId", "GoogleId")
 10274                        .IsUnique()
 10275                        .HasDatabaseName("ix_google_user_scope_id_google_id");
 10276
 10277                    b.ToTable("google_user", "heimdall");
 20278                });
 279
 10280            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.PasswordResetToken", b =>
 10281                {
 10282                    b.Property<long>("Id")
 10283                        .ValueGeneratedOnAdd()
 10284                        .HasColumnType("bigint")
 10285                        .HasColumnName("id")
 10286                        .HasColumnOrder(1);
 10287
 10288                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
 10289
 10290                    b.Property<DateTime>("ExpiresAt")
 10291                        .HasColumnType("timestamp with time zone")
 10292                        .HasColumnName("expires_at");
 10293
 10294                    b.Property<long>("PersonId")
 10295                        .HasColumnType("bigint")
 10296                        .HasColumnName("person_id");
 10297
 10298                    b.Property<string>("TokenHash")
 10299                        .IsRequired()
 10300                        .HasMaxLength(64)
 10301                        .HasColumnType("character varying(64)")
 10302                        .HasColumnName("token_hash");
 10303
 10304                    b.Property<bool>("Used")
 10305                        .ValueGeneratedOnAdd()
 10306                        .HasColumnType("boolean")
 10307                        .HasDefaultValue(false)
 10308                        .HasColumnName("used");
 10309
 10310                    b.HasKey("Id")
 10311                        .HasName("pk_password_reset_token");
 10312
 10313                    b.HasIndex("PersonId")
 10314                        .HasDatabaseName("ix_password_reset_token_person_id");
 10315
 10316                    b.HasIndex("TokenHash")
 10317                        .IsUnique()
 10318                        .HasDatabaseName("ix_password_reset_token_token_hash");
 10319
 10320                    b.ToTable("password_reset_token", "heimdall");
 20321                });
 322
 10323            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.Person", b =>
 10324                {
 10325                    b.Property<long>("Id")
 10326                        .ValueGeneratedOnAdd()
 10327                        .HasColumnType("bigint")
 10328                        .HasColumnName("id")
 10329                        .HasColumnOrder(1);
 10330
 10331                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
 10332
 10333                    b.Property<DateTime>("CreatedAt")
 10334                        .ValueGeneratedOnAdd()
 10335                        .HasColumnType("timestamp with time zone")
 10336                        .HasColumnName("created_at")
 10337                        .HasDefaultValueSql("now()");
 10338
 10339                    b.Property<string>("Email")
 10340                        .IsRequired()
 10341                        .HasMaxLength(256)
 10342                        .HasColumnType("character varying(256)")
 10343                        .HasColumnName("email");
 10344
 10345                    b.Property<bool>("EmailVerified")
 10346                        .ValueGeneratedOnAdd()
 10347                        .HasColumnType("boolean")
 10348                        .HasDefaultValue(false)
 10349                        .HasColumnName("email_verified");
 10350
 10351                    b.Property<int>("FailedLoginAttempts")
 10352                        .HasColumnType("integer")
 10353                        .HasColumnName("failed_login_attempts");
 10354
 10355                    b.Property<bool>("IsDeleted")
 10356                        .ValueGeneratedOnAdd()
 10357                        .HasColumnType("boolean")
 10358                        .HasDefaultValue(false)
 10359                        .HasColumnName("is_deleted");
 10360
 10361                    b.Property<DateTime?>("LockedOutUntil")
 10362                        .HasColumnType("timestamp with time zone")
 10363                        .HasColumnName("locked_out_until");
 10364
 10365                    b.Property<string>("Name")
 10366                        .IsRequired()
 10367                        .HasMaxLength(200)
 10368                        .HasColumnType("character varying(200)")
 10369                        .HasColumnName("name");
 10370
 10371                    b.Property<byte[]>("PasswordHash")
 10372                        .IsRequired()
 10373                        .HasColumnType("bytea")
 10374                        .HasColumnName("password_hash");
 10375
 10376                    b.Property<Guid>("PublicId")
 10377                        .HasColumnType("uuid")
 10378                        .HasColumnName("public_id");
 10379
 10380                    b.Property<long>("RoleId")
 10381                        .HasColumnType("bigint")
 10382                        .HasColumnName("role_id");
 10383
 10384                    b.Property<byte[]>("Salt")
 10385                        .IsRequired()
 10386                        .HasColumnType("bytea")
 10387                        .HasColumnName("salt");
 10388
 10389                    b.Property<long?>("ScopeId")
 10390                        .HasColumnType("bigint")
 10391                        .HasColumnName("scope_id");
 10392
 10393                    b.Property<DateTime>("UpdatedAt")
 10394                        .ValueGeneratedOnAdd()
 10395                        .HasColumnType("timestamp with time zone")
 10396                        .HasColumnName("updated_at")
 10397                        .HasDefaultValueSql("now()");
 10398
 10399                    b.HasKey("Id")
 10400                        .HasName("pk_person");
 10401
 10402                    b.HasIndex("Email")
 10403                        .HasDatabaseName("ix_person_email");
 10404
 10405                    b.HasIndex("PublicId")
 10406                        .IsUnique()
 10407                        .HasDatabaseName("ix_person_public_id");
 10408
 10409                    b.HasIndex("RoleId")
 10410                        .HasDatabaseName("ix_person_role_id");
 10411
 10412                    b.ToTable("person", "heimdall");
 20413                });
 414
 10415            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.Role", b =>
 10416                {
 10417                    b.Property<long>("Id")
 10418                        .HasColumnType("bigint")
 10419                        .HasColumnName("id")
 10420                        .HasColumnOrder(1);
 10421
 10422                    b.Property<string>("Description")
 10423                        .HasMaxLength(500)
 10424                        .HasColumnType("character varying(500)")
 10425                        .HasColumnName("description");
 10426
 10427                    b.Property<string>("Name")
 10428                        .IsRequired()
 10429                        .HasMaxLength(200)
 10430                        .HasColumnType("character varying(200)")
 10431                        .HasColumnName("name");
 10432
 10433                    b.Property<Guid>("PublicId")
 10434                        .HasColumnType("uuid")
 10435                        .HasColumnName("public_id");
 10436
 10437                    b.HasKey("Id")
 10438                        .HasName("pk_role");
 10439
 10440                    b.HasIndex("Name")
 10441                        .IsUnique()
 10442                        .HasDatabaseName("ix_role_name");
 10443
 10444                    b.HasIndex("PublicId")
 10445                        .IsUnique()
 10446                        .HasDatabaseName("ix_role_public_id");
 10447
 10448                    b.ToTable("role", "heimdall");
 20449                });
 450
 10451            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.Scope", b =>
 10452                {
 10453                    b.Property<long>("Id")
 10454                        .ValueGeneratedOnAdd()
 10455                        .HasColumnType("bigint")
 10456                        .HasColumnName("id")
 10457                        .HasColumnOrder(1);
 10458
 10459                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
 10460
 10461                    b.Property<DateTime>("CreatedAt")
 10462                        .ValueGeneratedOnAdd()
 10463                        .HasColumnType("timestamp with time zone")
 10464                        .HasColumnName("created_at")
 10465                        .HasDefaultValueSql("now()");
 10466
 10467                    b.Property<string>("Description")
 10468                        .HasMaxLength(500)
 10469                        .HasColumnType("character varying(500)")
 10470                        .HasColumnName("description");
 10471
 10472                    b.Property<bool>("GoogleSignInEnabled")
 10473                        .ValueGeneratedOnAdd()
 10474                        .HasColumnType("boolean")
 10475                        .HasDefaultValue(false)
 10476                        .HasColumnName("google_sign_in_enabled");
 10477
 10478                    b.Property<bool>("IsDeleted")
 10479                        .ValueGeneratedOnAdd()
 10480                        .HasColumnType("boolean")
 10481                        .HasDefaultValue(false)
 10482                        .HasColumnName("is_deleted");
 10483
 10484                    b.Property<string>("Name")
 10485                        .IsRequired()
 10486                        .HasMaxLength(200)
 10487                        .HasColumnType("character varying(200)")
 10488                        .HasColumnName("name");
 10489
 10490                    b.Property<Guid>("PublicId")
 10491                        .HasColumnType("uuid")
 10492                        .HasColumnName("public_id");
 10493
 10494                    b.Property<DateTime>("UpdatedAt")
 10495                        .ValueGeneratedOnAdd()
 10496                        .HasColumnType("timestamp with time zone")
 10497                        .HasColumnName("updated_at")
 10498                        .HasDefaultValueSql("now()");
 10499
 10500                    b.HasKey("Id")
 10501                        .HasName("pk_scope");
 10502
 10503                    b.HasIndex("Name")
 10504                        .IsUnique()
 10505                        .HasDatabaseName("ix_scope_name");
 10506
 10507                    b.HasIndex("PublicId")
 10508                        .IsUnique()
 10509                        .HasDatabaseName("ix_scope_public_id");
 10510
 10511                    b.ToTable("scope", "heimdall");
 20512                });
 513
 10514            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.ScopeOwner", b =>
 10515                {
 10516                    b.Property<long>("ScopeId")
 10517                        .HasColumnType("bigint")
 10518                        .HasColumnName("scope_id");
 10519
 10520                    b.Property<long>("PersonId")
 10521                        .HasColumnType("bigint")
 10522                        .HasColumnName("person_id");
 10523
 10524                    b.HasKey("ScopeId", "PersonId")
 10525                        .HasName("pk_scope_owner");
 10526
 10527                    b.HasIndex("PersonId")
 10528                        .HasDatabaseName("ix_scope_owner_person_id");
 10529
 10530                    b.ToTable("scope_owner", "heimdall");
 20531                });
 532
 10533            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.ScopePermission", b =>
 10534                {
 10535                    b.Property<long>("Id")
 10536                        .ValueGeneratedOnAdd()
 10537                        .HasColumnType("bigint")
 10538                        .HasColumnName("id")
 10539                        .HasColumnOrder(1);
 10540
 10541                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
 10542
 10543                    b.Property<DateTime>("CreatedAt")
 10544                        .ValueGeneratedOnAdd()
 10545                        .HasColumnType("timestamp with time zone")
 10546                        .HasColumnName("created_at")
 10547                        .HasDefaultValueSql("now()");
 10548
 10549                    b.Property<string>("Description")
 10550                        .HasMaxLength(500)
 10551                        .HasColumnType("character varying(500)")
 10552                        .HasColumnName("description");
 10553
 10554                    b.Property<bool>("IncludeAsJwtClaim")
 10555                        .ValueGeneratedOnAdd()
 10556                        .HasColumnType("boolean")
 10557                        .HasDefaultValue(false)
 10558                        .HasColumnName("include_as_jwt_claim");
 10559
 10560                    b.Property<bool>("IsDeleted")
 10561                        .ValueGeneratedOnAdd()
 10562                        .HasColumnType("boolean")
 10563                        .HasDefaultValue(false)
 10564                        .HasColumnName("is_deleted");
 10565
 10566                    b.Property<string>("Name")
 10567                        .IsRequired()
 10568                        .HasMaxLength(200)
 10569                        .HasColumnType("character varying(200)")
 10570                        .HasColumnName("name");
 10571
 10572                    b.Property<Guid>("PublicId")
 10573                        .HasColumnType("uuid")
 10574                        .HasColumnName("public_id");
 10575
 10576                    b.Property<long>("ScopeId")
 10577                        .HasColumnType("bigint")
 10578                        .HasColumnName("scope_id");
 10579
 10580                    b.Property<DateTime>("UpdatedAt")
 10581                        .ValueGeneratedOnAdd()
 10582                        .HasColumnType("timestamp with time zone")
 10583                        .HasColumnName("updated_at")
 10584                        .HasDefaultValueSql("now()");
 10585
 10586                    b.HasKey("Id")
 10587                        .HasName("pk_scope_permission");
 10588
 10589                    b.HasIndex("PublicId")
 10590                        .IsUnique()
 10591                        .HasDatabaseName("ix_scope_permission_public_id");
 10592
 10593                    b.HasIndex("ScopeId")
 10594                        .HasDatabaseName("ix_scope_permission_scope_id");
 10595
 10596                    b.ToTable("scope_permission", "heimdall");
 20597                });
 598
 10599            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.ScopeUser", b =>
 10600                {
 10601                    b.Property<long>("ScopeId")
 10602                        .HasColumnType("bigint")
 10603                        .HasColumnName("scope_id");
 10604
 10605                    b.Property<long>("PersonId")
 10606                        .HasColumnType("bigint")
 10607                        .HasColumnName("person_id");
 10608
 10609                    b.HasKey("ScopeId", "PersonId")
 10610                        .HasName("pk_scope_user");
 10611
 10612                    b.HasIndex("PersonId")
 10613                        .IsUnique()
 10614                        .HasDatabaseName("ix_scope_user_person_id");
 10615
 10616                    b.ToTable("scope_user", "heimdall");
 20617                });
 618
 10619            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.TwoFactorAuth", b =>
 10620                {
 10621                    b.Property<long>("Id")
 10622                        .ValueGeneratedOnAdd()
 10623                        .HasColumnType("bigint")
 10624                        .HasColumnName("id")
 10625                        .HasColumnOrder(1);
 10626
 10627                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
 10628
 10629                    b.Property<bool>("AppEnabled")
 10630                        .ValueGeneratedOnAdd()
 10631                        .HasColumnType("boolean")
 10632                        .HasDefaultValue(false)
 10633                        .HasColumnName("app_enabled");
 10634
 10635                    b.Property<DateTime>("CreatedAt")
 10636                        .ValueGeneratedOnAdd()
 10637                        .HasColumnType("timestamp with time zone")
 10638                        .HasColumnName("created_at")
 10639                        .HasDefaultValueSql("now()");
 10640
 10641                    b.Property<bool>("EmailEnabled")
 10642                        .ValueGeneratedOnAdd()
 10643                        .HasColumnType("boolean")
 10644                        .HasDefaultValue(false)
 10645                        .HasColumnName("email_enabled");
 10646
 10647                    b.Property<bool>("IsActive")
 10648                        .ValueGeneratedOnAdd()
 10649                        .HasColumnType("boolean")
 10650                        .HasDefaultValue(false)
 10651                        .HasColumnName("is_active");
 10652
 10653                    b.Property<long?>("LastTotpTimeStepUsed")
 10654                        .HasColumnType("bigint")
 10655                        .HasColumnName("last_totp_time_step_used");
 10656
 10657                    b.Property<long>("PersonId")
 10658                        .HasColumnType("bigint")
 10659                        .HasColumnName("person_id");
 10660
 10661                    b.Property<byte[]>("TotpSecretEncrypted")
 10662                        .HasColumnType("bytea")
 10663                        .HasColumnName("totp_secret_encrypted");
 10664
 10665                    b.Property<DateTime>("UpdatedAt")
 10666                        .ValueGeneratedOnAdd()
 10667                        .HasColumnType("timestamp with time zone")
 10668                        .HasColumnName("updated_at")
 10669                        .HasDefaultValueSql("now()");
 10670
 10671                    b.HasKey("Id")
 10672                        .HasName("pk_two_factor_auth");
 10673
 10674                    b.HasIndex("PersonId")
 10675                        .IsUnique()
 10676                        .HasDatabaseName("ix_two_factor_auth_person_id");
 10677
 10678                    b.ToTable("two_factor_auth", "heimdall");
 20679                });
 680
 10681            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.TwoFactorEmailCode", b =>
 10682                {
 10683                    b.Property<long>("Id")
 10684                        .ValueGeneratedOnAdd()
 10685                        .HasColumnType("bigint")
 10686                        .HasColumnName("id")
 10687                        .HasColumnOrder(1);
 10688
 10689                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
 10690
 10691                    b.Property<byte[]>("CodeHash")
 10692                        .IsRequired()
 10693                        .HasColumnType("bytea")
 10694                        .HasColumnName("code_hash");
 10695
 10696                    b.Property<DateTime>("CreatedAt")
 10697                        .ValueGeneratedOnAdd()
 10698                        .HasColumnType("timestamp with time zone")
 10699                        .HasColumnName("created_at")
 10700                        .HasDefaultValueSql("now()");
 10701
 10702                    b.Property<DateTime>("ExpiresAt")
 10703                        .HasColumnType("timestamp with time zone")
 10704                        .HasColumnName("expires_at");
 10705
 10706                    b.Property<int>("FailedAttempts")
 10707                        .HasColumnType("integer")
 10708                        .HasColumnName("failed_attempts");
 10709
 10710                    b.Property<byte[]>("Salt")
 10711                        .IsRequired()
 10712                        .HasColumnType("bytea")
 10713                        .HasColumnName("salt");
 10714
 10715                    b.Property<long>("TwoFactorAuthId")
 10716                        .HasColumnType("bigint")
 10717                        .HasColumnName("two_factor_auth_id");
 10718
 10719                    b.Property<bool>("Used")
 10720                        .ValueGeneratedOnAdd()
 10721                        .HasColumnType("boolean")
 10722                        .HasDefaultValue(false)
 10723                        .HasColumnName("used");
 10724
 10725                    b.HasKey("Id")
 10726                        .HasName("pk_two_factor_email_code");
 10727
 10728                    b.HasIndex("TwoFactorAuthId")
 10729                        .HasDatabaseName("ix_two_factor_email_code_two_factor_auth_id");
 10730
 10731                    b.ToTable("two_factor_email_code", "heimdall");
 20732                });
 733
 10734            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.TwoFactorRecoveryCode", b =>
 10735                {
 10736                    b.Property<long>("Id")
 10737                        .ValueGeneratedOnAdd()
 10738                        .HasColumnType("bigint")
 10739                        .HasColumnName("id")
 10740                        .HasColumnOrder(1);
 10741
 10742                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
 10743
 10744                    b.Property<byte[]>("CodeHash")
 10745                        .IsRequired()
 10746                        .HasColumnType("bytea")
 10747                        .HasColumnName("code_hash");
 10748
 10749                    b.Property<DateTime>("CreatedAt")
 10750                        .ValueGeneratedOnAdd()
 10751                        .HasColumnType("timestamp with time zone")
 10752                        .HasColumnName("created_at")
 10753                        .HasDefaultValueSql("now()");
 10754
 10755                    b.Property<long>("TwoFactorAuthId")
 10756                        .HasColumnType("bigint")
 10757                        .HasColumnName("two_factor_auth_id");
 10758
 10759                    b.Property<bool>("Used")
 10760                        .ValueGeneratedOnAdd()
 10761                        .HasColumnType("boolean")
 10762                        .HasDefaultValue(false)
 10763                        .HasColumnName("used");
 10764
 10765                    b.Property<DateTime?>("UsedAt")
 10766                        .HasColumnType("timestamp with time zone")
 10767                        .HasColumnName("used_at");
 10768
 10769                    b.HasKey("Id")
 10770                        .HasName("pk_two_factor_recovery_code");
 10771
 10772                    b.HasIndex("TwoFactorAuthId")
 10773                        .HasDatabaseName("ix_two_factor_recovery_code_two_factor_auth_id");
 10774
 10775                    b.ToTable("two_factor_recovery_code", "heimdall");
 20776                });
 777
 10778            modelBuilder.Entity("Microsoft.AspNetCore.DataProtection.EntityFrameworkCore.DataProtectionKey", b =>
 10779                {
 10780                    b.Property<int>("Id")
 10781                        .ValueGeneratedOnAdd()
 10782                        .HasColumnType("integer")
 10783                        .HasColumnName("id");
 10784
 10785                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
 10786
 10787                    b.Property<string>("FriendlyName")
 10788                        .HasColumnType("text")
 10789                        .HasColumnName("friendly_name");
 10790
 10791                    b.Property<string>("Xml")
 10792                        .HasColumnType("text")
 10793                        .HasColumnName("xml");
 10794
 10795                    b.HasKey("Id")
 10796                        .HasName("pk_data_protection_keys");
 10797
 10798                    b.ToTable("data_protection_keys", "heimdall");
 20799                });
 800
 10801            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.Application", b =>
 10802                {
 10803                    b.HasOne("ArturRios.Heimdall.Domain.Entities.Person", "Owner")
 10804                        .WithMany("OwnedApplications")
 10805                        .HasForeignKey("OwnerId")
 10806                        .OnDelete(DeleteBehavior.Cascade)
 10807                        .IsRequired()
 10808                        .HasConstraintName("fk_application_person_owner_id");
 10809
 10810                    b.HasOne("ArturRios.Heimdall.Domain.Entities.Scope", "Scope")
 10811                        .WithMany("Applications")
 10812                        .HasForeignKey("ScopeId")
 10813                        .OnDelete(DeleteBehavior.Cascade)
 10814                        .IsRequired()
 10815                        .HasConstraintName("fk_application_scope_scope_id");
 10816
 10817                    b.Navigation("Owner");
 10818
 10819                    b.Navigation("Scope");
 20820                });
 821
 10822            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.EmailVerificationToken", b =>
 10823                {
 10824                    b.HasOne("ArturRios.Heimdall.Domain.Entities.Person", "Person")
 10825                        .WithMany("EmailVerificationTokens")
 10826                        .HasForeignKey("PersonId")
 10827                        .OnDelete(DeleteBehavior.Cascade)
 10828                        .IsRequired()
 10829                        .HasConstraintName("fk_email_verification_token_person_person_id");
 10830
 10831                    b.Navigation("Person");
 20832                });
 833
 10834            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.GoogleUser", b =>
 10835                {
 10836                    b.HasOne("ArturRios.Heimdall.Domain.Entities.Scope", "Scope")
 10837                        .WithMany("GoogleUsers")
 10838                        .HasForeignKey("ScopeId")
 10839                        .OnDelete(DeleteBehavior.Cascade)
 10840                        .IsRequired()
 10841                        .HasConstraintName("fk_google_user_scope_scope_id");
 10842
 10843                    b.Navigation("Scope");
 20844                });
 845
 10846            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.PasswordResetToken", b =>
 10847                {
 10848                    b.HasOne("ArturRios.Heimdall.Domain.Entities.Person", "Person")
 10849                        .WithMany("PasswordResetTokens")
 10850                        .HasForeignKey("PersonId")
 10851                        .OnDelete(DeleteBehavior.Cascade)
 10852                        .IsRequired()
 10853                        .HasConstraintName("fk_password_reset_token_person_person_id");
 10854
 10855                    b.Navigation("Person");
 20856                });
 857
 10858            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.Person", b =>
 10859                {
 10860                    b.HasOne("ArturRios.Heimdall.Domain.Entities.Role", "Role")
 10861                        .WithMany("Persons")
 10862                        .HasForeignKey("RoleId")
 10863                        .OnDelete(DeleteBehavior.Restrict)
 10864                        .IsRequired()
 10865                        .HasConstraintName("fk_person_roles_role_id");
 10866
 10867                    b.Navigation("Role");
 20868                });
 869
 10870            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.ScopeOwner", b =>
 10871                {
 10872                    b.HasOne("ArturRios.Heimdall.Domain.Entities.Person", "Person")
 10873                        .WithMany("ScopeOwnerships")
 10874                        .HasForeignKey("PersonId")
 10875                        .OnDelete(DeleteBehavior.Cascade)
 10876                        .IsRequired()
 10877                        .HasConstraintName("fk_scope_owner_person_person_id");
 10878
 10879                    b.HasOne("ArturRios.Heimdall.Domain.Entities.Scope", "Scope")
 10880                        .WithMany("Owners")
 10881                        .HasForeignKey("ScopeId")
 10882                        .OnDelete(DeleteBehavior.Cascade)
 10883                        .IsRequired()
 10884                        .HasConstraintName("fk_scope_owner_scope_scope_id");
 10885
 10886                    b.Navigation("Person");
 10887
 10888                    b.Navigation("Scope");
 20889                });
 890
 10891            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.ScopePermission", b =>
 10892                {
 10893                    b.HasOne("ArturRios.Heimdall.Domain.Entities.Scope", "Scope")
 10894                        .WithMany("ScopePermissions")
 10895                        .HasForeignKey("ScopeId")
 10896                        .OnDelete(DeleteBehavior.Cascade)
 10897                        .IsRequired()
 10898                        .HasConstraintName("fk_scope_permission_scope_scope_id");
 10899
 10900                    b.Navigation("Scope");
 20901                });
 902
 10903            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.ScopeUser", b =>
 10904                {
 10905                    b.HasOne("ArturRios.Heimdall.Domain.Entities.Person", "Person")
 10906                        .WithOne("ScopeMembership")
 10907                        .HasForeignKey("ArturRios.Heimdall.Domain.Entities.ScopeUser", "PersonId")
 10908                        .OnDelete(DeleteBehavior.Cascade)
 10909                        .IsRequired()
 10910                        .HasConstraintName("fk_scope_user_person_person_id");
 10911
 10912                    b.HasOne("ArturRios.Heimdall.Domain.Entities.Scope", "Scope")
 10913                        .WithMany("Users")
 10914                        .HasForeignKey("ScopeId")
 10915                        .OnDelete(DeleteBehavior.Cascade)
 10916                        .IsRequired()
 10917                        .HasConstraintName("fk_scope_user_scope_scope_id");
 10918
 10919                    b.Navigation("Person");
 10920
 10921                    b.Navigation("Scope");
 20922                });
 923
 10924            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.TwoFactorAuth", b =>
 10925                {
 10926                    b.HasOne("ArturRios.Heimdall.Domain.Entities.Person", "Person")
 10927                        .WithOne("TwoFactorAuth")
 10928                        .HasForeignKey("ArturRios.Heimdall.Domain.Entities.TwoFactorAuth", "PersonId")
 10929                        .OnDelete(DeleteBehavior.Cascade)
 10930                        .IsRequired()
 10931                        .HasConstraintName("fk_two_factor_auth_person_person_id");
 10932
 10933                    b.Navigation("Person");
 20934                });
 935
 10936            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.TwoFactorEmailCode", b =>
 10937                {
 10938                    b.HasOne("ArturRios.Heimdall.Domain.Entities.TwoFactorAuth", "TwoFactorAuth")
 10939                        .WithMany("EmailCodes")
 10940                        .HasForeignKey("TwoFactorAuthId")
 10941                        .OnDelete(DeleteBehavior.Cascade)
 10942                        .IsRequired()
 10943                        .HasConstraintName("fk_two_factor_email_code_two_factor_auth_two_factor_auth_id");
 10944
 10945                    b.Navigation("TwoFactorAuth");
 20946                });
 947
 10948            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.TwoFactorRecoveryCode", b =>
 10949                {
 10950                    b.HasOne("ArturRios.Heimdall.Domain.Entities.TwoFactorAuth", "TwoFactorAuth")
 10951                        .WithMany("RecoveryCodes")
 10952                        .HasForeignKey("TwoFactorAuthId")
 10953                        .OnDelete(DeleteBehavior.Cascade)
 10954                        .IsRequired()
 10955                        .HasConstraintName("fk_two_factor_recovery_code_two_factor_auth_two_factor_auth_id");
 10956
 10957                    b.Navigation("TwoFactorAuth");
 20958                });
 959
 10960            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.Person", b =>
 10961                {
 10962                    b.Navigation("EmailVerificationTokens");
 10963
 10964                    b.Navigation("OwnedApplications");
 10965
 10966                    b.Navigation("PasswordResetTokens");
 10967
 10968                    b.Navigation("ScopeMembership");
 10969
 10970                    b.Navigation("ScopeOwnerships");
 10971
 10972                    b.Navigation("TwoFactorAuth");
 20973                });
 974
 10975            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.Role", b =>
 10976                {
 10977                    b.Navigation("Persons");
 20978                });
 979
 10980            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.Scope", b =>
 10981                {
 10982                    b.Navigation("Applications");
 10983
 10984                    b.Navigation("GoogleUsers");
 10985
 10986                    b.Navigation("Owners");
 10987
 10988                    b.Navigation("ScopePermissions");
 10989
 10990                    b.Navigation("Users");
 20991                });
 992
 10993            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.TwoFactorAuth", b =>
 10994                {
 10995                    b.Navigation("EmailCodes");
 10996
 10997                    b.Navigation("RecoveryCodes");
 20998                });
 999#pragma warning restore 612, 618
 101000        }
 1001    }
 1002}