diff --git a/Gemfile.lock b/Gemfile.lock
index 8a83f4cb3..6b12f2ead 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -3,29 +3,29 @@ GEM
specs:
action_text-trix (2.1.19)
railties
- actioncable (8.1.3.1)
- actionpack (= 8.1.3.1)
- activesupport (= 8.1.3.1)
+ actioncable (8.1.4)
+ actionpack (= 8.1.4)
+ activesupport (= 8.1.4)
nio4r (~> 2.0)
websocket-driver (>= 0.6.1)
zeitwerk (~> 2.6)
- actionmailbox (8.1.3.1)
- actionpack (= 8.1.3.1)
- activejob (= 8.1.3.1)
- activerecord (= 8.1.3.1)
- activestorage (= 8.1.3.1)
- activesupport (= 8.1.3.1)
+ actionmailbox (8.1.4)
+ actionpack (= 8.1.4)
+ activejob (= 8.1.4)
+ activerecord (= 8.1.4)
+ activestorage (= 8.1.4)
+ activesupport (= 8.1.4)
mail (>= 2.8.0)
- actionmailer (8.1.3.1)
- actionpack (= 8.1.3.1)
- actionview (= 8.1.3.1)
- activejob (= 8.1.3.1)
- activesupport (= 8.1.3.1)
+ actionmailer (8.1.4)
+ actionpack (= 8.1.4)
+ actionview (= 8.1.4)
+ activejob (= 8.1.4)
+ activesupport (= 8.1.4)
mail (>= 2.8.0)
rails-dom-testing (~> 2.2)
- actionpack (8.1.3.1)
- actionview (= 8.1.3.1)
- activesupport (= 8.1.3.1)
+ actionpack (8.1.4)
+ actionview (= 8.1.4)
+ activesupport (= 8.1.4)
nokogiri (>= 1.8.5)
rack (>= 2.2.4)
rack-session (>= 1.0.1)
@@ -33,36 +33,36 @@ GEM
rails-dom-testing (~> 2.2)
rails-html-sanitizer (~> 1.6)
useragent (~> 0.16)
- actiontext (8.1.3.1)
+ actiontext (8.1.4)
action_text-trix (~> 2.1.15)
- actionpack (= 8.1.3.1)
- activerecord (= 8.1.3.1)
- activestorage (= 8.1.3.1)
- activesupport (= 8.1.3.1)
+ actionpack (= 8.1.4)
+ activerecord (= 8.1.4)
+ activestorage (= 8.1.4)
+ activesupport (= 8.1.4)
globalid (>= 0.6.0)
nokogiri (>= 1.8.5)
- actionview (8.1.3.1)
- activesupport (= 8.1.3.1)
+ actionview (8.1.4)
+ activesupport (= 8.1.4)
builder (~> 3.1)
erubi (~> 1.11)
rails-dom-testing (~> 2.2)
rails-html-sanitizer (~> 1.6)
- activejob (8.1.3.1)
- activesupport (= 8.1.3.1)
+ activejob (8.1.4)
+ activesupport (= 8.1.4)
globalid (>= 0.3.6)
- activemodel (8.1.3.1)
- activesupport (= 8.1.3.1)
- activerecord (8.1.3.1)
- activemodel (= 8.1.3.1)
- activesupport (= 8.1.3.1)
+ activemodel (8.1.4)
+ activesupport (= 8.1.4)
+ activerecord (8.1.4)
+ activemodel (= 8.1.4)
+ activesupport (= 8.1.4)
timeout (>= 0.4.0)
- activestorage (8.1.3.1)
- actionpack (= 8.1.3.1)
- activejob (= 8.1.3.1)
- activerecord (= 8.1.3.1)
- activesupport (= 8.1.3.1)
+ activestorage (8.1.4)
+ actionpack (= 8.1.4)
+ activejob (= 8.1.4)
+ activerecord (= 8.1.4)
+ activesupport (= 8.1.4)
marcel (~> 1.0)
- activesupport (8.1.3.1)
+ activesupport (8.1.4)
base64
bigdecimal
concurrent-ruby (~> 1.0, >= 1.3.1)
@@ -116,7 +116,7 @@ GEM
erubi (~> 1.4)
parser (>= 2.4)
smart_properties
- bigdecimal (4.1.2)
+ bigdecimal (4.1.3)
bindex (0.8.1)
bootsnap (1.23.0)
msgpack (~> 1.2)
@@ -149,14 +149,14 @@ GEM
crack (1.0.1)
bigdecimal
rexml
- crass (1.0.7)
+ crass (1.0.8)
csv (3.3.5)
csv-safe (3.3.1)
csv (~> 3.0)
cuprite (0.17)
capybara (~> 3.0)
ferrum (~> 0.17.0)
- date (3.5.1)
+ date (3.6.0)
debug (1.11.1)
irb (~> 1.10)
reline (>= 0.3.8)
@@ -179,7 +179,7 @@ GEM
dotenv (3.2.0)
drb (2.2.3)
email_typo (0.2.3)
- erb (6.0.6)
+ erb (6.0.7)
erb_lint (0.9.0)
activesupport
better_html (>= 2.0.1)
@@ -195,8 +195,8 @@ GEM
railties (>= 6.1.0)
faker (3.6.1)
i18n (>= 1.8.11, < 2)
- faraday (2.14.3)
- faraday-net_http (>= 2.0, < 3.5)
+ faraday (2.15.1)
+ faraday-net_http (>= 2.0, < 3.6)
json
logger
faraday-follow_redirects (0.5.0)
@@ -264,14 +264,14 @@ GEM
strscan (>= 3.1.2)
i18n (1.15.2)
concurrent-ruby (~> 1.0)
- io-console (0.8.2)
+ io-console (0.9.5)
irb (1.18.0)
pp (>= 0.6.0)
prism (>= 1.3.0)
rdoc (>= 4.0.0)
reline (>= 0.4.2)
jmespath (1.6.2)
- json (2.21.2)
+ json (3.1.0)
jwt (3.2.0)
base64
language_server-protocol (3.17.0.5)
@@ -310,17 +310,17 @@ GEM
drb (~> 2.0)
prism (~> 1.5)
msgpack (1.8.4)
- multi_json (1.19.1)
+ multi_json (1.21.2)
net-http (0.9.1)
uri (>= 0.11.1)
- net-imap (0.6.6)
+ net-imap (0.6.8)
date
net-protocol
net-pop (0.1.2)
net-protocol
- net-protocol (0.2.2)
+ net-protocol (0.4.0)
timeout
- net-smtp (0.5.1)
+ net-smtp (0.5.2)
net-protocol
nio4r (2.7.5)
nokogiri (1.19.4-aarch64-linux-gnu)
@@ -361,7 +361,7 @@ GEM
prettyprint
pretender (1.0.0)
actionpack (>= 7.2)
- prettyprint (0.2.0)
+ prettyprint (0.2.1)
prism (1.9.0)
pry (0.16.0)
coderay (~> 1.1)
@@ -373,30 +373,30 @@ GEM
puma (8.0.2)
nio4r (~> 2.0)
racc (1.8.1)
- rack (3.2.6)
+ rack (3.2.7)
rack-proxy (0.7.7)
rack
rack-session (2.1.2)
base64 (>= 0.1.0)
rack (>= 3.0.0)
- rack-test (2.2.0)
+ rack-test (2.3.0)
rack (>= 1.3)
rackup (2.3.1)
rack (>= 3)
- rails (8.1.3.1)
- actioncable (= 8.1.3.1)
- actionmailbox (= 8.1.3.1)
- actionmailer (= 8.1.3.1)
- actionpack (= 8.1.3.1)
- actiontext (= 8.1.3.1)
- actionview (= 8.1.3.1)
- activejob (= 8.1.3.1)
- activemodel (= 8.1.3.1)
- activerecord (= 8.1.3.1)
- activestorage (= 8.1.3.1)
- activesupport (= 8.1.3.1)
+ rails (8.1.4)
+ actioncable (= 8.1.4)
+ actionmailbox (= 8.1.4)
+ actionmailer (= 8.1.4)
+ actionpack (= 8.1.4)
+ actiontext (= 8.1.4)
+ actionview (= 8.1.4)
+ activejob (= 8.1.4)
+ activemodel (= 8.1.4)
+ activerecord (= 8.1.4)
+ activestorage (= 8.1.4)
+ activesupport (= 8.1.4)
bundler (>= 1.15.0)
- railties (= 8.1.3.1)
+ railties (= 8.1.4)
rails-dom-testing (2.3.0)
activesupport (>= 5.0.0)
minitest
@@ -407,9 +407,9 @@ GEM
rails-i18n (8.1.0)
i18n (>= 0.7, < 2)
railties (>= 8.0.0, < 9)
- railties (8.1.3.1)
- actionpack (= 8.1.3.1)
- activesupport (= 8.1.3.1)
+ railties (8.1.4)
+ actionpack (= 8.1.4)
+ activesupport (= 8.1.4)
irb (~> 1.13)
rackup (>= 1.0.0)
rake (>= 12.2)
@@ -418,11 +418,11 @@ GEM
zeitwerk (~> 2.6)
rainbow (3.1.1)
rake (13.4.2)
- rbs (4.1.0)
+ rbs (4.2.0)
logger
prism (>= 1.6.0)
tsort
- rdoc (8.0.0)
+ rdoc (8.1.0)
erb
prism (>= 1.6.0)
rbs (>= 4.0.0)
@@ -430,7 +430,7 @@ GEM
redis-client (0.29.0)
connection_pool
regexp_parser (2.11.3)
- reline (0.6.3)
+ reline (0.7.0)
io-console (~> 0.5)
representable (3.2.0)
declarative (< 0.1.0)
@@ -466,14 +466,14 @@ GEM
rspec-mocks (>= 3.13.0, < 5.0.0)
rspec-support (>= 3.13.0, < 5.0.0)
rspec-support (3.13.7)
- rubocop (1.86.0)
- json (~> 2.3)
+ rubocop (1.92.1)
+ json (>= 2.3)
language_server-protocol (~> 3.17.0.2)
lint_roller (~> 1.1.0)
- parallel (~> 1.10)
+ parallel (>= 1.10)
parser (>= 3.3.0.2)
rainbow (>= 2.2.2, < 4.0)
- regexp_parser (>= 2.9.3, < 3.0)
+ regexp_parser (>= 2.11.3, < 3.0)
rubocop-ast (>= 1.49.0, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 2.4.0, < 4.0)
@@ -555,7 +555,7 @@ GEM
unicode-emoji (~> 4.1)
unicode-emoji (4.2.0)
uniform_notifier (1.18.0)
- uri (1.1.1)
+ uri (1.1.2)
useragent (0.16.11)
warden (1.2.9)
rack (>= 2.0.9)
@@ -587,7 +587,7 @@ GEM
xpath (3.2.0)
nokogiri (~> 1.8)
yaml (0.4.0)
- zeitwerk (2.8.2)
+ zeitwerk (2.8.3)
zip_kit (6.3.4)
PLATFORMS
diff --git a/SECURITY.md b/SECURITY.md
index b1692488c..c61204cc4 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -9,6 +9,7 @@ Out of scope vulnerabilities:
- CSRF
- DNSSEC, CAA, CSP headers
- DNS or email security related
+- SSRF
- Rate Limiting
Note: We reserve the right to classify any reported vulnerability as out of scope for the bug bounty program.
diff --git a/app/controllers/accounts_controller.rb b/app/controllers/accounts_controller.rb
index 37591527e..949cea168 100644
--- a/app/controllers/accounts_controller.rb
+++ b/app/controllers/accounts_controller.rb
@@ -54,14 +54,13 @@ class AccountsController < ApplicationController
email: true_user.email.sub('@', '+removed@'))
true_user.account.update!(archived_at: Time.current)
- # rubocop:disable Layout/LineLength
+ # rubocop:disable-next Layout/LineLength
render turbo_stream: turbo_stream.replace(
:account_delete_button,
html: helpers.tag.p(I18n.t('your_account_will_be_permanently_deleted_within_2_months_please_contact_us_if_you_want_to_keep_your_account')) +
helpers.tag.br +
helpers.tag.p(I18n.t('your_email_address_has_been_released_immediately_you_can_now_be_added_to_your_company_team_without_waiting_for_the_deletion_period_to_end'))
)
- # rubocop:enable Layout/LineLength
end
private
diff --git a/app/controllers/api/active_storage_blobs_proxy_controller.rb b/app/controllers/api/active_storage_blobs_proxy_controller.rb
index 0cddd9949..e55c1cb3d 100644
--- a/app/controllers/api/active_storage_blobs_proxy_controller.rb
+++ b/app/controllers/api/active_storage_blobs_proxy_controller.rb
@@ -11,7 +11,7 @@ module Api
before_action :set_noindex_headers
before_action :set_security_headers
- # rubocop:disable Metrics
+ # rubocop:disable-next Metrics
def show
blob_uuid, purp, exp = ApplicationRecord.signed_id_verifier.verified(params[:signed_uuid])
@@ -53,7 +53,6 @@ module Api
end
end
end
- # rubocop:enable Metrics
private
diff --git a/app/controllers/api/active_storage_blobs_proxy_legacy_controller.rb b/app/controllers/api/active_storage_blobs_proxy_legacy_controller.rb
deleted file mode 100644
index 3df2dae27..000000000
--- a/app/controllers/api/active_storage_blobs_proxy_legacy_controller.rb
+++ /dev/null
@@ -1,53 +0,0 @@
-# frozen_string_literal: true
-
-module Api
- class ActiveStorageBlobsProxyLegacyController < ApiBaseController
- include ActiveStorage::Streaming
-
- skip_before_action :authenticate_user!
- skip_authorization_check
-
- before_action :set_cors_headers
- before_action :set_noindex_headers
- before_action :set_security_headers
-
- # rubocop:disable Metrics
- def show
- Rollbar.info('Blob legacy') if defined?(Rollbar)
-
- blob = ActiveStorage::Blob.find_signed(params[:signed_blob_id] || params[:signed_id])
-
- return head :not_found unless blob
-
- if FilenameUtils.dangerous_extension(blob.filename)
- Rollbar.error('Dangerous extension') if defined?(Rollbar)
-
- return head :unprocessable_content
- end
-
- is_permitted = blob.attachments.any? do |a|
- (current_user && a.record.account.id == current_user.account_id) ||
- a.record.account.account_configs.any? { |e| e.key == 'legacy_blob_proxy' } ||
- a.name == 'logo'
- end
-
- unless is_permitted
- Rollbar.error("Blob account not found: #{blob.id}") if defined?(Rollbar)
-
- return render json: { error: 'Not authenticated' }, status: :unauthorized
- end
-
- if request.headers['Range'].present?
- send_blob_byte_range_data blob, request.headers['Range']
- else
- http_cache_forever public: true do
- response.headers['Accept-Ranges'] = 'bytes'
- response.headers['Content-Length'] = blob.byte_size.to_s
-
- send_blob_stream blob, disposition: params[:disposition]
- end
- end
- end
- # rubocop:enable Metrics
- end
-end
diff --git a/app/controllers/api/submitters_controller.rb b/app/controllers/api/submitters_controller.rb
index a547ba75a..eee1e835c 100644
--- a/app/controllers/api/submitters_controller.rb
+++ b/app/controllers/api/submitters_controller.rb
@@ -36,7 +36,7 @@ module Api
render json: Submitters::SerializeForApi.call(@submitter, with_template: true, with_events: true, params:)
end
- # rubocop:disable Metrics/MethodLength
+ # rubocop:disable-next Metrics/MethodLength
def update
submission = @submitter.submission
role = submission.template_submitters.find { |e| e['uuid'] == @submitter.uuid }['name']
@@ -84,7 +84,6 @@ module Api
render json: { error: e.message }, status: :unprocessable_content
end
- # rubocop:enable Metrics/MethodLength
def submitter_params
submitter_params = params.key?(:submitter) ? params.require(:submitter) : params
@@ -179,11 +178,29 @@ module Api
submitters = submitters.where(external_id: params[:external_id]) if params[:external_id].present?
submitters = submitters.where(slug: params[:slug]) if params[:slug].present?
submitters = submitters.where(submission_id: params[:submission_id]) if params[:submission_id].present?
- submitters = submitters.where(template_id: params[:template_id]) if params[:template_id].present?
+ submitters = filter_submitters_by_template_id(submitters, params) if params[:template_id].present?
maybe_filter_by_completed_at(submitters, params)
end
+ def filter_submitters_by_template_id(submitters, params)
+ return submitters.where(template_id: params[:template_id]) if params[:template_id].is_a?(Array)
+
+ template = Template.find_by(id: params[:template_id])
+
+ return submitters.none if template.nil? || !can?(:read, template)
+
+ if template.account_id == current_user.account_id &&
+ params[:completed_after].blank? && params[:completed_before].blank?
+ account_id_bind = Submitter.predicate_builder.build_bind_attribute('account_id', current_user.account_id)
+
+ submitters = submitters.unscope(where: :account_id)
+ .where((Submitter.arel_table[:account_id] + 0).eq(account_id_bind))
+ end
+
+ submitters.where(template_id: template.id)
+ end
+
def assign_external_id(submitter, attrs)
submitter.external_id = attrs[:application_key] if attrs.key?(:application_key)
submitter.external_id = attrs[:external_id] if attrs.key?(:external_id)
diff --git a/app/controllers/mcp/create_template_controller.rb b/app/controllers/mcp/create_template_controller.rb
index 2f54ce716..3d91686d6 100644
--- a/app/controllers/mcp/create_template_controller.rb
+++ b/app/controllers/mcp/create_template_controller.rb
@@ -30,7 +30,7 @@ module Mcp
}
}.freeze
- # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
+ # rubocop:disable-next Metrics/AbcSize, Metrics/MethodLength
def call
account = current_user.account
@@ -87,6 +87,5 @@ module Mcp
edit_url: edit_template_url(@template)
)
end
- # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
end
end
diff --git a/app/controllers/mcp/send_documents_controller.rb b/app/controllers/mcp/send_documents_controller.rb
index 7fadc8a17..a4c5a7125 100644
--- a/app/controllers/mcp/send_documents_controller.rb
+++ b/app/controllers/mcp/send_documents_controller.rb
@@ -66,7 +66,7 @@ module Mcp
}
}.freeze
- # rubocop:disable Metrics
+ # rubocop:disable-next Metrics
def call
@template = Template.accessible_by(current_ability).find(mcp_params['template_id'])
@@ -115,6 +115,5 @@ module Mcp
rescue Submissions::CreateFromSubmitters::BaseError => e
render_tool_error(e.message)
end
- # rubocop:enable Metrics
end
end
diff --git a/app/controllers/passwords_controller.rb b/app/controllers/passwords_controller.rb
index e166da35a..12240d65f 100644
--- a/app/controllers/passwords_controller.rb
+++ b/app/controllers/passwords_controller.rb
@@ -1,9 +1,8 @@
# frozen_string_literal: true
class PasswordsController < Devise::PasswordsController
- # rubocop:disable Rails/LexicallyScopedActionFilter
+ # rubocop:disable-next Rails/LexicallyScopedActionFilter
skip_before_action :require_no_authentication, only: %i[edit update]
- # rubocop:enable Rails/LexicallyScopedActionFilter
around_action :with_browser_locale
diff --git a/app/controllers/preview_document_page_controller.rb b/app/controllers/preview_document_page_controller.rb
index f43265904..ce4e02df0 100644
--- a/app/controllers/preview_document_page_controller.rb
+++ b/app/controllers/preview_document_page_controller.rb
@@ -53,7 +53,7 @@ class PreviewDocumentPageController < ActionController::API
File.open(file_path, File::RDWR | File::CREAT, 0o644) do |file|
file.flock(File::LOCK_EX)
- # rubocop:disable Style/ZeroLengthPredicate
+ # rubocop:disable-next Style/ZeroLengthPredicate
if file.size.zero?
cleanup_stale_tempfiles
@@ -63,7 +63,6 @@ class PreviewDocumentPageController < ActionController::API
else
FileUtils.touch(file_path)
end
- # rubocop:enable Style/ZeroLengthPredicate
file.flock(File::LOCK_UN)
diff --git a/app/controllers/send_submission_email_controller.rb b/app/controllers/send_submission_email_controller.rb
index 13bd5f161..5cb82a034 100644
--- a/app/controllers/send_submission_email_controller.rb
+++ b/app/controllers/send_submission_email_controller.rb
@@ -14,7 +14,7 @@ class SendSubmissionEmailController < ApplicationController
template = Template.find_by!(slug: params[:template_slug])
@submitter =
- Submitter.completed.where(submission: template.submissions).find_by(email: params[:email].to_s.downcase)
+ Submitter.completed.where(template_id: template.id).find_by(email: params[:email].to_s.downcase)
elsif params[:submission_slug]
submission = Submission.find_by!(slug: params[:submission_slug])
diff --git a/app/controllers/start_form_controller.rb b/app/controllers/start_form_controller.rb
index 86471d381..530b3b7be 100644
--- a/app/controllers/start_form_controller.rb
+++ b/app/controllers/start_form_controller.rb
@@ -34,7 +34,7 @@ class StartFormController < ApplicationController
@submitter = find_or_initialize_submitter(@template, submitter_params)
if @submitter.completed_at?
- redirect_to start_form_completed_path(@template.slug, submitter_params.compact_blank)
+ redirect_to start_form_completed_path(@template.slug, submitter_params.compact_blank.merge(lang:))
else
if Templates.filter_undefined_submitters(@template.submitters).size > 1 && @submitter.new_record?
@error_message = multiple_submitters_error_message
@@ -59,7 +59,7 @@ class StartFormController < ApplicationController
Submitters::StartForm.assign_start_form_cookie(@submitter, request)
- redirect_to submit_form_path(@submitter.slug)
+ redirect_to submit_form_path(@submitter.slug, lang:)
else
render :show, status: :unprocessable_content
end
@@ -80,7 +80,7 @@ class StartFormController < ApplicationController
raise ActionController::RoutingError, I18n.t('not_found') if required_params.any? { |_, v| v.blank? } ||
required_params.except('name').compact_blank.blank?
- @submitter = Submitter.where(submission: @template.submissions)
+ @submitter = Submitter.where(template_id: @template.id)
.where.not(completed_at: nil)
.find_by!(required_params.except('name'))
end
@@ -150,7 +150,7 @@ class StartFormController < ApplicationController
return render :show, status: :unprocessable_content if submitter.errors.present?
if Submitters::StartForm.verify_2fa_and_save_submitter(submitter, request, is_new_record: submitter.new_record?)
- redirect_to submit_form_path(submitter.slug)
+ redirect_to submit_form_path(submitter.slug, lang:)
else
if defined?(Rollbar) && template.preferences['shared_link_2fa'] != true
Rollbar.info("2FA link requested: #{submitter.id}")
@@ -167,10 +167,14 @@ class StartFormController < ApplicationController
render :error, status: :unprocessable_content
rescue Submitters::UnableToSendCode, Submitters::InvalidOtp => e
- redirect_to start_form_path(template.slug, params: submitter_params.merge(email_verification: true)),
+ redirect_to start_form_path(template.slug, lang:, params: submitter_params.merge(email_verification: true)),
alert: e.message
rescue RateLimit::LimitApproached
- redirect_to start_form_path(template.slug, params: submitter_params.merge(email_verification: true)),
+ redirect_to start_form_path(template.slug, lang:, params: submitter_params.merge(email_verification: true)),
alert: I18n.t(:too_many_attempts)
end
+
+ def lang
+ params[:lang].presence
+ end
end
diff --git a/app/controllers/start_form_email_2fa_send_controller.rb b/app/controllers/start_form_email_2fa_send_controller.rb
index 0787ab468..cb942bd55 100644
--- a/app/controllers/start_form_email_2fa_send_controller.rb
+++ b/app/controllers/start_form_email_2fa_send_controller.rb
@@ -16,21 +16,21 @@ class StartFormEmail2faSendController < ApplicationController
.submitters.new(**submitter_params, account_id: @template.account_id)
if @submitter.email.blank?
- return redirect_to start_form_path(@template.slug), alert: I18n.t(:provide_your_email_to_start)
+ return redirect_to start_form_path(@template.slug, lang:), alert: I18n.t(:provide_your_email_to_start)
end
Submitters.send_shared_link_email_verification_code(@submitter, request:)
redir_params = { notice: I18n.t(:code_has_been_resent) } if params[:resend]
- redirect_to start_form_path(@template.slug, params: submitter_params.merge(email_verification: true)),
+ redirect_to start_form_path(@template.slug, lang:, params: submitter_params.merge(email_verification: true)),
**redir_params
rescue Submitters::BouncedEmail => e
@error_message = e.message
render 'start_form/error', status: :unprocessable_content
rescue Submitters::UnableToSendCode => e
- redirect_to start_form_path(@template.slug, params: submitter_params.merge(email_verification: true)),
+ redirect_to start_form_path(@template.slug, lang:, params: submitter_params.merge(email_verification: true)),
alert: e.message
end
@@ -66,4 +66,8 @@ class StartFormEmail2faSendController < ApplicationController
attrs[:email] = Submissions.normalize_email(attrs[:email])
end
end
+
+ def lang
+ params[:lang].presence
+ end
end
diff --git a/app/controllers/submissions_export_controller.rb b/app/controllers/submissions_export_controller.rb
index d199e5850..7a42d6a5c 100644
--- a/app/controllers/submissions_export_controller.rb
+++ b/app/controllers/submissions_export_controller.rb
@@ -25,5 +25,7 @@ class SubmissionsExportController < ApplicationController
end
end
- def new; end
+ def new
+ render layout: turbo_native_android? ? 'plain' : true
+ end
end
diff --git a/app/controllers/submissions_filters_controller.rb b/app/controllers/submissions_filters_controller.rb
index 8c08bb1d6..ecebfefca 100644
--- a/app/controllers/submissions_filters_controller.rb
+++ b/app/controllers/submissions_filters_controller.rb
@@ -14,6 +14,6 @@ class SubmissionsFiltersController < ApplicationController
def show
return head :not_found unless ALLOWED_NAMES.include?(params[:name])
- render params[:name]
+ render params[:name], layout: turbo_native_android? ? 'plain' : true
end
end
diff --git a/app/controllers/submit_form_controller.rb b/app/controllers/submit_form_controller.rb
index 2f3ab0cb2..f2d95e713 100644
--- a/app/controllers/submit_form_controller.rb
+++ b/app/controllers/submit_form_controller.rb
@@ -20,7 +20,7 @@ class SubmitFormController < ApplicationController
return render :email_2fa unless Submitters::AuthorizedForForm.pass_email_2fa?(@submitter, request)
if @submitter.completed_at? || submission.completed_at?
- return redirect_to submit_form_completed_path(@submitter.slug)
+ return redirect_to submit_form_completed_path(@submitter.slug, lang:)
end
@form_configs = Submitters::FormConfigs.call(@submitter, CONFIG_KEYS)
@@ -96,7 +96,7 @@ class SubmitFormController < ApplicationController
return if Submitters::AuthorizedForForm.call(@submitter, current_user, request)
- redirect_to submit_form_path(params[:submit_form_slug])
+ redirect_to submit_form_path(params[:submit_form_slug], lang:)
end
def success; end
@@ -114,7 +114,7 @@ class SubmitFormController < ApplicationController
def maybe_require_link_2fa
return if Submitters::AuthorizedForForm.pass_link_2fa?(@submitter, current_user, request)
- redirect_to start_form_path(@submitter.submission.template.slug)
+ redirect_to start_form_path(@submitter.submission.template.slug, lang:)
end
def maybe_render_locked_page
@@ -144,4 +144,8 @@ class SubmitFormController < ApplicationController
ActiveStorage::Attachment.where(record: submission.submitters, name: :attachments)
.preload(:blob).index_by(&:uuid)
end
+
+ def lang
+ params[:lang].presence
+ end
end
diff --git a/app/controllers/submit_form_email_2fas_controller.rb b/app/controllers/submit_form_email_2fas_controller.rb
index 6f95e7544..6c73112b8 100644
--- a/app/controllers/submit_form_email_2fas_controller.rb
+++ b/app/controllers/submit_form_email_2fas_controller.rb
@@ -20,17 +20,17 @@ class SubmitFormEmail2fasController < ApplicationController
{ value: @submitter.slug, expires: Submitters::StartForm::COOKIES_TTL.from_now,
**Submitters::StartForm::COOKIES_DEFAULTS }
- redirect_to submit_form_path(@submitter.slug)
+ redirect_to submit_form_path(@submitter.slug, lang:)
else
- redirect_to submit_form_path(@submitter.slug, status: :error), alert: I18n.t(:invalid_code)
+ redirect_to submit_form_path(@submitter.slug, status: :error, lang:), alert: I18n.t(:invalid_code)
end
rescue RateLimit::LimitApproached
- redirect_to submit_form_path(@submitter.slug, status: :error), alert: I18n.t(:too_many_attempts)
+ redirect_to submit_form_path(@submitter.slug, status: :error, lang:), alert: I18n.t(:too_many_attempts)
end
def update
if @submitter.submission_events.where(event_type: 'send_2fa_email').exists?(created_at: 15.seconds.ago..)
- return redirect_to submit_form_path(@submitter.slug, status: :error), alert: I18n.t(:rate_limit_exceeded)
+ return redirect_to submit_form_path(@submitter.slug, status: :error, lang:), alert: I18n.t(:rate_limit_exceeded)
end
RateLimit.call("send-email-code-#{@submitter.id}", limit: 2, ttl: 45.seconds, enabled: true)
@@ -38,19 +38,24 @@ class SubmitFormEmail2fasController < ApplicationController
if Docuseal.multitenant? && Submitters.email_bounced_recently?(@submitter.email)
Rollbar.warning("Bounced OTP email for submitter: #{@submitter.id}") if defined?(Rollbar)
- return redirect_to submit_form_path(@submitter.slug, status: :error), alert: I18n.t(:verification_email_bounced)
+ return redirect_to submit_form_path(@submitter.slug, status: :error, lang:),
+ alert: I18n.t(:verification_email_bounced)
end
SendSubmitterVerificationEmailJob.perform_async('submitter_id' => @submitter.id, 'locale' => I18n.locale.to_s)
redir_params = params[:resend] ? { alert: I18n.t(:code_has_been_resent) } : {}
- redirect_to submit_form_path(@submitter.slug, status: :sent), **redir_params
+ redirect_to submit_form_path(@submitter.slug, status: :sent, lang:), **redir_params
rescue RateLimit::LimitApproached
- redirect_to submit_form_path(@submitter.slug, status: :error), alert: I18n.t(:too_many_attempts)
+ redirect_to submit_form_path(@submitter.slug, status: :error, lang:), alert: I18n.t(:too_many_attempts)
end
def load_submitter
@submitter = Submitter.find_by!(slug: params[:submitter_slug])
end
+
+ def lang
+ params[:lang].presence
+ end
end
diff --git a/app/controllers/template_folders_controller.rb b/app/controllers/template_folders_controller.rb
index 17fbc806f..8b24d2020 100644
--- a/app/controllers/template_folders_controller.rb
+++ b/app/controllers/template_folders_controller.rb
@@ -41,7 +41,9 @@ class TemplateFoldersController < ApplicationController
render_infinite_scroll(@pagy, @templates, @template_folders) if turbo_infinite_scroll?
end
- def edit; end
+ def edit
+ render layout: turbo_native_android? ? 'plain' : true
+ end
def update
if @template_folder != current_account.default_template_folder &&
diff --git a/app/controllers/templates_clone_controller.rb b/app/controllers/templates_clone_controller.rb
index d001087ff..8d5f62546 100644
--- a/app/controllers/templates_clone_controller.rb
+++ b/app/controllers/templates_clone_controller.rb
@@ -7,6 +7,8 @@ class TemplatesCloneController < ApplicationController
authorize!(:create, Template)
@template = Template.new(name: "#{@base_template.name} (#{I18n.t('clone')})")
+
+ render layout: turbo_native_android? ? 'plain' : true
end
def create
diff --git a/app/controllers/templates_folders_controller.rb b/app/controllers/templates_folders_controller.rb
index 05ee62d84..6f22669b0 100644
--- a/app/controllers/templates_folders_controller.rb
+++ b/app/controllers/templates_folders_controller.rb
@@ -3,7 +3,9 @@
class TemplatesFoldersController < ApplicationController
load_and_authorize_resource :template
- def edit; end
+ def edit
+ render layout: turbo_native_android? ? 'plain' : true
+ end
def update
authorize!(:update, @template)
diff --git a/app/controllers/user_initials_controller.rb b/app/controllers/user_initials_controller.rb
index 29562e642..1306444cc 100644
--- a/app/controllers/user_initials_controller.rb
+++ b/app/controllers/user_initials_controller.rb
@@ -4,7 +4,9 @@ class UserInitialsController < ApplicationController
before_action :load_user_config
authorize_resource :user_config
- def edit; end
+ def edit
+ render layout: turbo_native_android? ? 'plain' : true
+ end
def update
file = params[:file]
diff --git a/app/controllers/user_signatures_controller.rb b/app/controllers/user_signatures_controller.rb
index da2974eae..353e26092 100644
--- a/app/controllers/user_signatures_controller.rb
+++ b/app/controllers/user_signatures_controller.rb
@@ -4,7 +4,9 @@ class UserSignaturesController < ApplicationController
before_action :load_user_config
authorize_resource :user_config
- def edit; end
+ def edit
+ render layout: turbo_native_android? ? 'plain' : true
+ end
def update
file = params[:file]
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index d2371aa55..6298c0815 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -31,9 +31,13 @@ class UsersController < ApplicationController
end
end
- def new; end
+ def new
+ render layout: turbo_native_android? ? 'plain' : true
+ end
- def edit; end
+ def edit
+ render layout: turbo_native_android? ? 'plain' : true
+ end
def create
existing_user = User.accessible_by(current_ability).find_by(email: @user.email)
diff --git a/app/controllers/webhook_settings_controller.rb b/app/controllers/webhook_settings_controller.rb
index 77fa22bff..6b6cf9140 100644
--- a/app/controllers/webhook_settings_controller.rb
+++ b/app/controllers/webhook_settings_controller.rb
@@ -66,7 +66,7 @@ class WebhookSettingsController < ApplicationController
SendTestWebhookRequestJob.perform_async(
'submitter_id' => submitter.id,
- 'event_uuid' => SecureRandom.uuid,
+ 'event_uuid' => SecureRandom.uuid_v7,
'webhook_url_id' => @webhook_url.id
)
diff --git a/app/javascript/elements/signature_form.js b/app/javascript/elements/signature_form.js
index 845a6b6cf..f3129167e 100644
--- a/app/javascript/elements/signature_form.js
+++ b/app/javascript/elements/signature_form.js
@@ -55,7 +55,7 @@ export default targetable(class extends HTMLElement {
this.input.files = dataTransfer.files
- if (this.input.webkitEntries.length) {
+ if (this.input.webkitEntries?.length) {
this.input.dataset.file = `${dataTransfer.files[0].name}`
}
diff --git a/app/javascript/template_builder/builder.vue b/app/javascript/template_builder/builder.vue
index 620ab845a..7da438e5d 100644
--- a/app/javascript/template_builder/builder.vue
+++ b/app/javascript/template_builder/builder.vue
@@ -772,7 +772,7 @@
class="sticky bottom-0 z-20"
>