-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathProgram.cs
More file actions
130 lines (106 loc) · 3.97 KB
/
Program.cs
File metadata and controls
130 lines (106 loc) · 3.97 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
using Microsoft.EntityFrameworkCore;
using ACRTS.Data;
using ACRTS.Services;
using ACRTS.Filters;
var builder = WebApplication.CreateBuilder(args);
DotNetEnv.Env.Load();
// 1. Database Configuration
var databaseUrl = Environment.GetEnvironmentVariable("DATABASE_URL");
if (!string.IsNullOrEmpty(databaseUrl))
{
// Convert Railway PostgreSQL URL to Npgsql connection string
var uri = new Uri(databaseUrl);
var userInfo = uri.UserInfo.Split(':');
var npgsqlConnection = $"Host={uri.Host};Port={uri.Port};Database={uri.AbsolutePath.TrimStart('/')};Username={userInfo[0]};Password={userInfo[1]};SSL Mode=Require;Trust Server Certificate=true";
builder.Services.AddDbContext<ACRTSDbContext>(options =>
options.UseNpgsql(npgsqlConnection));
}
else
{
// SQLite for local development
builder.Services.AddDbContext<ACRTSDbContext>(options =>
options.UseSqlite("Data Source=Data/acrts.db"));
}
// 2. Session & Security Cookies
builder.Services.AddSession(options =>
{
options.IdleTimeout = TimeSpan.FromMinutes(builder.Configuration.GetValue<int>("AdminSettings:SessionTimeoutMinutes"));
options.Cookie.HttpOnly = true;
options.Cookie.IsEssential = true;
options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
});
// 3. MVC Setup
builder.Services.AddControllersWithViews();
builder.Services.AddHttpContextAccessor();
// 4. Custom Service Registrations
// Scoped Services
builder.Services.AddScoped<TrackingIdService>();
builder.Services.AddScoped<PriorityDetectorService>();
builder.Services.AddScoped<EvidenceService>();
builder.Services.AddScoped<DuplicateDetectionService>();
builder.Services.AddScoped<AlertService>();
builder.Services.AddScoped<SampleDataService>();
builder.Services.AddScoped<AdminAuthFilter>();
// Singleton / State Services
builder.Services.AddSingleton<EncryptionService>();
builder.Services.AddSingleton<InputSanitizerService>();
builder.Services.AddSingleton<RateLimitService>();
builder.Services.AddSingleton<LoggerService>();
// CORS
builder.Services.AddCors(options => {
options.AddPolicy("SameOrigin", policy => policy.WithOrigins("https://localhost:7084", "http://localhost:5084"));
});
var app = builder.Build();
// 5. Middleware Pipeline
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Home/Error");
app.UseStatusCodePagesWithReExecute("/Home/Error/{0}");
app.UseHsts();
}
else
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseCors("SameOrigin");
app.UseSession();
app.UseAuthorization();
// Security Headers Middleware
app.Use(async (context, next) => {
context.Response.Headers.Append("X-Content-Type-Options", "nosniff");
context.Response.Headers.Append("X-Frame-Options", "DENY");
context.Response.Headers.Append("X-XSS-Protection", "1; mode=block");
await next();
});
app.UseMiddleware<ACRTS.Middleware.AnonymityMiddleware>();
// Default Route
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
// 6. DB Initialization & Seeding
using (var scope = app.Services.CreateScope())
{
var context = scope.ServiceProvider.GetRequiredService<ACRTSDbContext>();
// Ensure directories exist for Railway deployment
var dataDir = Path.Combine(Directory.GetCurrentDirectory(), "Data");
if (!Directory.Exists(dataDir))
Directory.CreateDirectory(dataDir);
var evidenceDir = Path.Combine(Directory.GetCurrentDirectory(),
"wwwroot", "uploads", "evidence");
if (!Directory.Exists(evidenceDir))
Directory.CreateDirectory(evidenceDir);
// Ensure DB is created
context.Database.EnsureCreated();
if (app.Environment.IsDevelopment())
{
var seeder = scope.ServiceProvider.GetRequiredService<SampleDataService>();
// Seed sample data if empty
await seeder.SeedSampleData(context);
}
}
var port = Environment.GetEnvironmentVariable("PORT") ?? "8080";
app.Urls.Add($"http://0.0.0.0:{port}");
app.Run();