add Dockerfile and configure production app

pull/105/head
Alex Turchyn 2 years ago
parent 8bb6ff7ab3
commit 8a6430f117

@ -0,0 +1,29 @@
/db/*.sqlite3
/node_modules
/coverage
/doc
/.git
/.github
/.bundle
/.yardoc
/log/*
/tmp/*
!/log/.keep
!/tmp/.keep
/tmp/pids/*
!/tmp/pids/.keep
/storage/*
!/storage/.keep
.byebug_history
/config/master.key
/public/packs-test
LICENSE
/attachments
/docuseal
.DS_Store

3
.gitignore vendored

@ -33,4 +33,5 @@ yarn-debug.log*
.DS_Store
/coverage
/docuseal-attachments
/attachments
/docuseal

@ -0,0 +1,50 @@
FROM ruby:3.2.2-alpine as webpack
ENV RAILS_ENV=production
ENV NODE_ENV=production
WORKDIR /app
RUN apk add --no-cache nodejs yarn git build-base && \
gem install shakapacker
COPY ./package.json ./yarn.lock ./
RUN yarn install --network-timeout 1000000
COPY ./bin/shakapacker ./bin/shakapacker
COPY ./config/webpack ./config/webpack
COPY ./config/shakapacker.yml ./config/shakapacker.yml
COPY ./postcss.config.js ./postcss.config.js ./
COPY ./tailwind.config.js ./tailwind.config.js ./
COPY ./tailwind.form.config.js ./tailwind.form.config.js ./
COPY ./tailwind.application.config.js ./tailwind.application.config.js ./
COPY ./app/javascript ./app/javascript
COPY ./app/views ./app/views
RUN echo "gem 'shakapacker'" > Gemfile && ./bin/shakapacker
FROM ruby:3.2.2-alpine as app
ENV RAILS_ENV=production
ENV BUNDLE_WITHOUT="development:test"
WORKDIR /app
RUN apk add --no-cache build-base sqlite-dev libpq-dev vips-dev vips-poppler vips-heif libc6-compat ttf-freefont
COPY ./Gemfile ./Gemfile.lock ./
RUN bundle update --bundler && bundle install && rm -rf ~/.bundle
COPY . ./
COPY --from=webpack /app/public/packs ./public/packs
RUN bundle exec bootsnap precompile --gemfile app/ lib/
WORKDIR /data/docuseal
ENV WORKDIR=/data/docuseal
EXPOSE 3000
CMD ["/app/bin/rails", "server"]

@ -9,8 +9,8 @@ gem 'aws-sdk-s3'
gem 'azure-storage-blob'
gem 'bootsnap', require: false
gem 'devise'
gem 'dotenv', require: false
gem 'faraday'
gem 'geoip'
gem 'google-cloud-storage'
gem 'hexapdf'
gem 'image_processing'

@ -1,67 +1,67 @@
GEM
remote: https://rubygems.org/
specs:
actioncable (7.0.4.3)
actionpack (= 7.0.4.3)
activesupport (= 7.0.4.3)
actioncable (7.0.5)
actionpack (= 7.0.5)
activesupport (= 7.0.5)
nio4r (~> 2.0)
websocket-driver (>= 0.6.1)
actionmailbox (7.0.4.3)
actionpack (= 7.0.4.3)
activejob (= 7.0.4.3)
activerecord (= 7.0.4.3)
activestorage (= 7.0.4.3)
activesupport (= 7.0.4.3)
actionmailbox (7.0.5)
actionpack (= 7.0.5)
activejob (= 7.0.5)
activerecord (= 7.0.5)
activestorage (= 7.0.5)
activesupport (= 7.0.5)
mail (>= 2.7.1)
net-imap
net-pop
net-smtp
actionmailer (7.0.4.3)
actionpack (= 7.0.4.3)
actionview (= 7.0.4.3)
activejob (= 7.0.4.3)
activesupport (= 7.0.4.3)
actionmailer (7.0.5)
actionpack (= 7.0.5)
actionview (= 7.0.5)
activejob (= 7.0.5)
activesupport (= 7.0.5)
mail (~> 2.5, >= 2.5.4)
net-imap
net-pop
net-smtp
rails-dom-testing (~> 2.0)
actionpack (7.0.4.3)
actionview (= 7.0.4.3)
activesupport (= 7.0.4.3)
rack (~> 2.0, >= 2.2.0)
actionpack (7.0.5)
actionview (= 7.0.5)
activesupport (= 7.0.5)
rack (~> 2.0, >= 2.2.4)
rack-test (>= 0.6.3)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.2.0)
actiontext (7.0.4.3)
actionpack (= 7.0.4.3)
activerecord (= 7.0.4.3)
activestorage (= 7.0.4.3)
activesupport (= 7.0.4.3)
actiontext (7.0.5)
actionpack (= 7.0.5)
activerecord (= 7.0.5)
activestorage (= 7.0.5)
activesupport (= 7.0.5)
globalid (>= 0.6.0)
nokogiri (>= 1.8.5)
actionview (7.0.4.3)
activesupport (= 7.0.4.3)
actionview (7.0.5)
activesupport (= 7.0.5)
builder (~> 3.1)
erubi (~> 1.4)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.1, >= 1.2.0)
activejob (7.0.4.3)
activesupport (= 7.0.4.3)
activejob (7.0.5)
activesupport (= 7.0.5)
globalid (>= 0.3.6)
activemodel (7.0.4.3)
activesupport (= 7.0.4.3)
activerecord (7.0.4.3)
activemodel (= 7.0.4.3)
activesupport (= 7.0.4.3)
activestorage (7.0.4.3)
actionpack (= 7.0.4.3)
activejob (= 7.0.4.3)
activerecord (= 7.0.4.3)
activesupport (= 7.0.4.3)
activemodel (7.0.5)
activesupport (= 7.0.5)
activerecord (7.0.5)
activemodel (= 7.0.5)
activesupport (= 7.0.5)
activestorage (7.0.5)
actionpack (= 7.0.5)
activejob (= 7.0.5)
activerecord (= 7.0.5)
activesupport (= 7.0.5)
marcel (~> 1.0)
mini_mime (>= 1.1.0)
activesupport (7.0.4.3)
activesupport (7.0.5)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 1.6, < 2)
minitest (>= 5.1)
@ -76,17 +76,17 @@ GEM
activerecord (>= 5.0, < 7.1)
request_store (~> 1.2)
aws-eventstream (1.2.0)
aws-partitions (1.765.0)
aws-sdk-core (3.172.0)
aws-partitions (1.781.0)
aws-sdk-core (3.175.0)
aws-eventstream (~> 1, >= 1.0.2)
aws-partitions (~> 1, >= 1.651.0)
aws-sigv4 (~> 1.5)
jmespath (~> 1, >= 1.6.1)
aws-sdk-kms (1.64.0)
aws-sdk-core (~> 3, >= 3.165.0)
aws-sdk-kms (1.67.0)
aws-sdk-core (~> 3, >= 3.174.0)
aws-sigv4 (~> 1.1)
aws-sdk-s3 (1.122.0)
aws-sdk-core (~> 3, >= 3.165.0)
aws-sdk-s3 (1.126.0)
aws-sdk-core (~> 3, >= 3.174.0)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.4)
aws-sigv4 (1.5.2)
@ -99,7 +99,7 @@ GEM
faraday_middleware (~> 1.0, >= 1.0.0.rc1)
net-http-persistent (~> 4.0)
nokogiri (~> 1, >= 1.10.8)
bcrypt (3.1.18)
bcrypt (3.1.19)
better_html (2.0.1)
actionview (>= 6.0)
activesupport (>= 6.0)
@ -108,13 +108,13 @@ GEM
parser (>= 2.4)
smart_properties
bindex (0.8.1)
bootsnap (1.16.0)
bootsnap (1.15.0)
msgpack (~> 1.2)
builder (3.2.4)
bullet (7.0.7)
activesupport (>= 3.0.0)
uniform_notifier (~> 1.11)
capybara (3.39.1)
capybara (3.39.2)
addressable
matrix
mini_mime (>= 0.1.3)
@ -126,7 +126,7 @@ GEM
cmdparse (3.0.7)
coderay (1.1.3)
concurrent-ruby (1.2.2)
connection_pool (2.4.0)
connection_pool (2.4.1)
crack (0.4.5)
rexml
crass (1.0.6)
@ -150,6 +150,7 @@ GEM
digest-crc (0.6.4)
rake (>= 12.0.0, < 14.0.0)
docile (1.4.0)
dotenv (2.8.1)
erb_lint (0.4.0)
activesupport
better_html (>= 2.0.1)
@ -196,7 +197,6 @@ GEM
webrick (~> 1.7)
websocket-driver (>= 0.6, < 0.8)
ffi (1.15.5)
geoip (1.6.4)
geom2d (0.3.1)
globalid (1.1.0)
activesupport (>= 5.0)
@ -227,7 +227,7 @@ GEM
google-cloud-core (~> 1.6)
googleauth (>= 0.16.2, < 2.a)
mini_mime (~> 1.0)
googleauth (1.5.2)
googleauth (1.6.0)
faraday (>= 0.17.3, < 3.a)
jwt (>= 1.4, < 3.0)
memoist (~> 0.16)
@ -241,17 +241,18 @@ GEM
openssl (>= 2.2.1)
htmlentities (4.3.4)
httpclient (2.8.3)
i18n (1.13.0)
i18n (1.14.1)
concurrent-ruby (~> 1.0)
image_processing (1.12.2)
mini_magick (>= 4.9.5, < 5)
ruby-vips (>= 2.0.17, < 3)
io-console (0.6.0)
irb (1.6.4)
irb (1.7.0)
reline (>= 0.3.0)
jmespath (1.6.2)
json (2.6.3)
jwt (2.7.0)
jwt (2.7.1)
language_server-protocol (3.17.0.3)
launchy (2.5.2)
addressable (~> 2.8)
letter_opener (1.8.1)
@ -280,13 +281,14 @@ GEM
method_source (1.0.0)
mini_magick (4.12.0)
mini_mime (1.1.2)
minitest (5.18.0)
msgpack (1.7.0)
mini_portile2 (2.8.2)
minitest (5.18.1)
msgpack (1.7.1)
multi_json (1.15.0)
multipart-post (2.3.0)
net-http-persistent (4.0.2)
connection_pool (~> 2.2)
net-imap (0.3.4)
net-imap (0.3.6)
date
net-protocol
net-pop (0.1.2)
@ -296,16 +298,17 @@ GEM
net-smtp (0.3.3)
net-protocol
nio4r (2.5.9)
nokogiri (1.15.0-arm64-darwin)
nokogiri (1.15.2-arm64-darwin)
racc (~> 1.4)
oj (3.14.3)
oj (3.15.0)
openssl (3.1.0)
orm_adapter (0.5.0)
os (1.1.4)
pagy (6.0.4)
parallel (1.23.0)
parser (3.2.2.1)
parser (3.2.2.3)
ast (~> 2.4.1)
racc
pg (1.5.3)
premailer (1.21.0)
addressable
@ -321,44 +324,45 @@ GEM
pry-rails (0.3.9)
pry (>= 0.10.4)
public_suffix (5.0.1)
puma (6.2.2)
puma (6.3.0)
nio4r (~> 2.0)
racc (1.6.2)
racc (1.7.1)
rack (2.2.7)
rack-proxy (0.7.6)
rack
rack-test (2.1.0)
rack (>= 1.3)
rails (7.0.4.3)
actioncable (= 7.0.4.3)
actionmailbox (= 7.0.4.3)
actionmailer (= 7.0.4.3)
actionpack (= 7.0.4.3)
actiontext (= 7.0.4.3)
actionview (= 7.0.4.3)
activejob (= 7.0.4.3)
activemodel (= 7.0.4.3)
activerecord (= 7.0.4.3)
activestorage (= 7.0.4.3)
activesupport (= 7.0.4.3)
rails (7.0.5)
actioncable (= 7.0.5)
actionmailbox (= 7.0.5)
actionmailer (= 7.0.5)
actionpack (= 7.0.5)
actiontext (= 7.0.5)
actionview (= 7.0.5)
activejob (= 7.0.5)
activemodel (= 7.0.5)
activerecord (= 7.0.5)
activestorage (= 7.0.5)
activesupport (= 7.0.5)
bundler (>= 1.15.0)
railties (= 7.0.4.3)
railties (= 7.0.5)
rails-dom-testing (2.0.3)
activesupport (>= 4.2.0)
nokogiri (>= 1.6)
rails-html-sanitizer (1.5.0)
loofah (~> 2.19, >= 2.19.1)
railties (7.0.4.3)
actionpack (= 7.0.4.3)
activesupport (= 7.0.4.3)
rails-html-sanitizer (1.6.0)
loofah (~> 2.21)
nokogiri (~> 1.14)
railties (7.0.5)
actionpack (= 7.0.5)
activesupport (= 7.0.5)
method_source
rake (>= 12.2)
thor (~> 1.0)
zeitwerk (~> 2.5)
rainbow (3.1.1)
rake (13.0.6)
regexp_parser (2.8.0)
reline (0.3.3)
regexp_parser (2.8.1)
reline (0.3.5)
io-console (~> 0.5)
representable (3.2.0)
declarative (< 0.1.0)
@ -379,7 +383,7 @@ GEM
rspec-mocks (3.12.5)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.12.0)
rspec-rails (6.0.2)
rspec-rails (6.0.3)
actionpack (>= 6.1)
activesupport (>= 6.1)
railties (>= 6.1)
@ -388,26 +392,27 @@ GEM
rspec-mocks (~> 3.12)
rspec-support (~> 3.12)
rspec-support (3.12.0)
rubocop (1.51.0)
rubocop (1.53.0)
json (~> 2.3)
language_server-protocol (>= 3.17.0)
parallel (~> 1.10)
parser (>= 3.2.0.0)
parser (>= 3.2.2.3)
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 1.8, < 3.0)
rexml (>= 3.2.5, < 4.0)
rubocop-ast (>= 1.28.0, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 2.4.0, < 3.0)
rubocop-ast (1.28.1)
rubocop-ast (1.29.0)
parser (>= 3.2.1.0)
rubocop-capybara (2.18.0)
rubocop (~> 1.41)
rubocop-factory_bot (2.23.1)
rubocop (~> 1.33)
rubocop-performance (1.17.1)
rubocop-performance (1.18.0)
rubocop (>= 1.7.0, < 2.0)
rubocop-ast (>= 0.4.0)
rubocop-rails (2.19.1)
rubocop-rails (2.20.2)
activesupport (>= 4.2.0)
rack (>= 1.1)
rubocop (>= 1.33.0, < 2.0)
@ -420,7 +425,7 @@ GEM
ffi (~> 1.12)
ruby2_keywords (0.0.5)
semantic_range (3.0.0)
shakapacker (6.6.0)
shakapacker (7.0.0)
activesupport (>= 5.2)
rack-proxy (>= 0.6.1)
railties (>= 5.2)
@ -437,11 +442,12 @@ GEM
simplecov-html (0.12.3)
simplecov_json_formatter (0.1.4)
smart_properties (1.17.0)
sqlite3 (1.6.3-arm64-darwin)
sqlite3 (1.5.4)
mini_portile2 (~> 2.8.0)
strip_attributes (1.13.0)
activemodel (>= 3.0, < 8.0)
thor (1.2.2)
timeout (0.3.2)
timeout (0.4.0)
trailblazer-option (0.1.2)
turbo-rails (1.4.0)
actionpack (>= 6.0.0)
@ -472,7 +478,6 @@ GEM
xpath (3.2.0)
nokogiri (~> 1.8)
zeitwerk (2.6.8)
zip (2.0.2)
PLATFORMS
arm64-darwin-22
@ -489,11 +494,11 @@ DEPENDENCIES
cuprite
debug
devise
dotenv
erb_lint
factory_bot_rails
faker
faraday
geoip
google-cloud-storage
hexapdf
image_processing
@ -520,7 +525,6 @@ DEPENDENCIES
tzinfo-data
web-console
webmock
zip
RUBY VERSION
ruby 3.2.2p53

@ -1,2 +1,2 @@
web: PORT=3000 bundle exec rails s -p 3000
webpacker: bundle exec ./bin/webpacker-dev-server
webpacker: bundle exec ./bin/shakapacker-dev-server

@ -1,5 +1,8 @@
import '@hotwired/turbo-rails'
import { createApp, reactive } from 'vue'
import TemplateBuilder from './template_builder/builder'
import ToggleVisible from './elements/toggle_visible'
import DisableHidden from './elements/disable_hidden'
import TurboModal from './elements/turbo_modal'
@ -31,16 +34,8 @@ window.customElements.define('download-button', DownloadButton)
window.customElements.define('set-origin-url', SetOriginUrl)
window.customElements.define('template-builder', class extends HTMLElement {
async connectedCallback () {
const [
{ createApp, reactive },
{ default: TemplateBuilder }
] = await Promise.all([
import('vue'),
import('./template_builder/builder')
])
this.appElem = this.children[0]
connectedCallback () {
this.appElem = document.createElement('div')
this.app = createApp(TemplateBuilder, {
template: reactive(JSON.parse(this.dataset.template))
@ -55,5 +50,6 @@ window.customElements.define('template-builder', class extends HTMLElement {
disconnectedCallback () {
this.app?.unmount()
this.appElem?.remove()
}
})

@ -1,31 +1 @@
<template-builder data-template="<%= @template.to_json(include: { documents: { include: { preview_images: { methods: %i[url metadata filename] } } } }) %>">
<div>
<div style="max-width: 1600px" class="mx-auto pl-4">
<div class="flex justify-between py-1.5 items-center pr-4">
<div class="flex space-x-3">
<a href="/">
<%= render 'shared/logo', width: 40, height: 40 %>
</a>
<span class="text-3xl font-semibold focus:text-clip flex items-center">
<span>
<%= @template.name %>
</span>
</span>
</div>
<div class="space-x-3 flex items-center">
<button class="btn btn-primary disabled" disabled>
<%= svg_icon('users_plus', class: 'w-5') %>
Recipients
</button>
<button class="base-button disabled" disabled>
<%= svg_icon('device_floppy', class: 'w-5') %>
Save
</button>
</div>
</div>
<div class="flex items-center justify-center h-96">
<%= svg_icon('loader', class: 'animate-spin') %>
</div>
</div>
</div>
</template-builder>
<template-builder data-template="<%= @template.to_json(include: { documents: { include: { preview_images: { methods: %i[url metadata filename] } } } }) %>"></template-builder>

@ -0,0 +1,13 @@
#!/usr/bin/env ruby
ENV["RAILS_ENV"] ||= "development"
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", __FILE__)
require "bundler/setup"
require "shakapacker"
require "shakapacker/webpack_runner"
APP_ROOT = File.expand_path("..", __dir__)
Dir.chdir(APP_ROOT) do
Shakapacker::WebpackRunner.run(ARGV)
end

@ -0,0 +1,13 @@
#!/usr/bin/env ruby
ENV["RAILS_ENV"] ||= "development"
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", __FILE__)
require "bundler/setup"
require "shakapacker"
require "shakapacker/dev_server_runner"
APP_ROOT = File.expand_path("..", __dir__)
Dir.chdir(APP_ROOT) do
Shakapacker::DevServerRunner.run(ARGV)
end

@ -1,15 +0,0 @@
#!/usr/bin/env ruby
require "pathname"
require "bundler/setup"
require "webpacker"
require "webpacker/webpack_runner"
ENV["RAILS_ENV"] ||= "development"
ENV["NODE_ENV"] ||= ENV["RAILS_ENV"]
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", Pathname.new(__FILE__).realpath)
APP_ROOT = File.expand_path("..", __dir__)
Dir.chdir(APP_ROOT) do
Webpacker::WebpackRunner.run(ARGV)
end

@ -1,18 +0,0 @@
#!/usr/bin/env ruby
ENV["RAILS_ENV"] ||= "development"
ENV["NODE_ENV"] ||= ENV["RAILS_ENV"]
require "pathname"
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
Pathname.new(__FILE__).realpath)
require "bundler/setup"
require "webpacker"
require "webpacker/dev_server_runner"
APP_ROOT = File.expand_path("..", __dir__)
Dir.chdir(APP_ROOT) do
Webpacker::DevServerRunner.run(ARGV)
end

@ -21,5 +21,7 @@ module DocuSeal
config.active_storage.routes_prefix = ''
config.action_view.frozen_string_literal = true
config.middleware.insert_before ActionDispatch::Static, Rack::Deflater
end
end

@ -2,5 +2,27 @@
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
if ENV['RAILS_ENV'] == 'production' && ENV['SECRET_KEY_BASE'].to_s.empty?
require 'dotenv'
require 'securerandom'
dotenv_path = './docuseal.env'
unless File.exist?(dotenv_path)
default_env = <<~TEXT
DATABASE_URL= # keep empty to use sqlite or specify postgresql database URL
SECRET_KEY_BASE=#{SecureRandom.hex(64)}
TEXT
File.write(dotenv_path, default_env)
end
database_url = ENV.fetch('DATABASE_URL', nil)
Dotenv.load(dotenv_path)
ENV['DATABASE_URL'] = ENV['DATABASE_URL'].to_s.empty? ? database_url : ENV.fetch('DATABASE_URL', nil)
end
require 'bundler/setup' # Set up gems listed in the Gemfile.
require 'bootsnap/setup' # Speed up boot time by caching expensive operations.

@ -11,5 +11,6 @@ test:
database: docuseal_test
production:
<<: *default
database: db/production.sqlite3
adapter: <%= ENV['DATABASE_URL'].present? ? 'postgresql' : 'sqlite3' %>
encoding: unicode
database: <%= ENV['WORKDIR'] || '.' %>/db.sqlite3

@ -9,6 +9,11 @@ Rails.application.configure do
# Code is not reloaded between requests.
config.cache_classes = true
config.public_file_server.headers = {
'Cache-Control' => 'public, s-maxage=31536000, max-age=15552000',
'Expires' => 1.year.from_now.to_fs(:rfc822)
}
# Eager load code on boot. This eager loads most of Rails and
# your application in memory, allowing both threaded web servers
# and those relying on copy on write to perform better.
@ -18,6 +23,7 @@ Rails.application.configure do
# Full error reports are disabled and caching is turned on.
config.consider_all_requests_local = false
config.action_controller.perform_caching = true
config.active_record.sqlite3_production_warning = false
# Ensures that a master key has been made available in either ENV["RAILS_MASTER_KEY"]
# or in config/master.key. This key is used to decrypt credentials (and other encrypted files).
@ -75,12 +81,24 @@ Rails.application.configure do
logger.formatter = config.log_formatter
config.logger = ActiveSupport::TaggedLogging.new(logger)
encryption_secret = Digest::SHA256.hexdigest(ENV['SECRET_KEY_BASE'].to_s)
config.active_record.encryption = {
primary_key: ENV['SECRET_KEY_BASE'].first(32),
deterministic_key: ENV['SECRET_KEY_BASE'].last(32),
key_derivation_salt: ENV.fetch('SECRET_KEY_BASE', nil)
primary_key: encryption_secret.first(32),
deterministic_key: encryption_secret.last(32),
key_derivation_salt: encryption_secret
}
# Do not dump schema after migrations.
config.active_record.dump_schema_after_migration = false
config.lograge.enabled = true
config.lograge.formatter = Lograge::Formatters::Json.new
config.lograge.base_controller_class = ['ActionController::API', 'ActionController::Base']
config.lograge.custom_payload do |controller|
{
fwd: controller.request.ip
}
end
end

@ -6,6 +6,8 @@ ActiveSupport.on_load(:active_storage_attachment) do
has_many_attached :preview_images
end
ActiveStorage::LogSubscriber.detach_from(:active_storage) if Rails.env.production?
Rails.configuration.to_prepare do
ActiveStorage::DiskController.after_action do
response.set_header('Cache-Control', 'public, max-age=31536000') if action_name == 'show'

@ -0,0 +1,3 @@
# frozen_string_literal: true
ActiveRecord::Tasks::DatabaseTasks.migrate if ENV['RAILS_ENV'] == 'production'

@ -6,7 +6,7 @@
# the maximum value specified for Puma. Default is set to 5 threads for minimum
# and maximum; this matches the default thread size of Active Record.
#
max_threads_count = ENV.fetch('RAILS_MAX_THREADS', 10)
max_threads_count = ENV.fetch('RAILS_MAX_THREADS', 15)
min_threads_count = ENV.fetch('RAILS_MIN_THREADS') { max_threads_count }
threads min_threads_count, max_threads_count
@ -24,7 +24,7 @@ port ENV.fetch('PORT', 3000)
environment ENV.fetch('RAILS_ENV', 'development')
# Specifies the `pidfile` that Puma will use.
pidfile ENV.fetch('PIDFILE', 'tmp/pids/server.pid')
# pidfile ENV.fetch('PIDFILE', 'tmp/pids/server.pid')
# Specifies the number of `workers` to boot in clustered mode.
# Workers are forked web server processes. If using threads and workers together

@ -5,13 +5,14 @@ default: &default
public_root_path: public
public_output_path: packs
cache_path: tmp/webpacker
webpacker_precompile: true
shakapacker_precompile: true
webpack_compile_output: true
additional_paths: []
webpack_loader: 'babel'
compiler_strategy: digest
cache_manifest: false
ensure_consistent_versioning: false
useContentHash: false
development:
<<: *default

@ -1,11 +1,11 @@
local:
service: Disk
root: <%= ENV['WORKDIR'] %>docuseal-attachments
root: <%= ENV['WORKDIR'] || '.' %>/attachments
public: true
disk:
service: Disk
root: <%= ENV['WORKDIR'] %>docuseal-attachments
root: <%= ENV['WORKDIR'] || '.' %>/attachments
public: true
aws_s3:

@ -1,8 +1,8 @@
const { webpackConfig, merge } = require('shakapacker')
const { globalMutableWebpackConfig, merge } = require('shakapacker')
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
const { VueLoaderPlugin } = require('vue-loader')
const configs = merge(webpackConfig, {
const configs = merge(globalMutableWebpackConfig, {
resolve: {
extensions: ['.css', '.scss', '.vue']
},

@ -7,7 +7,11 @@ module Submissions
INFO_CREATOR = 'DocuSeal (https://www.docuseal.co)'
TEXT_LEFT_MARGIN = 1
TEXT_TOP_MARGIN = 1
A4_SIZE = [595, 842].freeze
SUPPORTED_IMAGE_TYPES = ['image/png', 'image/jpeg'].freeze
module_function
@ -39,7 +43,16 @@ module Submissions
case field['type']
when 'image', 'signature'
attachment = submitter.attachments.find { |a| a.uuid == value }
io = StringIO.new(attachment.download)
image_data =
if SUPPORTED_IMAGE_TYPES.include?(attachment.content_type)
attachment.download
else
Vips::Image.new_from_buffer(attachment.download, '')
.write_to_buffer('.jpg', Q: 40)
end
io = StringIO.new(image_data)
scale = [(area['w'] * width) / attachment.metadata['width'],
(area['h'] * height) / attachment.metadata['height']].min
@ -86,9 +99,9 @@ module Submissions
{
Type: :Annot, Subtype: :Link,
Rect: [
area['x'] * width,
(area['x'] * width) + TEXT_LEFT_MARGIN,
height - (area['y'] * height) - lines[...index].sum(&:height) + height_diff,
(area['x'] * width) + (area['w'] * width),
(area['x'] * width) + (area['w'] * width) + TEXT_LEFT_MARGIN,
height - (area['y'] * height) - lines[..next_index].sum(&:height) + height_diff
],
A: { Type: :Action, S: :URI, URI: attachment.url }
@ -99,7 +112,8 @@ module Submissions
end
layouter.fit(items, area['w'] * width, height_diff.positive? ? box_height : area['h'] * height)
.draw(canvas, area['x'] * width, height - (area['y'] * height) + height_diff)
.draw(canvas, (area['x'] * width) + TEXT_LEFT_MARGIN,
height - (area['y'] * height) + height_diff - TEXT_TOP_MARGIN)
when 'checkbox'
next unless value == true
@ -125,7 +139,8 @@ module Submissions
height_diff = [0, box_height - (area['h'] * height)].max
layouter.fit([text], area['w'] * width, height_diff.positive? ? box_height : area['h'] * height)
.draw(canvas, area['x'] * width, height - (area['y'] * height) + height_diff)
.draw(canvas, (area['x'] * width) + TEXT_LEFT_MARGIN,
height - (area['y'] * height) + height_diff - TEXT_TOP_MARGIN)
end
end
end
@ -167,7 +182,7 @@ module Submissions
def save_signed_pdf(pdf:, submitter:, cert:, uuid:, name:)
io = StringIO.new
pdf.trailer[:Info][:Creator] = INFO_CREATOR
pdf.trailer.info[:Creator] = INFO_CREATOR
pdf.sign(io, reason: "Signed by #{submitter.email} with docuseal.co",
certificate: OpenSSL::X509::Certificate.new(cert['cert']),

@ -25,7 +25,7 @@
"postcss-loader": "^7.3.0",
"sass": "^1.62.1",
"sass-loader": "^13.2.2",
"shakapacker": "6.6.0",
"shakapacker": "7.0.0",
"signature_pad": "^4.1.5",
"tailwindcss": "^3.3.2",
"terser-webpack-plugin": "5.3.8",

@ -4818,10 +4818,10 @@ setprototypeof@1.2.0:
resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424"
integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==
shakapacker@6.6.0:
version "6.6.0"
resolved "https://registry.yarnpkg.com/shakapacker/-/shakapacker-6.6.0.tgz#1e372a7ce6fa93f1a7bd1820737b8168679eb220"
integrity sha512-7sNnv8PXMlgm2Ob7vZOayLKu0+PPMN3q0HEyAlkFIJtHJt7wA3p1rObhlk0/OrNeBa4dio/9HiBUeEU7bZsHvw==
shakapacker@7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/shakapacker/-/shakapacker-7.0.0.tgz#788c96e86eb78e44ee84c3cc03b7c091e4621fc3"
integrity sha512-yL5lbCdgtI8nUxZHarL7X5aB40r069wAunHwb59Hgw1gPg6/nMuYo7ofNTGXg11v1eunwAdjx8EfYnk4XwX27Q==
dependencies:
glob "^7.2.0"
js-yaml "^4.1.0"

Loading…
Cancel
Save