Files
social-media/backend/src/Socialize.Api/Program.cs
Jonathan Bourdon b6eb348605
All checks were successful
deploy-socialize / image (push) Successful in 1m12s
deploy-socialize / deploy (push) Successful in 19s
feat: add release communications
2026-05-07 21:04:29 -04:00

168 lines
5.2 KiB
C#

using FastEndpoints;
using FastEndpoints.Swagger;
using Microsoft.AspNetCore.HttpOverrides;
using Microsoft.Extensions.Options;
using Socialize;
using Socialize.Api.Infrastructure.BlobStorage.Configuration;
using Socialize.Api.Infrastructure.BlobStorage.Services;
using Socialize.Api.Infrastructure;
using Socialize.Api.Infrastructure.TestData;
using Socialize.Api.Modules.Approvals;
using Socialize.Api.Modules.Assets;
using Socialize.Api.Modules.Channels;
using Socialize.Api.Modules.Clients;
using Socialize.Api.Modules.Comments;
using Socialize.Api.Modules.ContentItems;
using Socialize.Api.Modules.Feedback;
using Socialize.Api.Modules.Identity;
using Socialize.Api.Modules.Notifications;
using Socialize.Api.Modules.Campaigns;
using Socialize.Api.Modules.CalendarIntegrations;
using Socialize.Api.Modules.Organizations;
using Socialize.Api.Modules.ReleaseCommunications;
using Socialize.Api.Modules.Workspaces;
const string SeededTestDataMessage = "Seeded test data.";
var builder = WebApplication.CreateBuilder(args);
bool seedTestData = args.Any(arg => string.Equals(arg, "seed-testdata", StringComparison.OrdinalIgnoreCase));
string? vaultUri = Environment.GetEnvironmentVariable("VaultUri");
if (!string.IsNullOrWhiteSpace(vaultUri))
{
throw new InvalidOperationException("VaultUri configuration is not supported by this deployment. Move secrets to environment variables.");
}
builder.Services.AddCors(options =>
options.AddPolicy(
"AllowAll",
policy =>
policy.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
)
);
// Add services to the container.
builder.Services.AddWebServices();
builder.Services.AddAuthorizationAndAuthentication(builder.Configuration);
builder.Services.AddFastEndpoints();
builder.Services.SwaggerDocument(o =>
{
o.EnableGetRequestsWithBody = false;
o.EnableJWTBearerAuth = true;
o.DocumentSettings = s =>
{
s.Title = "Socialize API";
s.Version = "v1";
};
});
var postgresConnectionString = builder.Configuration.GetConnectionString("PostgresConnection")
?? throw new InvalidOperationException(
"Missing ConnectionStrings:PostgresConnection");
builder.Services.AddAppData(postgresConnectionString);
builder.AddInfrastructureModule();
builder.AddIdentityModule();
builder.AddOrganizationsModule();
builder.AddWorkspaceModule();
builder.AddChannelsModule();
builder.AddClientsModule();
builder.AddCampaignsModule();
builder.AddContentItemsModule();
builder.AddAssetsModule();
builder.AddCommentsModule();
builder.AddApprovalsModule();
builder.AddNotificationsModule();
builder.AddFeedbackModule();
builder.AddCalendarIntegrationsModule();
builder.AddReleaseCommunicationsModule();
var app = builder.Build();
if (seedTestData)
{
if (app.Environment.IsProduction()
&& !string.Equals(
Environment.GetEnvironmentVariable("CONFIRM_PRODUCTION_SEED"),
"true",
StringComparison.Ordinal))
{
throw new InvalidOperationException(
"Refusing to seed test data in Production without CONFIRM_PRODUCTION_SEED=true.");
}
await app.UseAppDataAsync();
await app.UseIdentityModuleAsync();
await app.Services.SeedTestDataAsync();
Console.WriteLine(SeededTestDataMessage);
return;
}
app.UseForwardedHeaders(
new ForwardedHeadersOptions { ForwardedHeaders = ForwardedHeaders.XForwardedProto }
);
app.UseCors("AllowAll");
app.UseAuthentication();
app.UseAuthorization();
// Initialize and seed the db.
await app.UseAppDataAsync();
await app.UseIdentityModuleAsync();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHealthChecks("/health");
LocalBlobStorageOptions localBlobStorageOptions = app.Services
.GetRequiredService<IOptions<LocalBlobStorageOptions>>()
.Value;
string localBlobStorageRoot = app.Services
.GetRequiredService<LocalBlobStorage>()
.GetRootPath();
string localBlobStorageRootWithSeparator = Path.EndsInDirectorySeparator(localBlobStorageRoot)
? localBlobStorageRoot
: $"{localBlobStorageRoot}{Path.DirectorySeparatorChar}";
Directory.CreateDirectory(localBlobStorageRoot);
app.MapGet(
$"{LocalBlobStorage.NormalizeRequestPath(localBlobStorageOptions.RequestPath)}/{{**blobPath}}",
async (
string blobPath,
CancellationToken ct) =>
{
string filePath = Path.GetFullPath(Path.Combine(localBlobStorageRoot, blobPath));
if (!filePath.StartsWith(localBlobStorageRootWithSeparator, StringComparison.Ordinal) ||
filePath.EndsWith(".content-type", StringComparison.OrdinalIgnoreCase) ||
!File.Exists(filePath))
{
return Results.NotFound();
}
string contentType = LocalBlobStorage.ReadContentType(filePath) ?? "application/octet-stream";
byte[] bytes = await File.ReadAllBytesAsync(filePath, ct);
return Results.File(bytes, contentType);
});
if (!app.Environment.IsDevelopment())
{
app.UseHttpsRedirection();
}
app.UseFastEndpoints();
app.UseSwaggerGen();
await app.RunAsync();