mirror of
https://github.com/docusealco/docuseal
synced 2026-11-08 23:42:32 -05:00
refactor routes
This commit is contained in:
1 parent
20ec614d3a
commit
ca7b9671f2
19 files changed
+173
-43
No files matched your search
@@ -1,10 +1,7 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module Api
|
module Api
|
||||||
class SubmitterEmailClicksController < ApiBaseController
|
class SubmitterEmailClicksController < ActionController::API
|
||||||
skip_before_action :authenticate_user!
|
|
||||||
skip_authorization_check
|
|
||||||
|
|
||||||
def create
|
def create
|
||||||
@submitter = Submitter.find_by!(slug: params[:submitter_slug])
|
@submitter = Submitter.find_by!(slug: params[:submitter_slug])
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,7 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module Api
|
module Api
|
||||||
class SubmitterFormViewsController < ApiBaseController
|
class SubmitterFormViewsController < ActionController::API
|
||||||
skip_before_action :authenticate_user!
|
|
||||||
skip_authorization_check
|
|
||||||
|
|
||||||
def create
|
def create
|
||||||
@submitter = Submitter.find_by!(slug: params[:submitter_slug])
|
@submitter = Submitter.find_by!(slug: params[:submitter_slug])
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class SubmitFormClickEmailController < ActionController::API
|
||||||
|
def create
|
||||||
|
@submitter = Submitter.find_by!(slug: params[:submit_form_slug])
|
||||||
|
|
||||||
|
if params[:t].present? && params[:t] == SubmissionEvents.build_tracking_param(@submitter, 'click_email')
|
||||||
|
SubmissionEvents.create_with_tracking_data(@submitter, 'click_email', request)
|
||||||
|
end
|
||||||
|
|
||||||
|
render json: {}
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -29,7 +29,9 @@ class SubmitFormCompletedDownloadController < ApplicationController
|
|||||||
Submissions::EnsureResultGenerated.call(last_submitter)
|
Submissions::EnsureResultGenerated.call(last_submitter)
|
||||||
|
|
||||||
if !signature_valid && !current_user_submitter?(last_submitter)
|
if !signature_valid && !current_user_submitter?(last_submitter)
|
||||||
return head :not_found unless Submitters::AuthorizedForForm.call(@submitter, current_user, request)
|
unless Submitters::AuthorizedForForm.call(@submitter, current_user, request, with_order: true)
|
||||||
|
return head :not_found
|
||||||
|
end
|
||||||
|
|
||||||
if last_submitter.completed_at < TTL.ago
|
if last_submitter.completed_at < TTL.ago
|
||||||
Rollbar.info("TTL: #{last_submitter.id}") if defined?(Rollbar)
|
Rollbar.info("TTL: #{last_submitter.id}") if defined?(Rollbar)
|
||||||
|
|||||||
@@ -15,7 +15,8 @@ class SubmitFormDelegateController < ApplicationController
|
|||||||
@submitter.viewer? ||
|
@submitter.viewer? ||
|
||||||
!Submitters::AuthorizedForForm.call(@submitter,
|
!Submitters::AuthorizedForForm.call(@submitter,
|
||||||
current_user,
|
current_user,
|
||||||
request)
|
request,
|
||||||
|
with_order: true)
|
||||||
|
|
||||||
@submitter.account.account_configs.find_by!(key: AccountConfig::ALLOW_TO_DELEGATE_KEY, value: true)
|
@submitter.account.account_configs.find_by!(key: AccountConfig::ALLOW_TO_DELEGATE_KEY, value: true)
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,8 @@ class SubmitFormDownloadController < ApplicationController
|
|||||||
AccountConfig.exists?(account_id: @submitter.account_id,
|
AccountConfig.exists?(account_id: @submitter.account_id,
|
||||||
key: AccountConfig::ALLOW_TO_PARTIAL_DOWNLOAD_KEY,
|
key: AccountConfig::ALLOW_TO_PARTIAL_DOWNLOAD_KEY,
|
||||||
value: false) ||
|
value: false) ||
|
||||||
!Submitters::AuthorizedForForm.call(@submitter, current_user, request)
|
!Submitters::AuthorizedForForm.call(@submitter, current_user, request,
|
||||||
|
with_order: true)
|
||||||
|
|
||||||
last_completed_submitter = @submitter.submission.submitters
|
last_completed_submitter = @submitter.submission.submitters
|
||||||
.where.not(id: @submitter.id)
|
.where.not(id: @submitter.id)
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ class SubmitFormDrawSignatureController < ApplicationController
|
|||||||
return redirect_to submit_form_path(@submitter.slug) if @submitter.viewer?
|
return redirect_to submit_form_path(@submitter.slug) if @submitter.viewer?
|
||||||
|
|
||||||
if @submitter.submission.template&.archived_at? || @submitter.submission.archived_at? ||
|
if @submitter.submission.template&.archived_at? || @submitter.submission.archived_at? ||
|
||||||
!Submitters::AuthorizedForForm.call(@submitter, current_user, request)
|
!Submitters::AuthorizedForForm.call(@submitter, current_user, request, with_order: true)
|
||||||
return redirect_to submit_form_path(@submitter.slug)
|
return redirect_to submit_form_path(@submitter.slug)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -39,6 +39,6 @@ class SubmitFormMetadataController < ApplicationController
|
|||||||
!submitter.submission.expired? &&
|
!submitter.submission.expired? &&
|
||||||
!submitter.submission.template&.archived_at? &&
|
!submitter.submission.template&.archived_at? &&
|
||||||
!submitter.account.archived_at? &&
|
!submitter.account.archived_at? &&
|
||||||
Submitters::AuthorizedForForm.call(submitter, current_user, request)
|
Submitters::AuthorizedForForm.call(submitter, current_user, request, with_order: true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class SubmitFormUploadController < ActionController::API
|
||||||
|
include ActionController::Cookies
|
||||||
|
include ActiveStorage::SetCurrent
|
||||||
|
|
||||||
|
before_action :load_submitter
|
||||||
|
before_action :authorize_upload!
|
||||||
|
|
||||||
|
COOKIE_STORE_LIMIT = 10
|
||||||
|
|
||||||
|
def create
|
||||||
|
file = params[:file]
|
||||||
|
|
||||||
|
if params[:type].in?(%w[initials signature])
|
||||||
|
image = ImageUtils.load_vips(file.read, content_type: file.content_type)
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
metadata = { analyzed: true, identified: true, width: image.width, height: image.height }
|
||||||
|
end
|
||||||
|
|
||||||
|
attachment = Submitters.create_attachment!(@submitter, file, metadata:)
|
||||||
|
|
||||||
|
if params[:remember_signature] == 'true' && @submitter.email.present?
|
||||||
|
cookies.encrypted[:signature_uuids] = build_new_cookie_signatures_json(@submitter, attachment)
|
||||||
|
end
|
||||||
|
|
||||||
|
render json: attachment.as_json(only: %i[uuid created_at], methods: %i[url filename content_type])
|
||||||
|
rescue Submitters::MaliciousFileExtension => e
|
||||||
|
Rollbar.error(e) if defined?(Rollbar)
|
||||||
|
|
||||||
|
render json: { error: e.message }, status: :unprocessable_content
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def load_submitter
|
||||||
|
@submitter = Submitter.find_by!(slug: params[:submit_form_slug])
|
||||||
|
end
|
||||||
|
|
||||||
|
def authorize_upload!
|
||||||
|
unless can_upload?(@submitter)
|
||||||
|
return render json: { error: I18n.t('form_has_been_archived') }, status: :unprocessable_content
|
||||||
|
end
|
||||||
|
|
||||||
|
return if Submitters::AuthorizedForForm.call(@submitter, current_user, request)
|
||||||
|
|
||||||
|
render json: { error: I18n.t('verification_required_refresh_the_page_and_pass_2fa') },
|
||||||
|
status: :unprocessable_content
|
||||||
|
end
|
||||||
|
|
||||||
|
def can_upload?(submitter)
|
||||||
|
!submitter.declined_at? &&
|
||||||
|
!submitter.completed_at? &&
|
||||||
|
!submitter.submission.archived_at? &&
|
||||||
|
!submitter.submission.expired? &&
|
||||||
|
!submitter.submission.template&.archived_at?
|
||||||
|
end
|
||||||
|
|
||||||
|
def build_new_cookie_signatures_json(submitter, attachment)
|
||||||
|
values =
|
||||||
|
begin
|
||||||
|
JSON.parse(cookies.encrypted[:signature_uuids].presence || '{}')
|
||||||
|
rescue JSON::ParserError
|
||||||
|
{}
|
||||||
|
end
|
||||||
|
|
||||||
|
values[submitter.email] = attachment.uuid
|
||||||
|
|
||||||
|
values = values.to_a.last(COOKIE_STORE_LIMIT).to_h if values.size > COOKIE_STORE_LIMIT
|
||||||
|
|
||||||
|
values.to_json
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class SubmitFormViewController < ActionController::API
|
||||||
|
def create
|
||||||
|
@submitter = Submitter.find_by!(slug: params[:submit_form_slug])
|
||||||
|
|
||||||
|
return head :not_found if Submitter.signed_id_verifier.verified(params[:v], purpose: :view_form) != @submitter.slug
|
||||||
|
|
||||||
|
@submitter.opened_at = Time.current
|
||||||
|
@submitter.save
|
||||||
|
|
||||||
|
SubmissionEvents.create_with_tracking_data(@submitter, 'view_form', request)
|
||||||
|
|
||||||
|
WebhookUrls.enqueue_events(@submitter, 'form.viewed')
|
||||||
|
|
||||||
|
render json: {}
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -41,6 +41,7 @@ safeRegisterElement('submission-form', class extends HTMLElement {
|
|||||||
language: this.dataset.language,
|
language: this.dataset.language,
|
||||||
paymentProvider: this.dataset.paymentProvider,
|
paymentProvider: this.dataset.paymentProvider,
|
||||||
dryRun: this.dataset.dryRun === 'true',
|
dryRun: this.dataset.dryRun === 'true',
|
||||||
|
viewToken: this.dataset.viewToken,
|
||||||
expand: ['true', 'false'].includes(this.dataset.expand) ? this.dataset.expand === 'true' : null,
|
expand: ['true', 'false'].includes(this.dataset.expand) ? this.dataset.expand === 'true' : null,
|
||||||
withSignatureId: this.dataset.withSignatureId === 'true',
|
withSignatureId: this.dataset.withSignatureId === 'true',
|
||||||
requireSigningReason: this.dataset.requireSigningReason === 'true',
|
requireSigningReason: this.dataset.requireSigningReason === 'true',
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ export default {
|
|||||||
IconCloudUpload,
|
IconCloudUpload,
|
||||||
IconInnerShadowTop
|
IconInnerShadowTop
|
||||||
},
|
},
|
||||||
inject: ['baseUrl', 't'],
|
inject: ['baseUrl', 'fetchOptions', 't'],
|
||||||
props: {
|
props: {
|
||||||
message: {
|
message: {
|
||||||
type: String,
|
type: String,
|
||||||
@@ -199,6 +199,7 @@ export default {
|
|||||||
|
|
||||||
return fetch(this.baseUrl + '/api/attachments', {
|
return fetch(this.baseUrl + '/api/attachments', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
|
headers: { ...this.fetchOptions.headers },
|
||||||
body: formData
|
body: formData
|
||||||
}).then(async (resp) => {
|
}).then(async (resp) => {
|
||||||
const data = await resp.json()
|
const data = await resp.json()
|
||||||
|
|||||||
@@ -775,6 +775,7 @@ export default {
|
|||||||
provide () {
|
provide () {
|
||||||
return {
|
return {
|
||||||
baseUrl: this.baseUrl,
|
baseUrl: this.baseUrl,
|
||||||
|
fetchOptions: this.fetchOptions,
|
||||||
scrollIntoArea: this.scrollIntoArea,
|
scrollIntoArea: this.scrollIntoArea,
|
||||||
scrollIntoField: this.scrollIntoField,
|
scrollIntoField: this.scrollIntoField,
|
||||||
t: this.t
|
t: this.t
|
||||||
@@ -1002,6 +1003,11 @@ export default {
|
|||||||
required: false,
|
required: false,
|
||||||
default: false
|
default: false
|
||||||
},
|
},
|
||||||
|
viewToken: {
|
||||||
|
type: String,
|
||||||
|
required: false,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
attribution: {
|
attribution: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: false,
|
required: false,
|
||||||
@@ -1531,15 +1537,10 @@ export default {
|
|||||||
const newUrl = [window.location.pathname, queryParams.toString()].filter(Boolean).join('?')
|
const newUrl = [window.location.pathname, queryParams.toString()].filter(Boolean).join('?')
|
||||||
window.history.replaceState({}, document.title, newUrl)
|
window.history.replaceState({}, document.title, newUrl)
|
||||||
|
|
||||||
return fetch(this.baseUrl + '/api/submitter_email_clicks', {
|
return fetch(this.baseUrl + `/s/${this.submitterSlug}/click_email`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: { 'Content-Type': 'application/json', ...this.fetchOptions.headers },
|
||||||
'Content-Type': 'application/json'
|
body: JSON.stringify({ t })
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
|
||||||
t,
|
|
||||||
submitter_slug: this.submitterSlug
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
return Promise.resolve({})
|
return Promise.resolve({})
|
||||||
@@ -1555,29 +1556,20 @@ export default {
|
|||||||
const newUrl = [window.location.pathname, queryParams.toString()].filter(Boolean).join('?')
|
const newUrl = [window.location.pathname, queryParams.toString()].filter(Boolean).join('?')
|
||||||
window.history.replaceState({}, document.title, newUrl)
|
window.history.replaceState({}, document.title, newUrl)
|
||||||
|
|
||||||
return fetch(this.baseUrl + '/api/submitter_sms_clicks', {
|
return fetch(this.baseUrl + `/s/${this.submitterSlug}/click_sms`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: { 'Content-Type': 'application/json', ...this.fetchOptions.headers },
|
||||||
'Content-Type': 'application/json'
|
body: JSON.stringify({ c })
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
|
||||||
c,
|
|
||||||
submitter_slug: this.submitterSlug
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
return Promise.resolve({})
|
return Promise.resolve({})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
trackViewForm () {
|
trackViewForm () {
|
||||||
fetch(this.baseUrl + '/api/submitter_form_views', {
|
fetch(this.baseUrl + `/s/${this.submitterSlug}/view`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: { 'Content-Type': 'application/json' },
|
||||||
'Content-Type': 'application/json'
|
body: JSON.stringify({ v: this.viewToken })
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
|
||||||
submitter_slug: this.submitterSlug
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
previousSignatureValueFor (field) {
|
previousSignatureValueFor (field) {
|
||||||
|
|||||||
@@ -202,7 +202,7 @@ export default {
|
|||||||
MarkdownContent,
|
MarkdownContent,
|
||||||
IconArrowsDiagonalMinimize2
|
IconArrowsDiagonalMinimize2
|
||||||
},
|
},
|
||||||
inject: ['baseUrl', 't'],
|
inject: ['baseUrl', 'fetchOptions', 't'],
|
||||||
props: {
|
props: {
|
||||||
field: {
|
field: {
|
||||||
type: Object,
|
type: Object,
|
||||||
@@ -443,6 +443,7 @@ export default {
|
|||||||
|
|
||||||
return fetch(this.baseUrl + '/api/attachments', {
|
return fetch(this.baseUrl + '/api/attachments', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
|
headers: { ...this.fetchOptions.headers },
|
||||||
body: formData
|
body: formData
|
||||||
}).then(async (resp) => {
|
}).then(async (resp) => {
|
||||||
if (resp.status === 422 || resp.status === 500) {
|
if (resp.status === 422 || resp.status === 500) {
|
||||||
|
|||||||
@@ -376,7 +376,7 @@ export default {
|
|||||||
IconSignature,
|
IconSignature,
|
||||||
IconArrowsDiagonalMinimize2
|
IconArrowsDiagonalMinimize2
|
||||||
},
|
},
|
||||||
inject: ['baseUrl', 't'],
|
inject: ['baseUrl', 'fetchOptions', 't'],
|
||||||
props: {
|
props: {
|
||||||
field: {
|
field: {
|
||||||
type: Object,
|
type: Object,
|
||||||
@@ -952,6 +952,7 @@ export default {
|
|||||||
|
|
||||||
return fetch(this.baseUrl + '/api/attachments', {
|
return fetch(this.baseUrl + '/api/attachments', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
|
headers: { ...this.fetchOptions.headers },
|
||||||
body: formData
|
body: formData
|
||||||
}).then(async (resp) => {
|
}).then(async (resp) => {
|
||||||
if (resp.status === 422 || resp.status === 500) {
|
if (resp.status === 422 || resp.status === 500) {
|
||||||
|
|||||||
@@ -2,4 +2,4 @@
|
|||||||
<% data_fields = Submissions.filtered_conditions_fields(submitter).to_json %>
|
<% data_fields = Submissions.filtered_conditions_fields(submitter).to_json %>
|
||||||
<% invite_submitters = (submitter.submission.template_submitters || submitter.submission.template.submitters).select { |s| s['invite_by_uuid'] == submitter.uuid && submitter.submission.submitters.none? { |e| e.uuid == s['uuid'] } }.to_json %>
|
<% invite_submitters = (submitter.submission.template_submitters || submitter.submission.template.submitters).select { |s| s['invite_by_uuid'] == submitter.uuid && submitter.submission.submitters.none? { |e| e.uuid == s['uuid'] } }.to_json %>
|
||||||
<% optional_invite_submitters = (submitter.submission.template_submitters || submitter.submission.template.submitters).select { |s| s['optional_invite_by_uuid'] == submitter.uuid && submitter.submission.submitters.none? { |e| e.uuid == s['uuid'] } }.to_json %>
|
<% optional_invite_submitters = (submitter.submission.template_submitters || submitter.submission.template.submitters).select { |s| s['optional_invite_by_uuid'] == submitter.uuid && submitter.submission.submitters.none? { |e| e.uuid == s['uuid'] } }.to_json %>
|
||||||
<submission-form data-native-platform="<%= turbo_native_ios? ? 'ios' : (turbo_native_android? ? 'android' : '') %>" data-attribution="<%= !turbo_native_app? %>" data-is-demo="<%= Docuseal.demo? %>" data-schema="<%= schema.to_json %>" data-reuse-signature="<%= configs[:reuse_signature] %>" data-require-signing-reason="<%= configs[:require_signing_reason] %>" data-with-signature-id="<%= configs[:with_signature_id] %>" data-with-field-labels="<%= configs[:with_field_labels] %>" data-with-confetti="<%= configs[:with_confetti] %>" data-completed-redirect-url="<%= submitter.preferences['completed_redirect_url'].presence || submitter.submission.template&.preferences&.dig('completed_redirect_url') %>" data-completed-message="<%= (configs[:completed_message]&.compact_blank.presence || submitter.submission.template&.preferences&.dig('completed_message') || {}).to_json %>" data-completed-button="<%= configs[:completed_button].to_json %>" data-go-to-last="<%= submitter.preferences.key?('go_to_last') ? submitter.preferences['go_to_last'] : submitter.opened_at? %>" data-submitter="<%= submitter.to_json(only: %i[uuid slug name phone email]) %>" data-can-send-email="<%= Docuseal.multitenant? || Accounts.can_send_emails?(submitter.submission.account) %>" data-optional-invite-submitters="<%= optional_invite_submitters %>" data-invite-submitters="<%= invite_submitters %>" data-attachments="<%= data_attachments %>" data-fields="<%= data_fields %>" data-values="<%= submitter.values.to_json %>" data-with-typed-signature="<%= configs[:with_typed_signature] %>" data-signature-text="<%= params[:signature] %>" data-previous-signature-value="<%= local_assigns[:signature_attachment]&.uuid %>" data-remember-signature="<%= configs[:prefill_signature] %>" data-dry-run="<%= local_assigns[:dry_run] %>" data-expand="<%= local_assigns[:expand] %>" data-scroll-padding="<%= local_assigns[:scroll_padding] %>" data-language="<%= I18n.locale.to_s.split('-').first %>"></submission-form>
|
<submission-form data-native-platform="<%= turbo_native_ios? ? 'ios' : (turbo_native_android? ? 'android' : '') %>" data-attribution="<%= !turbo_native_app? %>" data-is-demo="<%= Docuseal.demo? %>" data-schema="<%= schema.to_json %>" data-reuse-signature="<%= configs[:reuse_signature] %>" data-require-signing-reason="<%= configs[:require_signing_reason] %>" data-with-signature-id="<%= configs[:with_signature_id] %>" data-with-field-labels="<%= configs[:with_field_labels] %>" data-with-confetti="<%= configs[:with_confetti] %>" data-completed-redirect-url="<%= submitter.preferences['completed_redirect_url'].presence || submitter.submission.template&.preferences&.dig('completed_redirect_url') %>" data-completed-message="<%= (configs[:completed_message]&.compact_blank.presence || submitter.submission.template&.preferences&.dig('completed_message') || {}).to_json %>" data-completed-button="<%= configs[:completed_button].to_json %>" data-go-to-last="<%= submitter.preferences.key?('go_to_last') ? submitter.preferences['go_to_last'] : submitter.opened_at? %>" data-submitter="<%= submitter.to_json(only: %i[uuid slug name phone email]) %>" data-can-send-email="<%= Docuseal.multitenant? || Accounts.can_send_emails?(submitter.submission.account) %>" data-optional-invite-submitters="<%= optional_invite_submitters %>" data-invite-submitters="<%= invite_submitters %>" data-attachments="<%= data_attachments %>" data-fields="<%= data_fields %>" data-values="<%= submitter.values.to_json %>" data-with-typed-signature="<%= configs[:with_typed_signature] %>" data-signature-text="<%= params[:signature] %>" data-previous-signature-value="<%= local_assigns[:signature_attachment]&.uuid %>" data-remember-signature="<%= configs[:prefill_signature] %>" data-dry-run="<%= local_assigns[:dry_run] %>" data-view-token="<%= Submitter.signed_id_verifier.generate(submitter.slug, purpose: :view_form, expires_in: 1.minute) unless local_assigns[:dry_run] %>" data-expand="<%= local_assigns[:expand] %>" data-scroll-padding="<%= local_assigns[:scroll_padding] %>" data-language="<%= I18n.locale.to_s.split('-').first %>"></submission-form>
|
||||||
@@ -59,7 +59,7 @@
|
|||||||
<% else %>
|
<% else %>
|
||||||
<% if params[:t] %>
|
<% if params[:t] %>
|
||||||
<fetch-form data-onload="true">
|
<fetch-form data-onload="true">
|
||||||
<%= button_to '', api_submitter_email_clicks_path, params: { submitter_slug: @submitter.slug, t: params[:t] }, method: :post, class: 'hidden' %>
|
<%= button_to '', submit_form_click_email_path(@submitter.slug), params: { t: params[:t] }, method: :post, class: 'hidden' %>
|
||||||
</fetch-form>
|
</fetch-form>
|
||||||
<% end %>
|
<% end %>
|
||||||
<toggle-submit dir="auto" class="form-control">
|
<toggle-submit dir="auto" class="form-control">
|
||||||
|
|||||||
@@ -160,6 +160,9 @@ Rails.application.routes.draw do
|
|||||||
resources :delegate, only: %i[create], controller: 'submit_form_delegate'
|
resources :delegate, only: %i[create], controller: 'submit_form_delegate'
|
||||||
resources :invite, only: %i[create], controller: 'submit_form_invite'
|
resources :invite, only: %i[create], controller: 'submit_form_invite'
|
||||||
resources :metadata, only: %i[index], controller: 'submit_form_metadata'
|
resources :metadata, only: %i[index], controller: 'submit_form_metadata'
|
||||||
|
resource :click_email, only: %i[create], controller: 'submit_form_click_email'
|
||||||
|
resources :view, only: %i[create], controller: 'submit_form_view'
|
||||||
|
resources :upload, only: %i[create], controller: 'submit_form_upload'
|
||||||
resources :debug, only: %i[index], controller: 'submissions_debug' if Rails.env.development?
|
resources :debug, only: %i[index], controller: 'submissions_debug' if Rails.env.development?
|
||||||
get :completed
|
get :completed
|
||||||
get :delegated
|
get :delegated
|
||||||
|
|||||||
@@ -6,8 +6,24 @@ module Submitters
|
|||||||
|
|
||||||
module_function
|
module_function
|
||||||
|
|
||||||
def call(submitter, current_user, request)
|
def call(submitter, current_user, request, with_order: false)
|
||||||
pass_email_2fa?(submitter, request) && pass_link_2fa?(submitter, current_user, request)
|
pass_email_2fa?(submitter, request) &&
|
||||||
|
pass_link_2fa?(submitter, current_user, request) &&
|
||||||
|
(!with_order || pass_submitters_order?(submitter))
|
||||||
|
end
|
||||||
|
|
||||||
|
def pass_submitters_order?(submitter)
|
||||||
|
return false unless submitter
|
||||||
|
|
||||||
|
submission = submitter.submission
|
||||||
|
|
||||||
|
return true if submission.submitters_order_random?
|
||||||
|
return true if (submission.template_submitters || submission.template.submitters).size < 2
|
||||||
|
return true if submission.template&.preferences&.dig('submitters_order') != 'preserved' &&
|
||||||
|
!AccountConfig.exists?(account_id: submitter.account_id,
|
||||||
|
key: AccountConfig::ENFORCE_SIGNING_ORDER_KEY, value: true)
|
||||||
|
|
||||||
|
Submitters.current_submitter_order?(submitter)
|
||||||
end
|
end
|
||||||
|
|
||||||
def pass_email_2fa?(submitter, request)
|
def pass_email_2fa?(submitter, request)
|
||||||
|
|||||||
Reference in new issue
Block a user