feat: allow recipients to view completed PDF via QR share link

Add allowPublicCompletedDocumentAccess toggle at org/team level
(team inherits from org via null). Recipients see a "View completed
PDF" button on the signing completion page that links to /share/qr_*.

- DB migration adding toggle to OrganisationGlobalSettings and TeamGlobalSettings
- Settings UI for org and team document preferences
- Rate limiting on QR share view and file download endpoints
- Structured error responses with support codes in share route ErrorBoundary
- Exponential backoff retry when qrToken not yet available post-completion
- QR-authenticated viewers restricted to signed PDF only (no original)
- E2E tests covering happy path, not-yet-completed, invalid token, and toggle revocation
This commit is contained in:
ephraimduncan
2026-03-04 14:45:16 +00:00
parent 454f73f2a9
commit acb5a885c2
20 changed files with 1011 additions and 67 deletions
@@ -32,6 +32,7 @@ export const updateOrganisationSettingsRoute = authenticatedProcedure
documentDateFormat,
includeSenderDetails,
includeSigningCertificate,
allowPublicCompletedDocumentAccess,
includeAuditLog,
typedSignatureEnabled,
uploadSignatureEnabled,
@@ -143,6 +144,7 @@ export const updateOrganisationSettingsRoute = authenticatedProcedure
documentDateFormat,
includeSenderDetails,
includeSigningCertificate,
allowPublicCompletedDocumentAccess,
includeAuditLog,
typedSignatureEnabled,
uploadSignatureEnabled,
@@ -20,6 +20,7 @@ export const ZUpdateOrganisationSettingsRequestSchema = z.object({
documentDateFormat: ZDocumentMetaDateFormatSchema.optional(),
includeSenderDetails: z.boolean().optional(),
includeSigningCertificate: z.boolean().optional(),
allowPublicCompletedDocumentAccess: z.boolean().optional(),
includeAuditLog: z.boolean().optional(),
typedSignatureEnabled: z.boolean().optional(),
uploadSignatureEnabled: z.boolean().optional(),
@@ -35,6 +35,7 @@ export const updateTeamSettingsRoute = authenticatedProcedure
documentDateFormat,
includeSenderDetails,
includeSigningCertificate,
allowPublicCompletedDocumentAccess,
includeAuditLog,
typedSignatureEnabled,
uploadSignatureEnabled,
@@ -150,6 +151,7 @@ export const updateTeamSettingsRoute = authenticatedProcedure
documentDateFormat,
includeSenderDetails,
includeSigningCertificate,
allowPublicCompletedDocumentAccess,
includeAuditLog,
typedSignatureEnabled,
uploadSignatureEnabled,
@@ -24,6 +24,7 @@ export const ZUpdateTeamSettingsRequestSchema = z.object({
documentDateFormat: ZDocumentMetaDateFormatSchema.nullish(),
includeSenderDetails: z.boolean().nullish(),
includeSigningCertificate: z.boolean().nullish(),
allowPublicCompletedDocumentAccess: z.boolean().nullish(),
includeAuditLog: z.boolean().nullish(),
typedSignatureEnabled: z.boolean().nullish(),
uploadSignatureEnabled: z.boolean().nullish(),