diff --git a/Dockerfile b/Dockerfile index a5a8f855..1e397cf0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -50,7 +50,7 @@ ENV OPENSSL_CONF=/app/openssl_legacy.cnf WORKDIR /app -RUN echo '@edge https://dl-cdn.alpinelinux.org/alpine/edge/community' >> /etc/apk/repositories && apk add --no-cache sqlite-dev libpq-dev mariadb-dev vips-dev@edge redis libheif@edge vips-heif@edge gcompat ttf-freefont && mkdir /fonts && rm /usr/share/fonts/freefont/FreeSans.otf +RUN echo '@edge https://dl-cdn.alpinelinux.org/alpine/edge/community' >> /etc/apk/repositories && apk add --no-cache sqlite-dev libpq-dev mariadb-dev vips-dev@edge yaml-dev redis libheif@edge vips-heif@edge gcompat ttf-freefont && mkdir /fonts && rm /usr/share/fonts/freefont/FreeSans.otf RUN echo $'.include = /etc/ssl/openssl.cnf\n\ \n\ diff --git a/Gemfile.lock b/Gemfile.lock index df7255dd..493b46bb 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,29 +1,29 @@ GEM remote: https://rubygems.org/ specs: - actioncable (8.0.1) - actionpack (= 8.0.1) - activesupport (= 8.0.1) + actioncable (8.0.2.1) + actionpack (= 8.0.2.1) + activesupport (= 8.0.2.1) nio4r (~> 2.0) websocket-driver (>= 0.6.1) zeitwerk (~> 2.6) - actionmailbox (8.0.1) - actionpack (= 8.0.1) - activejob (= 8.0.1) - activerecord (= 8.0.1) - activestorage (= 8.0.1) - activesupport (= 8.0.1) + actionmailbox (8.0.2.1) + actionpack (= 8.0.2.1) + activejob (= 8.0.2.1) + activerecord (= 8.0.2.1) + activestorage (= 8.0.2.1) + activesupport (= 8.0.2.1) mail (>= 2.8.0) - actionmailer (8.0.1) - actionpack (= 8.0.1) - actionview (= 8.0.1) - activejob (= 8.0.1) - activesupport (= 8.0.1) + actionmailer (8.0.2.1) + actionpack (= 8.0.2.1) + actionview (= 8.0.2.1) + activejob (= 8.0.2.1) + activesupport (= 8.0.2.1) mail (>= 2.8.0) rails-dom-testing (~> 2.2) - actionpack (8.0.1) - actionview (= 8.0.1) - activesupport (= 8.0.1) + actionpack (8.0.2.1) + actionview (= 8.0.2.1) + activesupport (= 8.0.2.1) nokogiri (>= 1.8.5) rack (>= 2.2.4) rack-session (>= 1.0.1) @@ -31,35 +31,35 @@ GEM rails-dom-testing (~> 2.2) rails-html-sanitizer (~> 1.6) useragent (~> 0.16) - actiontext (8.0.1) - actionpack (= 8.0.1) - activerecord (= 8.0.1) - activestorage (= 8.0.1) - activesupport (= 8.0.1) + actiontext (8.0.2.1) + actionpack (= 8.0.2.1) + activerecord (= 8.0.2.1) + activestorage (= 8.0.2.1) + activesupport (= 8.0.2.1) globalid (>= 0.6.0) nokogiri (>= 1.8.5) - actionview (8.0.1) - activesupport (= 8.0.1) + actionview (8.0.2.1) + activesupport (= 8.0.2.1) builder (~> 3.1) erubi (~> 1.11) rails-dom-testing (~> 2.2) rails-html-sanitizer (~> 1.6) - activejob (8.0.1) - activesupport (= 8.0.1) + activejob (8.0.2.1) + activesupport (= 8.0.2.1) globalid (>= 0.3.6) - activemodel (8.0.1) - activesupport (= 8.0.1) - activerecord (8.0.1) - activemodel (= 8.0.1) - activesupport (= 8.0.1) + activemodel (8.0.2.1) + activesupport (= 8.0.2.1) + activerecord (8.0.2.1) + activemodel (= 8.0.2.1) + activesupport (= 8.0.2.1) timeout (>= 0.4.0) - activestorage (8.0.1) - actionpack (= 8.0.1) - activejob (= 8.0.1) - activerecord (= 8.0.1) - activesupport (= 8.0.1) + activestorage (8.0.2.1) + actionpack (= 8.0.2.1) + activejob (= 8.0.2.1) + activerecord (= 8.0.2.1) + activesupport (= 8.0.2.1) marcel (~> 1.0) - activesupport (8.0.1) + activesupport (8.0.2.1) base64 benchmark (>= 0.3) bigdecimal @@ -104,9 +104,9 @@ GEM faraday_middleware (~> 1.0, >= 1.0.0.rc1) net-http-persistent (~> 4.0) nokogiri (~> 1, >= 1.10.8) - base64 (0.2.0) + base64 (0.3.0) bcrypt (3.1.20) - benchmark (0.4.0) + benchmark (0.4.1) better_html (2.1.1) actionview (>= 6.0) activesupport (>= 6.0) @@ -114,7 +114,7 @@ GEM erubi (~> 1.4) parser (>= 2.4) smart_properties - bigdecimal (3.1.8) + bigdecimal (3.2.2) bindex (0.8.1) bootsnap (1.18.4) msgpack (~> 1.2) @@ -141,8 +141,8 @@ GEM cldr-plurals-runtime-rb (1.1.0) cmdparse (3.0.7) coderay (1.1.3) - concurrent-ruby (1.3.4) - connection_pool (2.4.1) + concurrent-ruby (1.3.5) + connection_pool (2.5.3) crack (1.0.0) bigdecimal rexml @@ -174,8 +174,9 @@ GEM rake (>= 12.0.0, < 14.0.0) docile (1.4.1) dotenv (3.1.7) - drb (2.2.1) + drb (2.2.3) email_typo (0.2.3) + erb (5.0.2) erb_lint (0.7.0) activesupport better_html (>= 2.0.1) @@ -276,13 +277,14 @@ GEM openssl (>= 2.2.1) htmlentities (4.3.4) httpclient (2.8.3) - i18n (1.14.6) + i18n (1.14.7) concurrent-ruby (~> 1.0) image_processing (1.13.0) mini_magick (>= 4.9.5, < 5) ruby-vips (>= 2.0.17, < 3) - io-console (0.8.0) - irb (1.14.3) + io-console (0.8.1) + irb (1.15.2) + pp (>= 0.6.0) rdoc (>= 4.0.0) reline (>= 0.4.2) jmespath (1.6.2) @@ -300,13 +302,13 @@ GEM letter_opener (~> 1.9) railties (>= 6.1) rexml - logger (1.6.4) + logger (1.7.0) lograge (0.14.0) actionpack (>= 4) activesupport (>= 4) railties (>= 4) request_store (~> 1.0) - loofah (2.23.1) + loofah (2.24.1) crass (~> 1.0.2) nokogiri (>= 1.12.0) mail (2.8.1) @@ -320,7 +322,7 @@ GEM mini_magick (4.13.2) mini_mime (1.1.5) mini_portile2 (2.8.9) - minitest (5.25.4) + minitest (5.25.5) msgpack (1.7.5) multi_json (1.15.0) multipart-post (2.4.1) @@ -328,14 +330,14 @@ GEM mysql2 (0.5.6) net-http-persistent (4.0.5) connection_pool (~> 2.2) - net-imap (0.5.6) + net-imap (0.5.9) date net-protocol net-pop (0.1.2) net-protocol net-protocol (0.2.2) timeout - net-smtp (0.5.0) + net-smtp (0.5.1) net-protocol nio4r (2.7.4) nokogiri (1.18.9) @@ -365,6 +367,8 @@ GEM ast (~> 2.4.1) racc pg (1.5.9) + pp (0.6.2) + prettyprint premailer (1.27.0) addressable css_parser (>= 1.19.0) @@ -375,42 +379,44 @@ GEM premailer (~> 1.7, >= 1.7.9) pretender (0.5.0) actionpack (>= 6.1) + prettyprint (0.2.0) pry (0.15.0) coderay (~> 1.1) method_source (~> 1.0) pry-rails (0.3.11) pry (>= 0.13.0) - psych (5.2.2) + psych (5.2.6) date stringio public_suffix (6.0.1) puma (6.5.0) nio4r (~> 2.0) racc (1.8.1) - rack (3.1.16) + rack (3.2.0) rack-proxy (0.7.7) rack - rack-session (2.0.0) + rack-session (2.1.1) + base64 (>= 0.1.0) rack (>= 3.0.0) - rack-test (2.1.0) + rack-test (2.2.0) rack (>= 1.3) rackup (2.2.1) rack (>= 3) - rails (8.0.1) - actioncable (= 8.0.1) - actionmailbox (= 8.0.1) - actionmailer (= 8.0.1) - actionpack (= 8.0.1) - actiontext (= 8.0.1) - actionview (= 8.0.1) - activejob (= 8.0.1) - activemodel (= 8.0.1) - activerecord (= 8.0.1) - activestorage (= 8.0.1) - activesupport (= 8.0.1) + rails (8.0.2.1) + actioncable (= 8.0.2.1) + actionmailbox (= 8.0.2.1) + actionmailer (= 8.0.2.1) + actionpack (= 8.0.2.1) + actiontext (= 8.0.2.1) + actionview (= 8.0.2.1) + activejob (= 8.0.2.1) + activemodel (= 8.0.2.1) + activerecord (= 8.0.2.1) + activestorage (= 8.0.2.1) + activesupport (= 8.0.2.1) bundler (>= 1.15.0) - railties (= 8.0.1) - rails-dom-testing (2.2.0) + railties (= 8.0.2.1) + rails-dom-testing (2.3.0) activesupport (>= 5.0.0) minitest nokogiri (>= 1.6) @@ -424,22 +430,23 @@ GEM actionview (> 3.1) activesupport (> 3.1) railties (> 3.1) - railties (8.0.1) - actionpack (= 8.0.1) - activesupport (= 8.0.1) + railties (8.0.2.1) + actionpack (= 8.0.2.1) + activesupport (= 8.0.2.1) irb (~> 1.13) rackup (>= 1.0.0) rake (>= 12.2) thor (~> 1.0, >= 1.2.2) zeitwerk (~> 2.6) rainbow (3.1.1) - rake (13.2.1) - rdoc (6.10.0) + rake (13.3.0) + rdoc (6.14.2) + erb psych (>= 4.0.0) redis-client (0.23.0) connection_pool regexp_parser (2.9.3) - reline (0.6.0) + reline (0.6.2) io-console (~> 0.5) representable (3.2.0) declarative (< 0.1.0) @@ -538,7 +545,7 @@ GEM sqlite3 (2.5.0-arm64-darwin) sqlite3 (2.5.0-x86_64-linux-gnu) sqlite3 (2.5.0-x86_64-linux-musl) - stringio (3.1.2) + stringio (3.1.7) strip_attributes (1.14.1) activemodel (>= 3.0, < 9.0) thor (1.4.0) @@ -574,12 +581,13 @@ GEM crack (>= 0.3.2) hashdiff (>= 0.4.0, < 2.0.0) webrick (1.9.1) - websocket-driver (0.7.6) + websocket-driver (0.8.0) + base64 websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) xpath (3.2.0) nokogiri (~> 1.8) - zeitwerk (2.7.1) + zeitwerk (2.7.3) PLATFORMS aarch64-linux diff --git a/app/controllers/accounts_controller.rb b/app/controllers/accounts_controller.rb index 5a2797ff..6409946e 100644 --- a/app/controllers/accounts_controller.rb +++ b/app/controllers/accounts_controller.rb @@ -27,7 +27,7 @@ class AccountsController < ApplicationController unless URI.parse(@encrypted_config.value.to_s).class.in?([URI::HTTP, URI::HTTPS]) @encrypted_config.errors.add(:value, I18n.t('should_be_a_valid_url')) - return render :show, status: :unprocessable_entity + return render :show, status: :unprocessable_content end @encrypted_config.save! @@ -39,7 +39,7 @@ class AccountsController < ApplicationController redirect_to settings_account_path, notice: I18n.t('account_information_has_been_updated') end rescue ActiveRecord::RecordInvalid - render :show, status: :unprocessable_entity + render :show, status: :unprocessable_content end def destroy diff --git a/app/controllers/api/api_base_controller.rb b/app/controllers/api/api_base_controller.rb index b681aa67..70b992ed 100644 --- a/app/controllers/api/api_base_controller.rb +++ b/app/controllers/api/api_base_controller.rb @@ -16,7 +16,7 @@ module Api check_authorization rescue_from Params::BaseValidator::InvalidParameterError do |e| - render json: { error: e.message }, status: :unprocessable_entity + render json: { error: e.message }, status: :unprocessable_content end rescue_from RateLimit::LimitApproached do |e| @@ -33,7 +33,7 @@ module Api rescue_from JSON::ParserError do |e| Rollbar.warning(e) if defined?(Rollbar) - render json: { error: "JSON parse error: #{e.message}" }, status: :unprocessable_entity + render json: { error: "JSON parse error: #{e.message}" }, status: :unprocessable_content end end diff --git a/app/controllers/api/attachments_controller.rb b/app/controllers/api/attachments_controller.rb index dca89f67..5051cfeb 100644 --- a/app/controllers/api/attachments_controller.rb +++ b/app/controllers/api/attachments_controller.rb @@ -16,14 +16,14 @@ module Api if ImageUtils.blank?(image) Rollbar.error("Empty signature: #{submitter.id}") if defined?(Rollbar) - return render json: { error: "#{params[:type]} is empty" }, status: :unprocessable_entity + return render json: { error: "#{params[:type]} is empty" }, status: :unprocessable_content end if ImageUtils.error?(image) Rollbar.error("Error signature: #{submitter.id}") if defined?(Rollbar) return render json: { error: "#{params[:type]} error, try to sign on another device" }, - status: :unprocessable_entity + status: :unprocessable_content end end diff --git a/app/controllers/api/submissions_controller.rb b/app/controllers/api/submissions_controller.rb index f75d7299..95ab2bda 100644 --- a/app/controllers/api/submissions_controller.rb +++ b/app/controllers/api/submissions_controller.rb @@ -50,12 +50,12 @@ module Api def create Params::SubmissionCreateValidator.call(params) - return render json: { error: 'Template not found' }, status: :unprocessable_entity if @template.nil? + return render json: { error: 'Template not found' }, status: :unprocessable_content if @template.nil? if @template.fields.blank? Rollbar.warning("Template does not contain fields: #{@template.id}") if defined?(Rollbar) - return render json: { error: 'Template does not contain fields' }, status: :unprocessable_entity + return render json: { error: 'Template does not contain fields' }, status: :unprocessable_content end params[:send_email] = true unless params.key?(:send_email) @@ -82,7 +82,7 @@ module Api DownloadUtils::UnableToDownload => e Rollbar.warning(e) if defined?(Rollbar) - render json: { error: e.message }, status: :unprocessable_entity + render json: { error: e.message }, status: :unprocessable_content end def destroy diff --git a/app/controllers/api/submitters_controller.rb b/app/controllers/api/submitters_controller.rb index 70fb107f..990f11ba 100644 --- a/app/controllers/api/submitters_controller.rb +++ b/app/controllers/api/submitters_controller.rb @@ -34,7 +34,7 @@ module Api def update if @submitter.completed_at? - return render json: { error: 'Submitter has already completed the submission.' }, status: :unprocessable_entity + return render json: { error: 'Submitter has already completed the submission.' }, status: :unprocessable_content end submission = @submitter.submission @@ -74,7 +74,7 @@ module Api rescue Submitters::NormalizeValues::BaseError, DownloadUtils::UnableToDownload => e Rollbar.warning(e) if defined?(Rollbar) - render json: { error: e.message }, status: :unprocessable_entity + render json: { error: e.message }, status: :unprocessable_content end def submitter_params diff --git a/app/controllers/api/tools_controller.rb b/app/controllers/api/tools_controller.rb index 63a50f89..09ea9235 100644 --- a/app/controllers/api/tools_controller.rb +++ b/app/controllers/api/tools_controller.rb @@ -7,8 +7,8 @@ module Api def merge files = params[:files] || [] - return render json: { error: 'Files are required' }, status: :unprocessable_entity if files.blank? - return render json: { error: 'At least 2 files are required' }, status: :unprocessable_entity if files.size < 2 + return render json: { error: 'Files are required' }, status: :unprocessable_content if files.blank? + return render json: { error: 'At least 2 files are required' }, status: :unprocessable_content if files.size < 2 render json: { data: Base64.encode64(PdfUtils.merge(files.map { |base64| StringIO.new(Base64.decode64(base64)) }).string) @@ -35,7 +35,7 @@ module Api end } rescue HexaPDF::MalformedPDFError - render json: { error: 'Malformed PDF' }, status: :unprocessable_entity + render json: { error: 'Malformed PDF' }, status: :unprocessable_content end end end diff --git a/app/controllers/email_smtp_settings_controller.rb b/app/controllers/email_smtp_settings_controller.rb index 766a9545..f918f172 100644 --- a/app/controllers/email_smtp_settings_controller.rb +++ b/app/controllers/email_smtp_settings_controller.rb @@ -15,12 +15,12 @@ class EmailSmtpSettingsController < ApplicationController redirect_to settings_email_index_path, notice: I18n.t('changes_have_been_saved') else - render :index, status: :unprocessable_entity + render :index, status: :unprocessable_content end rescue StandardError => e flash[:alert] = e.message - render :index, status: :unprocessable_entity + render :index, status: :unprocessable_content end private diff --git a/app/controllers/esign_settings_controller.rb b/app/controllers/esign_settings_controller.rb index 34feb84e..81c75fae 100644 --- a/app/controllers/esign_settings_controller.rb +++ b/app/controllers/esign_settings_controller.rb @@ -53,7 +53,7 @@ class EsignSettingsController < ApplicationController @cert_record.errors.add(:name, I18n.t('already_exists')) return render turbo_stream: turbo_stream.replace(:modal, template: 'esign_settings/new'), - status: :unprocessable_entity + status: :unprocessable_content end save_new_cert!(@encrypted_config, @cert_record) @@ -64,7 +64,7 @@ class EsignSettingsController < ApplicationController @cert_record.errors.add(:password, e.message) - render turbo_stream: turbo_stream.replace(:modal, template: 'esign_settings/new'), status: :unprocessable_entity + render turbo_stream: turbo_stream.replace(:modal, template: 'esign_settings/new'), status: :unprocessable_content end def update diff --git a/app/controllers/mfa_setup_controller.rb b/app/controllers/mfa_setup_controller.rb index 6ec74ccd..2ea90412 100644 --- a/app/controllers/mfa_setup_controller.rb +++ b/app/controllers/mfa_setup_controller.rb @@ -24,7 +24,7 @@ class MfaSetupController < ApplicationController @error_message = I18n.t('code_is_invalid') - render turbo_stream: turbo_stream.replace(:mfa_form, partial: 'mfa_setup/form'), status: :unprocessable_entity + render turbo_stream: turbo_stream.replace(:mfa_form, partial: 'mfa_setup/form'), status: :unprocessable_content end end @@ -36,7 +36,7 @@ class MfaSetupController < ApplicationController else @error_message = I18n.t('code_is_invalid') - render turbo_stream: turbo_stream.replace(:modal, template: 'mfa_setup/edit'), status: :unprocessable_entity + render turbo_stream: turbo_stream.replace(:modal, template: 'mfa_setup/edit'), status: :unprocessable_content end end diff --git a/app/controllers/profile_controller.rb b/app/controllers/profile_controller.rb index e0adb16e..668cd140 100644 --- a/app/controllers/profile_controller.rb +++ b/app/controllers/profile_controller.rb @@ -11,7 +11,7 @@ class ProfileController < ApplicationController if current_user.update(contact_params) redirect_to settings_profile_index_path, notice: I18n.t('contact_information_has_been_update') else - render :index, status: :unprocessable_entity + render :index, status: :unprocessable_content end end @@ -20,7 +20,7 @@ class ProfileController < ApplicationController bypass_sign_in(current_user) redirect_to settings_profile_index_path, notice: I18n.t('password_has_been_changed') else - render :index, status: :unprocessable_entity + render :index, status: :unprocessable_content end end diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index 8a7a5e5f..2281d56f 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -16,7 +16,7 @@ class SessionsController < Devise::SessionsController end if User.exists?(email:, otp_required_for_login: true) && sign_in_params[:otp_attempt].blank? - return render :otp, locals: { resource: User.new(sign_in_params) }, status: :unprocessable_entity + return render :otp, locals: { resource: User.new(sign_in_params) }, status: :unprocessable_content end super diff --git a/app/controllers/setup_controller.rb b/app/controllers/setup_controller.rb index 778255bc..734edbb5 100644 --- a/app/controllers/setup_controller.rb +++ b/app/controllers/setup_controller.rb @@ -23,10 +23,10 @@ class SetupController < ApplicationController unless URI.parse(encrypted_config_params[:value].to_s).class.in?([URI::HTTP, URI::HTTPS]) @encrypted_config.errors.add(:value, I18n.t('should_be_a_valid_url')) - return render :index, status: :unprocessable_entity + return render :index, status: :unprocessable_content end - return render :index, status: :unprocessable_entity unless @account.valid? + return render :index, status: :unprocessable_content unless @account.valid? if @user.save encrypted_configs = [ @@ -42,7 +42,7 @@ class SetupController < ApplicationController redirect_to newsletter_path else - render :index, status: :unprocessable_entity + render :index, status: :unprocessable_content end end diff --git a/app/controllers/start_form_controller.rb b/app/controllers/start_form_controller.rb index d71fba64..08778a3e 100644 --- a/app/controllers/start_form_controller.rb +++ b/app/controllers/start_form_controller.rb @@ -42,7 +42,7 @@ class StartFormController < ApplicationController if filter_undefined_submitters(@template).size > 1 && @submitter.new_record? @error_message = multiple_submitters_error_message - return render :show, status: :unprocessable_entity + return render :show, status: :unprocessable_content end if (is_new_record = @submitter.new_record?) @@ -60,7 +60,7 @@ class StartFormController < ApplicationController redirect_to submit_form_path(@submitter.slug) else - render :show, status: :unprocessable_entity + render :show, status: :unprocessable_content end end end @@ -206,7 +206,7 @@ class StartFormController < ApplicationController end def handle_require_2fa(submitter, is_new_record:) - return render :show, status: :unprocessable_entity if submitter.errors.present? + return render :show, status: :unprocessable_content if submitter.errors.present? is_otp_verified = Submitters.verify_link_otp!(params[:one_time_code], submitter) @@ -223,7 +223,7 @@ class StartFormController < ApplicationController redirect_to submit_form_path(submitter.slug) else - render :show, status: :unprocessable_entity + render :show, status: :unprocessable_content end else Submitters.send_shared_link_email_verification_code(submitter, request:) diff --git a/app/controllers/storage_settings_controller.rb b/app/controllers/storage_settings_controller.rb index 182e8ca8..4b3a8390 100644 --- a/app/controllers/storage_settings_controller.rb +++ b/app/controllers/storage_settings_controller.rb @@ -13,7 +13,7 @@ class StorageSettingsController < ApplicationController redirect_to settings_storage_index_path, notice: I18n.t('changes_have_been_saved') else - render :index, status: :unprocessable_entity + render :index, status: :unprocessable_content end end diff --git a/app/controllers/submissions_controller.rb b/app/controllers/submissions_controller.rb index 4f31322c..7dc689e0 100644 --- a/app/controllers/submissions_controller.rb +++ b/app/controllers/submissions_controller.rb @@ -66,7 +66,7 @@ class SubmissionsController < ApplicationController rescue Submissions::CreateFromSubmitters::BaseError => e render turbo_stream: turbo_stream.replace(:submitters_error, partial: 'submissions/error', locals: { error: e.message }), - status: :unprocessable_entity + status: :unprocessable_content end def destroy diff --git a/app/controllers/submit_form_controller.rb b/app/controllers/submit_form_controller.rb index 44d10445..f7bf565e 100644 --- a/app/controllers/submit_form_controller.rb +++ b/app/controllers/submit_form_controller.rb @@ -48,20 +48,20 @@ class SubmitFormController < ApplicationController def update if @submitter.completed_at? - return render json: { error: I18n.t('form_has_been_completed_already') }, status: :unprocessable_entity + return render json: { error: I18n.t('form_has_been_completed_already') }, status: :unprocessable_content end if @submitter.submission.template&.archived_at? || @submitter.submission.archived_at? - return render json: { error: I18n.t('form_has_been_archived') }, status: :unprocessable_entity + return render json: { error: I18n.t('form_has_been_archived') }, status: :unprocessable_content end if @submitter.submission.expired? - return render json: { error: I18n.t('form_has_been_expired') }, status: :unprocessable_entity + return render json: { error: I18n.t('form_has_been_expired') }, status: :unprocessable_content end if @submitter.declined_at? return render json: { error: I18n.t('form_has_been_declined') }, - status: :unprocessable_entity + status: :unprocessable_content end Submitters::SubmitValues.call(@submitter, params, request) @@ -70,9 +70,9 @@ class SubmitFormController < ApplicationController rescue Submitters::SubmitValues::RequiredFieldError => e Rollbar.warning("Required field #{@submitter.id}: #{e.message}") if defined?(Rollbar) - render json: { field_uuid: e.message }, status: :unprocessable_entity + render json: { field_uuid: e.message }, status: :unprocessable_content rescue Submitters::SubmitValues::ValidationError => e - render json: { error: e.message }, status: :unprocessable_entity + render json: { error: e.message }, status: :unprocessable_content end def completed; end diff --git a/app/controllers/submit_form_download_controller.rb b/app/controllers/submit_form_download_controller.rb index d357019c..d6e0b692 100644 --- a/app/controllers/submit_form_download_controller.rb +++ b/app/controllers/submit_form_download_controller.rb @@ -11,13 +11,13 @@ class SubmitFormDownloadController < ApplicationController return redirect_to submitter_download_index_path(@submitter.slug) if @submitter.completed_at? - return head :unprocessable_entity if @submitter.declined_at? || - @submitter.submission.archived_at? || - @submitter.submission.expired? || - @submitter.submission.template&.archived_at? || - AccountConfig.exists?(account_id: @submitter.account_id, - key: AccountConfig::ALLOW_TO_PARTIAL_DOWNLOAD_KEY, - value: false) + return head :unprocessable_content if @submitter.declined_at? || + @submitter.submission.archived_at? || + @submitter.submission.expired? || + @submitter.submission.template&.archived_at? || + AccountConfig.exists?(account_id: @submitter.account_id, + key: AccountConfig::ALLOW_TO_PARTIAL_DOWNLOAD_KEY, + value: false) last_completed_submitter = @submitter.submission.submitters .where.not(id: @submitter.id) diff --git a/app/controllers/submit_form_invite_controller.rb b/app/controllers/submit_form_invite_controller.rb index 0f400ad9..ab1f26c3 100644 --- a/app/controllers/submit_form_invite_controller.rb +++ b/app/controllers/submit_form_invite_controller.rb @@ -7,7 +7,7 @@ class SubmitFormInviteController < ApplicationController def create submitter = Submitter.find_by!(slug: params[:submit_form_slug]) - return head :unprocessable_entity unless can_invite?(submitter) + return head :unprocessable_content unless can_invite?(submitter) invite_submitters = filter_invite_submitters(submitter, 'invite_by_uuid') optional_invite_submitters = filter_invite_submitters(submitter, 'optional_invite_by_uuid') @@ -34,7 +34,7 @@ class SubmitFormInviteController < ApplicationController head :ok else - head :unprocessable_entity + head :unprocessable_content end end diff --git a/app/controllers/template_documents_controller.rb b/app/controllers/template_documents_controller.rb index abd72010..cfca1297 100644 --- a/app/controllers/template_documents_controller.rb +++ b/app/controllers/template_documents_controller.rb @@ -5,7 +5,7 @@ class TemplateDocumentsController < ApplicationController def create if params[:blobs].blank? && params[:files].blank? - return render json: { error: I18n.t('file_is_missing') }, status: :unprocessable_entity + return render json: { error: I18n.t('file_is_missing') }, status: :unprocessable_content end old_fields_hash = @template.fields.hash @@ -28,6 +28,6 @@ class TemplateDocumentsController < ApplicationController ) } rescue Templates::CreateAttachments::PdfEncrypted - render json: { error: 'PDF encrypted', status: 'pdf_encrypted' }, status: :unprocessable_entity + render json: { error: 'PDF encrypted', status: 'pdf_encrypted' }, status: :unprocessable_content end end diff --git a/app/controllers/templates_clone_and_replace_controller.rb b/app/controllers/templates_clone_and_replace_controller.rb index 21989067..f4acfd3f 100644 --- a/app/controllers/templates_clone_and_replace_controller.rb +++ b/app/controllers/templates_clone_and_replace_controller.rb @@ -4,7 +4,7 @@ class TemplatesCloneAndReplaceController < ApplicationController load_and_authorize_resource :template def create - return head :unprocessable_entity if params[:files].blank? + return head :unprocessable_content if params[:files].blank? ActiveRecord::Associations::Preloader.new( records: [@template], @@ -31,7 +31,7 @@ class TemplatesCloneAndReplaceController < ApplicationController rescue Templates::CreateAttachments::PdfEncrypted respond_to do |f| f.html { render turbo_stream: turbo_stream.append(params[:form_id], html: helpers.tag.prompt_password) } - f.json { render json: { error: 'PDF encrypted', status: 'pdf_encrypted' }, status: :unprocessable_entity } + f.json { render json: { error: 'PDF encrypted', status: 'pdf_encrypted' }, status: :unprocessable_content } end end end diff --git a/app/controllers/templates_controller.rb b/app/controllers/templates_controller.rb index a3d78606..3af0a0f2 100644 --- a/app/controllers/templates_controller.rb +++ b/app/controllers/templates_controller.rb @@ -78,7 +78,7 @@ class TemplatesController < ApplicationController maybe_redirect_to_template(@template) else - render turbo_stream: turbo_stream.replace(:modal, template: 'templates/new'), status: :unprocessable_entity + render turbo_stream: turbo_stream.replace(:modal, template: 'templates/new'), status: :unprocessable_content end end diff --git a/app/controllers/templates_debug_controller.rb b/app/controllers/templates_debug_controller.rb index 810c042a..676c2f64 100644 --- a/app/controllers/templates_debug_controller.rb +++ b/app/controllers/templates_debug_controller.rb @@ -3,6 +3,8 @@ class TemplatesDebugController < ApplicationController load_and_authorize_resource :template + DEBUG_FILE = '' + def show attachment = @template.documents.first @@ -16,6 +18,8 @@ class TemplatesDebugController < ApplicationController @template.update!(fields: Templates::ProcessDocument.normalize_attachment_fields(@template, [attachment])) + debug_file if DEBUG_FILE.present? + ActiveRecord::Associations::Preloader.new( records: [@template], associations: [schema_documents: { preview_images_attachments: :blob }] @@ -31,4 +35,27 @@ class TemplatesDebugController < ApplicationController render 'templates/edit', layout: 'plain' end + + def debug_file + tempfile = Tempfile.new + tempfile.binmode + tempfile.write(File.read(DEBUG_FILE)) + tempfile.rewind + + filename = File.basename(DEBUG_FILE) + + file = ActionDispatch::Http::UploadedFile.new( + tempfile:, + filename:, + type: Marcel::MimeType.for(tempfile) + ) + + params = { files: [file] } + + documents = Templates::CreateAttachments.call(@template, params) + + schema = documents.map { |doc| { attachment_uuid: doc.uuid, name: doc.filename.base } } + + @template.update!(schema:) + end end diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 9771fc4e..8f433577 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -27,7 +27,7 @@ class UsersController < ApplicationController if User.accessible_by(current_ability).exists?(email: @user.email) @user.errors.add(:email, I18n.t('already_exists')) - return render turbo_stream: turbo_stream.replace(:modal, template: 'users/new'), status: :unprocessable_entity + return render turbo_stream: turbo_stream.replace(:modal, template: 'users/new'), status: :unprocessable_content end @user.role = User::ADMIN_ROLE unless role_valid?(@user.role) @@ -37,7 +37,7 @@ class UsersController < ApplicationController redirect_back fallback_location: settings_users_path, notice: I18n.t('user_has_been_invited') else - render turbo_stream: turbo_stream.replace(:modal, template: 'users/new'), status: :unprocessable_entity + render turbo_stream: turbo_stream.replace(:modal, template: 'users/new'), status: :unprocessable_content end end @@ -57,7 +57,7 @@ class UsersController < ApplicationController if @user.update(attrs.except(current_user == @user ? :role : nil)) redirect_back fallback_location: settings_users_path, notice: I18n.t('user_has_been_updated') else - render turbo_stream: turbo_stream.replace(:modal, template: 'users/edit'), status: :unprocessable_entity + render turbo_stream: turbo_stream.replace(:modal, template: 'users/edit'), status: :unprocessable_content end end diff --git a/app/javascript/template_builder/builder.vue b/app/javascript/template_builder/builder.vue index cd2339f4..ad295068 100644 --- a/app/javascript/template_builder/builder.vue +++ b/app/javascript/template_builder/builder.vue @@ -660,7 +660,7 @@ export default { acceptFileTypes: { type: String, required: false, - default: 'image/*, application/pdf' + default: 'image/*, application/pdf, application/zip' }, baseUrl: { type: String, diff --git a/app/javascript/template_builder/controls.vue b/app/javascript/template_builder/controls.vue index 270aa623..2196fe56 100644 --- a/app/javascript/template_builder/controls.vue +++ b/app/javascript/template_builder/controls.vue @@ -66,7 +66,7 @@ export default { acceptFileTypes: { type: String, required: false, - default: 'image/*, application/pdf' + default: 'image/*, application/pdf, application/zip' }, withReplaceButton: { type: Boolean, diff --git a/app/javascript/template_builder/dropzone.vue b/app/javascript/template_builder/dropzone.vue index 9031f3d1..ff30e756 100644 --- a/app/javascript/template_builder/dropzone.vue +++ b/app/javascript/template_builder/dropzone.vue @@ -107,7 +107,7 @@ export default { acceptFileTypes: { type: String, required: false, - default: 'image/*, application/pdf' + default: 'image/*, application/pdf, application/zip' } }, emits: ['success', 'error', 'loading'], @@ -131,7 +131,7 @@ export default { message () { if (this.isLoading) { return this.t('uploading') - } else if (this.acceptFileTypes === 'image/*, application/pdf') { + } else if (this.acceptFileTypes === 'image/*, application/pdf, application/zip') { return this.title || this.t('add_pdf_documents_or_images') } else { return this.title || this.t('add_documents_or_images') @@ -146,7 +146,7 @@ export default { methods: { upload: Upload.methods.upload, onDropFiles (e) { - if (this.acceptFileTypes !== 'image/*, application/pdf' || [...e.dataTransfer.files].every((f) => f.type.match(/(?:image\/)|(?:application\/pdf)/))) { + if (this.acceptFileTypes !== 'image/*, application/pdf, application/zip' || [...e.dataTransfer.files].every((f) => f.type.match(/(?:image\/)|(?:application\/pdf)|(?:application\/zip)/))) { this.$refs.input.files = e.dataTransfer.files this.upload() diff --git a/app/javascript/template_builder/hover_dropzone.vue b/app/javascript/template_builder/hover_dropzone.vue index 575c832c..28a07281 100644 --- a/app/javascript/template_builder/hover_dropzone.vue +++ b/app/javascript/template_builder/hover_dropzone.vue @@ -78,7 +78,7 @@ export default { acceptFileTypes: { type: String, required: false, - default: 'image/*, application/pdf' + default: 'image/*, application/pdf, application/zip' } }, emits: ['add', 'replace', 'replace-and-clone', 'error'], diff --git a/app/javascript/template_builder/preview.vue b/app/javascript/template_builder/preview.vue index 7a60d71e..c83f58f7 100644 --- a/app/javascript/template_builder/preview.vue +++ b/app/javascript/template_builder/preview.vue @@ -157,7 +157,7 @@ export default { acceptFileTypes: { type: String, required: false, - default: 'image/*, application/pdf' + default: 'image/*, application/pdf, application/zip' }, withReplaceButton: { type: Boolean, diff --git a/app/javascript/template_builder/replace.vue b/app/javascript/template_builder/replace.vue index 6a467206..bc72b4f0 100644 --- a/app/javascript/template_builder/replace.vue +++ b/app/javascript/template_builder/replace.vue @@ -35,7 +35,7 @@ export default { acceptFileTypes: { type: String, required: false, - default: 'image/*, application/pdf' + default: 'image/*, application/pdf, application/zip' } }, emits: ['success'], diff --git a/app/javascript/template_builder/upload.vue b/app/javascript/template_builder/upload.vue index a502ff3e..bdb633ce 100644 --- a/app/javascript/template_builder/upload.vue +++ b/app/javascript/template_builder/upload.vue @@ -57,7 +57,7 @@ export default { acceptFileTypes: { type: String, required: false, - default: 'image/*, application/pdf' + default: 'image/*, application/pdf, application/zip' } }, emits: ['success', 'error'], diff --git a/app/jobs/process_submitter_completion_job.rb b/app/jobs/process_submitter_completion_job.rb index 647aab5f..49f79fcf 100644 --- a/app/jobs/process_submitter_completion_job.rb +++ b/app/jobs/process_submitter_completion_job.rb @@ -146,7 +146,8 @@ class ProcessSubmitterCompletionJob current_group_index = submitter_groups.find { |_, group| group.any? { |s| s['uuid'] == submitter.uuid } }&.first if submitter_groups[current_group_index + 1] && - submitters_index.values_at(*submitter_groups[current_group_index].pluck('uuid')).all?(&:completed_at?) + submitters_index.values_at(*submitter_groups[current_group_index].pluck('uuid')) + .compact.all?(&:completed_at?) submitter_groups[current_group_index + 1] end else @@ -159,7 +160,7 @@ class ProcessSubmitterCompletionJob end end - next_submitters = submitters_index.values_at(*Array.wrap(next_submitter_items).pluck('uuid')) + next_submitters = submitters_index.values_at(*Array.wrap(next_submitter_items).pluck('uuid')).compact Submitters.send_signature_requests(next_submitters) end diff --git a/app/views/submissions/show.html.erb b/app/views/submissions/show.html.erb index 0ab61c68..eb1999e1 100644 --- a/app/views/submissions/show.html.erb +++ b/app/views/submissions/show.html.erb @@ -109,7 +109,7 @@ <%= render 'submissions/annotation', annot: %> <% end %> <% fields_index.dig(document.uuid, index)&.each do |(area, field)| %> - <% value = values[field['uuid']] %> + <% value = values[field['uuid']].presence || (field['default_value'] != '{{date}}' && field['readonly'] == true && field['default_value'].present? ? Submitters::SubmitValues.template_default_value_for_submitter(field['default_value'], @submission.submitters.find { |e| e.uuid == field['submitter_uuid'] }, with_time: false) : nil) %> <% value ||= field['default_value'] if field['type'] == 'heading' %> <% next if value.blank? %> <% submitter = submitters_index[field['submitter_uuid']] %> @@ -238,7 +238,7 @@