diff --git a/app/controllers/account_configs_controller.rb b/app/controllers/account_configs_controller.rb index 3f0e6f77..d71d64a5 100644 --- a/app/controllers/account_configs_controller.rb +++ b/app/controllers/account_configs_controller.rb @@ -27,8 +27,9 @@ class AccountConfigsController < ApplicationController AccountConfig::DOCUMENT_FILENAME_FORMAT_KEY, AccountConfig::ENABLE_MCP_KEY, AccountConfig::IP_ALLOWLIST_KEY, - AccountConfig::AUTO_ARCHIVE_DAYS_KEY - AccountConfig::REQUIRE_CONSENT_KEY + AccountConfig::AUTO_ARCHIVE_DAYS_KEY, + AccountConfig::REQUIRE_CONSENT_KEY, + AccountConfig::REQUIRE_ID_VERIFICATION_KEY ].freeze InvalidKey = Class.new(StandardError) diff --git a/app/controllers/api/submitter_id_documents_controller.rb b/app/controllers/api/submitter_id_documents_controller.rb new file mode 100644 index 00000000..e17ee837 --- /dev/null +++ b/app/controllers/api/submitter_id_documents_controller.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +module Api + class SubmitterIdDocumentsController < ApiBaseController + skip_before_action :authenticate_user! + skip_authorization_check + + def create + @submitter = Submitter.find_by!(slug: params[:submitter_slug]) + + SubmissionEvents.create_with_tracking_data(@submitter, 'id_document_uploaded', request) + + render json: {} + end + end +end diff --git a/app/javascript/form.js b/app/javascript/form.js index 26b1aa50..ee4aa075 100644 --- a/app/javascript/form.js +++ b/app/javascript/form.js @@ -43,6 +43,7 @@ safeRegisterElement('submission-form', class extends HTMLElement { withFieldLabels: this.dataset.withFieldLabels !== 'false', withDisclosure: this.dataset.withDisclosure === 'true', requireConsent: this.dataset.requireConsent === 'true', + requireIdVerification: this.dataset.requireIdVerification === 'true', reuseSignature: this.dataset.reuseSignature !== 'false', withTypedSignature: this.dataset.withTypedSignature !== 'false', authenticityToken: document.querySelector('meta[name="csrf-token"]')?.content, diff --git a/app/javascript/submission_form/form.vue b/app/javascript/submission_form/form.vue index b2d4a799..050fbe01 100644 --- a/app/javascript/submission_form/form.vue +++ b/app/javascript/submission_form/form.vue @@ -99,7 +99,7 @@ type="submit" name="completed" value="true" - :disabled="isSubmittingComplete || (requireConsent && !consentAccepted)" + :disabled="isSubmittingComplete || (requireConsent && !consentAccepted) || (requireIdVerification && !idDocumentUploaded)" >
-
+
+

+ {{ t('id_verification_required') }} +

+

+ {{ t('please_upload_id_document') }} +

+ +
+
<% end %> <% end %> + <% account_config = AccountConfig.find_or_initialize_by(account: current_account, key: AccountConfig::REQUIRE_ID_VERIFICATION_KEY) %> + <% if can?(:manage, account_config) %> + <%= form_for account_config, url: account_configs_path, method: :post do |f| %> + <%= f.hidden_field :key %> +
+
+ <%= t('require_id_verification_before_signing') %> + + <%= svg_icon('info_circle', class: 'hidden md:inline-block w-4 h-4 shrink-0') %> + +
+ + <%= f.check_box :value, class: 'toggle', checked: account_config.value == true %> + +
+ <% end %> + <% end %> <% account_config = AccountConfig.find_or_initialize_by(account: current_account, key: AccountConfig::ALLOW_TYPED_SIGNATURE) %> <% if can?(:manage, account_config) %> <%= form_for account_config, url: account_configs_path, method: :post do |f| %> diff --git a/app/views/submit_form/_submission_form.html.erb b/app/views/submit_form/_submission_form.html.erb index b40ffa17..cf43d48f 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/config/locales/i18n.yml b/config/locales/i18n.yml index d9897bcc..9a0bd783 100644 --- a/config/locales/i18n.yml +++ b/config/locales/i18n.yml @@ -217,6 +217,8 @@ en: &en require_signing_reason: Require signing reason require_consent_before_signing: Require consent before signing require_signers_to_explicitly_consent_to_signing_the_document_electronically_before_they_can_submit: Require signers to explicitly consent to signing the document electronically before they can submit + require_id_verification_before_signing: Require ID verification before signing + require_signers_to_upload_a_government_issued_id_document_to_verify_their_identity_before_they_can_sign: Require signers to upload a government-issued ID document to verify their identity before they can sign allow_typed_text_signatures: Allow typed text signatures allow_to_resubmit_completed_forms: Allow to resubmit completed forms allow_to_decline_documents: Allow to decline documents @@ -1288,6 +1290,8 @@ es: &es require_signing_reason: Requerir motivo de firma require_consent_before_signing: Requerir consentimiento antes de firmar require_signers_to_explicitly_consent_to_signing_the_document_electronically_before_they_can_submit: Requerir que los firmantes consientan explícitamente firmar el documento electrónicamente antes de enviar + require_id_verification_before_signing: Requerir verificación de identidad antes de firmar + require_signers_to_upload_a_government_issued_id_document_to_verify_their_identity_before_they_can_sign: Requerir que los firmantes suban un documento de identidad oficial para verificar su identidad antes de firmar allow_typed_text_signatures: Permitir firmas de texto mecanografiadas allow_to_resubmit_completed_forms: Permitir reenviar formularios completados allow_to_decline_documents: Permitir rechazar documentos @@ -2352,6 +2356,8 @@ it: &it require_signing_reason: Richiedere il motivo della firma require_consent_before_signing: Richiedere il consenso prima della firma require_signers_to_explicitly_consent_to_signing_the_document_electronically_before_they_can_submit: Richiedere ai firmatari di acconsentire esplicitamente alla firma elettronica del documento prima dell'invio + require_id_verification_before_signing: Richiedere la verifica dell'identità prima della firma + require_signers_to_upload_a_government_issued_id_document_to_verify_their_identity_before_they_can_sign: Richiedere ai firmatari di caricare un documento d'identità ufficiale per verificare la propria identità prima di firmare allow_typed_text_signatures: Permettere firme con testo digitato allow_to_resubmit_completed_forms: Permettere di reinviare i moduli completati allow_to_decline_documents: Permettere di rifiutare i documenti @@ -3420,6 +3426,8 @@ fr: &fr require_signing_reason: Exiger un motif de signature require_consent_before_signing: Exiger le consentement avant la signature require_signers_to_explicitly_consent_to_signing_the_document_electronically_before_they_can_submit: Exiger des signataires qu'ils consentent explicitement à signer le document électroniquement avant de soumettre + require_id_verification_before_signing: Exiger la vérification d'identité avant la signature + require_signers_to_upload_a_government_issued_id_document_to_verify_their_identity_before_they_can_sign: Exiger des signataires qu'ils téléchargent une pièce d'identité officielle pour vérifier leur identité avant de signer allow_typed_text_signatures: Autoriser les signatures tapées allow_to_resubmit_completed_forms: Autoriser la nouvelle soumission des formulaires complétés allow_to_decline_documents: Autoriser le refus de documents @@ -4481,6 +4489,8 @@ pt: &pt require_signing_reason: Requerer motivo para assinatura require_consent_before_signing: Exigir consentimento antes de assinar require_signers_to_explicitly_consent_to_signing_the_document_electronically_before_they_can_submit: Exigir que os signatários consintam explicitamente em assinar o documento eletronicamente antes de enviar + require_id_verification_before_signing: Exigir verificação de identidade antes de assinar + require_signers_to_upload_a_government_issued_id_document_to_verify_their_identity_before_they_can_sign: Exigir que os signatários carreguem um documento de identidade oficial para verificar a sua identidade antes de assinar allow_typed_text_signatures: Permitir assinaturas digitadas allow_to_resubmit_completed_forms: Permitir reenviar formulários concluídos allow_to_decline_documents: Permitir recusar documentos @@ -5545,6 +5555,8 @@ de: &de require_signing_reason: Grund für die Signatur erforderlich require_consent_before_signing: Zustimmung vor dem Unterzeichnen erforderlich require_signers_to_explicitly_consent_to_signing_the_document_electronically_before_they_can_submit: Unterzeichner müssen vor dem Absenden ausdrücklich der elektronischen Unterzeichnung des Dokuments zustimmen + require_id_verification_before_signing: Identitätsprüfung vor der Unterzeichnung erforderlich + require_signers_to_upload_a_government_issued_id_document_to_verify_their_identity_before_they_can_sign: Unterzeichner müssen einen amtlichen Ausweis hochladen, um ihre Identität vor der Unterzeichnung zu bestätigen allow_typed_text_signatures: Getippte Unterschriften zulassen allow_to_resubmit_completed_forms: Erneutes Einreichen abgeschlossener Formulare zulassen allow_to_decline_documents: Ablehnen von Dokumenten erlauben @@ -6530,6 +6542,8 @@ pl: days: dni require_consent_before_signing: Wymagaj zgody przed podpisaniem require_signers_to_explicitly_consent_to_signing_the_document_electronically_before_they_can_submit: Wymagaj od podpisujących wyraźnej zgody na elektroniczne podpisanie dokumentu przed wysłaniem + require_id_verification_before_signing: Wymagaj weryfikacji tożsamości przed podpisaniem + require_signers_to_upload_a_government_issued_id_document_to_verify_their_identity_before_they_can_sign: Wymagaj od podpisujących przesłania dokumentu tożsamości w celu weryfikacji tożsamości przed podpisaniem uk: require_phone_2fa_to_open: Вимагати двофакторну автентифікацію через телефон для відкриття @@ -6641,6 +6655,8 @@ uk: days: днів require_consent_before_signing: Вимагати згоду перед підписанням require_signers_to_explicitly_consent_to_signing_the_document_electronically_before_they_can_submit: Вимагати від підписантів явної згоди на електронний підпис документа перед відправленням + require_id_verification_before_signing: Вимагати перевірку особи перед підписанням + require_signers_to_upload_a_government_issued_id_document_to_verify_their_identity_before_they_can_sign: Вимагати від підписантів завантаження посвідчення особи для підтвердження їхньої особи перед підписанням cs: require_phone_2fa_to_open: Vyžadovat otevření pomocí telefonního 2FA @@ -6752,6 +6768,8 @@ cs: days: dní require_consent_before_signing: Vyžadovat souhlas před podpisem require_signers_to_explicitly_consent_to_signing_the_document_electronically_before_they_can_submit: Vyžadovat od podepisujících výslovný souhlas s elektronickým podpisem dokumentu před odesláním + require_id_verification_before_signing: Vyžadovat ověření totožnosti před podpisem + require_signers_to_upload_a_government_issued_id_document_to_verify_their_identity_before_they_can_sign: Vyžadovat od podepisujících nahrání úředního dokladu totožnosti pro ověření identity před podpisem he: require_phone_2fa_to_open: דרוש אימות דו-שלבי באמצעות טלפון לפתיחה @@ -6863,6 +6881,8 @@ he: days: ימים require_consent_before_signing: דרוש הסכמה לפני החתימה require_signers_to_explicitly_consent_to_signing_the_document_electronically_before_they_can_submit: דרוש מהחותמים להסכים במפורש לחתום על המסמך באופן אלקטרוני לפני השליחה + require_id_verification_before_signing: דרוש אימות זהות לפני חתימה + require_signers_to_upload_a_government_issued_id_document_to_verify_their_identity_before_they_can_sign: דרוש מהחותמים להעלות תעודת זהות רשמית לאימות זהותם לפני החתימה nl: &nl knowledge_based_authentication: Kennisgebaseerde authenticatie @@ -7054,6 +7074,8 @@ nl: &nl require_signing_reason: Reden voor ondertekening verplicht stellen require_consent_before_signing: Toestemming vereist voor ondertekening require_signers_to_explicitly_consent_to_signing_the_document_electronically_before_they_can_submit: Ondertekenaars moeten expliciet toestemming geven voor het elektronisch ondertekenen van het document voordat ze kunnen indienen + require_id_verification_before_signing: Identiteitsverificatie vereist voor ondertekening + require_signers_to_upload_a_government_issued_id_document_to_verify_their_identity_before_they_can_sign: Ondertekenaars moeten een officieel identiteitsbewijs uploaden om hun identiteit te verifiëren voordat ze kunnen tekenen allow_typed_text_signatures: Handtekeningen met getypte tekst toestaan allow_to_resubmit_completed_forms: Opnieuw indienen van voltooide formulieren toestaan allow_to_decline_documents: Weigeren van documenten toestaan @@ -8035,6 +8057,8 @@ ar: days: أيام require_consent_before_signing: طلب الموافقة قبل التوقيع require_signers_to_explicitly_consent_to_signing_the_document_electronically_before_they_can_submit: يجب على الموقعين الموافقة صراحة على توقيع المستند إلكترونيًا قبل الإرسال + require_id_verification_before_signing: مطلوب التحقق من الهوية قبل التوقيع + require_signers_to_upload_a_government_issued_id_document_to_verify_their_identity_before_they_can_sign: يجب على الموقعين تحميل وثيقة هوية رسمية للتحقق من هويتهم قبل التوقيع ko: require_phone_2fa_to_open: 휴대폰 2FA를 열 때 요구함 @@ -8146,6 +8170,8 @@ ko: days: 일 require_consent_before_signing: 서명 전 동의 필요 require_signers_to_explicitly_consent_to_signing_the_document_electronically_before_they_can_submit: 서명자가 제출 전에 전자 서명에 명시적으로 동의해야 합니다 + require_id_verification_before_signing: 서명 전 신분증 확인 필요 + require_signers_to_upload_a_government_issued_id_document_to_verify_their_identity_before_they_can_sign: 서명자가 서명 전에 본인 확인을 위해 정부 발급 신분증을 업로드해야 합니다 ja: require_phone_2fa_to_open: 電話による2段階認証が必要です @@ -8257,6 +8283,8 @@ ja: days: 日 require_consent_before_signing: 署名前に同意が必要 require_signers_to_explicitly_consent_to_signing_the_document_electronically_before_they_can_submit: 署名者は送信前に電子署名に明示的に同意する必要があります + require_id_verification_before_signing: 署名前に本人確認が必要 + require_signers_to_upload_a_government_issued_id_document_to_verify_their_identity_before_they_can_sign: 署名者は署名前に本人確認のため公的身分証明書をアップロードする必要があります en-US: <<: *en diff --git a/config/routes.rb b/config/routes.rb index 4bf0381d..1726bb32 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -29,6 +29,7 @@ Rails.application.routes.draw do resources :submitter_email_clicks, only: %i[create] resources :submitter_form_views, only: %i[create] resources :submitter_consents, only: %i[create] + resources :submitter_id_documents, only: %i[create] resources :submitters, only: %i[index show update] resources :submissions, only: %i[index show create destroy] do resources :documents, only: %i[index], controller: 'submission_documents' diff --git a/lib/submitters/form_configs.rb b/lib/submitters/form_configs.rb index 48a771c5..20e4b146 100644 --- a/lib/submitters/form_configs.rb +++ b/lib/submitters/form_configs.rb @@ -19,6 +19,7 @@ module Submitters AccountConfig::WITH_TIMESTAMP_SECONDS_KEY, AccountConfig::WITH_SIGNATURE_ID_REASON_KEY, AccountConfig::REQUIRE_CONSENT_KEY, + AccountConfig::REQUIRE_ID_VERIFICATION_KEY, *(Docuseal.multitenant? ? [] : [AccountConfig::POLICY_LINKS_KEY])].freeze module_function @@ -44,13 +45,14 @@ module Submitters with_field_labels = find_safe_value(configs, AccountConfig::WITH_FIELD_LABELS_KEY) != false policy_links = find_safe_value(configs, AccountConfig::POLICY_LINKS_KEY) require_consent = find_safe_value(configs, AccountConfig::REQUIRE_CONSENT_KEY) == true + require_id_verification = find_safe_value(configs, AccountConfig::REQUIRE_ID_VERIFICATION_KEY) == true attrs = { completed_button:, with_typed_signature:, with_confetti:, reuse_signature:, with_decline:, with_delegate:, with_partial_download:, policy_links:, enforce_signing_order:, completed_message:, require_signing_reason:, prefill_signature:, with_submitter_timezone:, with_signature_id_reason:, with_signature_id:, with_field_labels:, with_timestamp_seconds:, - require_consent: } + require_consent:, require_id_verification: } keys.each do |key| attrs[key.to_sym] = configs.find { |e| e.key == key.to_s }&.value