diff --git a/app/controllers/send_submission_email_controller.rb b/app/controllers/send_submission_email_controller.rb index 6d1f34c3..ef6ff62b 100644 --- a/app/controllers/send_submission_email_controller.rb +++ b/app/controllers/send_submission_email_controller.rb @@ -11,15 +11,15 @@ class SendSubmissionEmailController < ApplicationController def create if params[:template_slug] - @submitter = Submitter.joins(submission: :template).find_by!(email: params[:email].to_s.downcase, - template: { slug: params[:template_slug] }) + @submitter = Submitter.completed.joins(submission: :template).find_by!(email: params[:email].to_s.downcase, + template: { slug: params[:template_slug] }) elsif params[:submission_slug] - @submitter = Submitter.joins(:submission).find_by(email: params[:email].to_s.downcase, - submission: { slug: params[:submission_slug] }) + @submitter = Submitter.completed.joins(:submission).find_by(email: params[:email].to_s.downcase, + submission: { slug: params[:submission_slug] }) return redirect_to submissions_preview_completed_path(params[:submission_slug], status: :error) unless @submitter else - @submitter = Submitter.find_by!(slug: params[:submitter_slug]) + @submitter = Submitter.completed.find_by!(slug: params[:submitter_slug]) end RateLimit.call("send-email-#{@submitter.id}", limit: 2, ttl: 5.minutes) diff --git a/app/controllers/start_form_controller.rb b/app/controllers/start_form_controller.rb index 40986a97..a7f113e9 100644 --- a/app/controllers/start_form_controller.rb +++ b/app/controllers/start_form_controller.rb @@ -8,7 +8,9 @@ class StartFormController < ApplicationController around_action :with_browser_locale, only: %i[show completed] before_action :maybe_redirect_com, only: %i[show completed] + before_action :load_resubmit_submitter, only: :update before_action :load_template + before_action :authorize_start!, only: :update def show raise ActionController::RoutingError, I18n.t('not_found') if @template.preferences['require_phone_2fa'] @@ -28,8 +30,6 @@ class StartFormController < ApplicationController end def update - return redirect_to start_form_path(@template.slug) if @template.archived_at? || !@template.shared_link? - @submitter = find_or_initialize_submitter(@template, submitter_params) if @submitter.completed_at? @@ -74,6 +74,24 @@ class StartFormController < ApplicationController private + def load_resubmit_submitter + @resubmit_submitter = + if params[:resubmit].present? && !params[:resubmit].in?([true, 'true']) + Submitter.find_by(slug: params[:resubmit]) + end + end + + def authorize_start! + return redirect_to start_form_path(@template.slug) if @template.archived_at? + + return if @resubmit_submitter + return if @template.shared_link? || (current_user && current_ability.can?(:read, @template)) + + Rollbar.warning("Not shared template: #{@template.id}") if defined?(Rollbar) + + redirect_to start_form_path(@template.slug) + end + def enqueue_submission_create_webhooks(submitter) WebhookUrls.for_account_id(submitter.account_id, 'submission.created').each do |webhook_url| SendSubmissionCreatedWebhookRequestJob.perform_async('submission_id' => submitter.submission_id, @@ -82,31 +100,29 @@ class StartFormController < ApplicationController end def find_or_initialize_submitter(template, submitter_params) - Submitter.where(submission: template.submissions.where(expire_at: Time.current..) - .or(template.submissions.where(expire_at: nil)).where(archived_at: nil)) - .order(id: :desc) - .where(declined_at: nil) - .where(external_id: nil) - .where(ip: [nil, request.remote_ip]) - .then { |rel| params[:resubmit].present? ? rel.where(completed_at: nil) : rel } - .find_or_initialize_by(email: submitter_params[:email], **submitter_params.compact_blank) + Submitter + .where(submission: template.submissions.where(expire_at: Time.current..) + .or(template.submissions.where(expire_at: nil)).where(archived_at: nil)) + .order(id: :desc) + .where(declined_at: nil) + .where(external_id: nil) + .where(ip: [nil, request.remote_ip]) + .then { |rel| params[:resubmit].present? || params[:selfsign].present? ? rel.where(completed_at: nil) : rel } + .find_or_initialize_by(email: submitter_params[:email], **submitter_params.compact_blank) end def assign_submission_attributes(submitter, template) - resubmit_submitter = - (Submitter.where(submission: template.submissions).find_by(slug: params[:resubmit]) if params[:resubmit].present?) - submitter.assign_attributes( uuid: (filter_undefined_submitters(template).first || @template.submitters.first)['uuid'], ip: request.remote_ip, ua: request.user_agent, - values: resubmit_submitter&.preferences&.fetch('default_values', nil) || {}, - preferences: resubmit_submitter&.preferences.presence || { 'send_email' => true }, - metadata: resubmit_submitter&.metadata.presence || {} + values: @resubmit_submitter&.preferences&.fetch('default_values', nil) || {}, + preferences: @resubmit_submitter&.preferences.presence || { 'send_email' => true }, + metadata: @resubmit_submitter&.metadata.presence || {} ) if submitter.values.present? - resubmit_submitter.attachments.each do |attachment| + @resubmit_submitter.attachments.each do |attachment| submitter.attachments << attachment.dup if submitter.values.value?(attachment.uuid) end end @@ -128,15 +144,21 @@ class StartFormController < ApplicationController end def submitter_params + return current_user.slice(:email) if params[:selfsign] + return @resubmit_submitter.slice(:name, :phone, :email) if @resubmit_submitter.present? + params.require(:submitter).permit(:email, :phone, :name).tap do |attrs| attrs[:email] = Submissions.normalize_email(attrs[:email]) end end def load_template - slug = params[:slug] || params[:start_form_slug] - - @template = Template.find_by!(slug:) + @template = + if @resubmit_submitter + @resubmit_submitter.template + else + Template.find_by!(slug: params[:slug] || params[:start_form_slug]) + end end def multiple_submitters_error_message diff --git a/app/javascript/template_builder/builder.vue b/app/javascript/template_builder/builder.vue index ab26e912..e36a3c61 100644 --- a/app/javascript/template_builder/builder.vue +++ b/app/javascript/template_builder/builder.vue @@ -79,13 +79,52 @@ name="buttons" />