Fix startup admin seeding connection scope

This commit is contained in:
2026-04-11 18:27:33 +02:00
parent 48cd83b442
commit fcccecefa3
2 changed files with 20 additions and 12 deletions
+5 -1
View File
@@ -75,7 +75,11 @@ builder.Services.AddDbContext<JobTrackerContext>((sp, options) =>
// We create Identity tables on startup in environments where `dotnet ef` isn't available.
// That can cause EF to detect "pending model changes" and throw on Migrate(). Ignore it.
options.ConfigureWarnings(w => w.Ignore(RelationalEventId.PendingModelChangesWarning));
options.ConfigureWarnings(w =>
{
w.Ignore(RelationalEventId.PendingModelChangesWarning);
w.Ignore(CoreEventId.PossibleIncorrectRequiredNavigationWithQueryFilterInteractionWarning);
});
});
// Enable CORS (allowlist by default)
@@ -888,21 +888,25 @@ public static class StartupInitializationExtensions
var adminPassword = (app.Configuration["Auth:AdminPassword"] ?? "").Trim();
if (!string.IsNullOrWhiteSpace(adminEmail) && !string.IsNullOrWhiteSpace(adminPassword))
{
using var adminScope = app.Services.CreateScope();
var adminDb = adminScope.ServiceProvider.GetRequiredService<JobTrackerContext>();
var adminUsers = adminScope.ServiceProvider.GetRequiredService<UserManager<ApplicationUser>>();
var adminRoles = adminScope.ServiceProvider.GetRequiredService<RoleManager<IdentityRole>>();
const string adminRole = "Admin";
if (!roles.RoleExistsAsync(adminRole).GetAwaiter().GetResult())
if (!adminRoles.RoleExistsAsync(adminRole).GetAwaiter().GetResult())
{
roles.CreateAsync(new IdentityRole(adminRole)).GetAwaiter().GetResult();
adminRoles.CreateAsync(new IdentityRole(adminRole)).GetAwaiter().GetResult();
}
var existing = users.FindByEmailAsync(adminEmail).GetAwaiter().GetResult();
var existing = adminUsers.FindByEmailAsync(adminEmail).GetAwaiter().GetResult();
if (existing is null)
{
var u = new ApplicationUser { UserName = adminEmail, Email = adminEmail, EmailConfirmed = true };
var created = users.CreateAsync(u, adminPassword).GetAwaiter().GetResult();
var created = adminUsers.CreateAsync(u, adminPassword).GetAwaiter().GetResult();
if (created.Succeeded)
{
users.AddToRoleAsync(u, adminRole).GetAwaiter().GetResult();
adminUsers.AddToRoleAsync(u, adminRole).GetAwaiter().GetResult();
app.Logger.LogInformation("Seeded admin user: {Email}", adminEmail);
}
else
@@ -912,17 +916,17 @@ public static class StartupInitializationExtensions
}
else
{
var inRole = users.IsInRoleAsync(existing, adminRole).GetAwaiter().GetResult();
if (!inRole) users.AddToRoleAsync(existing, adminRole).GetAwaiter().GetResult();
var inRole = adminUsers.IsInRoleAsync(existing, adminRole).GetAwaiter().GetResult();
if (!inRole) adminUsers.AddToRoleAsync(existing, adminRole).GetAwaiter().GetResult();
}
// One-time claim of legacy data for the admin user so enabling auth doesn't "hide" existing records.
var admin = users.FindByEmailAsync(adminEmail).GetAwaiter().GetResult();
var admin = adminUsers.FindByEmailAsync(adminEmail).GetAwaiter().GetResult();
if (admin is not null)
{
try
{
using var conn = db.Database.GetDbConnection();
using var conn = adminDb.Database.GetDbConnection();
conn.Open();
static bool ColumnExists(DbConnection c, string providerName, string table, string column)
@@ -963,12 +967,12 @@ public static class StartupInitializationExtensions
{
if (companyOwnershipExists)
{
db.Database.ExecuteSqlRaw("UPDATE Companies SET OwnerUserId = {0} WHERE OwnerUserId IS NULL;", admin.Id);
adminDb.Database.ExecuteSqlRaw("UPDATE Companies SET OwnerUserId = {0} WHERE OwnerUserId IS NULL;", admin.Id);
}
if (jobOwnershipExists)
{
db.Database.ExecuteSqlRaw("UPDATE JobApplications SET OwnerUserId = {0} WHERE OwnerUserId IS NULL;", admin.Id);
adminDb.Database.ExecuteSqlRaw("UPDATE JobApplications SET OwnerUserId = {0} WHERE OwnerUserId IS NULL;", admin.Id);
}
}
}