Files
yale-user-access/packages/backend/Program.cs
Liam Pietralla 69e4677d5f
All checks were successful
Build and Publish / Build Yale Access Frontend (pull_request) Successful in 50s
Build and Publish / Push Yale Access Frontend Docker Image (pull_request) Has been skipped
Build and Publish / Build Yale Access Backend (pull_request) Successful in 1m53s
Build and Publish / Push Yale Access Backend Docker Image (pull_request) Has been skipped
Merge branch 'main' into feat/logging-update
2026-02-18 09:11:24 +11:00

150 lines
4.8 KiB
C#

using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.HttpOverrides;
using Microsoft.EntityFrameworkCore;
using OpenTelemetry.Logs;
using YaleAccess.Data;
using YaleAccess.Models.Options;
using YaleAccess.Services;
using YaleAccess.Services.Interfaces;
var builder = WebApplication.CreateBuilder(args);
try
{
var useOtlpExporter = !string.IsNullOrWhiteSpace(builder.Configuration["OTEL_EXPORTER_OTLP_ENDPOINT"]);
builder.Logging.AddOpenTelemetry(logging =>
{
logging.IncludeFormattedMessage = true;
logging.IncludeScopes = true;
if (useOtlpExporter)
{
logging.AddOtlpExporter();
}
else
{
Console.WriteLine("OTEL_EXPORTER_OTLP_ENDPOINT is not set. Skipping OTLP exporter configuration.");
}
});
// Add services to the container.
builder.Services.AddControllers();
// Add the database context
builder.Services.AddDbContext<YaleContext>(options =>
{
options.UseSqlite(builder.Configuration.GetConnectionString(nameof(YaleContext)));
});
// Configure the options
builder.Services.Configure<AuthenticationOptions>(builder.Configuration.GetSection(AuthenticationOptions.Authentication));
builder.Services.Configure<CodesOptions>(builder.Configuration.GetSection(CodesOptions.Codes));
builder.Services.Configure<DevicesOptions>(builder.Configuration.GetSection(DevicesOptions.Devices));
builder.Services.Configure<ZWaveOptions>(builder.Configuration.GetSection(ZWaveOptions.ZWave));
builder.Services.Configure<TwiloOptions>(builder.Configuration.GetSection(TwiloOptions.Twilio));
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
// Get a copy of the configuration
IConfiguration configuration = builder.Configuration;
// Configure the DI services
builder.Services.AddScoped<SMSService>();
// If the environment is development and the mock option is set to true, use the mock service
if (builder.Environment.IsDevelopment() && configuration.GetValue<bool>("UseMockDevelopmentMode"))
{
builder.Services.AddSingleton<MockYaleData>();
builder.Services.AddSingleton<IYaleAccessor, MockYaleAccessor>();
}
else
{
builder.Services.AddSingleton<IYaleAccessor, YaleAccessor>();
}
// Setup CORS
string[] corsAllowedOrigins = (configuration["CorsAllowedOrigins"] ?? "http://localhost:3000").Split(",") ;
builder.Services.AddCors(options =>
{
options.AddDefaultPolicy(policy =>
{
policy.WithOrigins(corsAllowedOrigins)
.AllowCredentials()
.AllowAnyMethod()
.WithHeaders("Content-Type", "Authorization");
});
});
// Setup cookie authentication scheme
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options =>
{
// Set HTTP only to true to prevent XSS attacks
options.Cookie.HttpOnly = true;
// Set secure policy to always to prevent sending cookies over HTTP for production use, for development set to None
if (builder.Environment.IsDevelopment())
options.Cookie.SecurePolicy = CookieSecurePolicy.None;
else
options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
// Ensure that the API will return a 401 Unauthorized instead of redirecting to the login page
options.AccessDeniedPath = string.Empty;
options.LoginPath = string.Empty;
options.Events.OnRedirectToLogin = context =>
{
context.Response.StatusCode = 401;
return Task.CompletedTask;
};
});
var app = builder.Build();
// Create the database if it doesn't exist
using (var scope = app.Services.CreateScope())
{
var services = scope.ServiceProvider;
var context = services.GetRequiredService<YaleContext>();
context.Database.Migrate();
}
// Configure the forwarded headers middleware
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseCors();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();
}
catch (Exception ex)
{
// Ignore host aborted exceptions caused by build checks
if (ex is not HostAbortedException)
{
Console.WriteLine("Host terminated unexpectedly");
throw;
}
}