Introduced a feature to allow envelope receivers to request an access code via email on the login page. - Added `OnInitializedAsync` in `LoginReceiverPage.razor` to trigger access code requests using `AuthService`. - Implemented `RequestEnvelopeReceiverAccessCodeAsync` in `AuthService.cs` to handle API calls for access code requests. - Added a new endpoint in `AuthController` to process access code requests, including validation, history recording, and email dispatching. - Registered `IEnvelopeMailService` and `AddDispatcher` in `Program.cs` to support email dispatch and database operations. - Refactored `AuthController` constructor for readability and added necessary `using` directives. - Improved logging and error handling for better traceability and robustness. These changes ensure a seamless and secure process for envelope receivers to request access codes, enhancing the user experience.
124 lines
4.8 KiB
C#
124 lines
4.8 KiB
C#
using System.Net;
|
|
using System.Net.Http.Json;
|
|
|
|
namespace EnvelopeGenerator.Server.Client.Services;
|
|
|
|
public enum EnvelopeLoginResult { Success, InvalidCode, NotFound, Error }
|
|
|
|
public enum SenderLoginResult { Success, InvalidCredentials, Error }
|
|
|
|
public class AuthService(IHttpClientFactory httpClientFactory)
|
|
{
|
|
private HttpClient CreateDefaultClient() => httpClientFactory.CreateClient("EnvelopeGenerator.Server");
|
|
|
|
/// <summary>
|
|
/// Checks whether the current user holds a valid receiver token for the given envelope key.
|
|
/// Calls GET /api/auth/check/envelope/{envelopeKey}.
|
|
/// </summary>
|
|
public async Task<bool> CheckEnvelopeAccessAsync(string envelopeKey, CancellationToken cancel = default)
|
|
{
|
|
using var http = CreateDefaultClient();
|
|
var response = await http.GetAsync($"/api/auth/check/envelope/{Uri.EscapeDataString(envelopeKey)}", cancel);
|
|
return response.StatusCode == HttpStatusCode.OK;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Checks whether the current user holds a valid receiver token for the given envelope key.
|
|
/// Calls GET /api/auth/check/envelope/{envelopeKey}.
|
|
/// </summary>
|
|
public async Task<bool> CheckSenderAccessAsync(CancellationToken cancel = default)
|
|
{
|
|
using var http = CreateDefaultClient();
|
|
var response = await http.GetAsync($"/api/auth/check", cancel);
|
|
return response.StatusCode == HttpStatusCode.OK;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Triggers access code e-mail request flow for the receiver login page.
|
|
/// Calls POST /api/Auth/envelope-receiver/{key}/request-access-code.
|
|
/// </summary>
|
|
public async Task<bool> RequestEnvelopeReceiverAccessCodeAsync(string envelopeKey, CancellationToken cancel = default)
|
|
{
|
|
using var http = CreateDefaultClient();
|
|
var response = await http.PostAsync(
|
|
$"/api/Auth/envelope-receiver/{Uri.EscapeDataString(envelopeKey)}/request-access-code",
|
|
null,
|
|
cancel);
|
|
return response.IsSuccessStatusCode;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Submits the access code for the given envelope key.
|
|
/// Calls POST /api/Auth/envelope-receiver/{key} with multipart/form-data.
|
|
/// On success the API sets an authentication cookie automatically.
|
|
/// </summary>
|
|
public async Task<EnvelopeLoginResult> LoginEnvelopeReceiverAsync(string envelopeKey, string accessCode, CancellationToken cancel = default)
|
|
{
|
|
using var http = CreateDefaultClient();
|
|
var form = new MultipartFormDataContent
|
|
{
|
|
{ new StringContent(accessCode), "AccessCode" }
|
|
};
|
|
|
|
var response = await http.PostAsync(
|
|
$"/api/Auth/envelope-receiver/{Uri.EscapeDataString(envelopeKey)}",
|
|
form, cancel);
|
|
|
|
return response.StatusCode switch
|
|
{
|
|
HttpStatusCode.OK => EnvelopeLoginResult.Success,
|
|
HttpStatusCode.Unauthorized => EnvelopeLoginResult.InvalidCode,
|
|
HttpStatusCode.NotFound => EnvelopeLoginResult.NotFound,
|
|
_ => EnvelopeLoginResult.Error
|
|
};
|
|
}
|
|
|
|
/// <summary>
|
|
/// Removes the per-envelope receiver cookie for the given envelope key.
|
|
/// Calls POST /api/auth/logout/envelope/{envelopeKey}.
|
|
/// </summary>
|
|
public async Task<bool> LogoutEnvelopeReceiverAsync(string envelopeKey, CancellationToken cancel = default)
|
|
{
|
|
using var http = CreateDefaultClient();
|
|
var response = await http.PostAsync(
|
|
$"/api/auth/logout/envelope/{Uri.EscapeDataString(envelopeKey)}",
|
|
null, cancel);
|
|
return response.IsSuccessStatusCode;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Removes the per-envelope receiver cookie for the given envelope key.
|
|
/// Calls POST /api/auth/logout/envelope/{envelopeKey}.
|
|
/// </summary>
|
|
public async Task<bool> LogoutSenderAsync(CancellationToken cancel = default)
|
|
{
|
|
using var http = CreateDefaultClient();
|
|
var response = await http.PostAsync(
|
|
$"/api/auth/logout",
|
|
null, cancel);
|
|
return response.IsSuccessStatusCode;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Authenticates a sender user with username and password.
|
|
/// Calls POST /api/auth?cookie=true with JSON body.
|
|
/// On success the API sets an authentication cookie automatically.
|
|
/// </summary>
|
|
public async Task<SenderLoginResult> LoginSenderAsync(string username, string password, CancellationToken cancel = default)
|
|
{
|
|
using var http = CreateDefaultClient();
|
|
var requestBody = new { username, password };
|
|
|
|
var response = await http.PostAsJsonAsync(
|
|
$"/api/auth?cookie=true",
|
|
requestBody, cancel);
|
|
|
|
return response.StatusCode switch
|
|
{
|
|
HttpStatusCode.OK => SenderLoginResult.Success,
|
|
HttpStatusCode.Unauthorized => SenderLoginResult.InvalidCredentials,
|
|
_ => SenderLoginResult.Error
|
|
};
|
|
}
|
|
}
|