diff --git a/app/javascript/form.js b/app/javascript/form.js
index 00ec8743..f8561dc0 100644
--- a/app/javascript/form.js
+++ b/app/javascript/form.js
@@ -31,6 +31,7 @@ safeRegisterElement('submission-form', class extends HTMLElement {
isDemo: this.dataset.isDemo === 'true',
attribution: this.dataset.attribution !== 'false',
scrollPadding: this.dataset.scrollPadding || '-80px',
+ signatureText: this.dataset.signatureText,
language: this.dataset.language,
dryRun: this.dataset.dryRun === 'true',
expand: ['true', 'false'].includes(this.dataset.expand) ? this.dataset.expand === 'true' : null,
diff --git a/app/javascript/submission_form/form.vue b/app/javascript/submission_form/form.vue
index e2bdcf42..0f469459 100644
--- a/app/javascript/submission_form/form.vue
+++ b/app/javascript/submission_form/form.vue
@@ -402,6 +402,8 @@
:remember-signature="rememberSignature"
:attachments-index="attachmentsIndex"
:require-signing-reason="requireSigningReason"
+ :signature-text="signatureText"
+ :signature-src="signatureSrc"
:button-text="submitButtonText"
:dry-run="dryRun"
:with-disclosure="withDisclosure"
@@ -832,6 +834,16 @@ export default {
required: false,
default: ''
},
+ signatureText: {
+ type: String,
+ required: false,
+ default: ''
+ },
+ signatureSrc: {
+ type: String,
+ required: false,
+ default: ''
+ },
previousSignatureValue: {
type: String,
required: false,
diff --git a/app/javascript/submission_form/signature_step.vue b/app/javascript/submission_form/signature_step.vue
index 2651f8d5..fb59ef3b 100644
--- a/app/javascript/submission_form/signature_step.vue
+++ b/app/javascript/submission_form/signature_step.vue
@@ -408,6 +408,16 @@ export default {
required: false,
default: ''
},
+ signatureText: {
+ type: String,
+ required: false,
+ default: ''
+ },
+ signatureSrc: {
+ type: String,
+ required: false,
+ default: ''
+ },
modelValue: {
type: String,
required: false,
@@ -422,7 +432,7 @@ export default {
isOtherReason: false,
isUsePreviousValue: true,
isTouchAttachment: false,
- isTextSignature: this.field.preferences?.format === 'typed' || this.field.preferences?.format === 'typed_or_upload',
+ isTextSignature: !this.signatureSrc && (!!this.signatureText || this.field.preferences?.format === 'typed' || this.field.preferences?.format === 'typed_or_upload'),
uploadImageInputKey: Math.random().toString()
}
},
@@ -482,7 +492,9 @@ export default {
if (entry.isIntersecting) {
this.setCanvasSize()
- if (this.isTextSignature) {
+ if (this.signatureSrc) {
+ this.$nextTick(() => this.drawSignatureSrc())
+ } else if (this.isTextSignature) {
this.$nextTick(() => {
if (this.$refs.textInput) {
this.initTypedSignature()
@@ -686,7 +698,9 @@ export default {
}
},
async initTypedSignature () {
- if (this.submitter.name) {
+ if (this.signatureText) {
+ this.$refs.textInput.value = this.signatureText
+ } else if (this.submitter.name) {
this.$refs.textInput.value = this.submitter.name
}
@@ -696,6 +710,48 @@ export default {
this.updateWrittenSignature({ target: this.$refs.textInput })
}
},
+ drawSignatureSrc () {
+ const canvas = this.$refs.canvas
+
+ if (!canvas) return
+
+ const img = new Image()
+
+ img.crossOrigin = 'anonymous'
+
+ img.onload = () => {
+ const context = canvas.getContext('2d')
+
+ const aspectRatio = img.width / img.height
+ const canvasWidth = canvas.width / scale
+ const canvasHeight = canvas.height / scale
+
+ let targetWidth = canvasWidth
+ let targetHeight = canvasHeight
+
+ if (canvasWidth / canvasHeight > aspectRatio) {
+ targetWidth = canvasHeight * aspectRatio
+ } else {
+ targetHeight = canvasWidth / aspectRatio
+ }
+
+ const x = (canvasWidth - targetWidth) / 2
+ const y = (canvasHeight - targetHeight) / 2
+
+ context.clearRect(0, 0, canvasWidth, canvasHeight)
+ context.drawImage(img, x, y, targetWidth, targetHeight)
+
+ this.isSignatureStarted = true
+
+ this.$emit('start')
+ }
+
+ img.onerror = () => {
+ console.error(`Failed to load signature image from ${this.signatureSrc}. The remote server must send an Access-Control-Allow-Origin header to allow CORS access.`)
+ }
+
+ img.src = this.signatureSrc
+ },
drawImage (event) {
this.remove()
this.clear()
diff --git a/app/views/submit_form/_submission_form.html.erb b/app/views/submit_form/_submission_form.html.erb
index 0c13d8c7..b56123ff 100644
--- a/app/views/submit_form/_submission_form.html.erb
+++ b/app/views/submit_form/_submission_form.html.erb
@@ -2,4 +2,4 @@
<% 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 %>
<% 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 %>
-
+
diff --git a/lib/submitters/maybe_assign_default_browser_signature.rb b/lib/submitters/maybe_assign_default_browser_signature.rb
index 50ad4a57..6a77b1e8 100644
--- a/lib/submitters/maybe_assign_default_browser_signature.rb
+++ b/lib/submitters/maybe_assign_default_browser_signature.rb
@@ -9,29 +9,13 @@ module Submitters
def call(submitter, params, cookies = nil, attachments = [])
attachments = attachments.select { |e| e.record_id == submitter.id && e.record_type == 'Submitter' }
- if (value = params[:signature_src].presence || params[:signature].presence)
- find_or_create_signature_from_value(submitter, value, attachments)
- elsif params[:signed_signature_uuids].present?
+ if params[:signed_signature_uuids].present?
find_storage_signature(submitter, params[:signed_signature_uuids], attachments)
elsif cookies
find_session_signature(submitter, cookies, attachments)
end
end
- def find_or_create_signature_from_value(submitter, value, attachments)
- _, attachment = Submitters::NormalizeValues.normalize_attachment_value(value,
- { 'type' => 'signature' },
- submitter.account,
- attachments,
- for_submitter: submitter)
-
- attachment.record ||= submitter
-
- attachment.save!
-
- attachment
- end
-
def sign_signature_uuid(uuid)
ApplicationRecord.signed_id_verifier.generate(uuid, purpose: SIGNED_UUID_PURPPOSE)
end