Reorganize the wizard steps to prioritize "Receivers" (step 1)
before "Message and Options" (step 3). Update `_currentStep`
logic, conditional checks, and validation to reflect the new
step order. Adjust `GetStepTitle` and `GetStepDescription`
methods to align with the updated step titles and descriptions.
Ensure user input handling and step-skipping behavior are
consistent with the new flow.
Replaced custom wizard UI with MudBlazor's MudStepper for a modern and consistent design. Added dynamic step titles, descriptions, and forms for envelope creation, including advanced settings like certification, reminders, and email notifications. Integrated PDF upload with preview functionality.
Refactored `CreateEnvelopeWizardPopup.razor` for better maintainability and modularity. Removed redundant code and centralized step-related logic. Improved localization, accessibility, and user experience.
Updated `EnvelopeGenerator.Server.Client.csproj` and `EnvelopeGenerator.Server.csproj` to include MudBlazor. Registered MudBlazor services in `Program.cs` and added required CSS/JS in `App.razor`. Updated styles in `sender-page.css` to align with the new stepper design.
Expose signed and received notification endpoints, with reset random payload variants, to exercise rendering and delivery without running a full envelope workflow.
Fall back to a fixed recipient when no email is supplied.
Add IsReadAndConfirm to DocumentSignedNotification and derive the action, status, and final action labels from it so read-only envelopes do not report a signature.
Pass the envelope read-and-confirm mode when finalizing so the signed email matches the receiver workflow.
Send notifications via IMessagingServiceClient and PublishEmailViaSmtpCommand instead of the static EmailSender. The sender address now comes from NotificationOptions and attachments are added through the command builder.
Rename the Notify parameter to receiverEmail so the call site contract is explicit.
Replace the hard-coded RabbitMQ setup with NotificationOptions bound from a configurable section. The new ConsumerType switch wires either the HTTP API client or the RabbitMQ client, and startup now fails with a clear error when required settings are missing.
Bump DigitalData.MessagingService.Client to 3.0.1 for the abstraction used by both transports.
The private static method `ReplacePlaceHolders` was removed from `CreateEnvelopeCommandHandler.cs`. This method was used to replace placeholders in a string with values from a dictionary. Its removal indicates that this functionality is either no longer needed or has been refactored elsewhere in the codebase.
Refactored `DocumentReceivedNotification` to use new properties `Origin`, `EnvelopeUuid`, and `ReceiverSignature` for constructing `EnvelopeURL`. Updated `LinkToDocument` and `LinkToDocumentText` to derive from `EnvelopeURL`.
Simplified `CreateEnvelopeCommandHandler` with record-like syntax, removing private fields and directly injecting dependencies.
Renamed and refactored `QueueInvitationEmailsAsync` to `SendInvitationEmailsAsync`, using `EnvNtfService.Notify` for email notifications, centralizing logic and improving clarity.
Improved error handling in email sending with logging. Updated variable names for clarity and cleaned up `using` directives.
Updated the `ContractType` property in the `EnvelopeTypeDto` class from a nullable integer (`int?`) to a nullable `ContractType` enum (`ContractType?`). This change enhances type safety and clarifies the expected values for the property.
Introduce the IRequestContext interface with an Origin property
in the EnvelopeGenerator.Application.Common.Interfaces namespace.
Implement this interface in the new RequestContext class within
EnvelopeGenerator.Server.Services, using IHttpContextAccessor to
access the Origin header. Register IRequestContext with the DI
container in Program.cs using AddScoped. Update using directives
to include necessary namespaces and reorganize for clarity.
Modified the User property in Envelope.cs to be conditionally nullable using the nullable preprocessor directive. This change allows the property to be nullable when the nullable directive is defined, enhancing flexibility and compatibility with different C# versions and project configurations.
Added a using directive for `EnvelopeGenerator.Domain.Constants` to utilize constants from that namespace. Changed the `ContractType` property from a nullable integer (`int?`) to a nullable `ContractType` enum or class, enhancing type safety and clarity.
Changed the `ContractType` property in `EnvelopeDto`, `CreateEnvelopeCommandHandler`, and `Envelope` classes from a nullable `int` to a nullable `ContractType` enum. This improves type safety and consistency across the codebase by using a specific enum type instead of a generic integer. Updated logic in `CreateEnvelopeCommandHandler` to remove unnecessary casting.
Added new record types `CreateEnvelopeDocumentDto`, `CreateEnvelopeFieldDto`, and `CreateEnvelopeReceiverDto` with XML documentation in `CreateEnvelopeCommand.cs`. Marked `ConfigService` as obsolete in `CreateEnvelopeCommandHandler.cs`. Modified `CertificationType` usage in `Fake.cs` to use the enum directly. Updated `EnvelopeGenerator.Tests.csproj` with a new project reference and compile directives. Introduced `MailTemplatePlaceholderDbTests` and `ReplacePlaceholderExtensionsTests` to verify placeholder replacement functionality. Added supporting model classes for testing. These changes improve code functionality and test coverage.
Changed the `Attachments` property type in `EnvelopeNotificationBase.cs` from `List` to `IReadOnlyList` to enhance immutability and thread safety. Updated the `FinalizeEnvelopeCommandHandler` in `FinalizeEnvelopeCommand.cs` to use a single-line syntax for `Attachments` initialization, improving code readability.
Introduced `EnvelopeNotificationBase` as a new base class for notifications, providing a unified structure with an abstract `GetTemplateType` method and optional attachments. Added `DocumentReceivedNotification` and updated `DocumentSignedNotification` to inherit from this base class, streamlining attachment handling and template type determination.
Refactored `IEnvelopeNotificationService` to use a generic `Notify` method, allowing for flexibility with different notification types. Updated `FinalizeEnvelopeCommandHandler` to align with the new attachment handling.
Added `EnvelopeNotificationExtensions` for converting attachments to `EmailAttachmentDto` objects and introduced `ReplacePlaceholderExtensions` for dynamic placeholder replacement in email templates using reflection. Removed outdated placeholder logic from `EnvelopeNotificationService`.
Added a check in SendMailHandler to prevent sending emails for deleted envelopes with a status of EnvelopeSaved or lower. Updated project version in EnvelopeGenerator.Server.csproj from 1.7.0 to 1.8.0 to reflect these changes.
Implemented caching in the PdfRenderController using IMemoryCache to improve performance by avoiding redundant PDF rendering. Added a new constructor parameter for IMemoryCache and a static TimeSpan field for cache duration. Introduced a private method, BuildCacheKey, to generate unique cache keys based on the SHA256 hash of PDF bytes. Updated the RenderPages method to check for cached pages before rendering and store results in the cache.
Refactored `ReadDocumentDetailsQueryHandler` to remove AutoMapper, improving performance by manually selecting necessary data. Simplified `SenderEditorPage.razor` by removing bootstrap logic and updating the UI for a more compact design. Streamlined envelope creation in `SenderPage.razor` by eliminating the bootstrap token. Updated styles in `envelope-viewer.css` for better alignment and readability.
Enhanced the `SenderEditorPage.razor` by injecting the `EnvelopeReceiverService` to manage envelope receivers. Updated the UI to include a remove button for each receiver, invoking the new `RemoveReceiverAsync` method. This method handles the deletion of receivers from both the UI and the server.
Modified `ReceiverDraft` and `SignatureFieldDraft` models to include `ReceiverId` and `ReceiverDraftId` for better tracking. Updated logic for identifying receivers without signature fields and creating receiver commands to use these new identifiers.
Added `DeleteAsync` method in `EnvelopeReceiverService.cs` to send DELETE requests for removing receivers. Updated `envelope-viewer.css` to style the new remove button with distinct appearance and hover effects.
Introduced `RemoveEnvelopeReceiverCommand` and its handler to
facilitate the removal of envelope receivers. Updated the
`EnvelopeReceiverController` to use C# 9's record-like syntax
for dependency injection, eliminating explicit private fields.
Added a `RemoveAsync` method to handle DELETE requests for
removing envelope receivers. Enhanced code documentation with
additional XML comments.
Updated the `value` attributes of `<option>` elements in `CreateEnvelopeWizardPopup.razor` and `SenderEditorPage.razor` to use `@CertificationType.AdvancedElectronicSignature` and `@CertificationType.ElectronicSignature` instead of hardcoded values "1" and "2". This enhances code maintainability and readability by leveraging descriptive and potentially type-safe values.
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.
Introduce `SignatureFieldParams` class to manage signature field dimensions with configurable `Width` and `Height`. Integrate this configuration into the service collection and replace hardcoded dimensions in `CreateEnvelopeCommandHandler.cs` and `SenderEditorPage.razor`. Update `appsettings.json` to include the new configuration section, allowing runtime adjustments.
Changed CertificationType from int? to CertificationType? enum across multiple files, including EnvelopeDto, EnvelopeTypeDto, and CreateEnvelopeCommand, to improve type safety. Removed the NormalizeCertificationType method as it is no longer necessary. Updated components and records to use the enum directly, enhancing code clarity and reducing potential errors. Added necessary using directives for the enum.
Introduce `NormalizeCertificationType` method to ensure consistent handling of certification types across the application. Update `CreateEnvelopeCommandHandler`, `CreateEnvelopeWizardPopup.razor`, and `SenderEditorPage.razor` to use this method. Modify `CertificationType` enum to include `ElectronicSignature` and remove `QualifiedSignature`. Update UI components to reflect these changes by removing the `QualifiedSignature` option.
Updated the CSS grid layout for the `.sender-create-wizard__progress` class from 4 to 5 columns. This change allows for an additional column in the progress indicator, potentially accommodating more items or steps in the sender creation wizard.
Refactored the `EnvelopeController` to use C# 9's record syntax for dependency injection, directly injecting `ILogger<EnvelopeController>` and `IMediator` into the constructor. Removed private fields `_logger` and `_mediator`, replacing them with constructor-injected properties. Updated methods to use these properties for consistency. Moved `DeleteEnvelopeRequest` to a top-level class for better organization. Enhanced XML documentation for improved clarity.
Introduced a new boolean property `IncludeDocAndDocRes` in the `ReadEnvelopeQuery` class to control the inclusion of document and document result details in query results. Updated `ReadEnvelopeQueryHandler` to handle this property, returning a simplified `EnvelopeDto` when set to `false`.
Modified `SenderPage.razor` to exclude document details by passing `includeDocAndDocRes: false` to `EnvelopeService.GetAsync()`. Enhanced `EnvelopeService` to accept and process the `includeDocAndDocRes` parameter, ensuring API requests respect this preference.
The footer text in `MainLayout.razor` and the header title in `IndexPage.razor` have been updated to change the branding from "SignFlow" to "signFLOW". This change ensures consistent presentation of the brand across the application by adjusting the capitalization.
Revised FinalizeEnvelopeCommand to notify each receiver
individually instead of converting documents to Base64.
Adjusted IsActive method in EnvelopeStatusExtensions to
include EnvelopePartlySigned as active. Updated project
version to 1.7.0-beta to reflect these changes.
Replaced PKCS#11-based cryptographic operations with a new DocumentService API integration. Removed all PKCS#11-related code, configurations, and dependencies, including options, self-test status, and signing logic. Updated `FinalizeEnvelopeCommand` to include a notification service and added base64 conversion for documents. Updated `ServiceCollectionExtensions` to register the new DocumentService client. Removed outdated documentation and diagrams related to PKCS#11. Updated project files and configurations to reflect these changes and incremented the version number. Added a comment in `EnvelopeFinalizationWorker` for future RabbitMQ integration.
Updated `EnvelopeGenerator.Infrastructure.Crypt.csproj` to add `DocumentService.Client` version `1.3.0` and upgraded several Microsoft.Extensions packages to version `10.0.10`.
In `Program.cs`, changed `DocumentService` registration to use the fully qualified name `EnvelopeGenerator.Server.Client.Services.DocumentService`.
Updated `EnvelopeGenerator.Tests.csproj` to upgrade `Microsoft.Extensions.DependencyInjection` and related packages to version `10.0.10`, including changes for the `net8.0` target framework.
Replaced UnauthorizedAccessException with a custom
AuthorizationException in SignPdfByEnvelopeCommandHandler
to provide more meaningful error handling. Added the
EnvelopeGenerator.Domain.Exceptions namespace to support
this change.
Integrated `PdfSignatureService` to enable fetching and previewing signed PDFs for completed envelopes. Updated `SenderPage.razor` to dynamically adjust popup headers and filenames based on the envelope's status. Enhanced `OpenPreviewAsync` to conditionally fetch signed or original PDFs.
Registered `PdfSignatureService` and DevExpress PDF Viewer in `Program.cs`. Implemented `PdfSignatureService` to handle API calls for retrieving signed PDFs with error handling.
Introduced `ESignParams` for configurable e-signature settings,
including `ApplicationName` and `DefaultReason`. Updated
`DocReceiverElementDto` and `PdfSignOptionsDto` to support
new properties. Registered `ESignParams` in DI container.
Refactored `SignPdfByElementCommand` to include new fields
and improved error handling. Added `SignPdfByEnvelopeReceiverCommand`
to enable signing documents for envelope receivers.
Replaced DevExpress with PdfSharp for PDF rendering in
`ReceiverSignedPage.razor`, improving layout and flexibility.
Enhanced `PdfSignatureController` with a new endpoint for
signing documents by envelope key.
Added `DataIntegrityException` for better error handling.
Updated `appsettings.json` with `ESignParams` configuration.
Added enums `PdfSignatureCoordinateUnit` and `PdfSignatureCoordinateOrigin` to support defining signature coordinates in points or inches and relative to either the bottom-left or top-left corner of the page.
Updated `PdfSignatureAppearanceDto` to include `CoordinateUnit` and `CoordinateOrigin` parameters with default values. Refactored `PdfDigitalSignatureService` to use a new `BuildSignatureBounds` method for calculating signature bounds, which handles unit conversion, origin adjustments, and validation.
Introduced `GetPageHeightInPoints` to retrieve page height for top-left origin calculations. Improved signature field naming precision and added error handling for invalid dimensions and page numbers.
Included a TODO for optimizing the signature check algorithm.
Extended `DocReceiverElementDto` to include an optional `Document` reference. Enhanced `ReadDocReceiverElementQuery` with `Id` and `IncludeDocument` properties for filtering and document inclusion.
Updated `ReadDocReceiverElementQueryHandler` to handle new query properties, enabling filtering by `Id` and optionally including associated documents.
Introduced `SignPdfByElementCommand` and its handler to support signing PDFs using either a provided `DocReceiverElementDto` or an `ElementId`. Added validation via `SignPdfByElementCommandValidator` to ensure proper usage.
Refactored and added necessary `using` directives for new dependencies.
Added `DATABASE_STRUCTURE_CONTEXT.md` to provide detailed
documentation of the database structure for the envelope
domain. This includes entity-to-table mappings, schema
snapshots, EF relationships, constraints, stored procedure
behavior, and trigger wiring paths.
Highlighted model-to-database drift risks, trigger mismatch
alerts, and provided migration-safe operating rules. Added a
refresh checklist to validate metadata consistency before and
after database migrations.
Updated namespaces for `CreateEnvelopeReceiverCommand` and related classes to `EnvelopeGenerator.Application.EnvelopeReceivers.Commands.CreateEnvelopeReceiver` for better organization and clarity.
- Updated namespaces in `CreateEnvelopeReceiverCommand`, `CreateEnvelopeReceiverCommandHandler`, and `CreateEnvelopeReceiverResponse`.
- Adjusted imports in `MappingProfile.cs`, `EnvelopeReceiverService.cs`, and `Fake.cs` to reflect the new namespace.
- Modified `EnvelopeReceiverController.cs` to use the updated namespace and simplified type reference in a `foreach` loop.
Updated the `ComposeSignaturePreviewPng` method in the `IPdfPageImageRenderer` interface to return a `Stream` instead of a `byte[]` for improved memory efficiency when handling large image data.
- Added `ComposeSignaturePreviewPngBytes` extension method to convert the `Stream` to a `byte[]` for backward compatibility.
- Updated `PdfPageImageRenderer` to return a `Stream` and adjusted its internal logic to reset the `MemoryStream` position before returning.
- Modified `DevSignatureInkController` to use the `Stream`-based implementation for HTTP responses.
- Made minor formatting adjustments in `PdfPageImageRenderer`.
These changes optimize memory usage while maintaining compatibility with existing workflows that require `byte[]`.
Added a critical pre-commercial release TODO to remove
`SixLabors.ImageSharp` and `QRCoder-ImageSharp` dependencies
and replace them with permissive-license alternatives. Updated
TODOs to focus on modularizing `EnvelopeSenderPage.razor`
and other server pages by splitting large components,
centralizing shared logic, and improving maintainability.
Included a TODO for a senior-level performance review of
sender/receiver flows to address route transitions, loading
logic, and perceived latency issues. Removed outdated TODO
on reducing `EnvelopeSenderPage.razor` complexity.
Introduced `ISignatureInkPayload` interface to standardize signature ink data and metadata. Updated `DocReceiverElementDto` and `DocReceiverElement` to implement this interface. Enhanced `IPdfPageImageRenderer` with methods for signature preview generation and image format validation.
Replaced `PdfSharp` with `DevExpress` for PDF rendering in `ReceiverSignedPage.razor`. Added `DevSignatureInkController` with endpoints for downloading raw and composed signature images. Updated project files to remove `SixLabors.ImageSharp` and integrate DevExpress.
Added configuration for development endpoints in `appsettings.json`. Improved exception handling, validation, and code maintainability.
Updated `PdfSignOptionsDto` and `PdfSignatureCheckItemDto` to use `DocumentElementId` (long) instead of `UUID` (string). Modified `PdfDigitalSignatureService` to reflect this change, including updates to `SignatureReasonMetaRegex`, `BuildReasonWithMeta`, and `ParseReasonMeta`. Adjusted method signatures, return values, and property assignments to ensure consistent use of `DocumentElementId`. These changes align with a shift in the application's data model to use numeric identifiers for document elements.
Refactored `Pkcs11Options` by removing `DefaultCertificationLevel` and improving property documentation. Replaced `VisualSignature` in `PdfSignOptionsDto` with `Appearance` using the new `PdfSignatureAppearanceDto` class, which encapsulates signature appearance details, including font and color settings.
Enhanced `PdfSignatureCertificationLevel` enum with more descriptive values and added XML documentation. Updated `IPdfDigitalSignatureService` to support optional signature images and removed redundant methods.
Refactored `PdfDigitalSignatureService` to streamline appearance handling, validate inputs, and improve maintainability. Removed unused methods and added support for `PdfSignatureAppearanceDto`.
Simplified `PdfSignatureController` by consolidating form properties into `PdfSignOptionsDto`. Improved code readability and flexibility while removing redundant logic.
Refactored `PdfSignOptionsDto` and `PdfVisualSignatureOptionsDto`:
- Converted both to immutable `record` types with non-nullable properties.
- Added XML documentation comments for properties and parameters.
Simplified `PdfDigitalSignatureService`:
- Updated `SignPdfAsync` to enforce non-nullable `PdfSignOptionsDto`.
- Removed redundant null checks and inlined `CreateSignatureBounds`.
- Simplified signature appearance and image data logic.
- Refactored `TryGetKeySize` to use `bool` with `out` parameter.
General improvements:
- Enhanced code readability and maintainability.
- Reduced nullable references and enforced stricter type safety.
Enhanced `PdfSignOptionsDto` with a `VisualSignature` property and introduced the `PdfVisualSignatureOptionsDto` class for configuring visual signature options. Updated `PdfDigitalSignatureService` to handle visual signatures, including page number resolution, signature bounds calculation, and appearance customization.
Refactored `PdfSignatureController` to support visual signatures by extending `SignPdfForm` with `SignatureImageFile` and `VSignature` properties. Improved validation for page numbers and signature dimensions. Streamlined `Sign` and `IsSigned` endpoints for better clarity and reduced redundancy.
Added XML documentation for improved API clarity and performed general code cleanup to enhance maintainability.
Refactored `IPdfDigitalSignatureService` to replace `byte[]` with `Stream` for input and output, improving memory efficiency and scalability. Updated `PdfDigitalSignatureService` implementation to support stream-based operations, including signing, checking, and extracting PDFs.
Modified `SignPdfAsync` to handle multiple signatures sequentially using streams and ensured proper disposal of intermediate streams. Updated `CheckPdfSignatureAsync` and `ExtractOriginalPdfAsync` to use streams, reducing memory overhead.
Refactored `PdfSignatureController` to use streams for file handling, enabling efficient processing of large files. Introduced helper methods for stream handling and enhanced cancellation support. Improved code maintainability by consolidating common logic and reducing duplication.
Updated the `EnvelopeGenerator.Server` project version from `1.4.0-beta` to `1.5.0-beta`.
This includes updates to the file version (from `1.4.0.0` to `1.5.0.0`)
and the assembly version (from `1.4.0.0` to `1.5.0.0`).
Replaced the `ContactInfo` property with separate `Email` and `Phone` fields in `PdfSignOptionsDto` and `PdfSignatureCheckItemDto` for better granularity. Updated the `PdfDigitalSignatureService` to handle the new fields, introducing `BuildContactInfo` and `ParseContactInfo` methods for constructing and parsing contact information.
Modified the `PdfSignatureController` to reflect these changes, updating request models and the `SignPdfAsync` method. Updated the `README.md` to document the new structure. These changes improve the clarity and structure of contact information handling.
The `SigningTime` property has been removed from the `PdfSignOptionsDto` class and related client-side input handling. It is now set automatically on the server side based on the `UseUtcSigningTime` configuration (`UtcNow` or local time).
Updated the `PdfDigitalSignatureService` to always set `SigningTime` server-side, ensuring consistent and deterministic behavior. Removed `SigningTime` from the `PdfSignatureController` and adjusted the logic to exclude it from the `signOptions` object.
Updated the `README.md` to reflect these changes, clarifying that `SigningTime` is now server-side only. These changes improve security and simplify client integration.
The README.md has been extensively restructured to improve clarity, technical depth, and usability. Key changes include:
- Shifted most sections from English to German for localization.
- Consolidated distributed runbooks into a unified reference for PKCS#11/SoftHSM integration.
- Expanded architecture overview with deployment patterns and runtime paths.
- Replaced PKCS#11 basics with detailed setup instructions and troubleshooting tips.
- Updated runtime configuration examples with security best practices.
- Highlighted implemented services, models, and DTOs in the DI setup.
- Added sections on operational challenges, troubleshooting, and monitoring.
- Introduced an API health endpoint and smoke test recommendations.
- Clarified API behavior for signature metadata to ensure deterministic integration.
- Expanded security guidelines, including key rotation and SSH rollback procedures.
- Added a forward-looking section on potential improvements.
- Retained and updated references to official documentation and tools.
These changes aim to provide a comprehensive, structured, and production-aligned guide for developers and engineers.
Removed the `[HttpGet("sign/test")]` endpoint and its `Test`
method from the `PdfSignatureController`. This method
contained hardcoded Base64 PDF data and predefined signing
options for testing purposes. Eliminated the associated
logic for decoding the Base64 string, creating signing
options, signing the PDF, and returning the signed file.
These changes streamline the controller by removing
unnecessary and potentially insecure functionality,
ensuring cleaner and more production-ready code.
Updated the `Pkcs11Options` class to rename the `DefaultApplicationName` property to `ApplicationName`, clarifying its role as a globally controlled value embedded in PDF signature metadata.
Modified `PdfDigitalSignatureService` to source `ApplicationName` directly from `Pkcs11Options`, removing client-level overrides. Updated `PdfSignatureController` to reflect this change by removing the `ApplicationName` property from `SignOptions`.
Updated `appsettings.json` and `README.md` to reflect the property name change. These changes enforce stricter configuration control, improving metadata consistency and security.
The `CertificationLevel` property was removed from the `PdfSignatureOptions` class. It is now explicitly set to `PdfSignatureCertificationLevel.FormFillingAndAnnotations` in all instances where `PdfSignatureOptions` is instantiated.
Previously, `CertificationLevel` was nullable and dynamically set from the `request` object or defaulted to `PdfSignatureCertificationLevel.NoCertification`. These changes ensure consistent behavior by standardizing the certification level to `FormFillingAndAnnotations`.
Enhanced PDF signing with UUID and metadata handling:
- Added `UUID` and `OriginalDocumentSha256` to `PdfSignOptionsDto` and `PdfSignatureCheckItemDto`.
- Introduced `BusinessReason` to separate metadata from signature reasons.
- Updated `PdfDigitalSignatureService` to embed and parse metadata in signature reasons.
- Improved error handling to include metadata in validation results.
- Updated `PdfSignatureController` to handle `UUID` in signing requests.
Refactored PKCS#11 configuration:
- Replaced `LibraryPath` with `AssetsRootPath` for asset resolution.
- Added `ProxySocket` and `DefaultApplicationName` options.
- Clarified runtime behavior for asset resolution in `README.md`.
Updated documentation and examples to reflect these changes.
Updated `.gitignore` to exclude new files and directories, including `FodyWeavers.xsd` and `appsettings.Secrets.json`.
Refactored `PdfDigitalSignatureService`:
- Improved signing time handling by calculating fallback inline.
- Simplified `SignPdfAsync` by inlining signature building.
- Added `ParseByteRanges` to extract `/ByteRange` values from PDFs.
- Introduced `CoversWholeDocument` to validate document coverage.
Enhanced signature validation:
- Integrated `ParseByteRanges` and `CoversWholeDocument`.
- Streamlined `PdfSignatureCheckItemDto` construction.
- Updated properties to calculate values inline.
- Improved `Unchanged` property to check cryptographic validity and document coverage.
These changes enhance maintainability, readability, and functionality.
Integrated cryptographic functionality by adding a reference to `EnvelopeGenerator.Infrastructure.Crypt.csproj`. Updated `Program.cs` to include dependency injection for cryptographic services and load `appsettings.Secrets.json` for sensitive configurations. Added a new `Crypt` section in `appsettings.json` to configure PKCS#11 cryptographic operations, enhancing security and signing capabilities.
Introduced a cryptographic infrastructure for PDF signing and validation using PKCS#11-based hardware security modules (HSMs) or software tokens. Key changes include:
- Added `PdfDigitalSignatureService` for signing PDFs, multi-signature support, and signature validation.
- Implemented `Pkcs11ExternalSigner` and `Pkcs11PdfSigningRsa` for PKCS#11-based signing with DevExpress PDF infrastructure.
- Added utilities like `Pkcs11SessionRunner`, `Pkcs11InteropBootstrap`, and `Pkcs11ToolBridge` for session management, library initialization, and fallback mechanisms.
- Introduced `Pkcs11Options` for managing PKCS#11 configurations.
- Updated project dependencies to include `DevExpress.Document.Processor`, `System.Security.Cryptography.Pkcs`, and `Pkcs11Interop`.
- Enhanced error handling and fallback support for PKCS#11 operations.
These changes enable robust and extensible PDF signing capabilities with detailed signature metadata extraction and validation.
Introduced `Pkcs11Options` for configuring PKCS#11 signing workflows, including properties for library path, token selection, and signing metadata. Added `PdfSignOptionsDto` to represent signing options and `PdfSignatureCheckResultDto` with related DTOs for signature validation.
Defined `PdfSignatureCertificationLevel` enum for certification levels. Added `IPdfDigitalSignatureService` interface to support signing and validating PDF signatures. These changes enable robust and extensible handling of digital signatures.
Modified the `ByteData` property in `DocumentDto.cs` to use a `set` accessor instead of `init`, enabling updates after initialization.
Updated resource manager references in `frmEnvelopeMainData.vb` to use `CommonServices.My.Resources.Model.ResourceManager` for localized string retrieval.
Updated the project to support both net7.0 and net8.0 frameworks.
Modified `<TargetFramework>` to `<TargetFrameworks>` and added
conditional `<ItemGroup>` entries for dependencies and project
references specific to each framework. Updated package versions
(e.g., Microsoft.Extensions.DependencyInjection to 9.0.6) and
introduced new dependencies for net8.0, including
Microsoft.EntityFrameworkCore 8.0.17. Added a `<Compile Remove>`
directive for net7.0 to exclude Crypt-related files. Ensured
compatibility and maintained backward support for net7.0.
A new project, `EnvelopeGenerator.Infrastructure.Crypt`, has been added to the solution. This project targets `.NET 8.0` and includes several `Microsoft.Extensions` dependencies (e.g., `Configuration.Binder`, `DependencyInjection.Abstractions`, etc.) and the `Pkcs11Interop` package.
The solution file (`EnvelopeGenerator.sln`) has been updated to include the new project, its build configurations, and its nesting under the same parent as `EnvelopeGenerator.Infrastructure.Doc`.
Updated README.md for clarity and added official references. Introduced detailed infrastructure and integration plans for FES, including phased implementation, deployment options, and risk mitigations. Added FES workflow diagrams in draw.io and PDF formats. Documented SoftHSM testing process and integration details in ticket.md. Improved alignment with clean architecture principles and production readiness.
Updated the `TranslateCertificationType` and `TranslateFinalEmailType` functions to use the `ResourceManager` from the `CommonServices.My.Resources.Model` namespace instead of the `Resources.Model` namespace for consistency and improved resource management.
Added a detailed README for the `EnvelopeGenerator.Infrastructure.Crypt` project, explaining its purpose, functionality, and integration with PKCS#11-based cryptographic workflows.
Highlights include:
- Overview of the project's role in FES workflows.
- Explanation of SoftHSM and PKCS#11 deployment patterns.
- Mapping of functionality to FES diagram steps 6-8.
- Documentation of service interfaces and DI entry point.
- Configuration guidance with JSON examples and security best practices.
- Instructions for obtaining PKCS#11 values and setting up SoftHSM.
- Checklist for IT handover and environment setup.
- Steps for running cryptographic tests with PowerShell and Linux examples.
- Common failure diagnostics and their meanings.
- Clarification of signing semantics and validation requirements.
- FAQ addressing common questions about SoftHSM and PKCS#11 usage.
This update ensures clear guidance for developers and IT teams to configure and integrate the cryptographic layer effectively.
Added a `DxLoadingPanel` to display a loading indicator during the bootstrap process. Introduced the `IsBootstrapLoading` property to track bootstrap progress. Refactored `OnParametersSetAsync` to handle bootstrap tokens more effectively, including redirecting to `/sender` if no token is provided. Updated `TryApplyBootstrapAsync` to adjust navigation behavior when the bootstrap payload is `null`.
Enhanced `OnAfterRenderAsync` to process `_pendingBootstrapToken` more cleanly and removed redundant logic. Simplified navigation and improved code readability and maintainability.
Introduced a new step (step 2) in the `CreateEnvelopeWizardPopup` for configuring envelope settings, including security, reminders, and expiration options.
- Added fields for certification type, final email options, 2FA, access codes, and reminder settings.
- Updated step titles, descriptions, and total steps from 4 to 5.
- Implemented validation logic for the new settings step.
- Added methods to handle changes in settings fields and apply defaults.
- Updated `CreateEnvelopeWizardResult` and `CreateEnvelopeBootstrapPayload` to include new fields.
- Modified `SenderEditorPage` and `SenderPage` to handle new settings.
- Styled the new step with updated CSS for grids, groups, and toggles.
- Refactored state reset logic to initialize new fields.
Introduced a document preview feature in the `CreateEnvelopeWizardPopup` component. This includes:
- Injected `PdfRenderService` for rendering PDF pages.
- Replaced document metadata display with a preview card.
- Added `SenderPdfImageEditor` for interactive PDF previews.
- Implemented state management for preview pages and overlays.
- Added fallback logic to estimate PDF page count.
- Enhanced `ResetWizardState` to reset preview-related fields.
- Styled the preview card and wrap with new CSS classes.
- Added placeholder event handlers for editor interactions.
Replaced static upload message in `CreateEnvelopeWizardPopup.razor` with a new `PdfFileDropZone` component to enhance user experience. The component supports drag-and-drop functionality, file selection, and dynamic states (e.g., disabled, drag-active).
Introduced `PdfFileDropZone.razor` with customizable parameters such as `Disabled`, `HasDocument`, `UploadText`, and `DragDropHintText`. Added event handling for drag-and-drop interactions and file selection.
Updated `sender-page.css` to include styles for the new component, ensuring seamless integration with the existing layout. Adjusted styles for hover effects, drag-active state, and disabled state.
These changes improve usability and make PDF uploads more intuitive.
Introduced `ReceiverSuggestionFilterHandler` to refine the
filtering of recent receiver suggestions based on name and
email. Added `SuggestionLimit` constant to replace hardcoded
limits and ensure consistency. Updated UI to use the new
`FilteredRecentSuggestions` property, which leverages the
`BuildFilteredRecentSuggestions` method for grouping,
ordering, and limiting suggestions. Adjusted
`OnDocumentSelectedAsync` to use the new constant. Added
necessary `@using` directive for the filter handler.
Introduce `ReceiverFilterCriteria` to encapsulate filtering criteria for receivers, including normalization of `FullName` and `EmailAddress`. Add `ReceiverSuggestionFilterHandler` to filter `RecentReceiverSuggestionDto` objects based on the criteria. Includes methods for matching criteria and filtering suggestions.
Replaced receiver list with a tag-based `DxTagBox` for better flexibility and dynamic updates. Updated receiver management logic to synchronize `_receivers` and `_receiverTags`. Enhanced accessibility with ARIA attributes for the suggestion list.
Redesigned the "Add Receiver" button with custom styles, hover effects, and an inline SVG icon. Improved the suggestion list with horizontal scrolling and nowrap styling. Styled tags and added a remove button for each tag.
Increased recent receiver suggestions fetch limit to 20. Added validation to ensure default envelope type selection. Refactored empty state handling and cleaned up redundant code for better maintainability.
Updated the `Take` property in `ReadRecentReceiverSuggestionsQuery` to be nullable, allowing for unlimited results when not specified. Refactored the `Handle` method in `ReadRecentReceiverSuggestionsQueryHandler` to conditionally apply the `Take` limit only when provided. Renamed the cancellation token parameter for consistency. Improved code clarity and flexibility by removing redundant operations and dynamically applying the `Take` logic.
Added new localized strings for "Recently used recipients" and
"Skip" in German, English, and French resource files. Updated
the `CreateEnvelopeWizardPopup.razor` to enhance the "Add
Receiver" button with a primary render style and a new CSS
class. Introduced styles for the button in `sender-page.css`
to improve its appearance with a minimum width, bold font,
and box shadow.
Introduced a feature to display and apply recent receiver
suggestions in the `CreateEnvelopeWizardPopup` component.
Added a new section in step 2 to show recently used receivers,
with loading and state management logic. Updated the
`ReceiverService` to fetch suggestions from the backend API.
Enhanced the UI with new styles for the suggestions section
and improved localization support. Refactored state
management to handle loading, resetting, and applying
suggestions. Minor cleanup and adjustments to ensure proper
state transitions.
Updated RecentReceiverSuggestionDto to use `init` properties,
adding immutability and a new `LastUsedAt` field. Refactored
ReadRecentReceiverSuggestionsQueryHandler to simplify query
logic, remove `IMapper` dependency, and improve determinism
in results. Introduced tie-breaking for duplicate timestamps
and optimized ordering by `LastUsedAt` and `EmailAddress`.
Removed redundant `Include` and mapping steps for clarity.
Added a detailed plan document outlining the development of a "recent receiver suggestions" feature for step 3 of the sender wizard. The plan defines team working rules, objectives, functional requirements, and architecture direction across application, server, and client layers.
The implementation is divided into six phases, covering MediatR query creation, API endpoint addition, client integration, UI updates, regression testing, and technical debt tracking. Each phase includes black-box test suggestions to ensure quality and robustness. The plan emphasizes incremental development, user approval, and quality-focused processes.
Introduce `RecentReceiverSuggestionDto` to represent recent receiver suggestions with `FullName` and `EmailAddress`.
Add `ReadRecentReceiverSuggestionsQuery` to retrieve recent receiver suggestions scoped by sender username and limited to 3-5 results.
Implement `ReadRecentReceiverSuggestionsQueryHandler` to process the query using Entity Framework Core and AutoMapper.
Update `MappingProfile` to map `EnvelopeReceiver` to `RecentReceiverSuggestionDto`.
Added the `<LangVersion>` property to `EnvelopeGenerator.Application.csproj` with the value `latest`. This ensures the project uses the most up-to-date C# language features supported by the compiler, enabling access to new enhancements and features as they become available.
- Introduced a DevExpress toast-based notification system using `DxToastProvider` and `IToastNotificationService` for consistent feedback.
- Standardized request-to-domain mapping with AutoMapper/profile conventions or reflection-based mappers, enforced at the Core library level.
- Removed dynamic SQL string composition and migrated to parameterized queries to address SQL injection vulnerabilities. Added CI guardrails to prevent reintroduction.
- Refined UX on `EnvelopeSenderPage.razor` to enforce deterministic row double-click behavior and align row action buttons/tooltips.
- Enabled SPA-style language switching for immediate UI culture updates without page reloads.
- Added sender-scoped caching for "recent receiver suggestions" with short TTL, invalidation hooks, and cross-sender isolation.
Removed the placeholder option from the envelope type dropdown to simplify the UI. Introduced a new `GetDefaultEnvelopeTypeId()` method to centralize and enhance the logic for determining the default envelope type. This method prioritizes envelope types with titles containing "Handwritten Signature" if available, improving alignment with user preferences. Updated `_selectedEnvelopeTypeId` initialization to use the new method for better maintainability.
Added a new resource entry for the "Next" button in the
localization files for German (de-DE), English (en-US), and
French (fr-FR). Translations include "Weiter" in German,
"Next" in English, and "Suivant" in French.
Accept bootstrapToken query parameter and consume one-time payload from sessionStorage-backed service.
Hydrate editor state with title, message, envelope type, receivers, and PDF document from bootstrap data.
Refactor draft save into reusable core flow and trigger non-navigating auto-save after bootstrap is applied.
Prevent stale token replay by clearing query token from URL and handling invalid tokens gracefully.
Introduce a 4-step modal wizard on SenderPage for creating envelopes.
Validate required fields, support optional skip, receiver management, PDF upload, and keyboard shortcuts.
Persist wizard payload in sessionStorage via token-based bootstrap service and navigate to editor with bootstrapToken.
Register bootstrap storage service in both client and server DI containers and add dedicated sender wizard styling.
Added a "Markdown Audit Snapshot" section to document the status, gaps, and recommendations for markdown files in the repository. Included a "Documentation Audit TODO" checklist for tracking updates. Updated the "Active Architecture (Post-Migration)" section to reflect the current Blazor Auto (Server+WASM hybrid) setup. Identified and marked outdated or redundant markdown files for removal or archival. Highlighted the need for periodic synchronization of documentation with implementation progress.
Changed the `DxAccordionItem` in `SenderEditorPage.razor` to be collapsed by default. Removed unused elements (`sender-settings-chip` and `sender-settings-grid`) from the accordion's content template.
Updated `envelope-viewer.css` to refine the accordion header's appearance: reduced font size, font weight, and padding, and added a `line-height` property for better spacing.
Replaced inline styles with reusable CSS classes to improve maintainability, readability, and scalability. Updated the layout and styling of key components, including the action bar, title and message inputs, PDF metadata display, and buttons. Introduced a `DxAccordion` for envelope settings and redesigned the empty state and save result dialog. Added dynamic styling using CSS variables and centralized styles in `envelope-viewer.css`. Removed redundant inline styles and improved overall UI consistency.
Changed the `ILogger` dependency injection type parameter from `EnvelopeSenderPage` to `SenderPage` to ensure alignment with the correct class name or intended logging context.
Added new localized strings to `Model.en.resx`, `Model.fr-FR.resx`,
and `Model.resx` for additional features/settings in English,
French, and German. Updated `SenderEditorPage.razor` to inject
`ModelLocalizer` and modified the `L` function to prioritize
localized strings from `ModelLocalizer` over `UiLocalizer`.
Included `@using EnvelopeGenerator.Domain.Resources` to ensure
access to the `Model` resource file. These changes improve
localization flexibility and maintainability.
Refactored `PdfRenderController.cs` to replace JSON/base64 `byte[]` transport with binary streaming for PDF rendering, improving memory and latency performance for large files.
Introduced a DevExpress toast-based notification system using `DxToastProvider` and `IToastNotificationService` for consistent, actionable feedback.
Standardized request-to-domain mapping with AutoMapper/profile conventions or reflection-based mappers, enforced at the Core library level to reduce drift.
Addressed SQL injection risks by replacing dynamic SQL string composition with parameterized queries, conducted a repo-wide audit, and added CI guardrails.
Improved UX in `EnvelopeSenderPage.razor` by enforcing deterministic row double-click behavior and aligning row action buttons/tooltips.
Implemented SPA-style language switching for immediate UI culture updates without page reloads.
Updated the SQL Server connection string in `appsettings.json`.
Updated the `Navigation.NavigateTo` method in `LanguageControls.razor` to set the `forceLoad` parameter to `true`. This ensures that the application performs a full page reload when the language is changed, improving consistency in language updates.
The `EnvelopeSenderEditorPage.razor` file was completely removed, including all Razor markup, Blazor components, JavaScript references, CSS styles, and C# code-behind logic.
Key changes:
- Removed the `/sender/editor_legacy` route and all associated imports (`@using`) and dependency injections (`@inject`).
- Deleted the entire HTML structure, including UI elements for PDF editing, signature placement, and receiver management.
- Removed all references to external CSS and JavaScript files.
- Deleted Blazor components like `DxPdfViewer`, `DxPopup`, and `DxTextBox`.
- Removed C# code for state management, lifecycle methods, event handlers, and helper methods.
- Eliminated localization, validation logic, session persistence, and cache management.
- Removed PDF manipulation logic (e.g., placeholder rendering with `PdfSharp`).
- Deleted receiver management logic, including email suggestions and validation.
This change removes the entire functionality of the `EnvelopeSenderEditorPage`, including its UI, backend logic, and external integrations.
Centralized dependency injection registrations into dedicated
extension methods/modules to reduce startup composition sprawl
and improve maintainability.
Refactored `PdfRenderController.cs` and client service contract
to replace JSON/base64 `byte[]` transport with binary streaming
(`application/octet-stream` or multipart) for improved memory
and latency performance with large PDFs.
Introduced a DevExpress toast-based notification system using
`DxToastProvider` and `IToastNotificationService` for consistent,
actionable feedback across sender/receiver flows.
Standardized request-to-domain mapping with AutoMapper/profile
conventions or reflection/source-generator-based mappers to
eliminate manual mapping drift and enforce consistency across
services.
Addressed SQL injection vulnerabilities by replacing dynamic SQL
string composition with parameterized queries. Conducted a repo-
wide audit and added CI guardrails to prevent reintroduction.
Refined UX for `EnvelopeSenderPage.razor` to enforce deterministic
row double-click behavior (preview OR edit) and aligned row action
buttons/tooltips to eliminate ambiguous navigation.
- Removed unnecessary request/payload remapping in `Services/` and ensured direct request DTO usage where safe.
- Centralized DI registrations into extension methods/modules to reduce startup sprawl and improve maintainability.
- Refactored `PdfRenderController.cs` to replace JSON/base64 `byte[]` transport with binary streaming for better memory/latency performance.
- Implemented a DevExpress toast-based notification system with `DxToastProvider` and `IToastNotificationService` for consistent feedback flows.
- Standardized request-to-domain mapping using AutoMapper/profile conventions or source-generator-based mappers to eliminate drift.
- Addressed SQL injection risks by replacing dynamic SQL string composition with parameterized queries, conducted a repo-wide audit, and added CI guardrails.
Introduced a standardized mapping policy to eliminate manual
property-by-property mapping drift (e.g., in
`CreateEnvelopeCommandHandler`). This policy may leverage
AutoMapper with profile conventions or a reflection/source-
generator-based approach and will be enforced across envelope
workflows. The implementation will occur at the Core library
level to ensure consistent guardrails for all services.
Removed the instruction to manually audit redundant mappings
in `EnvelopeGenerator.Server.Client/Services/`, aligning with
the shift toward automated mapping standardization.
Updated the manual testing workflow to include the new mapping
policy requirement, emphasizing its role in improving
consistency and maintainability.
Centralized `HttpRequestException` creation with a new
`CreateHttpException` method to improve code reuse and
consistency. Updated methods to handle `HttpStatusCode.NotFound`
gracefully, returning `null` where appropriate instead of
throwing exceptions. Introduced `TryGetSenderDocumentBytesByEnvelopeIdAsync`
to encapsulate fallback logic for fetching document bytes.
Removed redundant inline exception handling and standardized
error handling across methods.
Updated `UpdateAsync` to include `e.Title`, `e.Message`, and `e.TfaEnabled` assignments, ensuring database updates reflect request values.
Set `e.Status` to `EnvelopeStatus.EnvelopeSaved` during the update process.
Updated in-memory `envelope` object to reflect changes to `Title`, `Message`, `TfaEnabled`, and `Status` fields.
Simplify and restructure conditional logic in `SenderPdfImageEditor.razor` for better readability and maintainability. Merge redundant `else` blocks and reorganize rendering logic for page previews and fields.
Enhance PDF loading and page preview generation in `SenderEditorPage.razor`. Add error handling for failed page rendering, log warnings, and ensure consistent `_pageCount` initialization based on available data.
These changes improve code clarity, robustness, and maintainability.
Introduced `ValidationBehavior` to validate MediatR requests using FluentValidation. Registered the behavior in the pipeline and added validators for `ReadDocumentDetailsQuery` and `ReadDocumentQuery`. Updated dependency injection to include validators and added FluentValidation NuGet packages. Improved exception handling with `BadRequestException` for validation failures. Refactored namespaces and imports to support the changes.
Introduced a new `ReadDocumentDetailsQuery` to fetch document
metadata (`DocumentDetailsDto`) without the binary payload.
Updated `MappingProfile` to map `Document` to `DocumentDetailsDto`.
Refactored `DocumentService` to handle separate fetching of
metadata and binary data, combining them into `DocumentDto`.
Changed the metadata endpoint to `/api/Document/details`.
Added a new `GetDocumentDetails` endpoint in `DocumentController`
to return metadata without binary data. Updated
`EnvelopeReceiverPageDataService` with a new method
`GetDocumentMetadataOfSenderAsync` for fetching metadata.
These changes improve efficiency by allowing clients to load
metadata without transferring large binary data when unnecessary.
Introduce a new `DocumentDetailsDto` record to encapsulate shared document metadata and elements without binary payload. Refactor `DocumentDto` to inherit from `DocumentDetailsDto`, eliminating redundant properties and improving code reuse.
Convert `DocumentDto` from a class to a record for immutability. Add a parameterized constructor to `DocumentDto` for initializing binary data alongside metadata. Update `ByteData` to use the `init` accessor.
These changes enhance maintainability, reduce duplication, and enforce immutability by leveraging C# records and inheritance.
Applied a modular page architecture to `EnvelopeSenderPage.razor` by splitting large pages into smaller subcomponents, eliminating duplicated code paths, and centralizing shared logic for maintainability.
Conducted a performance review of sender/receiver flows, addressing route transitions, component lifecycle behavior, loading-state correctness, and duplicate API calls. Treated loading logic defects as architectural issues.
Audited client `Services` to remove unnecessary request/payload remapping and simplify HTTP method transformations.
Centralized dependency injection registrations into extension methods/modules to reduce startup composition sprawl.
Refactored `PdfRenderController.cs` to replace JSON/base64 `byte[]` transport with binary streaming for improved memory/latency performance in large PDF rendering.
Implemented a DevExpress toast-based notification system using `DxToastProvider` and `IToastNotificationService` for consistent, actionable feedback across sender/receiver flows.
Refactor `EnvelopeSenderPage.razor` to focus on UI composition
and state orchestration, avoiding heavy domain logic. Adopt a
modular page architecture to improve maintainability by splitting
large pages into smaller subcomponents and centralizing shared
logic. Conduct a performance review of sender/receiver flows to
optimize route transitions, component lifecycle behavior, and
loading-state correctness.
Audit `Services` for redundant request/payload remapping and
eliminate unnecessary transformations. Centralize dependency
injection registrations into dedicated extension methods to
reduce startup composition sprawl.
Refactor `PdfRenderController.cs` and its client service contract
to replace JSON/base64 transport for PDF rendering with binary
streaming (`application/octet-stream` or multipart). Add a `TODO`
comment to highlight the need for further optimization of large
PDF handling to reduce payload size and memory pressure.
Removed AutoMapper dependency in `ReadEnvelopeTypesQueryHandler` and replaced it with manual projection to address null-materialization issues. Updated `EnvelopeType` entity properties to nullable types to align with the database schema. Adjusted computed properties to handle null values gracefully.
Enhanced `SenderEditorPage` with authentication checks, improved handling of reminder and expiry settings, and added validation for user input. Introduced `NormalizeSettings` and `ValidateSettings` methods to ensure consistent and valid configurations. Refactored checkbox value parsing for better reliability.
Injected `AuthService` and `IStringLocalizer` for authentication and localization support. Improved error messaging and localized validation errors. Performed minor code cleanup and refactoring for better readability and maintainability.
Moved sender dashboard business/status logic into dedicated
services and extension methods to decouple domain logic from
UI components. Refactored `EnvelopeSenderPage.razor` to focus
on UI composition and state orchestration.
Applied a modular page architecture by splitting large pages
into smaller subcomponents, eliminating duplicated code, and
centralizing shared logic for maintainability.
Conducted a senior-level performance review of sender/receiver
flows, addressing route transitions, loading-state correctness,
and perceived latency issues.
Audited client services for unnecessary request/payload
remapping, removing redundant transformations, and streamlining
HTTP methods. Centralized dependency injection registrations
into extension methods/modules to reduce startup composition
sprawl and improve maintainability.
Enhanced `EnvelopeDto` with new properties for advanced settings, including final email options, reminders, and expiration settings. Updated `SenderEditorPage.razor` to include a new UI section for configuring these settings, with dropdowns, checkboxes, and input fields.
Introduced `EnvelopeTypeService` to fetch envelope type data from the backend and applied defaults based on the selected envelope type. Registered the service in `Program.cs` for dependency injection.
Improved lifecycle methods in `SenderEditorPage.razor` to load and apply envelope settings. Enhanced localization, error handling, and data binding for the new settings. Updated `CreateEnvelopeCommand` to include the new properties.
Refactored code for better organization and maintainability, and added logging for debugging envelope type loading issues.
Refactored `EnvelopeSenderPage.razor` to reduce complexity by
moving business and status logic into dedicated services and
extension methods, focusing the component on UI composition
and state orchestration.
Introduced a modular page architecture by splitting large pages
into smaller subcomponents, eliminating duplicated code paths,
and centralizing shared UI/domain logic for better maintainability.
Performed an audit of `EnvelopeGenerator.Server.Client/Services/`
to remove unnecessary request/payload remapping and redundant
transformations, ensuring direct request DTO usage where safe.
Planned a senior-level performance review for sender/receiver
flows to address route transitions, loading-state correctness,
duplicate API calls, and perceived latency issues.
Updated `AGENTS.md` to document manual testing workflow changes
and reflect the refactoring efforts.
Refactored the `UpsertAsync` method in `EnvelopeService` to remove
manual construction of the HTTP POST payload. The method now
directly uses the `CreateEnvelopeCommand` object as the payload
for the `PostAsJsonAsync` call. This change reduces redundancy,
simplifies the code, and leverages the existing object structure
for better maintainability.
Added new optional properties to `CreateEnvelopeCommand` for detailed configuration, including `EnvelopeId`, `Language`, `UseAccessCode`, and expiration settings. Introduced `ResolveEnvelopeSettingsAsync` to centralize settings resolution logic. Updated `CreateEnvelopeCommandHandler` to handle new properties and improve envelope creation/update flow. Added `EnvelopeSettings` record for structured settings management. Enhanced SQL update logic with `UseSQLExecutor` support. Improved handling of language resolution, reminders, and expiration rules.
Refactored `EnvelopeSenderPage.razor` to reduce complexity by
moving business/status logic into dedicated services and
extension methods. Focused the component on UI composition
and state orchestration, avoiding heavy domain logic in the
Razor file.
Introduced a modular page architecture by splitting large
pages into smaller subcomponents, eliminating duplicated
code paths, and centralizing shared logic for better
maintainability.
Conducted a senior-level performance review for sender/
receiver flows, addressing route transitions, component
mount/unmount behavior, loading-state correctness, duplicate
API calls, and perceived latency. Treated loading logic
defects as architecture/performance issues.
Updated `Navigation.NavigateTo` calls across multiple files to set `forceLoad` to `false`, preventing unnecessary full page reloads.
- **LanguageControls.razor**: Prevent full reload when switching languages.
- **EnvelopeSenderPage.razor**: Avoid reload during logout navigation.
- **LoginReceiverPage.razor**: Skip reload after successful envelope receiver login.
- **LoginSenderPage.razor**: Prevent reload after successful sender login.
These changes improve performance and enhance user experience by enabling smoother page transitions.
Added a null-conditional operator (`?.`) to safely access the
`ByteData` property of the `senderDoc` object, preventing a
potential `NullReferenceException` when `senderDoc` is null.
Replaced `DxPdfViewer` with `SenderPdfImageEditor` to enable
PDF rendering, page previews, and field overlay editing.
Added dependency injection for `PdfRenderService` and new
state fields (`_previewPageCount`, `_previewPagePreviews`,
`_previewFileName`, `_previewFieldOverlays`) to manage PDF
metadata and interactions.
Updated `OpenPreviewAsync` to render PDF pages using
`PdfRenderService` and handle errors gracefully. Introduced
`PreviewPdfDataUrl` for generating data URLs and a static
helper `EstimatePdfPageCount` for fallback page count
estimation. Added placeholder methods for user interactions
with the editor.
Improved cleanup logic to reset state fields when the viewer
is unmounted. These changes enhance the PDF preview
functionality while maintaining backward compatibility.
Updated EnvelopeSenderPage to use InteractiveWebAssembly
rendering mode. Removed unused services and authentication
logic, replacing `ReceiverPageDataService` with
`DocumentService` for document retrieval. Improved error
handling by replacing `NotFoundException` with
`HttpRequestException` and a 404 status code check.
Added `GetSenderDocumentBytesByEnvelopeIdAsync` to the
`DocumentService` class. This method retrieves sender
document bytes using an HTTP GET request to the endpoint
`/api/Document?EnvelopeId={envelopeId}`. It handles HTTP
response errors by throwing an `HttpRequestException` and
supports cancellation via a `CancellationToken`.
Updated AGENTS.md to add a technical debt TODO for modularizing
server pages by splitting large components, reducing duplication,
and centralizing shared logic.
Enhanced ReceiverPage.razor with new state variables and logic
to support a "Reject" popup feature, including state management
for visibility, submission, and validation.
Improved sharing functionality in ReceiverPage.razor by adding
error handling, user feedback, and proper state updates during
asynchronous operations to enhance maintainability and UX.
Encapsulated the registration of IPdfPageImageRenderer into a new
AddDocInfrastructure extension method in the DependencyInjection
class within the EnvelopeGenerator.Infrastructure.Doc namespace.
Updated Program.cs to use the AddDocInfrastructure method, improving
modularity and centralizing the service registration logic.
Added `IsDownloading` and `IsPrinting` properties to manage
state during download and print operations in
`SenderPdfImageEditor.razor` and `SenderPdfImageEditorToolbar.razor`.
Updated `OnDownloadPdfAsync` and `OnPrintPdfAsync` to ensure
state cleanup with `finally` blocks.
Enhanced toolbar buttons to reflect busy states with dynamic
titles, disabled states, and a spinning animation. Updated
CSS in `envelope-viewer.css` to improve layout, spacing,
and responsiveness. Added hover, active, and focus-visible
styles for better interactivity. Styled a new zoom slider
with custom thumb and focus states.
Increased maximum width of key elements to 1040px and
adjusted padding/margin for better alignment. Improved
focus styles for input fields and aligned actions to the
right in specific scenarios.
Enabled PDF printing in `SenderPdfImageEditor` and `SenderPdfImageEditorToolbar`. Added `CanPrintPdf` property to determine print availability and a new `OnPrintPdfAsync` method for handling print logic via JavaScript interop. Updated the toolbar with a "Print" button that triggers the print functionality.
Implemented the `printDataUrlPdf` function in `envelope-editor.js` to handle printing from a data URL. This function creates an iframe, loads the PDF, and invokes the browser's print functionality with proper cleanup of resources.
Introduced the ability to download PDFs in the `SenderPdfImageEditor` component:
- Added `PdfFileName` parameter to specify the file name.
- Implemented `CanDownloadPdf` property to enable/disable downloads.
- Created `OnDownloadPdfAsync` method to handle download logic via JS interop.
Updated `SenderPdfImageEditorToolbar` to support downloads:
- Added `CanDownloadPdf` and `DownloadPdf` parameters.
- Enabled "Download PDF" button based on `CanDownloadPdf`.
- Added `DownloadPdfAsync` method to trigger the download callback.
Enhanced `SenderEditorPage` to pass `PdfFileName` to `SenderPdfImageEditor`.
Added `downloadDataUrlAsFile` function in `envelope-editor.js` to facilitate file downloads using a temporary `<a>` element.
Made minor adjustments for consistency, including adding `ZoomStepPercent` to the toolbar and refining `SetZoomPercent` logic.
Introduced zoom controls to the `SenderPdfImageEditor` component, including zoom in/out, dynamic zoom levels, and a slider in the toolbar.
- Added zoom-related properties and methods to manage zoom levels.
- Updated the toolbar with zoom buttons and a slider for precise control.
- Enhanced JavaScript to handle zoom overrides and smooth scrolling.
- Modified UI elements to dynamically apply zoom styles.
- Improved accessibility and usability with appropriate attributes.
- Refactored code to integrate zoom functionality seamlessly.
These changes enhance the user experience by providing greater control over PDF viewing and editing.
Added a new section in AGENTS.md to document technical debt tasks.
Outlined three specific areas for improvement:
- Refactor `EnvelopeSenderPage.razor` to reduce complexity.
- Move sender dashboard logic to dedicated services/extensions.
- Keep `EnvelopeSenderPage.razor` focused on UI/state orchestration.
These changes aim to improve code modularity, maintainability, and
separation of concerns.
Refactored status handling to use `GetEffectiveEnvelopeStatus`
for better accuracy and historical context. Updated methods
like `IsEnvelopeSent`, `IsEnvelopeEditable`, and others to
use effective status instead of raw status.
Enhanced receiver status display by adding logic for rejected
receivers (`IsReceiverRejected`) and updated the UI to show
rejection badges with icons and labels. Improved badge
rendering to differentiate between signed, unsigned, and
rejected states.
Improved envelope categorization by ensuring rejected
envelopes are not shown in the active tab. Introduced
`GetEffectiveEnvelopeStatus` to centralize status logic.
Sanitized grid layout filters to prevent persistence of
filter-related properties, ensuring grids appear complete
when restoring layouts. Added utility methods for clearing
filter properties dynamically.
Added comments and refactored code for better readability
and maintainability.
Enhanced SenderPdfImageEditor with page navigation features:
- Added methods to navigate to first, previous, next, last, or specific pages.
- Introduced `_currentPage` to track and validate the current page.
- Implemented `OnParametersSet` to initialize/clamp `_currentPage`.
- Integrated JavaScript interop for scrolling and visible page detection.
Updated SenderPdfImageEditorToolbar:
- Added navigation buttons with enable/disable states.
- Replaced static page display with input and dropdown for page selection.
- Added event callbacks for navigation actions.
Styled new toolbar elements in `envelope-viewer.css` and added:
- Input field and dropdown for page selection.
- Adjusted layout and appearance of navigation controls.
Extended `envelope-editor.js` with:
- `scrollToPdfPage` for smooth scrolling to a specific page.
- `getVisiblePdfPageNumber` to detect the most visible page.
The "Approval Gates" section in `SENDER_PDF_TOOLBAR_PLAN_EN.md`
was updated to include a new "Notes" subheading. A checklist
item was added under this section to indicate that visual
polish for the toolbar (e.g., icon sizing, balance, and
spacing adjustments) is still pending. This change provides
clarity on outstanding design tasks.
Reduced gaps, padding, and margins across various elements to create a more compact and visually streamlined layout. Adjusted `min-height`, `border-radius`, and `box-shadow` properties for toolbars and buttons to improve consistency. Updated dimensions and font sizes for value boxes and icons to align with the refined design. Applied similar adjustments for resizing states to maintain uniformity.
Refactored `SenderPdfImageEditor.razor` to improve readability and maintainability by introducing a new wrapper element (`sender-image-editor-shell`) and reorganizing the toolbar into a sticky container (`sender-image-editor__toolbar-host`). Updated conditional rendering logic to handle `PageCount` cases more effectively.
Enhanced styles in `envelope-viewer.css`:
- Added `.sender-image-editor-shell` for layout structure.
- Made toolbar sticky with `.sender-image-editor__toolbar-host`.
- Improved alignment, spacing, and responsiveness of elements.
- Adjusted padding and margins for better layout consistency.
These changes improve user experience and maintainability.
Introduced a `SenderPdfImageEditorToolbar` component to enhance the PDF editor with navigation, zoom, and action controls. Updated `SenderPdfImageEditor.razor` to display the toolbar when `PageCount > 0`.
Added parameters (`CurrentPage`, `TotalPages`, `ZoomPercent`) and computed properties to manage and display toolbar state dynamically.
Styled the toolbar in `envelope-viewer.css` with grid-based layout, responsive design, and hover/disabled states for buttons. Adjusted styles for smaller screens to improve usability.
Introduce a detailed migration plan to design and integrate a reusable toolbar component for the `SenderPdfImageEditor` in the `EnvelopeGenerator.Server` project.
The toolbar will support page navigation, zoom in/out, PDF download, and print functionality while preserving existing signature add/remove/drag-drop behavior.
The plan includes:
- Creation of a new `SenderPdfImageEditorToolbar` component.
- Updates to `.razor`, `.css`, and `.js` files.
- A non-regression strategy with incremental feature additions and manual black-box testing after each stage.
The migration is divided into five stages:
1. Visual toolbar skeleton.
2. Page navigation.
3. Zoom in/out with mouse override.
4. Download original PDF bytes.
5. Print output.
Approval gates are defined to ensure functionality is implemented correctly and regressions are avoided.
Refactored `SenderPdfImageEditor.razor` to use culture-invariant formatting for dynamic styles and introduced the `GetPageCanvasStyle` method for calculating `aspect-ratio` and `cursor` styles. Enhanced layout control with additional CSS properties.
Updated `envelope-editor.js` to include a throttling mechanism for mouse movement events using `_moveThrottle` and `requestAnimationFrame`. Added `getClickCoordsOnPdfPageThrottled` with a promise-based approach to improve performance during rapid interactions.
Changed the `cursor` property for `.sender-image-editor__field`
from `grab` to `move` and for its `:active` pseudo-class
from `grabbing` to `move`. This ensures consistent cursor
behavior when interacting with the element.
Refactored routing logic in `SenderEditorPage.razor` and `EnvelopeSenderEditorPage.razor`:
- Changed the route in `SenderEditorPage.razor` from `/sender/editor2` to `/sender/editor`.
- Updated `EnvelopeSenderEditorPage.razor` to use `/sender/editor_legacy` instead of `/sender/editor`.
- Adjusted `NavigationManager.NavigateTo` calls to reflect the new routes.
These changes separate the functionality of the two pages and clarify their respective roles.
Introduced a new rejection flow in `ReceiverPage.razor` to detect
rejected envelopes and redirect users to a dedicated rejection
page (`ReceiverRejectedPage.razor`).
- Added `IsRejected` helper method to check envelope rejection
status based on current status and history.
- Created `ReceiverRejectedPage.razor` to display rejection
messages, sender details, and navigation options.
- Implemented localized strings for dynamic rejection messages.
- Designed a visually distinct layout for the rejection page.
- Improved user experience with clear messaging and proper
handling of invalid or unauthorized access.
Introduced a new feature to allow users to reject envelopes with an optional reason. Added a `RejectAsync` method in `AnnotationService` to handle rejection requests. Updated `ReceiverPage.razor` to include a "Reject" button in the PDF toolbar and a rejection popup for user input.
Implemented state management for the rejection popup, including visibility, submission status, and validation messages. Updated `AnnotationController` to accept `envelopeKey` as a route parameter for the rejection endpoint. Modified `ReceiverClaimExtensions` to support multiple email claim types.
Added new CSS styles for the "Reject" button, including hover effects and dark theme support. Enhanced error handling and logging for the rejection process.
Updated the route for `SenderEditorPage.razor` to `/sender/editor` with `InteractiveWebAssembly` mode. Changed the route for `EnvelopeSenderEditorPage.razor` to `/sender/editorL` with `InteractiveServer` mode. Adjusted navigation logic in `EnvelopeSenderEditorPage.razor` to reflect the new `/sender/editorL` route for `esid`, `editQuery`, and `envelopeId` parameters.
Replaced the old drag-and-drop implementation with a custom solution using mouse events for better control and precision. Added `_isDragging` state and dynamic cursor updates to enhance user feedback during drag operations.
Introduced grab offset calculations to ensure accurate field positioning relative to the pointer. Added `OnEditorMouseUp` to reset the drag state and `GetPageSize` to retrieve page dimensions, defaulting to A4 if unavailable.
Updated `envelope-editor.js` to include `pageNumber` in `getClickCoordsOnPdfPage` and removed the obsolete `getDropCoordsOnPage` function. Enhanced `EditorCoords` to include `PageNumber` for improved page identification.
Introduced drag-and-drop functionality for fields in the PDF editor:
- Added `SenderPdfFieldMoveRequest` record to encapsulate field movement data.
- Enhanced `SenderPdfImageEditor.razor` with drag-and-drop event handlers (`OnFieldDragStart`, `OnPageDropAsync`) and updated field structure.
- Updated `SenderEditorPage.razor` to handle field movement via the `OnMoveFieldAsync` method.
- Improved CSS styles for draggable fields and added a delete button with hover effects.
- Added `getDropCoordsOnPage` function in `envelope-editor.js` to calculate normalized drop coordinates.
These changes improve the user experience by enabling intuitive field placement and management in the PDF editor.
Refactor the PDF upload button to dynamically adjust its
appearance and behavior based on `_isPageReady` and
`_isPdfUploadInProgress` states. Add a spinner to indicate
upload progress and disable the `<InputFile>` component
during uploads or when the page is not ready.
Introduce `_isPdfUploadInProgress` state to prevent multiple
uploads and ensure consistent UI updates. Update the
`OnPdfFileSelectedAsync` method to handle this state,
including a `finally` block to reset it and trigger UI
updates.
Consolidate redundant code for disabled states and improve
conditional rendering for better maintainability. Enhance
visual feedback for loading states and make minor style
adjustments for consistency.
Introduced `_isPageReady` state to manage page readiness and conditionally render the PDF upload button. Disabled the upload functionality and added a loading spinner when the page is not ready. Updated `OnPdfFileSelectedAsync` to prevent uploads before readiness.
Modified the "No Document Loaded" section to use `_isPageReady` for conditional rendering. Added `SENDER_SAVE_EDIT_MIGRATION_PLAN.md` to the solution. Improved user experience with better feedback during loading states.
Replaced `DxPdfViewer` with a custom PDF rendering solution in `SenderPdfImageEditor` to improve flexibility and control. Added support for displaying placeholder messages and interactive signature fields. Introduced the `SenderPdfFieldOverlay` record to encapsulate field data.
Updated `SenderEditorPage` logic to manage page counts, image URLs, and field overlays. Added a method to estimate PDF page counts. Refactored field removal logic to use index-based operations.
Enhanced styling in `envelope-viewer.css` for improved layout and responsiveness. Updated localization files with new strings for page labels and placeholders. Adjusted JavaScript selectors in `envelope-editor.js` to support the new rendering approach.
Transitioned Sender Editor away from DevExpress PDF viewer, introducing alternative solutions for PDF rasterization. Enforced new localization requirements for UI text using `IStringLocalizer<Resource>` with translations in DE/EN/FR resource files.
Ensured data compatibility for `CreateEnvelopeCommand` payload shape, field units, receiver-field mapping, and save/send behavior. Removed `esid` query parameter and `IMemoryCache`-based session persistence.
Prohibited use of `pdf.js` and DevExpress PDF viewer, requiring an MIT-licensed alternative if DevExpress rasterization is unsuitable. Maintained adherence to Clean Architecture layers and MediatR pattern. All code and comments are now standardized in English.
Introduced a new `SenderEditorPage` with a modern UI for managing envelopes, uploading PDFs, and placing signature fields. Integrated `DevExpress.Blazor.PdfViewer` for PDF rendering and interaction.
Key features include:
- PDF upload, rendering, and validation.
- Signature field placement with normalized coordinates.
- Receiver management with validation and email suggestions.
- Envelope metadata handling (title, message).
- Save as draft and send functionality with validation.
- Edit mode for existing envelopes.
- Improved UX with dynamic elements and color-coded receivers.
- Localization support for multi-language UI.
Updated `_Imports.razor` to include necessary namespaces for DevExpress components and the new `PdfEditor` namespace.
Added `ReceiverService` to the dependency injection container in `Program.cs` and implemented its functionality for fetching receiver email suggestions via API.
Enhanced `DocumentService` with a new method `GetSenderDocumentDetailsByEnvelopeIdAsync` to fetch sender document details by envelope ID. Introduced JSON handling improvements with `JsonSerializerOptions`.
These changes improve support for receiver-related operations and extend document-related capabilities.
The following files have been removed as part of a significant refactor or deprecation of envelope-related PDF viewing and signature functionality:
- `EnvelopeReceiverPage.razor`: A detailed PDF viewer with signature handling and interactive features.
- `EnvelopeReceiverPage_DxPdfViewer.razor`: A simplified PDF viewer using the `DxPdfViewer` component.
- `EnvelopeReceiverPage_DxReportViewer.razor`: A report viewer using the `DxReportViewer` component.
- `EnvelopeReceiverPage_embed.razor`: A minimalistic PDF viewer using the `<embed>` HTML tag.
These removals indicate a transition to a new approach for handling PDF viewing and related features or their complete deprecation.
A detailed migration plan has been added to replace the DevExpress PDF viewer in `EnvelopeSenderEditorPage.razor` with a new WebAssembly (WASM)-based PDF editor component.
The plan outlines the scope, constraints, and implementation strategy, ensuring feature parity, backend compatibility, and minimal disruption to the existing user experience. Key decisions include creating a reusable `SenderPdfImageEditor` component, using server-side PDF rasterization, and removing `esid` and `IMemoryCache`-based session persistence.
The document also defines testing and acceptance criteria to verify the migration's success, focusing on visual fidelity, functionality, and backend contract consistency.
Introduced the ability to share envelopes in read-only mode and view them via a dedicated page. Added `ShareEnvelopeReadOnlyAsync` in `AuthService.cs` to handle sharing logic. Updated `ReceiverPage.razor` with a "Share" button, popup UI, and validation for sharing inputs. Created `ReceiverReadOnlyPage.razor` for read-only document viewing with error handling and lifecycle management.
Added `EnvelopeKeyRedirectController.cs` to support legacy link redirection. Enhanced `ReadOnlyController.cs` to support envelope sharing with improved logging and `IMediator` integration. Improved state management, validation, and error handling across components. Performed general code cleanup and UI enhancements for better user experience.
Introduced a logout feature to the `ReceiverPage` component:
- Added a logout button to the toolbar with `_isLoggingOut` state.
- Implemented `LogoutAsync` method to handle logout logic, including navigation and error handling.
- Injected `IMediator` and `ILogger<ReceiverPage>` for logging and MediatR functionality.
- Added a check in `OnInitializedAsync` to redirect users to `/envelope/signed-result` if the envelope is already signed.
- Updated namespaces to include MediatR and custom extensions.
These changes improve user experience and enhance the component's functionality.
Updated the `applicationUrl` property in the "https (Blazor UI)"
profile of `launchSettings.json`. Changed the HTTPS port from
8089 to 8088 and the HTTP port from 5132 to 5131. This ensures
the development server uses the new port configuration and
avoids potential conflicts with other services.
Introduced a new `/envelope/signed-result` page to confirm
successful document signing with localized messages and
a visually appealing UI. Updated `ReceiverSignedPage.razor`
to redirect users to the new page after signing.
Enhanced styles in `app.css` for the signed result page,
including responsive layout, theme-specific designs, and
typography improvements. Added support for localization
using `IStringLocalizer` with fallback strings in German.
Improves user experience by providing clear feedback and
a polished confirmation page after signing.
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.
Introduced a new `AccessCode` property in `EnvelopeReceiverDto` to support displaying and copying access codes in the envelope sender page.
- Updated `EnvelopeReceiverDto` to include the nullable `AccessCode` property.
- Enhanced `EnvelopeSenderPage.razor` to display the `AccessCode` for each receiver, with a copy-to-clipboard button.
- Implemented `CopyAccessCodeAsync` for clipboard functionality using JavaScript interop.
- Styled the `AccessCode` section in `sender-page.css` for a responsive and user-friendly design.
- Improved error handling for clipboard operations with console warnings.
These changes improve the user experience by allowing senders to view and copy access codes for receivers.
Introduced functionality to queue and send invitation emails to envelope receivers. Added new dependencies and private properties to support email handling, including repositories for `EmailTemplate` and `EmailOut`, as well as configuration services for `MailParams` and `DispatcherParams`.
Added the `QueueInvitationEmailsAsync` method to generate personalized email content using placeholders and store outgoing emails in the `EmailOut` repository. Introduced a helper method `ReplacePlaceHolders` for placeholder substitution in email templates.
Updated the `Handle` method to invoke `QueueInvitationEmailsAsync` after setting the envelope status to `EnvelopeQueued`. These changes ensure a modular and reusable email queuing process.
Introduced a new feature for submitting signatures, including
backend and frontend changes. Added `SignatureSubmitDto` and
`SubmitAsync` in `SignatureService` to handle signature data
submission. Implemented a new `Submit` endpoint in
`SignatureController` to validate and process signature payloads.
Updated pipeline behaviors to include `SaveSignatureBehavior`
and adjusted the execution order. Enhanced query logic in
`EnvelopeReceiverResolutionBehavior` and `SaveSignatureBehavior`
to align with the updated data model.
Refactored `EGDbContext` to improve trigger handling and logging.
Updated `ReceiverSignedPage.razor` to integrate `SignatureService`
and handle submission errors gracefully. Adjusted application
URLs in `launchSettings.json` and added new database triggers
in `appsettings.json`.
Replaced separate `DxGrid` components for "active" and "completed" tabs with a single unified grid. Introduced dynamic properties (`CurrentGridData` and `CurrentGridKey`) to handle data and layout switching based on the active tab.
Refactored layout loading/saving methods into shared versions (`OnGridLayoutAutoLoading` and `OnGridLayoutAutoSaving`) using dynamic keys. Simplified export logic to use the unified grid instance.
Removed redundant code, templates, and private fields specific to the "completed" tab. Updated status filter logic to dynamically fetch data. Improved maintainability by consolidating logic and reducing duplication.
Added `Include` statements to the LINQ query in the
`ReadEnvelopeQueryHandler` class to eagerly load related
entities (`Type`, `EnvelopeReceivers` with `Receiver`, and
`Histories`). This change reduces lazy-loading overhead and
ensures all necessary data is retrieved in a single query,
improving performance.
Introduce `GetSignedReceiverCount` and `IsReceiverSigned` helper methods to centralize and improve the logic for determining the signed status of receivers. Replace inline logic with these methods for better encapsulation and reusability.
Update UI rendering logic to dynamically determine receiver badge states based on the new methods. These changes enhance code maintainability, reduce duplication, and ensure consistent behavior across the application.
Updated `DxGrid` components for `_activeEnvelopes` and `_completedEnvelopes`:
- Disabled `ShowFilterRow` and added `FilterMenuButtonDisplayMode` to always display filter menu buttons.
- Enabled sorting for the `Id` column with descending order and added a display format.
- Added `EditSettings` to the `Status` column with a `DxComboBoxSettings` for filtering, using the new `GetStatusFilterItems` method.
Introduced `GetStatusFilterItems` to generate distinct status filter items and added a private `StatusFilterItem` record type for encapsulating status values and labels.
Made minor adjustments to grid layout auto-saving logic for consistency.
This commit introduces comprehensive localization support for the application, enabling dynamic language switching and localized UI elements. Key changes include:
- Added `.resx` files for German (de-DE), English (en-US), and French (fr-FR).
- Updated Razor components to use `IStringLocalizer` for dynamic string localization.
- Introduced the `L(string key, string fallback)` helper method for consistent localized string retrieval with fallback support.
- Implemented dynamic culture initialization in `Program.cs` via an API call to `/api/Localization/lang`.
- Localized error pages, grid columns, tabs, popups, validation messages, and tooltips.
- Dynamically generated privacy policy links based on the current culture.
- Improved user experience with fully localized loading states, error handling, and UI labels.
These changes enhance accessibility and usability, making the application more user-friendly for a global audience.
Added `Model.fr-FR.resx` to support French localization.
Defined XML schema for the resource file structure, including
metadata, assembly, and data elements. Added localized
French strings for various application messages, ensuring
proper display when the locale is set to `fr-FR`.
Introduced a `LanguageControls` component for switching between
languages (`de-DE`, `en-US`, `fr-FR`) and integrated a new
`LocalizationService` to manage language preferences. Updated
`LocalizationController` to handle language persistence via
cookies and support multiple cultures. Enhanced the footer
layout to include the language selector alongside theme
controls.
Added `flag-icons` library for displaying country flags and
configured request localization in `Program.cs`. Styled the
language selector dropdown and improved sender page visuals
with updated CSS. Defaulted language handling to `de-DE` for
fallback scenarios. Cleaned up redundant code in
`LocalizationController`.
Added a new `Model` class in the `EnvelopeGenerator.Domain.Resources` namespace as a marker for `IStringLocalizer` resource lookup. Updated `EnvelopeSenderPage.razor` to use the new `Model` class for localization.
Modified `LocalizationController` to default to "de-DE" when no culture is specified or found. Refactored localization setup in `Program.cs` to use a fixed default culture of "de-DE" and persist culture via cookies. Removed dynamic culture setup and `QueryStringRequestCultureProvider`.
Performed minor cleanup in `LocalizationController` and `Program.cs` to align with the new localization approach.
Introduced a "Historie" section in `EnvelopeSenderPage.razor` to display envelope history with status badges, actor info, and timestamps. Updated `ReadEnvelopeQueryHandler` to include histories in queries.
Refactored `GetStatusInfo` to use localized labels and expanded supported statuses. Added helper methods for history processing and display.
Enhanced UI with new styles for the history section in `sender-page.css` and improved responsive design. Added dependency injections for localization and history handling.
Refactored sender email resolution into a new private async
method `ResolveSenderReferenceAsync` to improve code
reusability and readability. Replaced inline logic for
resolving sender references with this method.
Added a `CreateHistoryCommand` to log envelope creation
events, including envelope ID, sender reference, and status
(`EnvelopeCreated`). This enhances auditability and ensures
consistent event logging.
Removed `IDocReceiverElementWriter` interface and its implementation, replacing it with repository-based operations (`IRepository<DocReceiverElement>`). Updated `CreateEnvelopeCommandHandler` to use repository methods for deleting and creating `DocReceiverElement` records.
Cleaned up dependency injection by removing `IDocReceiverElementWriter` registration. Added new database triggers for `DocReceiverElement` in `appsettings.json` and `appsettings.Database.json`.
Introduced `SENDER_SAVE_EDIT_MIGRATION_PLAN.md` to outline the migration of the sender save/edit workflow to Blazor Server. This includes splitting save and send actions, supporting draft persistence, and enabling draft editing from the dashboard.
Removed unused namespaces and performed code cleanup. Updated testing strategies to ensure correctness and prevent regressions.
- expose POST /api/Envelope for sender-authenticated create/update/send operations
- replace client draft-specific call with EnvelopeService.UpsertAsync(CreateEnvelopeCommand)
- update sender editor save/send flow to persist draft first and send by envelope id
- allow editor hydration without document by making sender document fetch nullable
- extend CreateEnvelopeCommand to support draft updates and send intent
- merge draft save logic into CreateEnvelopeCommandHandler and remove duplicate handler
- add DocReceiverElement writer abstraction and infrastructure registration for SQL-based field upserts
The `EnvelopeGenerator.Server` project now serves as the unified runtime host for both the Blazor frontend and Web API backend, deprecating the `EnvelopeGenerator.API` project. All API endpoints have been merged into `EnvelopeGenerator.Server`.
Key changes:
- Updated `EnvelopeGenerator.Server` to include API controllers.
- Deprecated `EnvelopeGenerator.API` and removed it from the active solution.
- Simplified development workflow to run only `EnvelopeGenerator.Server`.
- Updated `appsettings.json` to consolidate configuration settings.
- Adjusted documentation to reflect the new unified architecture.
- Updated manual testing steps and environment variable references.
- Migrated legacy VB.NET app references to the new architecture.
These changes simplify development, deployment, and testing workflows while consolidating the solution architecture.
Updated SF-74-PLAN.md to document completed phases (6a–6e), including theme selection, dark mode, grid persistence, and logo placement. Highlighted pending tasks for phase 6f and clarified open questions.
Revised MIGRATION_PLAN.md with deep analysis findings and detailed steps for migrating `EnvelopeGenerator.Service_legacy` to a modern C# Worker Service. Addressed connection string handling, Quartz version mismatch, and TempFiles architecture.
Removed outdated markdown files from EnvelopeGenerator.sln and updated the solution structure for consistency.
Fixed incorrect "Read and confirmed" label in Signature Certificate reports for "Read and Sign" envelopes. Added branching logic in `ReportItem.vb` and updated resource files.
Resolved signature field formatting issues in finalized PDFs based on WISAG feedback. Added truncation logic in `PDFBurner.vb` and updated `PDFBurnerParams.vb` with per-field character limits.
Refactored the sender title in `EnvelopeSenderPage.razor` to use a structured layout with accessibility improvements. Introduced `.sender-title-main` and `.sender-title-sub` classes for better styling and responsiveness. Updated `.sender-page.css` to enhance layout flexibility, reduce gaps, and improve scaling for logos and titles.
Added media queries for better responsiveness on smaller screens, including adjustments to `.sender-title-section` and logo dimensions. Introduced theme-specific overrides for "purple" and "blazing-dark" themes to ensure consistent styling.
Minor adjustments were made to padding, margins, and font sizes to improve overall layout and visual hierarchy.
The "Grid persistence hint" feature was removed from `EnvelopeSenderPage.razor`, including its associated HTML `<div>` and SVG icon.
Corresponding styles for `.sf-grid-persistence-hint` were removed from `sender-page.css`, including display, alignment, padding, font size, color, background, and border.
Adjusted the padding for `.sender-grid-wrapper` in `sender-page.css` to account for the removal of the hint banner, setting it to `1rem 2rem 2rem`.
Updated `EnvelopeSenderPage.razor` to enhance customer logo rendering with dynamic height and class styling. Refined the "Nur ausgewählte" checkbox label for better styling.
Modified `sender-page.css` to improve layout and responsiveness:
- Added styles for `.sender-customer-logo-area` and `.signflow-company-logo` for proper scaling and alignment.
- Removed `.sender-export-label` styles and introduced `.sender-export-selected-text` for improved checkbox label design.
- Adjusted media queries for better layout on screens up to 1320px and 768px.
Enhanced overall responsiveness and accessibility of the sender page.
Finalized the implementation of the export feature for the
`EnvelopeSenderPage.razor` in the Blazor WASM Client. The feature
supports exporting grid data in XLSX, CSV, and PDF formats, with
an option to export only selected rows.
- Updated `SF-74-PLAN.6e.md` to reflect the completed Phase 6e.
- Integrated a compact UI for export controls in the toolbar:
- Dropdown for format selection (XLSX, CSV, PDF).
- Checkbox for "Only selected rows" option.
- Single `Exportieren` button to trigger the export.
- Implemented `ExportSelectedFormatAsync` to handle export logic:
- Supported formats: XLSX, CSV, PDF.
- Added options for `ExportSelectedRowsOnly` and grouping.
- Replaced placeholder `ExportToExcelAsync` with finalized logic.
- Documented known limitations (e.g., template columns not exported).
- Updated project status table to mark Phase 6e as complete.
This commit ensures a streamlined and user-friendly export UX,
consistent with the existing design, while addressing known
DevExpress limitations.
Replaced placeholder export method with a fully implemented
`ExportSelectedFormatAsync` method to support exporting grid
data in CSV, PDF, or XLSX formats. Added a loading spinner
to the export button to indicate progress during export
operations. Updated the `IsExportDisabled` method to account
for the new `_isExporting` state.
Disabled exporting for "Status" and "EnvelopeReceivers"
columns by setting their `ExportEnabled` property to `false`.
Made minor grid layout adjustments, including adding the
`KeyFieldName` property for proper grid behavior.
Introduced a new export feature to the EnvelopeSenderPage, including a dropdown for selecting export formats (XLSX, CSV, PDF) and a checkbox to export only selected rows. Added a placeholder export button ("Exportieren") that is currently disabled, with export logic to be implemented in a future phase.
Added private fields `_selectedExportFormat` and `_exportSelectedRowsOnly` to manage the export state. Implemented `IsExportDisabled()` to control button availability and a placeholder method `ExportSelectedFormatPlaceholderAsync()`.
Updated `sender-page.css` to style the export feature, including the export button, dropdown, and checkbox. Added theme-specific styles for "purple" and "blazing-dark" themes. Adjusted toolbar element order to position the export group before the logout button.
Implemented the first phase of a planned multi-format export feature for the `/sender` dashboard. Added a compact export block to the right action bar in `EnvelopeSenderPage.razor`, including a format dropdown (XLSX, CSV, PDF), a "Selected Rows Only" toggle, and an "Export" button.
The UI is fully integrated with responsive design and theme consistency across `blazing-berry`, `blazing-dark`, and `purple`. No export logic is implemented yet; placeholder handlers are in place for the export button. Styles were added to `wwwroot/css/sender-page.css` to ensure alignment with the existing design language and mobile usability.
This commit completes Phase 1 of the implementation plan. Phase 2 will add the actual export functionality.
Updated the "Letzte Aktualisierung" date in SF-74-PLAN.md to
reflect the latest progress. Added requirement 6d for a PDF
Preview Popup using `DxPdfViewer` and marked it as completed.
Provided additional context for Phase 6d, explaining the
read-only behavior of envelopes after sending and the technical
approach for implementing the PDF preview functionality.
Replace inline styles and magic-number height calculations with a proper
BEM CSS class system. Attach HeaderCssClass and BodyCssClass to DxPopup
so DevExpress DOM targets can be styled reliably without deep selector
hacks.
Layout changes:
- Remove hardcoded calc(90vh - 114px) height from viewer wrapper; use
flex layout so the body fills available space naturally
- Change overflow on DxPdfViewer wrapper from hidden to auto to allow
horizontal scrolling at high zoom levels
- Center PDF pages horizontally inside dxbrv-document-surface via flex
New CSS classes (BEM):
- .sender-preview-popup root shell, accent top border
- .sender-preview-popup__header styled header via HeaderCssClass
- .sender-preview-popup__body flex column body via BodyCssClass
- .sender-preview-viewer-wrap padding wrapper for the PDF viewer
- .sender-preview-pdf-viewer viewer shell with rounded corners / shadow
- .sender-preview-state-wrap centered container for loading/error states
- .sender-preview-error-card error message card with left accent border
- .sender-preview-error-icon circular icon wrapper
- .sender-preview-error-title/msg typography helpers
Theme support:
- Purple, Blazing Dark variants via data-sf-theme attribute overrides
Custom scrollbars:
- WebKit scrollbar styling scoped to .sender-preview-popup__body
Inline style cleanup in EnvelopeSenderPage.razor:
- Replace all ad-hoc style= attributes with the new CSS classes above
Decouple Scalar from Swagger so each can be enabled/disabled separately
via the UseScalar config flag. When Scalar is enabled without Swagger,
the bare OpenAPI JSON endpoint is still registered so Scalar has a
spec to load from.
- Add UseScalar flag to appsettings.json (default: true)
- Resolve useScalar from config in Program.cs
- Map Scalar only when useScalar is true
- Ensure UseSwagger() is called if Scalar needs it but Swagger UI is off
Replace the placeholder preview popup with a fully functional DxPdfViewer
popup:
- Popup resized to 80vw × 90vh with drag, resize and background shading.
- OpenPreviewAsync: unmounts viewer, fetches PDF bytes via
GetDocumentOfSenderAsync, then mounts DxPdfViewer only after bytes are
ready (prevents DevExpress ProcessDocumentChangedAsync NRE).
- Loading spinner shown while fetching; typed error panel shown on
NotFoundException or general failure.
- OnPreviewClosed: unmounts viewer before nulling byte array so DevExpress
async render never touches a disposed reference.
- Inject ReceiverPageDataService, EnvelopeAuthService and ILogger.
app.css: Disable text/image selection globally; re-enable for
input/textarea/[contenteditable] so typing and pasting still work.
sender-page.css: Add .sender-preview-popup, .sender-preview-viewer-wrap
and .sender-preview-pdf-viewer rules. DxPdfViewer requires an explicit
pixel-height parent — percentage heights resolve to 0 inside popup body
flex containers and cause DevExpress NullReferenceExceptions.
Loads the PDF bytes for a given envelope on behalf of the authenticated
sender (uses SenderId() claim extension). Throws NotFoundException when
no document data is available so callers can surface a typed error.
Previously Swagger UI was only registered in Development. Add a
'UseSwagger' config key so staging/production environments can opt in
without code changes.
JwtBearer middleware does not run for WebSocket upgrade requests, so
HttpContext.User is anonymous inside Blazor Server components. Fall back
to manual cookie parsing + token validation (same pattern used by
EnvelopeReceiverAuthorizationService). Cache the resulting principal on
HttpContext.User for subsequent calls within the same circuit.
Also inject IOptionsMonitor<JwtBearerOptions> and IOptions<AuthTokenKeys>
to support the validation path.
Extracts the authenticated sender's integer ID from the 'sub' /
NameIdentifier claim. Mirrors the existing ReceiverId() helper and is
required by GetDocumentOfSenderAsync.
Adds an optional UserId parameter to ReadDocumentQuery so callers
can scope document lookups to envelopes owned by a specific sender.
Also adds AsNoTracking() to the base query for read-only scenarios.
Updated the method name in EnvelopeReceiverPageDataService
to clarify its purpose of retrieving documents for a receiver.
Refactored all references in Razor pages (ReceiverPage.razor,
ReceiverSignedPage.razor, EnvelopeReceiverPage.razor) to use
the new method name. No changes were made to the method's
logic or functionality. This improves code clarity and consistency.
Updated documentation to reflect the migration from WebUI to EnvelopeGenerator.Server, including a new "Documentation Catalog" in `AGENTS.md`. Adjusted route mappings, render modes, and directory structure for Blazor components.
Revised coordinate system documentation and CSS for status colors to align with the new architecture. Updated YARP proxy and PDF.js configuration paths.
Migrated `MIGRATION_PLAN.md` to modernize `EnvelopeGenerator.Service` with C# Worker Service equivalents. Updated `FORM_APPLICATION_CONTEXT.md` and `RECEIVER_PDF_VIEWER_CONTEXT.md` to reflect the new architecture and planned viewer integration.
Fixed German translation issues in `fix-report-label-read-and-confirmed.md`. Standardized formatting and terminology across all files.
Updated the `@rendermode` directive in `EnvelopeSenderPage.razor`
to replace `InteractiveWebAssemblyRenderMode` (with `prerender: false`)
with `InteractiveServer`. This change transitions the rendering
approach from WebAssembly-based interactive mode to server-side
interactive mode.
Refactored row selection logic to leverage DevExpress's native
`@bind-SelectedDataItem` for automatic updates to the
`_selectedEnvelope` variable. Added `AllowSelectRowByClick`
to enable row selection via single click. Updated event
handlers for layout auto-loading and auto-saving to use
specific methods for different grids. Simplified `OnRowClick`
method by removing redundant manual selection logic and
retaining toggle behavior for deselecting the same row.
Updated comments to reflect these changes.
Enhanced the UI with a "Vorschau" (Preview) button to display
PDF previews of selected envelopes. Introduced a `DxPopup`
to show envelope details, including ID and title, with a
"Schließen" (Close) button.
Replaced `SelectedDataItemChanged` with `RowClick` and
`RowDoubleClick` events for improved row selection.
Single-click toggles row selection, while double-click opens
the preview popup. Added `_previewVisible` to manage popup
visibility and implemented `ShowPreview` for button-triggered
previews. Removed `OnSelectedEnvelopeChanged` as it is now
handled by the new row events. Updated grid layout persistence
to align with the new event structure.
Reflect completion of phases 6a–6c in the project plan:
- Marked phases 6a (signFLOW logo), 6b (customer logo placeholder),
and 6c (grid columns + persistence hint) as completed.
- Updated dependency rule to reflect the change from
`EnvelopeGenerator.Server.Client` to `Blazor WASM Client`.
- Reiterated key decisions, including the use of `TBDD_CACHE`,
`SenderOrReceiver` policy, and `signflow.theme` in localStorage.
- Noted DevExpress 25.2.3 lacks `.dark.`-suffix files.
A new file, `SF-74-PLAN.md`, was added to the `EnvelopeGenerator.Server` project under the `SolutionItems` section in the solution file (`EnvelopeGenerator.sln`). This change ensures the file is tracked as part of the solution.
Added dynamic version resolution from the `<Version>` tag in the
`.csproj` file, enabling versioned output directories. Updated
`setlocal` to use `enabledelayedexpansion` for better variable
handling. Enhanced logging of build parameters and streamlined
the "Publishing" step by removing redundant logs.
Improved output verification with additional checks for critical
files (`hostfxr.dll`, `coreclr.dll`, etc.), logging failures if
files are missing. Updated success messages to include the
resolved version and generalized next-step instructions.
Updated versioning details in `EnvelopeGenerator.Server.csproj`:
- Changed `<Version>` from `1.0.1-beta` to `1.1.0-beta`.
- Updated `<FileVersion>` from `1.0.1.0` to `1.1.0.0`.
- Updated `<AssemblyVersion>` from `1.0.1.0` to `1.1.0.0`.
This minor version update reflects new features or improvements
while maintaining backward compatibility.
Refactored code for improved readability, consistency, and maintainability. Removed the WASM boot loading overlay and its associated styles/scripts. Updated SVG paths to use self-closing tags for HTML compliance. Reformatted conditional blocks, state management, and session data logic. Enhanced error handling, spinner visibility, and empty state displays.
Removed redundant comments and unused code. Added `envelope-editor.js` for new functionality. Cleaned up CSS and JavaScript related to the removed WASM overlay. Improved grid layout persistence and signature field logic. Adjusted localization strings for better alignment with German translations.
- Updated `MappingProfile.cs` to add detailed mapping for `Envelope` to `EnvelopeDto`, including `EnvelopeTypeTitle`.
- Added a grid persistence hint banner in `EnvelopeSenderPage.razor` with an SVG icon and German message.
- Introduced three new columns (`EnvelopeTypeTitle`, `AddedWhen`, `ChangedWhen`) to the grid in `EnvelopeSenderPage.razor`.
- Refactored boot overlay removal logic in `App.razor` into a reusable function `sfRemoveBootOverlay`.
- Simplified event handling for overlay removal and fallback logic in `App.razor`.
- Adjusted `.sender-grid-wrapper` padding in `sender-page.css` and added styles for the new grid persistence hint banner.
The `ConnectionStrings.Default` value in `appsettings.json` was updated.
The connection string now points to the testing environment
(`SDD-VHP04-SQL19\DD_TESTING01`) instead of the development environment
(`SDD-VMP04-SQL17\DD_DEVELOP01`). The password was also updated to
`123456789dD!` to reflect the new environment credentials.
Introduced a customer logo section in `EnvelopeSenderPage.razor` that dynamically displays a customer logo or a placeholder when no logo is configured. The logo is fetched from the `CustomImagesService` and styled using new CSS classes in `sender-page.css`.
- Added `_companyLogo` property to store customer logo configuration.
- Updated `CustomImagesService` to fetch both app and customer logos.
- Modified `appsettings.json` to include logo paths and styles.
- Enhanced CSS for a three-section action bar layout.
- Added placeholder styling for missing customer logos.
- Updated initialization logic to load logos dynamically.
- Documented implementation details in `SF-74-PLAN.md`.
The implementation is modular and deployment-specific, allowing logo paths and styles to be updated via configuration without code changes.
Introduced `ThemeService` to manage themes and dark mode, with a new footer UI for theme selection and toggling dark mode. Added dynamic CSS loading and Bootstrap theme support. Registered `UserPreferencesService` and `ThemeService` for SSR compatibility. Removed hardcoded DevExpress theme links.
Fixed German localization issues in `LoginReceiverPage` and `LoginSenderPage`. Updated `app.css` with styles for the new footer controls. Simplified font loading in `MainLayout.razor`.
Introduce ThemeService to manage themes and dark mode state,
including initialization, persistence, and server sync.
Add UserPreferencesService to handle API communication for
retrieving and saving user preferences with in-memory caching
to reduce network overhead.
Register both services in the DI container in Program.cs.
Enhance ThemeService with detailed documentation and introduce
ThemeOption record for selectable themes. Improve server-side
caching in UserPreferencesService for consistency and efficiency.
Introduced `UserPreferencesDto` to represent UI preferences,
including theme, dark mode, and grid layouts. Added the
`IUserPreferencesService` interface and implemented it in
`UserPreferencesService` to manage preferences stored in
the distributed cache (`dbo.TBDD_CACHE`).
Registered `UserPreferencesService` in dependency injection
and added a NuGet reference for `Microsoft.Extensions.Caching.Abstractions`.
Created `UserPreferencesController` with `GET` and `PUT`
endpoints to retrieve and save user preferences. Validated
theme names in the `PUT` endpoint.
Updated `Program.cs` to ensure proper service registration.
Updated `createAnnotations` to initialize a `PSPDFKit.Annotations.WidgetAnnotation` object, enabling the creation of widget annotations.
Modified `ctx.strokeStyle` in `createAnnotationFrameBlob` to use 'darkblue' instead of 'darkgray', improving the visual appearance of the annotation frame.
Updated `EnvelopeGenerator.Service.csproj` to target a single framework (`net4.6.2`) by replacing `<TargetFrameworks>` with `<TargetFramework>`.
Added `DefaultProfile.pubxml` to define a publish profile with settings for release configuration, platform, and file system-based publishing.
Migrated the legacy VB.NET Windows Service to a modern C# Worker Service targeting .NET Framework 4.6.2. Key changes include:
- Added `Microsoft.Extensions.Hosting.WindowsServices`, `NLog`, and `Quartz` for logging and scheduling.
- Introduced `LogConfigFactory` to bridge `ServiceConfig` and `LogConfig` for Quartz jobs.
- Rewrote `Worker` to handle the full service lifecycle, including database connection, temp file management, and scheduler initialization.
- Implemented `SchedulerFinishEnvelope` and `SchedulerEnvelopeTaskApi` for Quartz job scheduling.
- Created `TempFiles` for service-level temp file management.
- Configured `NLog` for file and console logging.
- Updated `appsettings.json` for connection strings and service-specific configuration.
- Replaced legacy `ProjectInstaller` with `AddWindowsService()` for SCM integration.
Introduced a new project `EnvelopeGenerator.Service` to the solution as a .NET Worker Service targeting the `net4.6.2` framework.
- Configured the project with nullable reference types, implicit usings, and `LangVersion` set to `latest`.
- Added a `Worker` class that logs periodic messages while running.
- Updated `Program.cs` to configure and run the Worker Service.
- Added `launchSettings.json` for development environment configuration.
- Added `appsettings.json` and `appsettings.Development.json` for logging configuration.
- Included the project in `EnvelopeGenerator.sln` with appropriate build configurations and hierarchy updates.
The project `EnvelopeGenerator.Service` has been removed from the solution and replaced with a new project, `EnvelopeGenerator.Service_legacy`.
Updated build configuration mappings to reflect the addition of `Service_legacy` and the removal of `Service`. Adjusted project nesting to place `Service_legacy` under the same parent as the removed `Service`.
Updated the `handleReset` method in `app.js` to await the
`Swal.fire` call, ensuring proper asynchronous handling.
Added logic to reset editable text form fields and restore
widget backgrounds after signing.
Refactored `app.min.js` to align with changes in `app.js`,
ensuring consistency between the minified and non-minified
versions. Improved code readability and maintainability
across both files.
Increased the maximum width values for the "position" and "city" keys in the `TextMaxWidths` property of `Jobs.FinalizeDocument` (PDFBurnerParams.vb) from `1.25F` to `1.41F`. This change allows more text to fit before truncation occurs, improving text rendering flexibility.
Updated `appsettings.UI.json` to adjust annotation properties for better alignment and positioning. Refactored `createAnnotations` and `createAnnotationFrameBlob` in `annotation.js` to improve readability, reusability, and asynchronous handling.
Enhanced the `App` class in `app.js` by introducing `signatureWidgets` for stable frame placement and added logic to find and update the nearest signature widget. Improved bounding box calculations and removed widget backgrounds after signing.
Refactored `handleAnnotationsCreate` to align with new logic and updated `app.min.js` to reflect these changes. General improvements include better code maintainability, reduced redundancy, and enhanced user experience.
Replaced character-based truncation with pixel-accurate truncation based on rendered width in inches. Updated `TruncateText` in `PDFBurner.vb` to use `Graphics.MeasureString` for width calculation and introduced a binary search for efficient truncation. Renamed `egName` to `fieldEgName` for clarity.
Replaced `TextMaxLengths` with `TextMaxWidths` in `PDFBurnerParams.vb`, specifying maximum render widths in inches. Updated default values for `position`, `city`, and `date`. Revised XML documentation to reflect the new truncation logic.
Address customer feedback on signature field layout issues:
- Added truncation logic in `PDFBurner.vb` to limit text length
based on per-field maximums, appending a suffix (e.g., `..`).
- Enhanced `PDFBurnerParams.vb` with `TextMaxLengths` and
`TruncationSuffix` for configurable truncation behavior.
- Improved spacing and layout handling for signature fields to
prevent text collisions within fixed dimensions.
- Updated `EnvelopeGenerator.sln` with documentation for the
signature formatting fix (`fix-signature-field-formatting.md`).
- Applied truncation consistently across `AddFormFieldValue`
overloads and ensured deterministic rendering of annotations.
Updated the Signature Certificate report to display the correct
label "Read and confirmed" for "Read and Sign" envelopes.
- Added `DocumentSignedRaC` resource key to `Model.resx` and
`Model.en.resx` with localized values ("Gelesen und bestätigt"
and "Read and confirmed").
- Updated `ReportItem.vb` to include conditional logic in
`ItemStatusTranslated` for "Read and Sign" envelopes.
- Added strongly-typed property for `DocumentSignedRaC` in
`Model.Designer.cs`.
- Updated `fix-report-label-read-and-confirmed.md` documentation
to reflect changes, including testing steps and task completion.
These changes ensure accurate status labels in the report for
different envelope types.
Addressed an issue where the Signature Certificate report incorrectly displayed "Document signed" for "Read and Sign" envelopes. Added a new resource key, `DocumentSignedRaC`, with translations ("Read and confirmed" / "Gelesen und bestätigt") to resolve this.
Updated `ItemStatusTranslated` in `ReportItem.vb` to use the new key for "Read and Sign" envelopes (`EnvelopeTypeId == 2`) while retaining existing behavior for other envelope types. Leveraged `Envelope.IsReadAndConfirm()` to determine envelope type.
Pending tasks include adding the new resource key to resource files and updating `Model.Designer.cs` with a strongly-typed property. Testing instructions provided to verify correct label behavior.
The .gitignore file was updated to ignore the following files and
directories:
- `FodyWeavers.xsd`
- `/EnvelopeGenerator.Tests.Application/annotations.json`
- `/EnvelopeGenerator.Server/EnvelopeGenerator.Server/TekH - SoftHSM Test.md`
- `/EnvelopeGenerator.Server/EnvelopeGenerator.Server/tekh_softHSM_test.md`
- `/EnvelopeGenerator.Server/EnvelopeGenerator.Server/publish-output`
- `/EnvelopeGenerator.Server/EnvelopeGenerator.Server/tekh_softHSM_test.md+/ignore/EnvelopeGenerator.Form`
These changes ensure that unnecessary or sensitive files are not
tracked in version control.
Updated the `DesktopBuildPackageLocation` property in
`IISProfileNet8.pubxml` and `IISProfile.pubxml` to store
build packages in the `PreRelease` directory.
- Updated `EnvelopeGenerator.API.zip` and `EnvelopeGenerator.Server.zip` paths in `IISProfileNet8.pubxml`.
- Updated `EnvelopeGenerator.ReceiverUI.zip` path in `IISProfile.pubxml`.
No other properties or configurations were modified.
Updated the `.gitignore` file to exclude the `MigrationBackup/`
directory. Added `publish-output` and `tekh_softHSM_test.md`
to the `EnvelopeGenerator.Server` directory.
Modified the `EnvelopeGenerator.sln` file to include a new
solution item `RECEIVER_PDF_VIEWER_CONTEXT.md` under the
`src` project section. No structural changes were made to
existing projects in the solution.
Added a `dotnet-tools.json` file to define a .NET tool manifest, specifying the `dotnet-ef` tool with version `10.0.9`.
Introduced a `publish.bat` script for publishing the `EnvelopeGenerator.Server` project as a self-contained application targeting `win-x64` and .NET 8. The script handles cleaning, publishing, output verification, and provides deployment instructions for IIS.
Updated the `EnvelopeGenerator.sln` file to include a reference to the `publish.bat` script under the `EnvelopeGenerator.Server` project using a `SolutionItems` section.
Updated `<Version>`, `<FileVersion>`, and `<AssemblyVersion>` in `EnvelopeGenerator.Server.csproj` to reflect a minor version update (1.0.0-beta -> 1.0.1-beta). This likely includes bug fixes, small improvements, or other non-breaking changes.
Updated the IISProfileNet8.pubxml file to enable self-contained deployment by setting `<SelfContained>` to `true`. Target runtime was specified as `win-x64` using the `<RuntimeIdentifier>` property. Configured the environment for production by adding the `<EnvironmentName>` property set to `Production`.
Added a detailed "Publish & Deployment Guide" to the README for the `EnvelopeGenerator.Server` project. The guide includes:
- Table of contents for easy navigation.
- Explanation of differences between `EnvelopeGenerator.Server` and a standard ASP.NET Core API.
- Justification for self-contained publishing and its benefits.
- Recommended `dotnet publish` command with parameter explanations.
- IIS configuration steps, including Application Pool settings, `web.config` adjustments, and module requirements.
- Verification checklist for published output files.
- Instructions for setting up logging and recycling the IIS Application Pool.
- Directory structure overview post-publish.
- Troubleshooting common deployment errors with solutions.
This guide ensures developers and administrators can successfully publish and deploy the application.
The `.gitignore` file was updated to ignore `FodyWeavers.xsd`.
Added a new directory `/publish-output` to the server folder.
The file `tekh_softHSM_test.md` was removed and re-added,
indicating potential modifications or reorganization.
Updated `.gitignore` to include `MigrationBackup/`. Added new files: `FodyWeavers.xsd`, `annotations.json`, and two markdown files for SoftHSM testing. Modified `/EnvelopeGenerator.Web/.config/dotnet-tools.json`, `/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/.vscode`, and `/EnvelopeGenerator.Tests.Application/Services/BugFixTests.cs` to reflect configuration and testing updates.
Updated the `DxGridDataColumn` for the `Id` field in
`EnvelopeSenderPage.razor` to include default sorting.
The column now has `SortIndex=0` and `SortOrder=GridColumnSortOrder.Descending`,
ensuring the grid sorts by ID in descending order by default.
Updated `<Version>` to `1.0.0-beta` to reflect a pre-release version. Aligned `<FileVersion>` and `<AssemblyVersion>` with the new versioning scheme (`1.0.0.0`). Replaced `<PackageOutputPath>` with `<Copyright>` for better metadata alignment. No changes to `<DocumentationFile>`.
Replaced `<TargetFramework>` with `<TargetFrameworks>` to allow for future multi-targeting. Enabled XML documentation file generation with `<GenerateDocumentationFile>`. Added project metadata including `<PackageId>`, `<Authors>`, `<Company>`, `<Product>`, and versioning properties (`<Version>`, `<FileVersion>`, `<AssemblyVersion>`). Included copyright notice and documentation file path configuration.
A new `IISProfileNet8.pubxml` file was added to configure publishing settings for a .NET 8.0 application. Key configurations include:
- Publish method set to `Package`.
- Build configuration set to `Release` and platform to `Any CPU`.
- Automatic site launch after publishing enabled.
- `App_Data` folder included in the package.
- Unique project identifier defined.
- Build package location specified with a version placeholder.
- Package created as a single file.
- IIS application path set to `EnvelopeGenerator`.
- Deployment target set to `IISWebDeployPackage`.
- Target framework set to .NET 8.0.
Introduced input fields for "Title" and "Message" in the
EnvelopeSenderEditorPage, allowing users to specify metadata
for envelopes. The "Title" field is required and validated,
while the "Message" field is optional with a default value.
Updated the save logic to validate the title and display
appropriate error messages. Persisted the "Title" and
"Message" fields in the session cache via the
`EditorSessionData` record.
Modified the `CreateEnvelopeReceiverCommand` to use the
user-provided "Title" and "Message" values. Adjusted the UI
layout and styling to accommodate the new fields, ensuring
a seamless user experience.
Updated navigation logic and routes to remove the `/report` suffix, simplifying the URL structure for envelope-related pages.
- Updated `LoginReceiverPage.razor` and `ReceiverSignedPage.razor` to redirect to `/envelope/{EnvelopeKey}`.
- Changed `ReceiverPage.razor` route to `/envelope/{EnvelopeKey}`.
- Updated `ILogger` dependencies in `ReceiverPage.razor` and `ReceiverSignedPage.razor` to reflect new class names.
- Modified `EnvelopeReceiverPage.razor` route to `/envelope/{EnvelopeKey}/deprc`, indicating deprecation or restructuring.
Added a custom DelegatingHandler, SenderAuthCookieHandler, to forward the browser's Cookie header to outgoing HttpClient requests in Blazor Server. Registered the handler as a transient service and integrated it into the named HttpClient pipeline for internal API calls. This enables Blazor Server components to make authenticated API calls using cookie-based JWT authentication (AuthScheme.Sender).
Introduced the ability to create envelopes with documents and receivers via a new `CreateAsync` method in `EnvelopeReceiverService`. Integrated this functionality into `EnvelopeSenderEditorPage.razor` with UI updates, including a save button spinner, validation checks, and a result popup for success or error feedback.
- Added `CreateAsync` method to handle `POST /api/EnvelopeReceiver` API calls.
- Injected `EnvelopeReceiverService` into `EnvelopeSenderEditorPage.razor`.
- Implemented save logic with validation for PDF upload, receivers, and signature fields.
- Added success and error popups for user feedback.
- Improved logging for envelope creation and validation warnings.
- Refactored save logic for better readability and maintainability.
Added warning logs in `EnvelopeReceiverController` to handle
cases where stored procedures return `OUT_SUCCESS=false`.
For `PRSIG_API_ADD_DOC_RECEIVER_ELEM`, log `DOC_ID`,
`RECEIVER_ID`, and `Page`. For `PRSIG_API_ADD_HISTORY_STATE`,
log `EnvelopeUuid`. These changes enhance error visibility
and debugging.
Updated the SQL query in `EnvelopeReceiverAddReadSQL.cs` to change the data type of the `@OUT_RECEIVER_ID` variable from `int` to `bigint`. This modification ensures support for larger identifier values, addressing potential limitations of the previous `int` type.
Updated `Authorize` attributes in multiple controllers to use
`AuthenticationSchemes = AuthScheme.Sender` instead of
`Policy = AuthPolicy.Sender`, reflecting a shift in the
authentication mechanism.
Added detailed logging in `EnvelopeReceiverController` to handle
cases where stored procedures return `OUT_SUCCESS=false`,
providing contextual information for debugging.
Removed unused SQL code and declarations in
`EnvelopeReceiverController` to improve code readability and
maintainability.
Introduced a `Color` property to `ReceiverDraft` and `SignatureFieldDraft` models, enabling dynamic color assignment from a predefined palette (`ReceiverPalette`). Updated the UI to reflect receiver-specific colors in the sender-receiver chips, placement mode hint bar, and signature placement button.
Refactored PDF rendering logic to dynamically derive visual styles (fill, border, and text colors) from receiver colors. Added a `HexToXColor` utility for converting hex color strings to `PdfSharp.Drawing.XColor`.
Removed hardcoded visual styles and replaced them with dynamic, receiver-specific styling. Simplified receiver addition logic to automatically assign colors from the palette. These changes improve clarity and maintainability while enhancing the user experience.
The session ID generation and redirection logic was moved from
OnInitialized to OnAfterRenderAsync to address issues with
NavigationException during SSR prerendering. OnInitialized is
now intentionally left empty, and the new OnAfterRenderAsync
method ensures the session ID is appended to the URL only after
the first interactive render, when SignalR is connected and
NavigateTo is safe.
- Added `IMemoryCache` for session persistence and caching.
- Introduced session persistence via query parameter (`esid`).
- Replaced overlay-based click handling with normalized PDF coordinates.
- Added `PdfSharp` integration to render signature placeholders.
- Updated button behavior for receiver-specific signature placement.
- Improved receiver popup validation and email suggestion handling.
- Removed unused overlay synchronization logic.
- Refactored CSS for better PDF viewer layout and toolbar alignment.
- Enhanced logging with additional context for signature actions.
- General code cleanup for readability and maintainability.
- Injected `NavigationManager` into `IndexPage.razor` to enable navigation.
- Improved layout alignment with additional classes in `<div>`.
- Added a new button for navigation to `/sender` with icons and text.
- Introduced a feature badge for "PDF-Export" with an SVG icon.
- Updated `.home-btn-primary` styles in `app.css`:
- Ensured text color is always white with `!important`.
- Made text bolder by increasing `font-weight` to `700`.
Added the `NavigationManager` service injection to the
`EnvelopeSenderEditorPage.razor` file to enable navigation.
Introduced a "Cancel" button in the toolbar, styled with
`pdf-toolbar__btn pdf-toolbar__btn--reset`, which triggers
the `Cancel` method on click. The `Cancel` method navigates
the user to the `/sender` route, improving the user experience
by providing a clear way to cancel the current operation.
Refactored the handling of email suggestions to separate selection
and commitment logic. Updated `<DxListBox>`'s `ValueChanged`
handler to use `OnReceiverEmailSuggestionCommittedAsync` for
finalizing selections. Introduced `SelectReceiverEmailSuggestion`
as a synchronous helper method for managing selection updates.
Centralized clearing of suggestions in the new
`OnReceiverEmailSuggestionCommittedAsync` method. Simplified
keyboard navigation logic by replacing asynchronous calls with
synchronous selection handling. These changes improve code
clarity and reduce unnecessary asynchronous operations.
Added functionality to display a receiver's phone number in the
sender-receiver chip if provided. Introduced a new input field
in the receiver popup for entering an optional phone number.
Updated the `ReceiverDraft` model and `_receivers` list to
include and store phone numbers. Modified methods to handle
phone number input and saving. Added CSS styles for displaying
the phone number in the sender-receiver chip.
Enhanced the email suggestion feature by adding keyboard navigation support (`ArrowUp`, `ArrowDown`, `Enter`, `Escape`) and introducing `_selectedReceiverEmailSuggestion` to track the current selection. Updated methods to synchronize input and suggestions, pre-select matching suggestions, and reset the state when the popup is opened or closed. Improved error handling and ensured clean state management for better user experience.
Replaced DevExpress DxButton components with standard HTML
<button> elements in EnvelopeSenderEditorPage.razor for
"Add Receiver" and "Add Signature" actions. The new buttons
include SVG icons and text for improved customization and
styling.
Updated envelope-viewer.css to add new styles for the
buttons, including `.sender-toolbar-action-btn` and
`.sender-toolbar-action-btn--compact` classes. Removed
unused styles related to DxButton components and adjusted
`.sender-receiver-chip__action` for proper width handling.
These changes improve design flexibility and maintainability.
Introduced a new "Receivers" panel in `EnvelopeSenderEditorPage` to manage receivers. Added a popup for adding receivers with validation, email suggestions, and caching for performance. Updated the layout to display receiver details and signature fields.
Injected `EnvelopeReceiverPageDataService` for receiver-related operations. Added a `ReceiverDraft` model and implemented methods for managing receivers. Enhanced CSS for the new UI elements and ensured responsiveness. Minor refactoring and cleanup included.
Replaced the placeholder console log in the `CreateEnvelope` method with actual navigation functionality. The method now uses `Navigation.NavigateTo` to redirect users to the `/sender/editor` page, enabling the intended behavior for creating envelopes.
The namespace of the `ReceiverController` class was updated from `EnvelopeGenerator.GeneratorAPI.Controllers` to `EnvelopeGenerator.Server.Controllers`.
The `Get` method was enhanced with the following changes:
- Added `[Authorize]` attribute with `AuthScheme.Sender`.
- Updated the method signature to include an optional `ReadReceiverQuery? receiver` parameter (defaulting to `null`) and a new `bool onlyEmailAddress` parameter (defaulting to `false`).
- Modified logic to handle `receiver` being `null` by creating a new `ReadReceiverQuery`.
- Added handling for `onlyEmailAddress` to return a list of email addresses if true.
- Simplified the result handling and removed the previous `receiver.HasAnyCriteria` logic.
- Added `[NotMapped]` attribute to `HasAnyCriteria` in `ReceiverQueryBase` to exclude it from database mapping.
- Made `HasAnyCriteria` in `ReceiverQueryBase` virtual for overriding.
- Introduced `EmailAddressSearch` in `ReadReceiverQuery` for partial email matching.
- Overrode `HasAnyCriteria` in `ReadReceiverQuery` to include `EmailAddressSearch`.
- Updated `ReadReceiverQueryHandler` to support partial email matching using `EF.Functions.Like`.
Refactor `EnvelopeSenderEditorPage.razor` to enhance the structure and behavior of the PDF editor wrapper:
- Add `class="pdf-editor-wrapper"` and update `overflow` to `auto`.
- Update `DxPdfViewer`'s `CssClass` to `sender-editor-pdf-viewer`.
- Introduce `OnAfterRenderAsync` to synchronize the overlay with the viewer.
Add new styles in `envelope-viewer.css` for better layout:
- Ensure `.pdf-editor-wrapper` and `.sender-editor-pdf-viewer` occupy full dimensions.
- Center and align content within the PDF viewer.
Enhance `envelope-editor.js` with `syncOverlayToPage`:
- Dynamically adjust overlay position and size relative to the viewer.
- Use `MutationObserver` and event listeners for real-time synchronization.
- Handle delayed rendering with scheduled sync attempts.
These changes improve overlay alignment, user experience, and code maintainability.
Added the `@rendermode InteractiveWebAssembly` directive to
`IndexPage.razor` to enable interactive WebAssembly rendering.
Included a `<link>` element to reference the `blazing-berry.bs5.min.css`
stylesheet from the `DevExpress.Blazor.Themes` content folder to
apply the "blazing-berry" theme for enhanced styling.
The user-facing text in `EnvelopeReceiverReportSignedPage.razor` has been updated to provide a more detailed and formal confirmation message for signing a document.
- Replaced "Dokument erfolgreich unterschrieben" with "Möchten Sie das Dokument verbindlich unterschreiben?".
- Updated the follow-up message to clarify the irreversibility of the action and the electronic signing process.
Additionally, the logout navigation behavior has been modified:
- Changed the post-logout redirect from `/envelope/login/{EnvelopeKey}` to the root page (`/`), while retaining the `forceLoad` parameter.
Added dependency injection for `AuthService`, `ReceiverAuthorizationService`, `PageDataService`, and `Logger` to enable their usage in the component. Introduced a "Submit" button in the UI to confirm the signing process and complete the workflow.
Implemented a `DxPopup` component to display a confirmation dialog when the "Submit" button is clicked. The popup includes a message about the successful signing of the document and asks the user to confirm whether to complete the process and log out.
Added state variables `_isLoggingOut` and `_submitConfirmVisible` to manage the popup visibility and logout process. Created `OpenSubmitConfirmPopup` to toggle the popup and `SubmitAndLogoutAsync` to handle the submission process, including logging out via `AuthService` and navigating to the login page.
Updated the `@code` block with the new state variables and methods for managing the submit and logout functionality.
Added a check for `_sig` being `null` to handle cache misses or missing `sid`. Logged a warning with `Sid` and `EnvelopeKey` details when this occurs. Implemented a redirection to the report page (`/envelope/{EnvelopeKey}/report`) using `Navigation.NavigateTo` with `forceLoad: true`. Added an early return to prevent further execution after redirection.
Refactored the signature box layout to dynamically calculate
positions based on content, improving flexibility and precision.
Introduced new constants (`lineH`, `bgPad`) to standardize
spacing and replaced hardcoded values for better maintainability.
Adjusted background rectangle sizing to fit content dynamically
and improved text layout logic to handle optional fields more
gracefully. Simplified image area logic and reduced redundant
calculations. Overall, improved code readability and alignment
for a cleaner, more compact layout.
Introduced a new Blazor page `EnvelopeSenderEditorPage.razor` for editing envelopes with an interactive interface. Integrated `DxPdfViewer` for rendering PDFs and added functionality for uploading, viewing, and interacting with PDF files.
Key features:
- Action bar with buttons for uploading PDFs, toggling signature placement mode, clearing fields, and saving.
- Placement mode for adding signature fields via an overlay, with visual placeholders.
- JavaScript interop (`envelope-editor.js`) for precise click coordinate mapping.
- Error handling for unsupported file types and size limits (50 MB).
- Logging for debugging key actions like PDF uploads and field placements.
Defined constants for accurate signature field dimensions and scaling. Added models (`SignatureFieldDraft`, `OverlayCoords`) to manage state and interactions.
Updated the signature box proportions by adjusting `imgRatio` to 52% and `textRatio` to 43%. Added a cream-tone background with extra padding (`bgPad`) and rendered it behind the signature content. Tightened gaps between the image, separator line, and text area. Increased text row height slightly for better spacing.
Added functionality to render captured signatures onto a PDF document using the PdfSharp library. Introduced a new `_signatures` field to store signature data and updated `OnInitializedAsync` to fetch and process signatures. Implemented the `DrawSignaturesOnPdf` method to overlay signature images, separator lines, and signer details (name, position, place, date) onto the PDF. Added a helper method `DataUrlToBytes` for decoding Base64-encoded signature images. Defined constants for layout and styling to ensure consistent rendering. Updated `Dispose` to clean up resources.
Removed all signature capture and validation functionality, including the signature popup, JavaScript interop, and related backend logic. Simplified the `DxReportViewer` initialization to directly display the signed document. Added support for retrieving cached signatures via the `sid` query parameter. Streamlined error handling, logging, and page metadata. Cleaned up unused imports, constants, and methods to reduce complexity.
Updated button logic to display "Unterschreiben" only when signature fields exist. Changed `_signaturePopupVisible` to always be `false` for consistent popup behavior. Improved navigation after caching a signature by nullifying `_report`, adding a delay for UI updates, and using `forceLoad: true` for clean circuit teardown. These changes enhance user experience and prevent potential crashes.
Changed the navigation path in `LoginReceiverPage.razor` to redirect users to `/envelope/{EnvelopeKey}/report` instead of `/envelope/{EnvelopeKey}` upon a successful login. The `forceLoad: true` parameter remains unchanged to ensure a full page reload.
Replaced the previous signature persistence mechanism with
`IMemoryCache` for temporary storage of captured signatures
using a unique `Guid` key and a 1-minute TTL. Added logging
to track cached signatures and their associated envelope keys.
Removed the logic for rebuilding and displaying reports with
overlaid signatures. Instead, implemented navigation to a
new signed page (`/envelope/{EnvelopeKey}/signed`) with the
signature ID passed as a query parameter.
Added a `PdfSharpFontResolver` class to enable font resolution
for PdfSharp in .NET 8, addressing the lack of system font
access. The resolver reads fonts from the Windows Fonts folder
and supports the Arial font family. Registered the resolver
globally in `Program.cs` using `GlobalFontSettings.FontResolver`.
Updated `Program.cs` with comments explaining the necessity of
the resolver for .NET 8. The resolver includes methods to map
font family names to specific font files and load font data.
Throws a `FileNotFoundException` if required fonts are missing.
Made minor formatting changes in `Program.cs` without altering
the `SwaggerDoc` description functionality.
Refactored `EnvelopeReceiverReportPage.razor` to replace the logic for burning captured signatures with a new approach that draws placeholder boxes for signature fields using the `DrawSignaturePlaceholders` method. Removed the `BurnSignaturesIntoPdf` method and introduced `PDFsharp` for rendering placeholders.
Added `EnvelopeReceiverReportSignedPage.razor` to handle signed envelopes, including a detailed UI for document display, metadata, and a signature popup with "Draw," "Text," and "Image" modes. Integrated JavaScript interop for signature creation and validation.
Updated `EnvelopeGenerator.Server.csproj` to include the `PDFsharp` library. Enhanced error handling, logging, and UI feedback. Improved code readability and maintainability through cleanup and refactoring.
Replaced iText-based PDF processing with DevExpress PdfGraphics API.
Removed `itext` and `itext.bouncy-castle-adapter` dependencies.
Simplified `BuildReport` to burn signatures directly into PDFs
and render all pages using `XRPdfContent` with `GenerateOwnPages = true`.
Consolidated subreport logic into `BuildReport` and removed
`BuildPageSubreport`. Eliminated unused constants and methods,
including `GetPdfPageCount`. Updated XML documentation to reflect
the new implementation. Placeholder implementation for
`BurnSignaturesIntoPdf` added, pending further development.
Added a new Razor page `EnvelopeReceiverReportPage.razor` to display and manage envelope reports at the route `/envelope/{EnvelopeKey}/report`. Integrated DevExpress Blazor Reporting components (`DxReportViewer`, `DxPopup`) for rendering PDF documents and capturing user signatures.
Implemented a multi-tab signature capture interface supporting drawing, text input with font selection, and image uploads. Added support for dynamically overlaying captured signatures on PDF documents using `XRPictureBox`.
Introduced dependency injection for services like `AuthService`, `ReceiverAuthorizationService`, and `PageDataService` to handle authentication, data retrieval, and logging. Included lifecycle methods for user authorization, PDF loading, and restoring cached signatures.
Added validation for signature input, error handling for missing data, and utility methods for building reports, extracting PDF page counts, and converting base64 data URLs. Integrated JavaScript interop for canvas-based signature handling.
Included custom styles and assets, and implemented disposal logic for cleaning up resources.
2026-06-30 23:27:20 +02:00
413 changed files with 22250 additions and 31608 deletions
- **`COPILOT_CONTEXT.md`** - Architecture, coordinate systems, migration status
- **`FORM_APPLICATION_CONTEXT.md`** - Legacy VB.NET features to migrate
---
## Documentation Catalog
This section explains every markdown file in the repo: what it contains, why it exists, and when you need it. Read this before deciding which file to open.
**What:** Deep-dive architecture reference. Covers the full Blazor Auto hybrid setup, authentication flows (JWT + cookies, per-envelope receiver tokens), service registration patterns, coordinate system proof, and an explicit "prefer Server/Server.Client over old WebUI/ReceiverUI" rule.
**Why it exists:** Prevents agents from re-deriving or misinterpreting the hybrid SSR+WASM architecture. Also documents coordinate system evidence to prevent regressions (inches vs. points vs. pixels).
**When you need it:**
- Implementing any new page or service
- Debugging auth/cookie issues
- Any coordinate conversion question
- Unsure which project a new file should go in
**Maintenance:** Update when render mode assignments change, new auth schemes are added, or the coordinate system is touched.
#### `FORM_APPLICATION_CONTEXT.md`
**What:** Comprehensive reverse-engineering of the legacy VB.NET WinForms app (`EnvelopeGenerator.Form`). Documents every form (frmMain, frmEnvelopeEditor, frmFieldEditor, etc.), their UI layout, toolbar actions, data models, coordinate system, and a feature-by-feature migration mapping table to `EnvelopeGenerator.Server`.
**Why it exists:** The WinForms app is the functional specification for the sender-side web UI. It documents the full intended workflow that is being migrated to Blazor — especially the envelope creation, signature field placement, and dashboard features that are not yet implemented.
**When you need it:**
- Implementing any sender-side feature (`/sender`, `/sender/editor`, `/sender/envelope/{id}`)
- Understanding what a specific toolbar button or form should do
- Designing API endpoints for sender workflow
- Checking coordinate system behavior (INCHES proof is here)
**Maintenance:** Update the mapping table as features are implemented (change `❌ Not implemented` → `✅ Exists`). Do not rename `ReceiverUI` back — it was the old project name; current target is `EnvelopeGenerator.Server`.
#### `RECEIVER_PDF_VIEWER_CONTEXT.md`
**What:** Detailed technical reference for the receiver-side PDF viewer (`EnvelopeReceiverPage.razor`). Documents the PDF.js integration, signature button rendering, JS interop API (`window.pdfViewer`), signature capture flow, HiDPI/zoom/thumbnail config, and the full component lifecycle.
**Why it exists:** The receiver PDF viewer is the most complex component in the codebase. This doc prevents agents from misunderstanding the JS↔Blazor boundary, re-implementing already-solved problems (HiDPI, zoom, signature caching), or breaking the signing flow.
**When you need it:**
- Working on `EnvelopeReceiverPage.razor` or `pdf-viewer.js`
- Adding new signature field rendering logic
- Debugging signature rendering, zoom, or thumbnail issues
- Implementing sender-side PDF.js overlay (signature field placement) — the receiver side is the reference implementation
**Maintenance:** Update when `pdf-viewer.js` API changes, new JS interop functions are added, or the signing flow is modified.
#### `DATABASE_STRUCTURE_CONTEXT.md`
**What:** Deep DB documentation for the envelope domain. Includes table/column snapshot, entity-to-table mapping, EF relationship/constraint map, stored procedure behavior + call sites, and trigger behavior + wiring path.
**Why it exists:** DB is centralized and can evolve independently; this file preserves migration-critical data semantics when historical DB context is hard to recover.
**When you need it:**
- Planning or reviewing DB/schema changes
- Debugging status transitions/history side effects
- Tracing where `PRSIG_*` procedures or DB triggers affect app behavior
- Reconciling Domain entities with physical SQL schema
**Maintenance:** Refresh on each DB migration, trigger/procedure change, or significant Domain/EGDbContext model change.
**What:** IIS publish and deployment guide for `EnvelopeGenerator.Server`. Covers why self-contained publish is required (WASM assembly version strictness), the exact `dotnet publish` command, IIS Application Pool settings (`No Managed Code`), directory structure after publish, and common deployment errors.
**Why it exists:** Blazor Auto (Server + WASM hybrid) has non-obvious deployment requirements that differ from a standard ASP.NET Core app. Forgetting self-contained publish or using the wrong app pool will break WASM loading in production.
**When you need it:**
- Deploying to IIS for the first time
- Troubleshooting 500 errors on production after deploy
- Setting up a new deployment environment
**Maintenance:** Update if the publish target, IIS config, or runtime version changes.
---
## Markdown Audit Snapshot (2026-10-05)
The following table summarizes repository markdown files by practical status: completed, partially complete, or removable candidates.
| File | Type | Status | Missing / Gap | Removal Recommendation |
|---|---|---|---|---|
| `AGENTS.md` | Agent onboarding | Partially complete | Route/migration statements can drift from real code over time. | Keep |
| `COPILOT_CONTEXT.md` | Architecture reference | Partially complete | Some route/render details may be out of sync with other docs; needs regular reconciliation. | Keep |
| `FORM_APPLICATION_CONTEXT.md` | Legacy-to-modern feature spec | Partially complete | Large sections still marked not implemented / needs implementation. | Keep |
| `RECEIVER_PDF_VIEWER_CONTEXT.md` | Receiver PDF viewer deep-dive | Partially complete | Long migration plan needs periodic sync with active implementation. | Keep |
| `SENDER_SAVE_EDIT_MIGRATION_PLAN.md` | Sender workflow implementation plan | Partially complete | No explicit implementation progress markers per phase. | Keep (until migration closes) |
| `ignore/EnvelopeGenerator/EnvelopeGenerator.Web/wwwroot/lib/bootstrap-icons/README.md` | Vendor README in archive area | Secondary | Archive-only utility, not active docs. | Removable/archive |
| `ignore/EnvelopeGenerator/EnvelopeGenerator.Web/wwwroot/lib/jquery-validation/LICENSE.md` | Duplicate license in archive area | Redundant | Duplicate copy under `ignore/`. | Removable/archive (if legal policy allows) |
- [ ] Validate this markdown audit table against the current codebase and update statuses (`complete`, `partial`, `incomplete`, `removable`) when implementation changes land.
**Backend + API Host:**`EnvelopeGenerator.Server` (ASP.NET Core 8.0, merged Blazor + Web API host)
**Proxy:** YARP in WebUI routes `/api/*` → `localhost:8088` (API)
**Proxy:** YARP in `EnvelopeGenerator.Server` is used for external integrations (for example AuthHub forwarding), not for routing app APIs to `EnvelopeGenerator.API`.
### Deprecated Projects - DO NOT USE
-`EnvelopeGenerator.ReceiverUI` - Pure WASM (migrated to WebUI)
-`EnvelopeGenerator.Web` - Razor Pages (replaced by WebUI)
-`EnvelopeGenerator.ReceiverUI` - Pure WASM (migrated to Server)
-`EnvelopeGenerator.Web` - Razor Pages (replaced by Server)
1. Start API (`dotnet run` in `EnvelopeGenerator.API`)
2.Start WebUI (`dotnet run` in `EnvelopeGenerator.WebUI\EnvelopeGenerator.WebUI`)
3.Navigate to `https://localhost:5131` (or check console output for port)
4. Test sender login at `/sender/login`
5. Test receiver flow at `/envelope/login/{envelopeKey}`
1. Start EnvelopeGenerator.Server (`dotnet run` in `EnvelopeGenerator.Server\EnvelopeGenerator.Server`)
2.Navigate to `https://localhost:5131` (or check console output for port)
3.Test sender login at `/sender/login`
4. Test receiver flow at `/envelope/login/{envelopeKey}`
## Technical Debt TODOs
- **CRITICAL (Licensing / pre-commercial release):** Remove all `SixLabors.ImageSharp` and `QRCoder-ImageSharp` package dependencies from production/runtime projects before commercial release. Replace remaining QR/image paths with permissive-license alternatives (no copyleft/share-source obligations), run repo-wide package audit (`*.csproj`), and add CI guardrails to block reintroduction.
- Refactor `EnvelopeGenerator.Server/EnvelopeGenerator.Server/Components/Pages/EnvelopeSenderPage.razor` to reduce complexity.
- Move sender dashboard business/status logic into dedicated services and extension methods (for example effective status resolution, tab classification, receiver signed/rejected detection, and grid-layout filter sanitation).
- Keep `EnvelopeSenderPage.razor` focused on UI composition/state orchestration; avoid embedding heavy domain logic directly in the Razor component.
- Apply a modular page architecture across Server pages (starting with `EnvelopeGenerator.Server/EnvelopeGenerator.Server/Components/Pages/EnvelopeSenderPage.razor`): split large pages into smaller subcomponents/partial modules, eliminate duplicated code paths, and centralize shared UI/domain logic for maintainability.
- Perform a senior-level page performance review across sender/receiver flows before further UX changes: verify route transitions, component mount/unmount behavior, loading-state correctness, duplicate API calls, and perceived latency (first meaningful paint and return-navigation responsiveness). Treat loading logic defects as architecture/performance issues first, not styling problems.
- Audit `EnvelopeGenerator.Server/EnvelopeGenerator.Server.Client/Services/` for unnecessary request/payload remapping and remove redundant mappings where direct request DTO usage is safe; review client HTTP methods end-to-end for similar avoidable transformation layers.
- Centralize dependency injection registrations into dedicated extension methods/modules (especially server + client service registrations in `Program.cs`) to reduce startup composition sprawl and improve maintainability.
- Refactor `EnvelopeGenerator.Server/EnvelopeGenerator.Server/Controllers/PdfRenderController.cs` + matching client service contract to remove JSON/base64 `byte[]` transport for PDF rendering; prefer binary streaming (`application/octet-stream` or multipart), avoid `data:` URL bloat where possible, and validate end-to-end memory/latency behavior with large PDFs.
- Establish a DevExpress toast-based notification architecture using `DxToastProvider` + `IToastNotificationService` (tab/page-scoped provider strategy, standardized `ToastOptions` factory, and severity-to-style mapping) so sender/receiver flows show consistent, non-duplicated, actionable feedback.
- Eliminate manual property-by-property request→domain mapping drift (example: `CreateEnvelopeCommandHandler`) by introducing a standardized mapping policy (AutoMapper/profile conventions or reflection/source-generator based mapper) and enforcing it across envelope workflows; this needs to be solved in the shared company Core library level so all services get the same guardrails by default.
- P1 security workstream: remove dynamic SQL string composition/interpolation from active save/create/update paths (`string.Format`, `$"...{input}..."`, `ToSqlParam`) and migrate to parameterized queries only; treat this as a potential SQL injection vulnerability (stability + security risk), execute repo-wide audit, and add CI guardrails to block reintroduction.
- Alternative UX design (Server component): in `EnvelopeGenerator.Server/EnvelopeGenerator.Server/Components/Pages/EnvelopeSenderPage.razor`, enforce deterministic row double-click behavior as exactly one action (preview OR edit), and keep row action buttons/tooltips aligned with the same rule to eliminate ambiguous navigation.
- Implement SPA-style language switching so the UI culture updates immediately without a full page reload.
- Implement sender-scoped caching for "recent receiver suggestions" used during envelope creation (wizard/editor flows): cache key should include sender identity, support short TTL + invalidation hooks after successful envelope receiver writes, and prevent cross-sender suggestion leakage.
## Database
**SQL Server** (DD_ECM)
- Connection string in `API/appsettings.json`
- Connection string in `EnvelopeGenerator.Server/EnvelopeGenerator.Server/appsettings.json`
- EF Core migrations NOT used (manual SQL scripts)
- Stored procedures: `PRSIG_*` prefix
**Key Tables:**
-`TBSIG_ENVELOPE` - Envelope metadata
-`TBSIG_ENVELOPE_RECEIVER` - Receiver assignments
-`TBSIG_DOC_RECEIVER_ELEMENT` - Signature fields (X, Y in INCHES)
-`TBSIG_DOCUMENT_RECEIVER_ELEMENT` - Signature fields (X, Y in INCHES)
-`TBSIG_RECEIVER` - Receiver registry
-`TBSIG_DOCUMENT` - PDF binary data
-`TBSIG_ENVELOPE_DOCUMENT` - PDF binary data
-`TBSIG_ENVELOPE_HISTORY` - Audit trail
### Data Structure (Domain + EGDbContext)
Use this as the canonical quick map before touching sender/receiver workflow code.
#### Core Aggregate Shape
-`Envelope` (`TBSIG_ENVELOPE`) is the root aggregate for sending workflow.
-`Envelope -> Documents` is `1:N` via `Document.EnvelopeId` (`TBSIG_ENVELOPE_DOCUMENT`).
-`Envelope -> Histories` is `1:N` via `History.EnvelopeId` (`TBSIG_ENVELOPE_HISTORY`).
-`Envelope <-> Receiver` is `N:N` through `EnvelopeReceiver` (`TBSIG_ENVELOPE_RECEIVER`, composite PK `{EnvelopeId, ReceiverId}`).
-`Document -> DocReceiverElement` is `1:N` via `DocReceiverElement.DocumentId` (`TBSIG_DOCUMENT_RECEIVER_ELEMENT`).
-`DocReceiverElement -> ElementAnnotation` is `1:N` via `ElementAnnotation.ElementId` (`TBSIG_DOCUMENT_RECEIVER_ELEMENT_ANNOTATION`).
_logger.LogError("EmailAddress claim is not found in envelope-receiver-read-only creation process. Create DTO is:\n {dto}",JsonConvert.SerializeObject(createDto));
_logger.LogError("Although the envelope was sent as read-only, the EnvelopeShared history could not be saved. Create DTO:\n{createDto}",JsonConvert.SerializeObject(createDto));
varmessage=$"Required claim(s) '{string.Join("','", claimTypes)}' are missing for user '{principalName}' (auth: {authType}). Available claims: [{availableClaims}].";
thrownewInvalidOperationException(message);
}
/// <summary>
/// Gets the authenticated envelope UUID from the claims.
varmessage=$"Required claim among [{string.Join(",", claimTypes)}] is missing for user '{principalName}' (auth: {authType}). Available claims: [{availableClaims}].";
thrownewInvalidOperationException(message);
}
/// <summary>
/// Retrieves the user's ID from the claims. Throws an exception if the ID is missing or invalid.
/// </summary>
/// <param name="user">The <see cref="ClaimsPrincipal"/> representing the user.</param>
/// <returns>The user's ID as an integer.</returns>
/// <exception cref="InvalidOperationException">Thrown if the user ID claim is missing or invalid.</exception>
Guten Tag [NAME_RECEIVER],<br /> <br /> Der Vorgang <B><I>'[DOCUMENT_TITLE]'</I></B> wurde erfolgreich abgeschlossen.<br /> <br /> Sie erhalten das Dokument mit einem detaillierten Ergebnisbericht als Anhang zu dieser Email.<br /> <br /> Mit freundlichen Grüßen<br /> <br /> [NAME_PORTAL]
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.