All checks were successful
Build and Deploy / deploy (push) Successful in 40s
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>
58 lines
2.5 KiB
C#
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 });
|
|
});
|
|
}
|
|
}
|