Introduce a new feature allowing users to open URLs for receiver envelopes directly from the sender page. This includes: - Injecting `EnvelopeReceiverService` in `SenderPage.razor`. - Adding a UI button to open receiver envelope URLs. - Implementing `OpenReceiverEnvelopeUrlAsync` for URL handling. - Extending `EnvelopeReceiverService` with methods for URL retrieval and feature check. - Updating `EnvelopeReceiverController` with new endpoints for URL access. - Introducing `SenderFeatureAccessOptions` for managing feature access. - Configuring feature access in `Program.cs` and `appsettings.json`. - Restricting feature usage to specified email addresses.
97 lines
4.4 KiB
C#
97 lines
4.4 KiB
C#
using System.Net;
|
||
using System.Net.Http;
|
||
using System.Net.Http.Json;
|
||
using System.Text.Json;
|
||
using EnvelopeGenerator.Application.EnvelopeReceivers.Commands.CreateEnvelopeReceiver;
|
||
using EnvelopeGenerator.Server.Client.Models;
|
||
|
||
namespace EnvelopeGenerator.Server.Client.Services;
|
||
|
||
/// <summary>
|
||
/// Retrieves the <see cref="EnvelopeReceiverDto"/> for the authenticated receiver
|
||
/// from <c>GET /api/EnvelopeReceiver/{envelopeKey}</c>.
|
||
/// Also creates new envelopes via <c>POST /api/EnvelopeReceiver</c>.
|
||
/// </summary>
|
||
public class EnvelopeReceiverService(IHttpClientFactory httpClientFactory)
|
||
{
|
||
private static readonly JsonSerializerOptions _jsonOptions = new(JsonSerializerDefaults.Web);
|
||
private sealed record ReceiverEnvelopeUrlResponse(string Url);
|
||
private sealed record ReceiverEnvelopeUrlEnabledResponse(bool Enabled);
|
||
|
||
/// <summary>
|
||
/// Fetches the envelope receiver data for the given envelope key from the API.
|
||
/// Throws HttpRequestException on failure with appropriate status code.
|
||
/// </summary>
|
||
/// <exception cref="HttpRequestException">Thrown when the API request fails.</exception>
|
||
public async Task<EnvelopeReceiverDto?> GetAsync(string envelopeKey, CancellationToken cancel = default)
|
||
{
|
||
using var http = httpClientFactory.CreateClient("EnvelopeGenerator.Server");
|
||
var url = $"/api/EnvelopeReceiver/{Uri.EscapeDataString(envelopeKey)}";
|
||
var response = await http.GetAsync(url, cancel);
|
||
|
||
if (!response.IsSuccessStatusCode)
|
||
{
|
||
var statusCode = (int)response.StatusCode;
|
||
var reasonPhrase = response.ReasonPhrase ?? "Unknown error";
|
||
throw new HttpRequestException(
|
||
$"Failed to load envelope receiver data. Status: {statusCode} ({reasonPhrase})",
|
||
null,
|
||
response.StatusCode);
|
||
}
|
||
|
||
return await response.Content.ReadFromJsonAsync<EnvelopeReceiverDto>(_jsonOptions, cancel);
|
||
}
|
||
|
||
/// <summary>
|
||
/// Creates a new envelope with document and receivers via <c>POST /api/EnvelopeReceiver</c>.
|
||
/// Requires sender authentication cookie to be present in the request.
|
||
/// </summary>
|
||
/// <exception cref="HttpRequestException">Thrown when the API request fails.</exception>
|
||
public async Task<CreateEnvelopeReceiverResponse?> CreateAsync(
|
||
CreateEnvelopeReceiverCommand request,
|
||
CancellationToken cancel = default)
|
||
{
|
||
using var http = httpClientFactory.CreateClient("EnvelopeGenerator.Server");
|
||
var response = await http.PostAsJsonAsync("/api/EnvelopeReceiver", request, _jsonOptions, cancel);
|
||
|
||
if (!response.IsSuccessStatusCode)
|
||
{
|
||
var body = await response.Content.ReadAsStringAsync(cancel);
|
||
throw new HttpRequestException(
|
||
$"Fehler beim Erstellen des Umschlags. Status: {(int)response.StatusCode} – {body}",
|
||
null,
|
||
response.StatusCode);
|
||
}
|
||
|
||
return await response.Content.ReadFromJsonAsync<CreateEnvelopeReceiverResponse>(_jsonOptions, cancel);
|
||
}
|
||
|
||
public async Task<string?> GetReceiverEnvelopeUrlAsync(string envelopeUuid, string receiverSignature, CancellationToken cancel = default)
|
||
{
|
||
if (string.IsNullOrWhiteSpace(envelopeUuid) || string.IsNullOrWhiteSpace(receiverSignature))
|
||
return null;
|
||
|
||
using var http = httpClientFactory.CreateClient("EnvelopeGenerator.Server");
|
||
var url = $"/api/EnvelopeReceiver/receiver-envelope-url?envelopeUuid={Uri.EscapeDataString(envelopeUuid)}&receiverSignature={Uri.EscapeDataString(receiverSignature)}";
|
||
var response = await http.GetAsync(url, cancel);
|
||
|
||
if (!response.IsSuccessStatusCode)
|
||
return null;
|
||
|
||
var payload = await response.Content.ReadFromJsonAsync<ReceiverEnvelopeUrlResponse>(_jsonOptions, cancel);
|
||
return payload?.Url;
|
||
}
|
||
|
||
public async Task<bool> GetReceiverEnvelopeUrlFeatureEnabledAsync(CancellationToken cancel = default)
|
||
{
|
||
using var http = httpClientFactory.CreateClient("EnvelopeGenerator.Server");
|
||
var response = await http.GetAsync("/api/EnvelopeReceiver/receiver-envelope-url/enabled", cancel);
|
||
|
||
if (!response.IsSuccessStatusCode)
|
||
return false;
|
||
|
||
var payload = await response.Content.ReadFromJsonAsync<ReceiverEnvelopeUrlEnabledResponse>(_jsonOptions, cancel);
|
||
return payload?.Enabled == true;
|
||
}
|
||
}
|