84 lines
3.1 KiB
C#
84 lines
3.1 KiB
C#
using Microsoft.EntityFrameworkCore;
|
|
using Nexus.Api.Data;
|
|
using Nexus.Api.Helpers;
|
|
using Nexus.Api.Middleware;
|
|
using Nexus.Api.Services;
|
|
|
|
namespace Nexus.Api.Extensions;
|
|
|
|
/// <summary>
|
|
/// Extension methods for configuring the Nexus application pipeline and startup.
|
|
/// </summary>
|
|
public static class ApplicationBuilderExtensions
|
|
{
|
|
/// <summary>
|
|
/// Applies pending EF Core migrations and seeds the initial owner account if none exist.
|
|
/// </summary>
|
|
public static async Task EnsureDatabaseAsync(this WebApplication app)
|
|
{
|
|
var configuration = app.Configuration;
|
|
|
|
await using (var scope = app.Services.CreateAsyncScope())
|
|
{
|
|
var db = scope.ServiceProvider.GetRequiredService<NexusDbContext>();
|
|
await db.Database.MigrateAsync();
|
|
|
|
var ownerEmail = configuration["Owner:Email"]?.Trim().ToLowerInvariant();
|
|
var ownerPassword = configuration["Owner:Password"];
|
|
var ownerDisplayName = configuration["Owner:DisplayName"]?.Trim();
|
|
var hasUsers = await db.Users.AnyAsync();
|
|
|
|
if (!hasUsers)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(ownerEmail))
|
|
throw new InvalidOperationException("Owner:Email is required for initial setup.");
|
|
|
|
var initialDisplayName = string.IsNullOrWhiteSpace(ownerDisplayName)
|
|
? PasswordHelper.BuildOwnerDisplayName(ownerEmail)
|
|
: ownerDisplayName;
|
|
var initialPassword = string.IsNullOrWhiteSpace(ownerPassword)
|
|
? PasswordHelper.GenerateTemporaryPassword()
|
|
: ownerPassword;
|
|
|
|
if (!string.IsNullOrWhiteSpace(ownerPassword) && ownerPassword.Length < 10)
|
|
throw new InvalidOperationException("Owner:Password must be at least 10 characters when provided explicitly.");
|
|
|
|
db.Users.Add(new NexusUser
|
|
{
|
|
Email = ownerEmail,
|
|
NormalizedEmail = AuthService.NormalizeEmail(ownerEmail),
|
|
DisplayName = initialDisplayName,
|
|
PasswordHash = PasswordSecurity.Hash(initialPassword),
|
|
Role = "owner"
|
|
});
|
|
await db.SaveChangesAsync();
|
|
|
|
if (string.IsNullOrWhiteSpace(ownerPassword))
|
|
{
|
|
Console.Error.WriteLine($"[nexus] Initial owner credentials generated: displayName={initialDisplayName}, password={initialPassword}");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Configures the HTTP middleware pipeline: forwarded headers, rate limiting, auth, security headers, and Swagger in development.
|
|
/// </summary>
|
|
public static IApplicationBuilder UseNexusPipeline(this IApplicationBuilder app, IWebHostEnvironment env)
|
|
{
|
|
app.UseForwardedHeaders();
|
|
app.UseRateLimiter();
|
|
app.UseAuthentication();
|
|
app.UseAuthorization();
|
|
app.UseSecurityHeaders();
|
|
|
|
if (env.IsDevelopment())
|
|
{
|
|
app.UseSwagger();
|
|
app.UseSwaggerUI();
|
|
}
|
|
|
|
return app;
|
|
}
|
|
}
|