* Fix PDF regeneration after change requests
Allow PDFs to be regenerated when a submitter re-completes after a change
request by using timestamp-based detection. This ensures new PDFs are
generated while preserving old ones for audit trail.
Changes:
- Allow multiple 'complete' events per submitter (remove unique constraint)
- Compare event timestamps with completion time to detect stale events
- Add current_documents method to get latest PDF generation
- Prevent waiting forever on stale retry/start events from previous attempts
* Update audit trail generation for change requests
Regenerate audit trail PDF when submitter re-completes after a change request.
Remove DocuSeal branding from audit trail header and add missing translations
for request_changes events.
Changes:
- Regenerate audit trail when created before latest completion timestamp
- Remove DocuSeal logo and branding from audit trail header
- Add request_changes_by_html translations (English and Spanish)
- Generate new audit trail before cleaning up old ones (safer approach)
- Clean up old audit trail PDFs, keeping only the newest
* Change 'Request Changes' button text to 'Submit'
* Remove Download button from submissions view
* Fix download endpoint to return current documents after re-completion
* Add comprehensive tests and apply rubocop fixes
- Add tests for Submitter#current_documents method
- Add tests for PDF regeneration on re-completion
- Add tests for audit trail regeneration logic
- Apply rubocop fixes: use Rails range syntax, fix indentation
- Extract generate_and_record_documents to reduce method length
* fix potential NoMethodError and rubocop fixes
* Use ActiveStorage::Attachment directly instead of `#audit_trail`
* Fix line length in `process`
* Scope email and external_user_id uniqueness to account
Allow the same email and external_user_id to exist across different accounts
while maintaining uniqueness within each account.
Changes:
- Scope external_user_id uniqueness to account_id
- Scope email uniqueness to account_id
- Remove Devise :validatable to avoid global email uniqueness
- Update ExternalAuthService to use account-scoped queries
- Update TokenRefreshService to use account-scoped queries
- Add custom email validation with account scope
* Add and update tests for account-scoped user uniqueness
* Run migrations and update schema
* Document account-scoped user lookup behavior
* skip password test
* we use access token validation via iframe, not passwords so this test is not necessary.
* update test for rubocop
* Add download URL generator endpoint for API
* rubocop/spec fixes
* move logic out of view into controller
* move build_signed_urls method logic into new SignedDocumentUrlBuilder service
* slim down controller and its request specs
* Fix download filenames to exclude CloudFront query parameters
- Strip query parameters from URLs before extracting filenames in download buttons
- Add Content-Disposition headers to CloudFront signed URLs for proper browser filename handling
* remove Download combined PDF
* we don't do multiple submissions in the iframe, so this button is not needed
* line length fix
* add fallback filename and tests
* rubocop changes
* refactor build_cloudfront_url
reduce complexity of method by extracting into other methods, also reduces need for more in line comments.
* remove unused buttons
* remove "Resubmit" button and Docuseal logo/header in iframe
* remove template name in preview
* fix line length
* allow there to be no header
* fixed failing tests expecting header
* we don't typically want the header rendered in the iframe
* fix erb_lint violation
* Add partnership template authorization and ability system
* Update template authorization to support partnership context
* Add request context-based authorization for API access
* Implement hybrid partnership/account authorization logic
* Add submission authorization conditions for partnerships
* Support global partnership template access
* Add template cloning services for partnership workflows
* Update template cloning to require explicit target parameters, to allow for cloning for either account or from partnership
* Add Templates::CloneToAccount service for partnership to account cloning
* Add Templates::CloneToPartnership service for global to partnership cloning
* Add logic to detect account vs partnership template cloning with validation
* Add folder assignment logic for cloned templates
* Add external authentication and partnership support
* Update ExternalAuthService to support partnership OR account authentication
* Implement user assignment to accounts when partnership context is provided
* Support pure partnership authentication without account assignment
* Update API controllers for partnership template support
* Add partnership request context to API base controller
* Update submissions controller to support partnership templates
* Add partnership template cloning to templates clone controller
* Refactor template controller webhook logic to reduce complexity
* Support external_account_id parameter for partnership workflows
* Update web controllers and views for partnership template support
* Add tests
* erb_lint fixes
* add local claude file
* shared concern for handling partnership context
* remove overly permissive case
* global templates should be available for partnerships and accounts
* pass through access context in vue
* add tests
* add partnership context and tests to submissions
* add token refresh as last resort for a corrupted token
Remove hardcoded CloudFront domains and key pair IDs from repository.
All CloudFront configuration now loaded from ENV variables for security:
- CF_URL: CloudFront distribution URL
- CF_KEY_PAIR_ID: CloudFront key pair identifier
- CF_KEY_SECRET: AWS Secrets Manager path for private key
- SECURED_STORAGE_BUCKET: S3 bucket name
- SECURED_STORAGE_REGION: AWS region
This prevents exposure of infrastructure identifiers in public repository.
Configuration should be set via cpdocuseal deployment module.
- Migration updates to change data type from integer to string for external_account_group_id
- Updated database schema and annotation comments
- Fixed service parameter type handling
- Updated test expectations to match new string type
- Added storage location field and index for completed documents
- Removed obsolete search_entries table from schema
Implement compliance storage configuration using AWS CloudFront signed URLs for completed documents. This reuses the existing ATS infrastructure to provide secure, time-limited access to document storage while maintaining backward compatibility with legacy storage.
- Add aws-sdk-cloudfront dependency for URL signing
- Create DocumentSecurityService for CloudFront signed URL generation
- Add secured storage service configuration in storage.yml
- Update completed_documents model with storage_location tracking
- Modify download controllers to use signed URLs for secured storage
- Add compliance_storage.yml configuration for different environments
- Update submitter completion job to track storage location
BREAKING CHANGE: Requires SECURED_STORAGE_BUCKET and SECURED_STORAGE_REGION environment variables for staging/production environments
* account group to partnership rename
* this is mostly converting the name account_group => partnership
* partnership user relationships are API request based
* so we don't need to maintain relational information in two databases, this many to many relationship is now handled via API context
* rubocop and test fixes
- Add account_groups table and model
- Add account_group references to accounts, users, templates, template_folders
- Make account_id nullable on users, templates, template_folders
- Add controllers and specs
* Consolidate account groups migrations
- Replace 8 separate migrations with 2 consolidated ones
- Create account groups and relationships in one migration
- Make account_id columns nullable in second migration
* this logic is being handled in external_auth_controller
* remove unnecessary controllers
* remove unnecessary routes
* refactor account_group.default_template_folder
* align method with Account version of this method
* refactor controllers to move complex logic to service
* move account/account group validation to concern
* this method is not yet needed
* we may implement this differently in next ticket to handle account and account group syncing for templates.
* rubocop violation fixes
* a few more refactors and add tests
* Change external_account_group_id to integer type
* Refactored external_account_group_id from string to integer in models, migrations, factories, and specs for consistency.
* Merged account_id nullability changes into a single migration and removed the obsolete migrations.
* Updated authentication logic to require either account or account_group presence for user activation.
- Extract complex ATS prefill logic from PrefillFieldsHelper into dedicated AtsPrefill service
- Create modular service objects: FieldExtractor, FieldMapper, ValueMerger, and CacheManager
- Implement proper caching strategy with Rails.cache for performance optimization
- Add comprehensive test coverage for all new service components
- Maintain backward compatibility through facade methods in PrefillFieldsHelper
- Improve security by validating field name patterns and sanitizing inputs
- Enhance performance with optimized field lookup caching
BREAKING CHANGE: PrefillFieldsHelper now delegates to AtsPrefill service layer. Direct usage of helper methods remains unchanged, but internal implementation has been refactored.
* Add external_id fields to accounts and users tables
Adds external_account_id and external_user_id fields to support
integration with external ATS systems. These fields will map
DocuSeal accounts/users to their corresponding ATS entities.
* Add external ID support to Account and User models
Implements find_or_create_by_external_id methods for both Account
and User models to support automatic provisioning from external
ATS systems. Users now have access tokens for authentication.
* Add external authentication API endpoint
Creates /api/external_auth/get_user_token endpoint for external API systems
to authenticate users and receive access tokens.
* Refactor authentication to support token-based login
Replaces demo user authentication and setup redirect logic with token-based authentication via params, session, or X-Auth-Token header.
Users do not login, they are just authenticated via token.
* Replace authenticate_user! with authenticate_via_token!
Refactored controllers to use authenticate_via_token! instead of authenticate_user! for authentication. Added authenticate_via_token! method to ApiBaseController.
* Update controller authentication and authorization logic
Removed and replaced several before_action and authorization checks in ExportController, SetupController, and TemplateDocumentsController.
* Add external authentication API endpoint
* Add IframeAuthentication concern for AJAX requests in iframe context
* Create shared concern to handle authentication from HTTP referer
* Extracts auth token from referer URL when AJAX requests don't include token
* Supports Vue component requests within iframes
* Remove old user authentication from dashboard controller
* Quick fix for request changes
Now that we have scoped users, we're changing this to compare to the template authot
* rubocop fixes
* Add and update authentication and model specs
Introduces new specs for iframe authentication, account, user, application controller, and external auth API.
* add safe navigation and remove dead method
- Replace present? check with blank? for better nil handling
- Add input size validation to prevent DoS attacks (64KB limit)
- Fix string formatting and indentation in audit logging
- Optimize caching with proper error handling for Redis failures
- Simplify conditional logic in field value merging
- Add frozen string literal comments for Ruby 3.4 compatibility
- Improve test coverage with better mocking and assertions
Security improvements include input validation and audit logging for ATS prefill usage tracking.
- Add input size limits (64KB for encoded, 32KB for decoded JSON) to prevent DoS attacks
- Implement audit logging for ATS prefill usage tracking
- Add caching layer for field UUID lookups with 30-minute TTL
- Optimize field resolution with O(1) lookup cache instead of O(n) search
- Add comprehensive error handling and logging throughout prefill pipeline
- Validate ATS field names against allowed patterns with security checks
- Add Base64-encoded JSON parameter support for ATS prefill values
- Implement field mapping between ATS field names and template field UUIDs
- Enhance merge logic to preserve existing submitter values while adding ATS prefill data
- Add comprehensive error handling for invalid Base64 and JSON parsing
- Update form rendering to use merged ATS values for prefill functionality
- Add integration tests for complete ATS prefill workflow
Add support for fetching prefill values from ATS system when task_assignment_id parameter is provided. This includes:
- New ATS API integration in PrefillFieldsHelper to fetch prefill values
- Cache layer for ATS prefill values with 30-minute TTL
- Merge logic to respect existing submitter values over ATS prefill values
- Error handling and logging for ATS API failures
- Integration with SubmitFormController to fetch values before form rendering
The feature allows forms to be pre-populated with candidate data from the ATS system while preserving any values already entered by submitters.