Adding embedding functionality - fixing issues

pull/668/head
Eros Stein 1 month ago
parent 46838a2b79
commit 7551d7c7e0

@ -14,28 +14,8 @@ module Api
set_embed_cors_headers set_embed_cors_headers
unless can_upload?(submitter) return if render_upload_error?(submitter)
Rollbar.error("Can't upload: #{submitter.id}") if defined?(Rollbar) return if render_signature_error?(submitter)
return render json: { error: I18n.t('form_has_been_archived') }, status: :unprocessable_content
end
if params[:type].in?(%w[initials signature])
image = Vips::Image.new_from_file(params[:file].path)
if ImageUtils.blank?(image)
Rollbar.error("Empty signature: #{submitter.id}") if defined?(Rollbar)
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_content
end
end
attachment = Submitters.create_attachment!(submitter, params) attachment = Submitters.create_attachment!(submitter, params)
@ -50,6 +30,39 @@ module Api
render json: { error: e.message }, status: :unprocessable_content render json: { error: e.message }, status: :unprocessable_content
end end
private
def render_upload_error?(submitter)
return false if can_upload?(submitter)
Rollbar.error("Can't upload: #{submitter.id}") if defined?(Rollbar)
render json: { error: I18n.t('form_has_been_archived') }, status: :unprocessable_content
end
def render_signature_error?(submitter)
return false unless params[:type].in?(%w[initials signature])
image = Vips::Image.new_from_file(params[:file].path)
return render_empty_signature_error(submitter) if ImageUtils.blank?(image)
return render_invalid_signature_error(submitter) if ImageUtils.error?(image)
false
end
def render_empty_signature_error(submitter)
Rollbar.error("Empty signature: #{submitter.id}") if defined?(Rollbar)
render json: { error: "#{params[:type]} is empty" }, status: :unprocessable_content
end
def render_invalid_signature_error(submitter)
Rollbar.error("Error signature: #{submitter.id}") if defined?(Rollbar)
render json: { error: "#{params[:type]} error, try to sign on another device" }, status: :unprocessable_content
end
def can_upload?(submitter) def can_upload?(submitter)
!submitter.declined_at? && !submitter.declined_at? &&
!submitter.completed_at? && !submitter.completed_at? &&

@ -38,9 +38,11 @@ module EmbedCors
end end
def configured_embed_origins_for_account(account) def configured_embed_origins_for_account(account)
normalize_embed_origins( return [] unless account
account&.account_configs&.find_by(key: AccountConfig::EMBED_ALLOWED_ORIGINS_KEY)&.value
) config = account.account_configs.find_by(key: AccountConfig::EMBED_ALLOWED_ORIGINS_KEY)
normalize_embed_origins(config&.value)
end end
def configured_embed_origins def configured_embed_origins

@ -39,8 +39,7 @@ module Embed
private private
def form_json_for_template(template) def form_json_for_template(template)
raise ActiveRecord::RecordNotFound if template.archived_at? || template.account.archived_at? validate_shared_link_template!(template)
raise ActiveRecord::RecordNotFound unless template.shared_link?
attrs = submitter_params attrs = submitter_params
@ -48,60 +47,35 @@ module Embed
submitter = find_or_initialize_submitter(template, attrs) submitter = find_or_initialize_submitter(template, attrs)
if selected_template_submitter(template).blank? && filter_undefined_submitters(template).size > 1 && submitter.new_record? return shared_link_multiple_parties_error if multiple_parties_shared_link?(template, submitter)
return { error: I18n.t('this_template_has_multiple_parties_which_prevents_the_use_of_a_sharing_link') }
end
if submitter.new_record?
assign_submission_attributes(submitter, template)
Submissions::AssignDefinedSubmitters.call(submitter.submission)
else
submitter.assign_attributes(ip: request.remote_ip, ua: request.user_agent)
end
submitter.values = values_param.presence || submitter.values prepare_shared_link_submitter(submitter, template)
submitter.metadata = metadata_param.presence || submitter.metadata assign_shared_link_params(submitter)
submitter.external_id = params[:external_id].presence || submitter.external_id
if template.preferences['shared_link_2fa'] == true && if shared_link_2fa_required?(template, submitter)
!Submitters::AuthorizedForForm.pass_link_2fa?(submitter, nil, request)
Submitters.send_shared_link_email_verification_code(submitter, request: request) Submitters.send_shared_link_email_verification_code(submitter, request: request)
return { template: template_json(template), unverified_email: submitter.email, logo: logo_json(template.account) } return unverified_shared_link_email_json(template, submitter)
end end
if submitter.errors.blank? && submitter.save save_shared_link_submitter(submitter)
enqueue_new_submitter_jobs(submitter) if submitter.previous_changes.key?('id')
form_json(submitter)
else
{ error: submitter.errors.full_messages.to_sentence }
end
end end
def form_json(submitter) def form_json(submitter)
raise ActiveRecord::RecordNotFound if submitter.account.archived_at? raise ActiveRecord::RecordNotFound if submitter.account.archived_at?
return { expired_submitter: submitter_json(submitter), submission: submission_json(submitter.submission, submitter), unavailable_payload = unavailable_submitter_json(submitter)
template: template_json(submitter.template), logo: logo_json(submitter.account) } if submitter.submission.expired?
return { completed_submitter: submitter_json(submitter), submission: submission_json(submitter.submission, submitter), return unavailable_payload if unavailable_payload
template: template_json(submitter.template), logo: logo_json(submitter.account) } if submitter.completed_at?
return { expired_submitter: submitter_json(submitter), submission: submission_json(submitter.submission, submitter), pending_payload = pending_verification_json(submitter)
template: template_json(submitter.template), logo: logo_json(submitter.account) } if submitter.declined_at?
unless Submitters::AuthorizedForForm.pass_email_2fa?(submitter, request) return pending_payload if pending_payload
return { submitter_email_2fa: submitter_json(submitter),
submission: submission_json(submitter.submission, submitter),
template: template_json(submitter.template), logo: logo_json(submitter.account) }
end
unless Submitters::AuthorizedForForm.pass_link_2fa?(submitter, nil, request) ready_submitter_json(submitter)
return { unverified_email: submitter.email, submission: submission_json(submitter.submission, submitter), end
template: template_json(submitter.template), logo: logo_json(submitter.account) }
end
def ready_submitter_json(submitter)
submission = submitter.submission submission = submitter.submission
Submissions.preload_with_pages(submission) Submissions.preload_with_pages(submission)
@ -118,14 +92,99 @@ module Embed
} }
end end
def unavailable_submitter_json(submitter)
return submitter_status_json(submitter, :expired_submitter) if submitter.submission.expired?
return submitter_status_json(submitter, :completed_submitter) if submitter.completed_at?
return submitter_status_json(submitter, :expired_submitter) if submitter.declined_at?
end
def submitter_status_json(submitter, key)
{
key => submitter_json(submitter),
submission: submission_json(submitter.submission, submitter),
template: template_json(submitter.template),
logo: logo_json(submitter.account)
}
end
def pending_verification_json(submitter)
unless Submitters::AuthorizedForForm.pass_email_2fa?(submitter, request)
return submitter_status_json(submitter, :submitter_email_2fa)
end
return if Submitters::AuthorizedForForm.pass_link_2fa?(submitter, nil, request)
{
unverified_email: submitter.email,
submission: submission_json(submitter.submission, submitter),
template: template_json(submitter.template),
logo: logo_json(submitter.account)
}
end
def validate_shared_link_template!(template)
raise ActiveRecord::RecordNotFound if template.archived_at? || template.account.archived_at?
raise ActiveRecord::RecordNotFound unless template.shared_link?
end
def multiple_parties_shared_link?(template, submitter)
selected_template_submitter(template).blank? &&
filter_undefined_submitters(template).size > 1 &&
submitter.new_record?
end
def shared_link_multiple_parties_error
{ error: I18n.t('this_template_has_multiple_parties_which_prevents_the_use_of_a_sharing_link') }
end
def prepare_shared_link_submitter(submitter, template)
if submitter.new_record?
assign_submission_attributes(submitter, template)
Submissions::AssignDefinedSubmitters.call(submitter.submission)
else
submitter.assign_attributes(ip: request.remote_ip, ua: request.user_agent)
end
end
def assign_shared_link_params(submitter)
submitter.values = values_param.presence || submitter.values
submitter.metadata = metadata_param.presence || submitter.metadata
submitter.external_id = params[:external_id].presence || submitter.external_id
end
def shared_link_2fa_required?(template, submitter)
template.preferences['shared_link_2fa'] == true &&
!Submitters::AuthorizedForForm.pass_link_2fa?(submitter, nil, request)
end
def unverified_shared_link_email_json(template, submitter)
{
template: template_json(template),
unverified_email: submitter.email,
logo: logo_json(template.account)
}
end
def save_shared_link_submitter(submitter)
if submitter.errors.blank? && submitter.save
enqueue_new_submitter_jobs(submitter) if submitter.previous_changes.key?('id')
form_json(submitter)
else
{ error: submitter.errors.full_messages.to_sentence }
end
end
def template_json(template) def template_json(template)
template.as_json(only: %i[id name slug preferences schema submitters archived_at account_id]) template.as_json(only: %i[id name slug preferences schema submitters archived_at account_id])
end end
def submission_json(submission, submitter = nil) def submission_json(submission, submitter = nil)
submission.as_json( submission.as_json(
only: %i[id slug name source submitters_order expire_at archived_at created_at updated_at template_id account_id], only: %i[
methods: %i[expired?], id slug name source submitters_order expire_at archived_at created_at updated_at template_id account_id
],
methods: %i[expired?]
).merge( ).merge(
'template_schema' => Submissions.filtered_conditions_schema(submission, 'template_schema' => Submissions.filtered_conditions_schema(submission,
include_submitter_uuid: submitter&.uuid), include_submitter_uuid: submitter&.uuid),

@ -12,22 +12,9 @@ class SendSubmissionEmailController < ApplicationController
SEND_DURATION = 30.minutes SEND_DURATION = 30.minutes
def create def create
if params[:template_slug] @submitter = find_completed_submitter
template = Template.find_by!(slug: params[:template_slug])
@submitter =
Submitter.completed.where(submission: template.submissions).find_by!(email: params[:email].to_s.downcase)
elsif params[:submission_slug]
submission = Submission.find_by(slug: params[:submission_slug])
if submission return redirect_to submissions_preview_completed_path(params[:submission_slug], status: :error) unless @submitter
@submitter = Submitter.completed.find_by(submission: submission, email: params[:email].to_s.downcase)
end
return redirect_to submissions_preview_completed_path(params[:submission_slug], status: :error) unless @submitter
else
@submitter = Submitter.completed.find_by!(slug: params[:submitter_slug])
end
@embed_cors_account = @submitter.account @embed_cors_account = @submitter.account
set_embed_cors_headers set_embed_cors_headers
@ -44,6 +31,30 @@ class SendSubmissionEmailController < ApplicationController
private private
def find_completed_submitter
if params[:template_slug]
template = Template.find_by!(slug: params[:template_slug])
Submitter.completed.where(submission: template.submissions).find_by!(email: normalized_email_param)
elsif params[:submission_slug]
find_completed_submitter_for_submission
else
Submitter.completed.find_by!(slug: params[:submitter_slug])
end
end
def find_completed_submitter_for_submission
submission = Submission.find_by(slug: params[:submission_slug])
return unless submission
Submitter.completed.find_by(submission: submission, email: normalized_email_param)
end
def normalized_email_param
params[:email].to_s.downcase
end
def can_send?(submitter) def can_send?(submitter)
return false if submitter.account.archived_at? return false if submitter.account.archived_at?
return false if EmailEvent.exists?(tag: :submitter_documents_copy, email: submitter.email, emailable: submitter, return false if EmailEvent.exists?(tag: :submitter_documents_copy, email: submitter.email, emailable: submitter,

@ -12,13 +12,7 @@ class SubmitFormMetadataController < ApplicationController
set_embed_cors_headers set_embed_cors_headers
return head :not_found if submitter.declined_at? || return head :not_found unless render_metadata?(submitter)
submitter.completed_at? ||
submitter.submission.archived_at? ||
submitter.submission.expired? ||
submitter.submission.template&.archived_at? ||
submitter.account.archived_at? ||
!Submitters::AuthorizedForForm.call(submitter, current_user, request)
submission = submitter.submission submission = submitter.submission
values = submission.submitters.reduce({}) { |acc, sub| acc.merge(sub.values) } values = submission.submitters.reduce({}) { |acc, sub| acc.merge(sub.values) }
@ -39,4 +33,22 @@ class SubmitFormMetadataController < ApplicationController
render json: { text_runs: text_runs } render json: { text_runs: text_runs }
end end
private
def render_metadata?(submitter)
return false if unavailable_submitter?(submitter)
return false unless Submitters::AuthorizedForForm.call(submitter, current_user, request)
true
end
def unavailable_submitter?(submitter)
submitter.declined_at? ||
submitter.completed_at? ||
submitter.submission.archived_at? ||
submitter.submission.expired? ||
submitter.submission.template&.archived_at? ||
submitter.account.archived_at?
end
end end

Loading…
Cancel
Save