Add client-side DTOs for envelopes and authentication
Introduced EnvelopeDtos.cs and ReceiverAuthDtos.cs under EnvelopeGenerator.ReceiverUI.Web.Client.Api.Models. These files define client-side DTOs that mirror server-side models, exposing only the fields required by the receiver UI. EnvelopeDtos.cs covers envelopes, documents, receivers, and signature elements, while ReceiverAuthDtos.cs handles authentication responses and requests. All DTOs are documented and structured for camelCase JSON serialization, improving maintainability and clarity for API interactions in the receiver UI.
This commit is contained in:
@@ -0,0 +1,126 @@
|
|||||||
|
namespace EnvelopeGenerator.ReceiverUI.Web.Client.Api.Models;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Client-side DTOs for envelope display. These mirror the server-side
|
||||||
|
/// EnvelopeReceiverDto / EnvelopeDto / DocumentDto used by the existing
|
||||||
|
/// API endpoints, but expose only the fields the receiver UI actually needs.
|
||||||
|
/// JSON serialization is camelCase by default (System.Text.Json).
|
||||||
|
/// </summary>
|
||||||
|
public class EnvelopeReceiverDto
|
||||||
|
{
|
||||||
|
public long EnvelopeId { get; set; }
|
||||||
|
public long ReceiverId { get; set; }
|
||||||
|
public string? Name { get; set; }
|
||||||
|
public bool HasPhoneNumber { get; set; }
|
||||||
|
public EnvelopeDto? Envelope { get; set; }
|
||||||
|
public ReceiverDto? Receiver { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class EnvelopeDto
|
||||||
|
{
|
||||||
|
public long Id { get; set; }
|
||||||
|
public string? Uuid { get; set; }
|
||||||
|
public string? Title { get; set; }
|
||||||
|
public string? Message { get; set; }
|
||||||
|
public bool ReadOnly { get; set; }
|
||||||
|
public bool UseAccessCode { get; set; }
|
||||||
|
public bool TFAEnabled { get; set; }
|
||||||
|
public DateTime AddedWhen { get; set; }
|
||||||
|
public SenderUserDto? User { get; set; }
|
||||||
|
public List<DocumentDto>? Documents { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class SenderUserDto
|
||||||
|
{
|
||||||
|
public string? Email { get; set; }
|
||||||
|
public string? Prename { get; set; }
|
||||||
|
public string? Name { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ReceiverDto
|
||||||
|
{
|
||||||
|
public long Id { get; set; }
|
||||||
|
public string? EmailAddress { get; set; }
|
||||||
|
public string? Signature { get; set; }
|
||||||
|
public string? Prename { get; set; }
|
||||||
|
public string? Name { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class DocumentDto
|
||||||
|
{
|
||||||
|
public long Id { get; set; }
|
||||||
|
public string? Name { get; set; }
|
||||||
|
public List<DocumentElementDto>? Elements { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Signature placement on a PDF document. Pixel/inch units follow the same
|
||||||
|
/// convention as the legacy PSPDFKit pipeline.
|
||||||
|
/// </summary>
|
||||||
|
public class DocumentElementDto
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
public int Page { get; set; }
|
||||||
|
public double Left { get; set; }
|
||||||
|
public double Top { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Body for <c>POST /api/readonly</c> (share read-only link with another e-mail).
|
||||||
|
/// </summary>
|
||||||
|
public class ReadOnlyShareRequest
|
||||||
|
{
|
||||||
|
public string ReceiverMail { get; set; } = string.Empty;
|
||||||
|
public DateTime DateValid { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returned by <c>GET /api/annotation/elements</c>. Each item describes a
|
||||||
|
/// signature placeholder the authenticated receiver must sign on the
|
||||||
|
/// current envelope. Coordinates are in PDF points relative to the page.
|
||||||
|
/// </summary>
|
||||||
|
public class SignatureElementDto
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
public int Page { get; set; }
|
||||||
|
public double X { get; set; }
|
||||||
|
public double Y { get; set; }
|
||||||
|
public double Width { get; set; }
|
||||||
|
public double Height { get; set; }
|
||||||
|
public bool Required { get; set; }
|
||||||
|
public string? Tooltip { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Body of <c>POST /api/annotation/blazor</c> — mirrors the API-side
|
||||||
|
/// <c>BlazorSignaturePayload</c>.
|
||||||
|
/// </summary>
|
||||||
|
public class BlazorSignaturePayload
|
||||||
|
{
|
||||||
|
public List<BlazorSignatureEntry> Signatures { get; set; } = new();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class BlazorSignatureEntry
|
||||||
|
{
|
||||||
|
public int ElementId { get; set; }
|
||||||
|
/// <summary>Image as data URL (e.g. <c>data:image/png;base64,...</c>).</summary>
|
||||||
|
public string SignatureDataUrl { get; set; } = string.Empty;
|
||||||
|
public string? Position { get; set; }
|
||||||
|
public string? City { get; set; }
|
||||||
|
public DateTime SignedAt { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Response of <c>GET /api/tfa/{envelopeReceiverId}</c>. The API serializes
|
||||||
|
/// the anonymous type in <c>TfaRegistrationController.RegisterAsync</c>; the
|
||||||
|
/// shape mirrored here is the camelCased JSON that crosses the wire.
|
||||||
|
/// </summary>
|
||||||
|
public class TfaRegistrationResponse
|
||||||
|
{
|
||||||
|
public int EnvelopeId { get; set; }
|
||||||
|
public string? Uuid { get; set; }
|
||||||
|
public string? Signature { get; set; }
|
||||||
|
public DateTime? TfaRegDeadline { get; set; }
|
||||||
|
/// <summary>Base64-encoded PNG suitable for <c>data:image/png;base64,...</c>.</summary>
|
||||||
|
public string? TotpQR64 { get; set; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
namespace EnvelopeGenerator.ReceiverUI.Web.Client.Api.Models;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Mirrors <c>EnvelopeGenerator.API.Models.ReceiverAuthResponse</c>.
|
||||||
|
/// The Status string determines which fields are relevant.
|
||||||
|
/// Possible values:
|
||||||
|
/// requires_access_code, requires_tfa, show_document,
|
||||||
|
/// already_signed, rejected, not_found, expired, error.
|
||||||
|
/// </summary>
|
||||||
|
public class ReceiverAuthResponse
|
||||||
|
{
|
||||||
|
public string Status { get; set; } = string.Empty;
|
||||||
|
public string? Title { get; set; }
|
||||||
|
public string? Message { get; set; }
|
||||||
|
public string? SenderEmail { get; set; }
|
||||||
|
public string? ReceiverName { get; set; }
|
||||||
|
public bool TfaEnabled { get; set; }
|
||||||
|
public bool HasPhoneNumber { get; set; }
|
||||||
|
public bool ReadOnly { get; set; }
|
||||||
|
|
||||||
|
/// <summary>"sms" or "authenticator" when Status == "requires_tfa".</summary>
|
||||||
|
public string? TfaType { get; set; }
|
||||||
|
public DateTime? TfaExpiration { get; set; }
|
||||||
|
public string? ErrorMessage { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class AccessCodeRequest
|
||||||
|
{
|
||||||
|
public string AccessCode { get; set; } = string.Empty;
|
||||||
|
public bool PreferSms { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TfaCodeRequest
|
||||||
|
{
|
||||||
|
public string Code { get; set; } = string.Empty;
|
||||||
|
/// <summary>"sms" or "authenticator".</summary>
|
||||||
|
public string Type { get; set; } = "authenticator";
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Status strings returned by <see cref="ReceiverAuthResponse.Status"/>.
|
||||||
|
/// </summary>
|
||||||
|
public static class ReceiverAuthStatus
|
||||||
|
{
|
||||||
|
public const string RequiresAccessCode = "requires_access_code";
|
||||||
|
public const string RequiresTfa = "requires_tfa";
|
||||||
|
public const string ShowDocument = "show_document";
|
||||||
|
public const string AlreadySigned = "already_signed";
|
||||||
|
public const string Rejected = "rejected";
|
||||||
|
public const string NotFound = "not_found";
|
||||||
|
public const string Expired = "expired";
|
||||||
|
public const string Error = "error";
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user