Single helper extension: MapSvrntyAltchaChallenge() exposes
GET /api/altcha/challenge (configurable prefix) that fetches a fresh
challenge from IAltchaChallengeProvider and projects it onto the
JSON shape the altcha widget v3 expects from its challengeurl —
{ algorithm, challenge, salt, signature, maxnumber } in lowercase.
AllowAnonymous on purpose: the whole point is gating mutations from
unauthenticated callers, so the challenge endpoint must be reachable
without credentials.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
51 lines
1.8 KiB
C#
51 lines
1.8 KiB
C#
using Microsoft.AspNetCore.Builder;
|
|
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.AspNetCore.Routing;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Svrnty.CQRS.Altcha.Abstractions;
|
|
|
|
namespace Svrnty.CQRS.Altcha.MinimalApi;
|
|
|
|
public static class EndpointRouteBuilderExtensions
|
|
{
|
|
/// <summary>
|
|
/// Maps <c>GET {routePrefix}</c> (default <c>/api/altcha/challenge</c>)
|
|
/// returning a fresh challenge in the JSON shape the
|
|
/// <a href="https://altcha.org/docs/v2/widget-v3/">altcha widget</a>
|
|
/// consumes via its <c>challengeurl</c> attribute.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// Requires an <see cref="IAltchaChallengeProvider"/> to be registered
|
|
/// (typically by <c>AddSvrntyAltchaGrpcVerifier(...)</c>). The endpoint
|
|
/// allows anonymous access — the whole point is gating mutations from
|
|
/// unauthenticated callers, so the challenge endpoint must be reachable
|
|
/// without credentials.
|
|
/// </remarks>
|
|
public static IEndpointRouteBuilder MapSvrntyAltchaChallenge(
|
|
this IEndpointRouteBuilder endpoints,
|
|
string routePrefix = "/api/altcha/challenge")
|
|
{
|
|
endpoints.MapGet(routePrefix, async (
|
|
IAltchaChallengeProvider provider,
|
|
CancellationToken cancellationToken) =>
|
|
{
|
|
var challenge = await provider.CreateAsync(cancellationToken);
|
|
return Results.Ok(new AltchaChallengeDto
|
|
{
|
|
Algorithm = challenge.Algorithm,
|
|
Challenge = challenge.Challenge,
|
|
Salt = challenge.Salt,
|
|
Signature = challenge.Signature,
|
|
MaxNumber = challenge.MaxNumber
|
|
});
|
|
})
|
|
.AllowAnonymous()
|
|
.WithName("Altcha_Challenge_Get")
|
|
.WithTags("Altcha")
|
|
.Produces<AltchaChallengeDto>(200)
|
|
.Produces(503);
|
|
|
|
return endpoints;
|
|
}
|
|
}
|