Each direct mailer.sendMail() call is replaced by a dedicated background
job so that email delivery failures can be retried independently.
New jobs: send-pending-email, send-completed-email, send-forgot-password-email,
send-document-super-delete-email, send-recipient-removed-email,
send-document-deleted-emails, send-2fa-token-email, send-resend-document-email,
send-direct-template-created-email.
Existing handlers (send-document-cancelled-emails, send-organisation-member-*,
send-recipient-signed-email) have io.runTask wrappers removed since they
interfere with the job scheduler. Job triggers are dispatched after
transactions commit to avoid race conditions with uncommitted data.
## Description
Resolves an issue where individual plan customers who cancel are not
correctly put down to the free plan.
To resolve this, we delete the subscription on the stripe subscription
delete webhook. Since the customerId is stored on the organisation they
can still access their old invoices.
This PR introduces automatic detection and placement of fields and
recipients based on PDF placeholders.
The placeholders have the following structure:
- `{{fieldType,recipientPosition,fieldMeta}}`
- `{{text,r1,required=true,textAlign=right,fontSize=50}}`
When the user uploads a PDF document containing such placeholders, they
get converted automatically to Documenso fields and assigned to
recipients.
This PR introduces bulk actions for documents, allowing users to select
multiple envelopes and perform actions such as moving or deleting 1 or
more documents simultaneously.
The prompt option was being discarded for OAuth authorize URLs after
adding support for the NEXT_PRIVATE_OIDC_PROMPT env var. This meant
select_account (used elsewhere) was not being passed through.
Now defaults prompt to the provided option (or 'login'), and only
overwrites it when a valid OIDC prompt env var is set. Also adds a
type guard to validate the env var value.
The contact form accepts teamId as an optional param based on
where the user clicks "Support" from. Previously, when opened
from a non-team context, the null teamId would be parsed to NaN
and fail validation, causing the form to error out. Now the
validation only runs when a teamId is actually provided.
This PR fixes a bug in the `/api/v2/template` endpoint where the
pagination parameter `perPage` was being ignored. Previously, the
endpoint would return all matching templates regardless of the requested
limit, which could lead to performance issues and incorrect API
behavior.
API users were inadvertently sending documents without signature fields,
causing confusion for recipients and breaking their signing flows.
- Add getRecipientsWithMissingFields helper in recipients.ts
- Add server-side validation in sendDocument to block distribution
- Fix v1 API to return 400 instead of 500 for validation errors
- Consolidate UI signature field checks to use isSignatureFieldType
- Add E2E tests for both v1 and v2 APIs
Migrate from @documenso/pdf-sign and @cantoo/pdf-lib to @libpdf/core
for all PDF manipulation and signing operations. This includes:
- New signing transports for Google Cloud KMS and local certificates
- Consolidated PDF operations using libpdf API
- Added TSA (timestamp authority) helper for digital signatures
- Removed deprecated flatten and insert utilities
- Updated tests to use new PDF library
The v9 packages are deprecated. This updates to v13 which includes
breaking API changes: optionsJSON wrapper for auth functions,
renamed properties (authenticator→credential), and base64 encoding
for credential IDs via isoBase64URL helper.