Files
Website/BlazorApp/Endpoints/DeveloperEndpoints.cs
SysAdmin 33b21959d8
All checks were successful
Build and Deploy / deploy (push) Successful in 40s
fix(developers): distinguish API errors from taken usernames in availability check
CheckUsernameAsync returned false (taken) on any API failure, making every
username appear taken when SilverDESK was unreachable. Now returns nullable
bool so errors show a warning instead of blocking submission.

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

58 lines
2.5 KiB
C#

using SilverLabs.Website.Models;
using SilverLabs.Website.Services;
namespace SilverLabs.Website.Endpoints;
public static class DeveloperEndpoints
{
public static void MapDeveloperEndpoints(this WebApplication app)
{
var group = app.MapGroup("/api/developers");
group.MapGet("/check-username/{username}", async (string username, DeveloperApplicationService service) =>
{
var available = await service.CheckUsernameAsync(username);
if (available is null)
return Results.Problem("Unable to verify username availability", statusCode: 503);
return Results.Ok(new { available = available.Value });
});
group.MapPost("/apply", async (DeveloperApplication application, DeveloperApplicationService service) =>
{
var (success, message, token) = await service.SubmitApplicationAsync(application);
return success
? Results.Ok(new { message, token })
: Results.Problem(message, statusCode: 502);
});
group.MapPost("/approve/{ticketId}", async (
string ticketId,
DeveloperTicketParsingService ticketService,
ProvisioningService provisioningService,
HttpContext context,
IConfiguration config) =>
{
var apiKey = context.Request.Headers["X-Api-Key"].FirstOrDefault();
var expectedKey = config["AdminApiKey"];
if (string.IsNullOrEmpty(expectedKey) || apiKey != expectedKey)
return Results.Unauthorized();
var ticket = await ticketService.FetchTicketAsync(ticketId);
if (ticket is null)
return Results.Problem("Failed to fetch ticket from SilverDESK", statusCode: 502);
var description = ticket.Value.GetProperty("description").GetString() ?? "";
var (fullName, email, desiredUsername) = ticketService.ParseApplicationFromDescription(description);
if (string.IsNullOrEmpty(fullName) || string.IsNullOrEmpty(email) || string.IsNullOrEmpty(desiredUsername))
return Results.Problem("Could not parse applicant details from ticket description", statusCode: 422);
var (success, message) = await provisioningService.ApproveApplicationAsync(
ticketId, desiredUsername, email, fullName);
return Results.Ok(new { success, message });
});
}
}