allow to disable text signature via account prefs
This commit is contained in:
@@ -0,0 +1,32 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class AccountConfigsController < ApplicationController
|
||||||
|
before_action :load_account_config
|
||||||
|
authorize_resource :account_config
|
||||||
|
|
||||||
|
ALLOWED_KEYS = [
|
||||||
|
AccountConfig::ALLOW_TYPED_SIGNATURE,
|
||||||
|
AccountConfig::FORCE_MFA
|
||||||
|
].freeze
|
||||||
|
|
||||||
|
def create
|
||||||
|
@account_config.update!(account_config_params)
|
||||||
|
|
||||||
|
head :ok
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def load_account_config
|
||||||
|
return head :not_found unless ALLOWED_KEYS.include?(account_config_params[:key])
|
||||||
|
|
||||||
|
@account_config =
|
||||||
|
AccountConfig.find_or_initialize_by(account: current_account, key: account_config_params[:key])
|
||||||
|
end
|
||||||
|
|
||||||
|
def account_config_params
|
||||||
|
params.required(:account_config).permit!.tap do |attrs|
|
||||||
|
attrs[:value] = attrs[:value] == '1' if attrs[:value].in?(%w[1 0])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class MfaForceController < ApplicationController
|
|
||||||
before_action :load_account_config
|
|
||||||
authorize_resource :account_config
|
|
||||||
|
|
||||||
def create
|
|
||||||
@account_config.update!(value: !@account_config.value)
|
|
||||||
|
|
||||||
redirect_back fallback_location: settings_users_path,
|
|
||||||
notice: "Force 2FA has been #{@account_config.value ? 'enabled' : 'disabled'}."
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def load_account_config
|
|
||||||
@account_config =
|
|
||||||
AccountConfig.find_or_initialize_by(account: current_account, key: AccountConfig::FORCE_MFA)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -17,6 +17,7 @@ window.customElements.define('submission-form', class extends HTMLElement {
|
|||||||
isDemo: this.dataset.isDemo === 'true',
|
isDemo: this.dataset.isDemo === 'true',
|
||||||
attribution: this.dataset.attribution !== 'false',
|
attribution: this.dataset.attribution !== 'false',
|
||||||
withConfetti: true,
|
withConfetti: true,
|
||||||
|
withTypedSignature: this.dataset.withTypedSignature !== 'false',
|
||||||
values: reactive(JSON.parse(this.dataset.values)),
|
values: reactive(JSON.parse(this.dataset.values)),
|
||||||
completedButton: JSON.parse(this.dataset.completedButton),
|
completedButton: JSON.parse(this.dataset.completedButton),
|
||||||
attachments: reactive(JSON.parse(this.dataset.attachments)),
|
attachments: reactive(JSON.parse(this.dataset.attachments)),
|
||||||
|
|||||||
@@ -223,6 +223,7 @@
|
|||||||
:field="currentField"
|
:field="currentField"
|
||||||
:previous-value="previousSignatureValue"
|
:previous-value="previousSignatureValue"
|
||||||
:is-direct-upload="isDirectUpload"
|
:is-direct-upload="isDirectUpload"
|
||||||
|
:with-typed-signature="withTypedSignature"
|
||||||
:attachments-index="attachmentsIndex"
|
:attachments-index="attachmentsIndex"
|
||||||
:submitter-slug="submitterSlug"
|
:submitter-slug="submitterSlug"
|
||||||
@attached="attachments.push($event)"
|
@attached="attachments.push($event)"
|
||||||
@@ -386,6 +387,11 @@ export default {
|
|||||||
required: false,
|
required: false,
|
||||||
default: false
|
default: false
|
||||||
},
|
},
|
||||||
|
withTypedSignature: {
|
||||||
|
type: Boolean,
|
||||||
|
required: false,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
baseUrl: {
|
baseUrl: {
|
||||||
type: String,
|
type: String,
|
||||||
required: false,
|
required: false,
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
</a>
|
</a>
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
v-else
|
v-else-if="withTypedSignature"
|
||||||
class="tooltip"
|
class="tooltip"
|
||||||
:data-tip="t('type_text')"
|
:data-tip="t('type_text')"
|
||||||
>
|
>
|
||||||
@@ -149,6 +149,11 @@ export default {
|
|||||||
required: true,
|
required: true,
|
||||||
default: false
|
default: false
|
||||||
},
|
},
|
||||||
|
withTypedSignature: {
|
||||||
|
type: Boolean,
|
||||||
|
required: false,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
attachmentsIndex: {
|
attachmentsIndex: {
|
||||||
type: Object,
|
type: Object,
|
||||||
required: false,
|
required: false,
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ class AccountConfig < ApplicationRecord
|
|||||||
SUBMITTER_DOCUMENTS_COPY_EMAIL_KEY = 'submitter_documents_copy_email'
|
SUBMITTER_DOCUMENTS_COPY_EMAIL_KEY = 'submitter_documents_copy_email'
|
||||||
BCC_EMAILS = 'bcc_emails'
|
BCC_EMAILS = 'bcc_emails'
|
||||||
FORCE_MFA = 'force_mfa'
|
FORCE_MFA = 'force_mfa'
|
||||||
|
ALLOW_TYPED_SIGNATURE = 'allow_typed_signature'
|
||||||
SUBMITTER_REMAILERS = 'submitter_reminders'
|
SUBMITTER_REMAILERS = 'submitter_reminders'
|
||||||
FORM_COMPLETED_BUTTON_KEY = 'form_completed_button'
|
FORM_COMPLETED_BUTTON_KEY = 'form_completed_button'
|
||||||
|
|
||||||
|
|||||||
@@ -36,6 +36,35 @@
|
|||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
<% if can?(:manage, AccountConfig) %>
|
||||||
|
<div class="px-1 mt-8">
|
||||||
|
<h2 class="text-2xl font-bold mb-2">Preferences</h2>
|
||||||
|
<% account_config = AccountConfig.find_or_initialize_by(account: current_account, key: AccountConfig::FORCE_MFA) %>
|
||||||
|
<% if can?(:manage, account_config) %>
|
||||||
|
<%= form_for account_config, url: account_configs_path, method: :post do |f| %>
|
||||||
|
<%= f.hidden_field :key %>
|
||||||
|
<div class="flex items-center justify-between py-2.5">
|
||||||
|
<span>
|
||||||
|
Force 2FA with Authenticator App
|
||||||
|
</span>
|
||||||
|
<%= f.check_box :value, class: 'toggle', checked: account_config.value, onchange: 'this.form.requestSubmit()' %>
|
||||||
|
</div>
|
||||||
|
<% 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| %>
|
||||||
|
<%= f.hidden_field :key %>
|
||||||
|
<div class="flex items-center justify-between py-2.5">
|
||||||
|
<span>
|
||||||
|
Allow typed text signatures
|
||||||
|
</span>
|
||||||
|
<%= f.check_box :value, class: 'toggle', checked: account_config.value != false, onchange: 'this.form.requestSubmit()' %>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
<div class="w-0 md:w-52"></div>
|
<div class="w-0 md:w-52"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<%= form_for '', url: mfa_setup_path, data: { turbo_frame: :_top }, html: { id: 'mfa_form'} do |f| %>
|
<%= form_for '', url: mfa_setup_path, data: { turbo_frame: :_top }, html: { id: 'mfa_form' } do |f| %>
|
||||||
<p class="text-center">
|
<p class="text-center">
|
||||||
Use an authenticator mobile app like Google Authenticator or 1Password to scan the QR code below.
|
Use an authenticator mobile app like Google Authenticator or 1Password to scan the QR code below.
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<% data_attachments = attachments_index.values.select { |e| e.record_id == submitter.id }.to_json(only: %i[uuid], methods: %i[url filename content_type]) %>
|
<% data_attachments = attachments_index.values.select { |e| e.record_id == submitter.id }.to_json(only: %i[uuid], methods: %i[url filename content_type]) %>
|
||||||
<% data_fields = (submitter.submission.template_fields || submitter.submission.template.fields).select { |f| f['submitter_uuid'] == submitter.uuid }.to_json %>
|
<% data_fields = (submitter.submission.template_fields || submitter.submission.template.fields).select { |f| f['submitter_uuid'] == submitter.uuid }.to_json %>
|
||||||
<% completed_button_params = submitter.submission.template.account.account_configs.find_by(key: AccountConfig::FORM_COMPLETED_BUTTON_KEY)&.value || {} %>
|
<% configs = Submitters::FormConfigs.call(submitter) %>
|
||||||
<submission-form data-is-demo="<%= Docuseal.demo? %>" data-completed-button="<%= completed_button_params.to_json %>" data-go-to-last="<%= submitter.opened_at? %>" data-is-direct-upload="<%= Docuseal.active_storage_public? %>" data-submitter="<%= submitter.to_json(only: %i[uuid slug name phone email]) %>" data-can-send-email="<%= Accounts.can_send_emails?(Struct.new(:id).new(@submitter.submission.template.account_id)) %>" data-attachments="<%= data_attachments %>" data-fields="<%= data_fields %>" data-authenticity-token="<%= form_authenticity_token %>" data-values="<%= submitter.values.to_json %>"></submission-form>
|
<submission-form data-is-demo="<%= Docuseal.demo? %>" data-completed-button="<%= configs[:completed_button].to_json %>" data-go-to-last="<%= submitter.opened_at? %>" data-is-direct-upload="<%= Docuseal.active_storage_public? %>" data-submitter="<%= submitter.to_json(only: %i[uuid slug name phone email]) %>" data-can-send-email="<%= Accounts.can_send_emails?(Struct.new(:id).new(@submitter.submission.template.account_id)) %>" data-attachments="<%= data_attachments %>" data-fields="<%= data_fields %>" data-authenticity-token="<%= form_authenticity_token %>" data-values="<%= submitter.values.to_json %>" data-with-typed-signature="<%= configs[:with_typed_signature] %>"></submission-form>
|
||||||
|
|||||||
@@ -4,19 +4,6 @@
|
|||||||
<div class="flex justify-between mb-4">
|
<div class="flex justify-between mb-4">
|
||||||
<h1 class="text-4xl font-bold">Team</h1>
|
<h1 class="text-4xl font-bold">Team</h1>
|
||||||
<div class="flex items-center space-x-4">
|
<div class="flex items-center space-x-4">
|
||||||
<% if !Docuseal.multitenant? %>
|
|
||||||
<% account_config = AccountConfig.find_or_initialize_by(account: current_account, key: AccountConfig::FORCE_MFA) %>
|
|
||||||
<% if can?(:manage, account_config) %>
|
|
||||||
<%= form_for :force_mfa, url: mfa_force_path do |f| %>
|
|
||||||
<label for="force_mfa_value" class="flex items-center justify-between space-x-2 border py-2.5 px-3 rounded-md">
|
|
||||||
<span>
|
|
||||||
Force 2FA
|
|
||||||
</span>
|
|
||||||
<%= f.check_box :value, class: 'toggle', checked: account_config.value, onchange: 'this.form.requestSubmit()' %>
|
|
||||||
</label>
|
|
||||||
<% end %>
|
|
||||||
<% end %>
|
|
||||||
<% end %>
|
|
||||||
<% if can?(:create, User.new(account: current_account)) %>
|
<% if can?(:create, User.new(account: current_account)) %>
|
||||||
<%= link_to new_user_path, class: 'btn btn-primary btn-md gap-2', data: { turbo_frame: 'modal' } do %>
|
<%= link_to new_user_path, class: 'btn btn-primary btn-md gap-2', data: { turbo_frame: 'modal' } do %>
|
||||||
<%= svg_icon('plus', class: 'w-6 h-6') %>
|
<%= svg_icon('plus', class: 'w-6 h-6') %>
|
||||||
|
|||||||
+1
-1
@@ -49,7 +49,7 @@ Rails.application.routes.draw do
|
|||||||
|
|
||||||
resources :verify_pdf_signature, only: %i[create]
|
resources :verify_pdf_signature, only: %i[create]
|
||||||
resource :mfa_setup, only: %i[show new edit create destroy], controller: 'mfa_setup'
|
resource :mfa_setup, only: %i[show new edit create destroy], controller: 'mfa_setup'
|
||||||
resource :mfa_force, only: %i[create], controller: 'mfa_force'
|
resources :account_configs, only: %i[create]
|
||||||
resources :dashboard, only: %i[index]
|
resources :dashboard, only: %i[index]
|
||||||
resources :setup, only: %i[index create]
|
resources :setup, only: %i[index create]
|
||||||
resource :newsletter, only: %i[show update]
|
resource :newsletter, only: %i[show update]
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module Submitters
|
||||||
|
module FormConfigs
|
||||||
|
module_function
|
||||||
|
|
||||||
|
def call(submitter)
|
||||||
|
configs = submitter.submission.template.account.account_configs
|
||||||
|
.where(key: [AccountConfig::FORM_COMPLETED_BUTTON_KEY,
|
||||||
|
AccountConfig::ALLOW_TYPED_SIGNATURE])
|
||||||
|
|
||||||
|
completed_button = configs.find { |e| e.key == AccountConfig::FORM_COMPLETED_BUTTON_KEY }&.value || {}
|
||||||
|
|
||||||
|
with_typed_signature = configs.find { |e| e.key == AccountConfig::ALLOW_TYPED_SIGNATURE }&.value != false
|
||||||
|
|
||||||
|
{ completed_button:, with_typed_signature: }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
Reference in New Issue
Block a user