Files
Website/BlazorApp/Program.cs
SysAdmin 9cbbd2d4f2
All checks were successful
Build and Deploy / deploy (push) Successful in 41s
feat(developers): add password-synced provisioning and deployment confirmation flow
Replace random unrecoverable passwords with a confirmation-based flow:
admin approval generates a secure token and sends a ticket reply with a
confirmation link; the developer clicks the link, enters their SilverDESK
password, and all services (Mattermost, Mailcow, Gitea) are provisioned
with that password. Adds password sync endpoint for SilverDESK resets and
updates the post-signup success panel to redirect to SilverDESK login with
the username pre-populated.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 21:16:13 +00:00

85 lines
3.2 KiB
C#

using SilverLabs.Website.Components;
using SilverLabs.Website.Endpoints;
using SilverLabs.Website.Services;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents();
// HttpClient for SilverDESK (used by DeveloperApplicationService directly)
builder.Services.AddHttpClient<DeveloperApplicationService>(client =>
{
client.BaseAddress = new Uri(builder.Configuration["SilverDesk:BaseUrl"] ?? "https://silverdesk.silverlabs.uk");
var apiKey = builder.Configuration["SilverDesk:ApiKey"];
if (!string.IsNullOrEmpty(apiKey))
client.DefaultRequestHeaders.Add("X-API-Key", apiKey);
});
// HttpClient for DeveloperTicketParsingService (fetches tickets from SilverDESK)
builder.Services.AddHttpClient<DeveloperTicketParsingService>(client =>
{
client.BaseAddress = new Uri(builder.Configuration["SilverDesk:BaseUrl"] ?? "https://silverdesk.silverlabs.uk");
var apiKey = builder.Configuration["SilverDesk:ApiKey"];
if (!string.IsNullOrEmpty(apiKey))
client.DefaultRequestHeaders.Add("X-API-Key", apiKey);
});
// Named HttpClients for provisioning
builder.Services.AddHttpClient("SilverDesk", client =>
{
client.BaseAddress = new Uri(builder.Configuration["SilverDesk:BaseUrl"] ?? "https://silverdesk.silverlabs.uk");
var apiKey = builder.Configuration["SilverDesk:ApiKey"];
if (!string.IsNullOrEmpty(apiKey))
client.DefaultRequestHeaders.Add("X-API-Key", apiKey);
});
builder.Services.AddHttpClient("Mattermost", client =>
{
client.BaseAddress = new Uri(builder.Configuration["Mattermost:BaseUrl"] ?? "https://ops.silverlined.uk");
var token = builder.Configuration["Mattermost:ApiToken"];
if (!string.IsNullOrEmpty(token))
client.DefaultRequestHeaders.Add("Authorization", $"Bearer {token}");
});
builder.Services.AddHttpClient("Mailcow", client =>
{
client.BaseAddress = new Uri(builder.Configuration["Mailcow:BaseUrl"] ?? "https://mail.silverlined.uk");
var apiKey = builder.Configuration["Mailcow:ApiKey"];
if (!string.IsNullOrEmpty(apiKey))
client.DefaultRequestHeaders.Add("X-API-Key", apiKey);
});
builder.Services.AddHttpClient("Gitea", client =>
{
client.BaseAddress = new Uri(builder.Configuration["Gitea:BaseUrl"] ?? "https://git.silverlabs.uk");
var token = builder.Configuration["Gitea:ApiToken"];
if (!string.IsNullOrEmpty(token))
client.DefaultRequestHeaders.Add("Authorization", $"token {token}");
});
builder.Services.AddScoped<ProvisioningService>();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error", createScopeForErrors: true);
// 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.UseHttpsRedirection(); // Disabled - running behind reverse proxy
app.UseAntiforgery();
app.MapStaticAssets();
app.MapRazorComponents<App>()
.AddInteractiveServerRenderMode();
app.MapDeveloperEndpoints();
app.Run();