diff --git a/Gemfile b/Gemfile index 9705eaa8..9e47f8f3 100644 --- a/Gemfile +++ b/Gemfile @@ -24,6 +24,7 @@ gem 'pg', require: false gem 'premailer-rails' gem 'puma' gem 'rails' +gem 'rails_autolink' gem 'rails-i18n' gem 'rollbar', require: ENV.key?('ROLLBAR_ACCESS_TOKEN') gem 'ruby-vips' diff --git a/Gemfile.lock b/Gemfile.lock index f892df69..66557037 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -379,6 +379,10 @@ GEM rails-i18n (7.0.7) i18n (>= 0.7, < 2) railties (>= 6.0.0, < 8) + rails_autolink (1.1.8) + actionview (> 3.1) + activesupport (> 3.1) + railties (> 3.1) railties (7.0.5) actionpack (= 7.0.5) activesupport (= 7.0.5) @@ -554,6 +558,7 @@ DEPENDENCIES puma rails rails-i18n + rails_autolink rollbar rspec-rails rubocop diff --git a/app/controllers/personalization_settings_controller.rb b/app/controllers/personalization_settings_controller.rb new file mode 100644 index 00000000..5c1b272e --- /dev/null +++ b/app/controllers/personalization_settings_controller.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +class PersonalizationSettingsController < ApplicationController + def show; end + + def create + account_config = + current_account.account_configs.find_or_initialize_by(key: encrypted_config_params[:key]) + + account_config.update!(encrypted_config_params) + + redirect_back(fallback_location: settings_personalization_path, notice: 'Settings have been saved.') + end + + private + + def encrypted_config_params + params.require(:account_config).permit! + end +end diff --git a/app/controllers/start_form_controller.rb b/app/controllers/start_form_controller.rb index 57df31ef..285e2c79 100644 --- a/app/controllers/start_form_controller.rb +++ b/app/controllers/start_form_controller.rb @@ -36,7 +36,9 @@ class StartFormController < ApplicationController end def completed - @submitter = Submitter.where(submission: @template.submissions).find_by!(email: params[:email]) + @submitter = Submitter.where(submission: @template.submissions) + .where.not(completed_at: nil) + .find_by!(email: params[:email]) end private diff --git a/app/mailers/application_mailer.rb b/app/mailers/application_mailer.rb index 08ad2233..b2995af1 100644 --- a/app/mailers/application_mailer.rb +++ b/app/mailers/application_mailer.rb @@ -6,6 +6,10 @@ class ApplicationMailer < ActionMailer::Base register_interceptor ActionMailerConfigsInterceptor + before_action do + ActiveStorage::Current.url_options = Docuseal.default_url_options + end + def default_url_options Docuseal.default_url_options end diff --git a/app/mailers/submitter_mailer.rb b/app/mailers/submitter_mailer.rb index 1c90288f..7faeb454 100644 --- a/app/mailers/submitter_mailer.rb +++ b/app/mailers/submitter_mailer.rb @@ -4,15 +4,26 @@ class SubmitterMailer < ApplicationMailer DEFAULT_MESSAGE = %(You have been invited to submit the "%s" form:) def invitation_email(submitter, message: '') + @current_account = submitter.submission.template.account @submitter = submitter @message = message.presence || format(DEFAULT_MESSAGE, name: submitter.submission.template.name) + @email_config = @current_account.account_configs.find_by(key: AccountConfig::SUBMITTER_INVITATION_EMAIL_KEY) + + subject = + if @email_config + ReplaceEmailVariables.call(@email_config.value['subject'], submitter:) + else + 'You have been invited to submit a form' + end + mail(to: @submitter.email, - subject: 'You have been invited to submit a form', + subject:, reply_to: submitter.submission.created_by_user&.friendly_name) end def completed_email(submitter, user) + @current_account = submitter.submission.template.account @submitter = submitter @user = user @@ -21,6 +32,7 @@ class SubmitterMailer < ApplicationMailer end def documents_copy_email(submitter) + @current_account = submitter.submission.template.account @submitter = submitter Submissions::EnsureResultGenerated.call(@submitter) diff --git a/app/mailers/user_mailer.rb b/app/mailers/user_mailer.rb index 97c57075..276928ad 100644 --- a/app/mailers/user_mailer.rb +++ b/app/mailers/user_mailer.rb @@ -2,6 +2,7 @@ class UserMailer < ApplicationMailer def invitation_email(user) + @current_account = user.account @user = user @token = @user.send(:set_reset_password_token) diff --git a/app/models/account.rb b/app/models/account.rb index 96a1d9f3..d06f1421 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -14,6 +14,7 @@ class Account < ApplicationRecord has_many :users, dependent: :destroy has_many :encrypted_configs, dependent: :destroy + has_many :account_configs, dependent: :destroy has_many :templates, dependent: :destroy has_many :submissions, through: :templates has_many :submitters, through: :submissions diff --git a/app/models/account_config.rb b/app/models/account_config.rb new file mode 100644 index 00000000..44e5fa32 --- /dev/null +++ b/app/models/account_config.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +# == Schema Information +# +# Table name: account_configs +# +# id :bigint not null, primary key +# key :string not null +# value :text not null +# created_at :datetime not null +# updated_at :datetime not null +# account_id :bigint not null +# +# Indexes +# +# index_account_configs_on_account_id (account_id) +# index_account_configs_on_account_id_and_key (account_id,key) UNIQUE +# +# Foreign Keys +# +# fk_rails_... (account_id => accounts.id) +# +class AccountConfig < ApplicationRecord + SUBMITTER_INVITATION_EMAIL_KEY = 'submitter_invitation_email' + + DEFAULT_VALUES = { + SUBMITTER_INVITATION_EMAIL_KEY => { + 'subject' => 'You have been invited to submit a form', + 'body' => "Hi there,\n\n" \ + "You have been invited to submit the \"{{template.name}}\" form:\n\n" \ + "{{submitter.link}}\n\n" \ + "Please contact us by replying to this email if you didn't request this.\n\n" \ + "Thanks,\n" \ + '{{account.name}}' + } + }.freeze + + belongs_to :account + + serialize :value, JSON +end diff --git a/app/views/layouts/mailer.html.erb b/app/views/layouts/mailer.html.erb index 015c1959..f8f91468 100644 --- a/app/views/layouts/mailer.html.erb +++ b/app/views/layouts/mailer.html.erb @@ -8,11 +8,6 @@ <%= yield %> -

- --- -

-

- Sent using <%= Docuseal::PRODUCT_NAME %> free document signing. -

+ <%= render partial: 'shared/mailer_attribution' %> diff --git a/app/views/personalization_settings/_logo_form.html.erb b/app/views/personalization_settings/_logo_form.html.erb new file mode 100644 index 00000000..fc6f3ac7 --- /dev/null +++ b/app/views/personalization_settings/_logo_form.html.erb @@ -0,0 +1 @@ +<%= render 'logo_placeholder' %> diff --git a/app/views/personalization_settings/_logo_placeholder.html.erb b/app/views/personalization_settings/_logo_placeholder.html.erb new file mode 100644 index 00000000..1ba3b631 --- /dev/null +++ b/app/views/personalization_settings/_logo_placeholder.html.erb @@ -0,0 +1,11 @@ +
+ <%= svg_icon('info_circle', class: 'w-6 h-6') %> +
+

Unlock with DocuSeal Enterprise

+

+ Display your company name and logo when signing documents. +
+ Learn More +

+
+
diff --git a/app/views/personalization_settings/show.html.erb b/app/views/personalization_settings/show.html.erb new file mode 100644 index 00000000..bfb51a41 --- /dev/null +++ b/app/views/personalization_settings/show.html.erb @@ -0,0 +1,27 @@ +
+ <%= render 'shared/settings_nav' %> +
+

Signature Request Email

+ <%= form_for AccountConfigs.find_or_initialize_for_key(current_account, AccountConfig::SUBMITTER_INVITATION_EMAIL_KEY), url: settings_personalization_path, method: :post, html: { autocomplete: 'off', class: 'space-y-4' } do |f| %> + <%= f.hidden_field :key %> + <%= f.fields_for :value, OpenStruct.new(f.object.value) do |ff| %> +
+ <%= ff.label :subject, class: 'label' %> + <%= ff.text_field :subject, required: true, class: 'base-input' %> +
+
+ <%= ff.label :body, class: 'label' %> + + <%= ff.text_area :body, required: true, class: 'base-input w-full py-2' %> + +
+ <% end %> +
+ <%= f.button button_title(title: 'Save', disabled_with: 'Saving'), class: 'base-button' %> +
+ <% end %> +

Company Logo

+ <%= render 'logo_form' %> +
+
+
diff --git a/app/views/send_submission_email/success.html.erb b/app/views/send_submission_email/success.html.erb index 24b7e3fe..ac5c10b1 100644 --- a/app/views/send_submission_email/success.html.erb +++ b/app/views/send_submission_email/success.html.erb @@ -2,12 +2,7 @@
Email has been sent diff --git a/app/views/shared/_email_attribution.html.erb b/app/views/shared/_email_attribution.html.erb new file mode 100644 index 00000000..76bd890d --- /dev/null +++ b/app/views/shared/_email_attribution.html.erb @@ -0,0 +1,6 @@ +

+ --- +

+

+ Sent using <%= Docuseal::PRODUCT_NAME %> free document signing. +

diff --git a/app/views/shared/_mailer_attribution.html.erb b/app/views/shared/_mailer_attribution.html.erb new file mode 100644 index 00000000..b9fa9276 --- /dev/null +++ b/app/views/shared/_mailer_attribution.html.erb @@ -0,0 +1 @@ +<%= render 'shared/email_attribution' %> diff --git a/app/views/shared/_settings_nav.html.erb b/app/views/shared/_settings_nav.html.erb index 62279b7b..5423831a 100644 --- a/app/views/shared/_settings_nav.html.erb +++ b/app/views/shared/_settings_nav.html.erb @@ -31,6 +31,9 @@ <%= link_to 'Webhooks', settings_webhooks_path, class: 'text-base hover:bg-base-300' %> <% end %> +
  • + <%= link_to 'Personalization', settings_personalization_path, class: 'text-base hover:bg-base-300' %> +
  • <% unless Docuseal.demo? %>
  • <%= link_to Docuseal.multitenant? ? console_redirect_index_path : Docuseal::CONSOLE_URL, class: 'text-base hover:bg-base-300', data: { prefetch: false } do %> diff --git a/app/views/start_form/_banner.html.erb b/app/views/start_form/_banner.html.erb new file mode 100644 index 00000000..6b843a19 --- /dev/null +++ b/app/views/start_form/_banner.html.erb @@ -0,0 +1 @@ +<%= render 'docuseal_logo' %> diff --git a/app/views/start_form/_docuseal_logo.html.erb b/app/views/start_form/_docuseal_logo.html.erb new file mode 100644 index 00000000..735c607c --- /dev/null +++ b/app/views/start_form/_docuseal_logo.html.erb @@ -0,0 +1,6 @@ + + + <%= render 'shared/logo', width: '50px', height: '50px' %> + +

    DocuSeal

    +
    diff --git a/app/views/start_form/completed.html.erb b/app/views/start_form/completed.html.erb index 758442aa..376e377b 100644 --- a/app/views/start_form/completed.html.erb +++ b/app/views/start_form/completed.html.erb @@ -2,12 +2,7 @@
    diff --git a/app/views/start_form/show.html.erb b/app/views/start_form/show.html.erb index f3779baa..8e98de71 100644 --- a/app/views/start_form/show.html.erb +++ b/app/views/start_form/show.html.erb @@ -2,12 +2,7 @@
    - - - <%= render 'shared/logo', width: '50px', height: '50px' %> - -

    DocuSeal

    -
    + <%= render 'banner' %>

    You have been invited to submit a form

    diff --git a/app/views/submissions/new.html.erb b/app/views/submissions/new.html.erb index 41bdafa4..e6d964da 100644 --- a/app/views/submissions/new.html.erb +++ b/app/views/submissions/new.html.erb @@ -40,7 +40,7 @@
    <% is_smtp_configured = Accounts.can_send_emails?(current_account) %> <%= f.label :send_email, class: 'flex items-center cursor-pointer' do %> - <%= f.check_box :send_email, class: 'base-checkbox', disabled: !is_smtp_configured, onchange: "message_field.classList.toggle('hidden', !event.currentTarget.checked)" %> + <%= f.check_box :send_email, class: 'base-checkbox', disabled: !is_smtp_configured, onchange: "window.message_field && message_field.classList.toggle('hidden', !event.currentTarget.checked)" %> Send Email <% end %> <% unless is_smtp_configured %> @@ -57,21 +57,23 @@
    <% end %>
    -