mirror of
https://github.com/docusealco/docuseal
synced 2026-11-04 14:42:32 -05:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4486f8040e | ||
|
|
a98caad968 | ||
|
|
ffb75238b4 | ||
|
|
cba3e74f3a | ||
|
|
8d3f0b5b98 | ||
|
|
a2598b30f7 | ||
|
|
8d11f5ddae | ||
|
|
6ffc88b4ed | ||
|
|
640b451727 | ||
|
|
db6e2eb7ca | ||
|
|
407816b576 | ||
|
|
486cc493e6 | ||
|
|
3eb0b8a89f | ||
|
|
c23eca0ade | ||
|
|
67de153016 | ||
|
|
ba2da69a67 | ||
|
|
111bef14e1 | ||
|
|
22d4c1bd10 | ||
|
|
e3dfb0ae83 | ||
|
|
8d7c3f0e26 | ||
|
|
b11775ebda | ||
|
|
608191183a | ||
|
|
2ba903e170 | ||
|
|
342b64d502 | ||
|
|
1a8f048aaa | ||
|
|
7309581b75 | ||
|
|
36d59c40a7 | ||
|
|
ed3c7c324b |
No files matched your search
+4
-5
@@ -10,7 +10,7 @@ RUN apk --no-cache add fontforge wget && \
|
|||||||
wget https://github.com/Maxattax97/gnu-freefont/raw/master/ttf/FreeSans.ttf && \
|
wget https://github.com/Maxattax97/gnu-freefont/raw/master/ttf/FreeSans.ttf && \
|
||||||
wget https://github.com/impallari/DancingScript/raw/master/OFL.txt && \
|
wget https://github.com/impallari/DancingScript/raw/master/OFL.txt && \
|
||||||
wget -O /model.onnx "https://github.com/docusealco/fields-detection/releases/download/2.0.0/model_704_int8.onnx" && \
|
wget -O /model.onnx "https://github.com/docusealco/fields-detection/releases/download/2.0.0/model_704_int8.onnx" && \
|
||||||
wget -O pdfium-linux.tgz "https://github.com/docusealco/pdfium-binaries/releases/latest/download/pdfium-linux-$(uname -m | sed 's/x86_64/x64/;s/aarch64/arm64/').tgz" && \
|
wget -O pdfium-linux.tgz "https://github.com/bblanchon/pdfium-binaries/releases/latest/download/pdfium-linux-musl-$(uname -m | sed 's/x86_64/x64/;s/aarch64/arm64/').tgz" && \
|
||||||
mkdir -p /pdfium-linux && \
|
mkdir -p /pdfium-linux && \
|
||||||
tar -xzf pdfium-linux.tgz -C /pdfium-linux
|
tar -xzf pdfium-linux.tgz -C /pdfium-linux
|
||||||
|
|
||||||
@@ -47,13 +47,11 @@ FROM ruby:4.0.1-alpine AS app
|
|||||||
|
|
||||||
ENV RAILS_ENV=production
|
ENV RAILS_ENV=production
|
||||||
ENV BUNDLE_WITHOUT="development:test"
|
ENV BUNDLE_WITHOUT="development:test"
|
||||||
ENV LD_PRELOAD=/lib/libgcompat.so.0
|
|
||||||
ENV OPENSSL_CONF=/etc/openssl_legacy.cnf
|
ENV OPENSSL_CONF=/etc/openssl_legacy.cnf
|
||||||
ENV VIPS_MAX_COORD=15000
|
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
RUN apk add --no-cache sqlite-dev libpq-dev vips-dev yaml-dev redis libheif vips-heif gcompat ttf-freefont onnxruntime && mkdir /fonts && rm /usr/share/fonts/freefont/FreeSans.otf
|
RUN apk add --no-cache libpq vips redis vips-heif ttf-freefont onnxruntime && mkdir /fonts && rm /usr/share/fonts/freefont/FreeSans.otf
|
||||||
|
|
||||||
RUN addgroup -g 2000 docuseal && adduser -u 2000 -G docuseal -s /bin/sh -D -h /home/docuseal docuseal
|
RUN addgroup -g 2000 docuseal && adduser -u 2000 -G docuseal -s /bin/sh -D -h /home/docuseal docuseal
|
||||||
|
|
||||||
@@ -71,7 +69,7 @@ activate = 1' >> /etc/openssl_legacy.cnf
|
|||||||
|
|
||||||
COPY --chown=docuseal:docuseal ./Gemfile ./Gemfile.lock ./
|
COPY --chown=docuseal:docuseal ./Gemfile ./Gemfile.lock ./
|
||||||
|
|
||||||
RUN apk add --no-cache build-base git && bundle install && apk del --no-cache build-base git && rm -rf ~/.bundle /usr/local/bundle/cache && ruby -e "puts Dir['/usr/local/bundle/**/{spec,rdoc,resources/shared,resources/collation,resources/locales}']" | xargs rm -rf && ln -sf /usr/lib/libonnxruntime.so.1 $(ruby -e "print Dir[Gem::Specification.find_by_name('onnxruntime').gem_dir + '/vendor/*.so'].first")
|
RUN apk add --no-cache build-base git libpq-dev yaml-dev && bundle install && apk del --no-cache build-base git libpq-dev yaml-dev && rm -rf ~/.bundle /usr/local/bundle/cache && ruby -e "puts Dir['/usr/local/bundle/**/{spec,rdoc,resources/shared,resources/collation,resources/locales,resources/unicode_data/properties}'] + Dir['/usr/local/bundle/gems/*/{test,tests,examples,sample,misc,doc,docs}'] + Dir['/usr/local/bundle/gems/*/ext/**/*.{c,h,o,S}']" | xargs rm -rf && ln -sf /usr/lib/libonnxruntime.so.1 $(ruby -e "print Dir[Gem::Specification.find_by_name('onnxruntime').gem_dir + '/vendor/*.so'].first")
|
||||||
|
|
||||||
COPY --chown=docuseal:docuseal ./bin ./bin
|
COPY --chown=docuseal:docuseal ./bin ./bin
|
||||||
COPY --chown=docuseal:docuseal ./app ./app
|
COPY --chown=docuseal:docuseal ./app ./app
|
||||||
@@ -98,6 +96,7 @@ RUN ln -s /fonts /app/public/fonts && \
|
|||||||
WORKDIR /data/docuseal
|
WORKDIR /data/docuseal
|
||||||
ENV HOME=/home/docuseal
|
ENV HOME=/home/docuseal
|
||||||
ENV WORKDIR=/data/docuseal
|
ENV WORKDIR=/data/docuseal
|
||||||
|
ENV VIPS_MAX_COORD=17000
|
||||||
|
|
||||||
EXPOSE 3000
|
EXPOSE 3000
|
||||||
CMD ["/app/bin/bundle", "exec", "puma", "-C", "/app/config/puma.rb", "--dir", "/app"]
|
CMD ["/app/bin/bundle", "exec", "puma", "-C", "/app/config/puma.rb", "--dir", "/app"]
|
||||||
@@ -4,6 +4,7 @@ source 'https://rubygems.org'
|
|||||||
|
|
||||||
ruby '4.0.1'
|
ruby '4.0.1'
|
||||||
|
|
||||||
|
gem 'addressable'
|
||||||
gem 'arabic-letter-connector', require: false
|
gem 'arabic-letter-connector', require: false
|
||||||
gem 'aws-sdk-s3', require: false
|
gem 'aws-sdk-s3', require: false
|
||||||
gem 'aws-sdk-secretsmanager', require: false
|
gem 'aws-sdk-secretsmanager', require: false
|
||||||
@@ -28,7 +29,6 @@ gem 'oj'
|
|||||||
gem 'onnxruntime', require: false
|
gem 'onnxruntime', require: false
|
||||||
gem 'pagy'
|
gem 'pagy'
|
||||||
gem 'pg', require: false
|
gem 'pg', require: false
|
||||||
gem 'premailer-rails'
|
|
||||||
gem 'pretender'
|
gem 'pretender'
|
||||||
gem 'puma', require: false
|
gem 'puma', require: false
|
||||||
gem 'rack'
|
gem 'rack'
|
||||||
@@ -43,7 +43,7 @@ gem 'shakapacker'
|
|||||||
gem 'sidekiq'
|
gem 'sidekiq'
|
||||||
gem 'sqlite3', require: false
|
gem 'sqlite3', require: false
|
||||||
gem 'strip_attributes'
|
gem 'strip_attributes'
|
||||||
gem 'trilogy', github: 'trilogy-libraries/trilogy', glob: 'contrib/ruby/*.gemspec', require: false
|
gem 'trilogy', require: false
|
||||||
gem 'turbo-rails'
|
gem 'turbo-rails'
|
||||||
gem 'twitter_cldr', require: false
|
gem 'twitter_cldr', require: false
|
||||||
gem 'tzinfo-data'
|
gem 'tzinfo-data'
|
||||||
|
|||||||
+85
-100
@@ -1,39 +1,31 @@
|
|||||||
GIT
|
|
||||||
remote: https://github.com/trilogy-libraries/trilogy.git
|
|
||||||
revision: 3963d490459df7a2b5bedb42424c3285f25eab22
|
|
||||||
glob: contrib/ruby/*.gemspec
|
|
||||||
specs:
|
|
||||||
trilogy (2.10.0)
|
|
||||||
bigdecimal
|
|
||||||
|
|
||||||
GEM
|
GEM
|
||||||
remote: https://rubygems.org/
|
remote: https://rubygems.org/
|
||||||
specs:
|
specs:
|
||||||
action_text-trix (2.1.16)
|
action_text-trix (2.1.17)
|
||||||
railties
|
railties
|
||||||
actioncable (8.1.2)
|
actioncable (8.1.3)
|
||||||
actionpack (= 8.1.2)
|
actionpack (= 8.1.3)
|
||||||
activesupport (= 8.1.2)
|
activesupport (= 8.1.3)
|
||||||
nio4r (~> 2.0)
|
nio4r (~> 2.0)
|
||||||
websocket-driver (>= 0.6.1)
|
websocket-driver (>= 0.6.1)
|
||||||
zeitwerk (~> 2.6)
|
zeitwerk (~> 2.6)
|
||||||
actionmailbox (8.1.2)
|
actionmailbox (8.1.3)
|
||||||
actionpack (= 8.1.2)
|
actionpack (= 8.1.3)
|
||||||
activejob (= 8.1.2)
|
activejob (= 8.1.3)
|
||||||
activerecord (= 8.1.2)
|
activerecord (= 8.1.3)
|
||||||
activestorage (= 8.1.2)
|
activestorage (= 8.1.3)
|
||||||
activesupport (= 8.1.2)
|
activesupport (= 8.1.3)
|
||||||
mail (>= 2.8.0)
|
mail (>= 2.8.0)
|
||||||
actionmailer (8.1.2)
|
actionmailer (8.1.3)
|
||||||
actionpack (= 8.1.2)
|
actionpack (= 8.1.3)
|
||||||
actionview (= 8.1.2)
|
actionview (= 8.1.3)
|
||||||
activejob (= 8.1.2)
|
activejob (= 8.1.3)
|
||||||
activesupport (= 8.1.2)
|
activesupport (= 8.1.3)
|
||||||
mail (>= 2.8.0)
|
mail (>= 2.8.0)
|
||||||
rails-dom-testing (~> 2.2)
|
rails-dom-testing (~> 2.2)
|
||||||
actionpack (8.1.2)
|
actionpack (8.1.3)
|
||||||
actionview (= 8.1.2)
|
actionview (= 8.1.3)
|
||||||
activesupport (= 8.1.2)
|
activesupport (= 8.1.3)
|
||||||
nokogiri (>= 1.8.5)
|
nokogiri (>= 1.8.5)
|
||||||
rack (>= 2.2.4)
|
rack (>= 2.2.4)
|
||||||
rack-session (>= 1.0.1)
|
rack-session (>= 1.0.1)
|
||||||
@@ -41,36 +33,36 @@ GEM
|
|||||||
rails-dom-testing (~> 2.2)
|
rails-dom-testing (~> 2.2)
|
||||||
rails-html-sanitizer (~> 1.6)
|
rails-html-sanitizer (~> 1.6)
|
||||||
useragent (~> 0.16)
|
useragent (~> 0.16)
|
||||||
actiontext (8.1.2)
|
actiontext (8.1.3)
|
||||||
action_text-trix (~> 2.1.15)
|
action_text-trix (~> 2.1.15)
|
||||||
actionpack (= 8.1.2)
|
actionpack (= 8.1.3)
|
||||||
activerecord (= 8.1.2)
|
activerecord (= 8.1.3)
|
||||||
activestorage (= 8.1.2)
|
activestorage (= 8.1.3)
|
||||||
activesupport (= 8.1.2)
|
activesupport (= 8.1.3)
|
||||||
globalid (>= 0.6.0)
|
globalid (>= 0.6.0)
|
||||||
nokogiri (>= 1.8.5)
|
nokogiri (>= 1.8.5)
|
||||||
actionview (8.1.2)
|
actionview (8.1.3)
|
||||||
activesupport (= 8.1.2)
|
activesupport (= 8.1.3)
|
||||||
builder (~> 3.1)
|
builder (~> 3.1)
|
||||||
erubi (~> 1.11)
|
erubi (~> 1.11)
|
||||||
rails-dom-testing (~> 2.2)
|
rails-dom-testing (~> 2.2)
|
||||||
rails-html-sanitizer (~> 1.6)
|
rails-html-sanitizer (~> 1.6)
|
||||||
activejob (8.1.2)
|
activejob (8.1.3)
|
||||||
activesupport (= 8.1.2)
|
activesupport (= 8.1.3)
|
||||||
globalid (>= 0.3.6)
|
globalid (>= 0.3.6)
|
||||||
activemodel (8.1.2)
|
activemodel (8.1.3)
|
||||||
activesupport (= 8.1.2)
|
activesupport (= 8.1.3)
|
||||||
activerecord (8.1.2)
|
activerecord (8.1.3)
|
||||||
activemodel (= 8.1.2)
|
activemodel (= 8.1.3)
|
||||||
activesupport (= 8.1.2)
|
activesupport (= 8.1.3)
|
||||||
timeout (>= 0.4.0)
|
timeout (>= 0.4.0)
|
||||||
activestorage (8.1.2)
|
activestorage (8.1.3)
|
||||||
actionpack (= 8.1.2)
|
actionpack (= 8.1.3)
|
||||||
activejob (= 8.1.2)
|
activejob (= 8.1.3)
|
||||||
activerecord (= 8.1.2)
|
activerecord (= 8.1.3)
|
||||||
activesupport (= 8.1.2)
|
activesupport (= 8.1.3)
|
||||||
marcel (~> 1.0)
|
marcel (~> 1.0)
|
||||||
activesupport (8.1.2)
|
activesupport (8.1.3)
|
||||||
base64
|
base64
|
||||||
bigdecimal
|
bigdecimal
|
||||||
concurrent-ruby (~> 1.0, >= 1.3.1)
|
concurrent-ruby (~> 1.0, >= 1.3.1)
|
||||||
@@ -116,7 +108,7 @@ GEM
|
|||||||
cgi
|
cgi
|
||||||
rexml
|
rexml
|
||||||
base64 (0.3.0)
|
base64 (0.3.0)
|
||||||
bcrypt (3.1.21)
|
bcrypt (3.1.22)
|
||||||
better_html (2.2.0)
|
better_html (2.2.0)
|
||||||
actionview (>= 7.0)
|
actionview (>= 7.0)
|
||||||
activesupport (>= 7.0)
|
activesupport (>= 7.0)
|
||||||
@@ -158,8 +150,6 @@ GEM
|
|||||||
bigdecimal
|
bigdecimal
|
||||||
rexml
|
rexml
|
||||||
crass (1.0.6)
|
crass (1.0.6)
|
||||||
css_parser (1.21.1)
|
|
||||||
addressable
|
|
||||||
csv (3.3.5)
|
csv (3.3.5)
|
||||||
csv-safe (3.3.1)
|
csv-safe (3.3.1)
|
||||||
csv (~> 3.0)
|
csv (~> 3.0)
|
||||||
@@ -171,16 +161,16 @@ GEM
|
|||||||
irb (~> 1.10)
|
irb (~> 1.10)
|
||||||
reline (>= 0.3.8)
|
reline (>= 0.3.8)
|
||||||
declarative (0.0.20)
|
declarative (0.0.20)
|
||||||
devise (4.9.4)
|
devise (5.0.3)
|
||||||
bcrypt (~> 3.0)
|
bcrypt (~> 3.0)
|
||||||
orm_adapter (~> 0.1)
|
orm_adapter (~> 0.1)
|
||||||
railties (>= 4.1.0)
|
railties (>= 7.0)
|
||||||
responders
|
responders
|
||||||
warden (~> 1.2.3)
|
warden (~> 1.2.3)
|
||||||
devise-two-factor (6.3.1)
|
devise-two-factor (6.4.0)
|
||||||
activesupport (>= 7.0, < 8.2)
|
activesupport (>= 7.2, < 8.2)
|
||||||
devise (>= 4.0, < 5.0)
|
devise (>= 4.0, < 6.0)
|
||||||
railties (>= 7.0, < 8.2)
|
railties (>= 7.2, < 8.2)
|
||||||
rotp (~> 6.0)
|
rotp (~> 6.0)
|
||||||
diff-lcs (1.6.2)
|
diff-lcs (1.6.2)
|
||||||
digest-crc (0.7.0)
|
digest-crc (0.7.0)
|
||||||
@@ -189,7 +179,7 @@ GEM
|
|||||||
dotenv (3.2.0)
|
dotenv (3.2.0)
|
||||||
drb (2.2.3)
|
drb (2.2.3)
|
||||||
email_typo (0.2.3)
|
email_typo (0.2.3)
|
||||||
erb (6.0.1)
|
erb (6.0.2)
|
||||||
erb_lint (0.9.0)
|
erb_lint (0.9.0)
|
||||||
activesupport
|
activesupport
|
||||||
better_html (>= 2.0.1)
|
better_html (>= 2.0.1)
|
||||||
@@ -272,19 +262,19 @@ GEM
|
|||||||
geom2d (~> 0.4, >= 0.4.1)
|
geom2d (~> 0.4, >= 0.4.1)
|
||||||
openssl (>= 2.2.1)
|
openssl (>= 2.2.1)
|
||||||
strscan (>= 3.1.2)
|
strscan (>= 3.1.2)
|
||||||
htmlentities (4.4.2)
|
|
||||||
i18n (1.14.8)
|
i18n (1.14.8)
|
||||||
concurrent-ruby (~> 1.0)
|
concurrent-ruby (~> 1.0)
|
||||||
image_processing (1.14.0)
|
image_processing (1.14.0)
|
||||||
mini_magick (>= 4.9.5, < 6)
|
mini_magick (>= 4.9.5, < 6)
|
||||||
ruby-vips (>= 2.0.17, < 3)
|
ruby-vips (>= 2.0.17, < 3)
|
||||||
io-console (0.8.2)
|
io-console (0.8.2)
|
||||||
irb (1.16.0)
|
irb (1.17.0)
|
||||||
pp (>= 0.6.0)
|
pp (>= 0.6.0)
|
||||||
|
prism (>= 1.3.0)
|
||||||
rdoc (>= 4.0.0)
|
rdoc (>= 4.0.0)
|
||||||
reline (>= 0.4.2)
|
reline (>= 0.4.2)
|
||||||
jmespath (1.6.2)
|
jmespath (1.6.2)
|
||||||
json (2.18.1)
|
json (2.19.2)
|
||||||
jwt (3.1.2)
|
jwt (3.1.2)
|
||||||
base64
|
base64
|
||||||
language_server-protocol (3.17.0.5)
|
language_server-protocol (3.17.0.5)
|
||||||
@@ -306,7 +296,7 @@ GEM
|
|||||||
activesupport (>= 4)
|
activesupport (>= 4)
|
||||||
railties (>= 4)
|
railties (>= 4)
|
||||||
request_store (~> 1.0)
|
request_store (~> 1.0)
|
||||||
loofah (2.25.0)
|
loofah (2.25.1)
|
||||||
crass (~> 1.0.2)
|
crass (~> 1.0.2)
|
||||||
nokogiri (>= 1.12.0)
|
nokogiri (>= 1.12.0)
|
||||||
mail (2.9.0)
|
mail (2.9.0)
|
||||||
@@ -321,13 +311,14 @@ GEM
|
|||||||
mini_magick (5.3.1)
|
mini_magick (5.3.1)
|
||||||
logger
|
logger
|
||||||
mini_mime (1.1.5)
|
mini_mime (1.1.5)
|
||||||
minitest (6.0.1)
|
minitest (6.0.2)
|
||||||
|
drb (~> 2.0)
|
||||||
prism (~> 1.5)
|
prism (~> 1.5)
|
||||||
msgpack (1.8.0)
|
msgpack (1.8.0)
|
||||||
multi_json (1.19.1)
|
multi_json (1.19.1)
|
||||||
net-http (0.9.1)
|
net-http (0.9.1)
|
||||||
uri (>= 0.11.1)
|
uri (>= 0.11.1)
|
||||||
net-imap (0.6.2)
|
net-imap (0.6.3)
|
||||||
date
|
date
|
||||||
net-protocol
|
net-protocol
|
||||||
net-pop (0.1.2)
|
net-pop (0.1.2)
|
||||||
@@ -337,17 +328,17 @@ GEM
|
|||||||
net-smtp (0.5.1)
|
net-smtp (0.5.1)
|
||||||
net-protocol
|
net-protocol
|
||||||
nio4r (2.7.5)
|
nio4r (2.7.5)
|
||||||
nokogiri (1.19.1-aarch64-linux-gnu)
|
nokogiri (1.19.2-aarch64-linux-gnu)
|
||||||
racc (~> 1.4)
|
racc (~> 1.4)
|
||||||
nokogiri (1.19.1-aarch64-linux-musl)
|
nokogiri (1.19.2-aarch64-linux-musl)
|
||||||
racc (~> 1.4)
|
racc (~> 1.4)
|
||||||
nokogiri (1.19.1-arm64-darwin)
|
nokogiri (1.19.2-arm64-darwin)
|
||||||
racc (~> 1.4)
|
racc (~> 1.4)
|
||||||
nokogiri (1.19.1-x86_64-linux-gnu)
|
nokogiri (1.19.2-x86_64-linux-gnu)
|
||||||
racc (~> 1.4)
|
racc (~> 1.4)
|
||||||
nokogiri (1.19.1-x86_64-linux-musl)
|
nokogiri (1.19.2-x86_64-linux-musl)
|
||||||
racc (~> 1.4)
|
racc (~> 1.4)
|
||||||
numo-narray-alt (0.9.13)
|
numo-narray-alt (0.10.3)
|
||||||
oj (3.16.13)
|
oj (3.16.13)
|
||||||
bigdecimal (>= 3.0)
|
bigdecimal (>= 3.0)
|
||||||
ostruct (>= 0.2)
|
ostruct (>= 0.2)
|
||||||
@@ -376,18 +367,10 @@ GEM
|
|||||||
pg (1.6.3-x86_64-linux-musl)
|
pg (1.6.3-x86_64-linux-musl)
|
||||||
pp (0.6.3)
|
pp (0.6.3)
|
||||||
prettyprint
|
prettyprint
|
||||||
premailer (1.27.0)
|
|
||||||
addressable
|
|
||||||
css_parser (>= 1.19.0)
|
|
||||||
htmlentities (>= 4.0.0)
|
|
||||||
premailer-rails (1.12.0)
|
|
||||||
actionmailer (>= 3)
|
|
||||||
net-smtp
|
|
||||||
premailer (~> 1.7, >= 1.7.9)
|
|
||||||
pretender (0.6.0)
|
pretender (0.6.0)
|
||||||
actionpack (>= 7.1)
|
actionpack (>= 7.1)
|
||||||
prettyprint (0.2.0)
|
prettyprint (0.2.0)
|
||||||
prism (1.8.0)
|
prism (1.9.0)
|
||||||
pry (0.16.0)
|
pry (0.16.0)
|
||||||
coderay (~> 1.1)
|
coderay (~> 1.1)
|
||||||
method_source (~> 1.0)
|
method_source (~> 1.0)
|
||||||
@@ -411,33 +394,33 @@ GEM
|
|||||||
rack (>= 1.3)
|
rack (>= 1.3)
|
||||||
rackup (2.3.1)
|
rackup (2.3.1)
|
||||||
rack (>= 3)
|
rack (>= 3)
|
||||||
rails (8.1.2)
|
rails (8.1.3)
|
||||||
actioncable (= 8.1.2)
|
actioncable (= 8.1.3)
|
||||||
actionmailbox (= 8.1.2)
|
actionmailbox (= 8.1.3)
|
||||||
actionmailer (= 8.1.2)
|
actionmailer (= 8.1.3)
|
||||||
actionpack (= 8.1.2)
|
actionpack (= 8.1.3)
|
||||||
actiontext (= 8.1.2)
|
actiontext (= 8.1.3)
|
||||||
actionview (= 8.1.2)
|
actionview (= 8.1.3)
|
||||||
activejob (= 8.1.2)
|
activejob (= 8.1.3)
|
||||||
activemodel (= 8.1.2)
|
activemodel (= 8.1.3)
|
||||||
activerecord (= 8.1.2)
|
activerecord (= 8.1.3)
|
||||||
activestorage (= 8.1.2)
|
activestorage (= 8.1.3)
|
||||||
activesupport (= 8.1.2)
|
activesupport (= 8.1.3)
|
||||||
bundler (>= 1.15.0)
|
bundler (>= 1.15.0)
|
||||||
railties (= 8.1.2)
|
railties (= 8.1.3)
|
||||||
rails-dom-testing (2.3.0)
|
rails-dom-testing (2.3.0)
|
||||||
activesupport (>= 5.0.0)
|
activesupport (>= 5.0.0)
|
||||||
minitest
|
minitest
|
||||||
nokogiri (>= 1.6)
|
nokogiri (>= 1.6)
|
||||||
rails-html-sanitizer (1.6.2)
|
rails-html-sanitizer (1.7.0)
|
||||||
loofah (~> 2.21)
|
loofah (~> 2.25)
|
||||||
nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0)
|
nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0)
|
||||||
rails-i18n (8.1.0)
|
rails-i18n (8.1.0)
|
||||||
i18n (>= 0.7, < 2)
|
i18n (>= 0.7, < 2)
|
||||||
railties (>= 8.0.0, < 9)
|
railties (>= 8.0.0, < 9)
|
||||||
railties (8.1.2)
|
railties (8.1.3)
|
||||||
actionpack (= 8.1.2)
|
actionpack (= 8.1.3)
|
||||||
activesupport (= 8.1.2)
|
activesupport (= 8.1.3)
|
||||||
irb (~> 1.13)
|
irb (~> 1.13)
|
||||||
rackup (>= 1.0.0)
|
rackup (>= 1.0.0)
|
||||||
rake (>= 12.2)
|
rake (>= 12.2)
|
||||||
@@ -446,7 +429,7 @@ GEM
|
|||||||
zeitwerk (~> 2.6)
|
zeitwerk (~> 2.6)
|
||||||
rainbow (3.1.1)
|
rainbow (3.1.1)
|
||||||
rake (13.3.1)
|
rake (13.3.1)
|
||||||
rdoc (7.1.0)
|
rdoc (7.2.0)
|
||||||
erb
|
erb
|
||||||
psych (>= 4.0.0)
|
psych (>= 4.0.0)
|
||||||
tsort
|
tsort
|
||||||
@@ -560,8 +543,10 @@ GEM
|
|||||||
activemodel (>= 3.0, < 9.0)
|
activemodel (>= 3.0, < 9.0)
|
||||||
strscan (3.1.7)
|
strscan (3.1.7)
|
||||||
thor (1.5.0)
|
thor (1.5.0)
|
||||||
timeout (0.6.0)
|
timeout (0.6.1)
|
||||||
trailblazer-option (0.1.2)
|
trailblazer-option (0.1.2)
|
||||||
|
trilogy (2.10.0)
|
||||||
|
bigdecimal
|
||||||
tsort (0.2.0)
|
tsort (0.2.0)
|
||||||
turbo-rails (2.0.21)
|
turbo-rails (2.0.21)
|
||||||
actionpack (>= 7.1.0)
|
actionpack (>= 7.1.0)
|
||||||
@@ -601,7 +586,7 @@ GEM
|
|||||||
xpath (3.2.0)
|
xpath (3.2.0)
|
||||||
nokogiri (~> 1.8)
|
nokogiri (~> 1.8)
|
||||||
yaml (0.4.0)
|
yaml (0.4.0)
|
||||||
zeitwerk (2.7.4)
|
zeitwerk (2.7.5)
|
||||||
|
|
||||||
PLATFORMS
|
PLATFORMS
|
||||||
aarch64-linux
|
aarch64-linux
|
||||||
@@ -611,6 +596,7 @@ PLATFORMS
|
|||||||
x86_64-linux-musl
|
x86_64-linux-musl
|
||||||
|
|
||||||
DEPENDENCIES
|
DEPENDENCIES
|
||||||
|
addressable
|
||||||
annotaterb
|
annotaterb
|
||||||
arabic-letter-connector
|
arabic-letter-connector
|
||||||
aws-sdk-s3
|
aws-sdk-s3
|
||||||
@@ -647,7 +633,6 @@ DEPENDENCIES
|
|||||||
onnxruntime
|
onnxruntime
|
||||||
pagy
|
pagy
|
||||||
pg
|
pg
|
||||||
premailer-rails
|
|
||||||
pretender
|
pretender
|
||||||
pry-rails
|
pry-rails
|
||||||
puma
|
puma
|
||||||
@@ -669,7 +654,7 @@ DEPENDENCIES
|
|||||||
simplecov
|
simplecov
|
||||||
sqlite3
|
sqlite3
|
||||||
strip_attributes
|
strip_attributes
|
||||||
trilogy!
|
trilogy
|
||||||
turbo-rails
|
turbo-rails
|
||||||
twitter_cldr
|
twitter_cldr
|
||||||
tzinfo-data
|
tzinfo-data
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ class AccountConfigsController < ApplicationController
|
|||||||
AccountConfig::FORCE_MFA,
|
AccountConfig::FORCE_MFA,
|
||||||
AccountConfig::ALLOW_TO_RESUBMIT,
|
AccountConfig::ALLOW_TO_RESUBMIT,
|
||||||
AccountConfig::ALLOW_TO_DECLINE_KEY,
|
AccountConfig::ALLOW_TO_DECLINE_KEY,
|
||||||
|
AccountConfig::ALLOW_TO_DELEGATE_KEY,
|
||||||
AccountConfig::FORM_PREFILL_SIGNATURE_KEY,
|
AccountConfig::FORM_PREFILL_SIGNATURE_KEY,
|
||||||
AccountConfig::ESIGNING_PREFERENCE_KEY,
|
AccountConfig::ESIGNING_PREFERENCE_KEY,
|
||||||
AccountConfig::FORM_WITH_CONFETTI_KEY,
|
AccountConfig::FORM_WITH_CONFETTI_KEY,
|
||||||
@@ -36,7 +37,7 @@ class AccountConfigsController < ApplicationController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
raise InvalidKey unless ALLOWED_KEYS.include?(@account_config.key)
|
raise InvalidKey unless allowed_keys.include?(@account_config.key)
|
||||||
|
|
||||||
@account_config.destroy!
|
@account_config.destroy!
|
||||||
|
|
||||||
@@ -45,8 +46,12 @@ class AccountConfigsController < ApplicationController
|
|||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def allowed_keys
|
||||||
|
ALLOWED_KEYS
|
||||||
|
end
|
||||||
|
|
||||||
def load_account_config
|
def load_account_config
|
||||||
raise InvalidKey unless ALLOWED_KEYS.include?(account_config_params[:key])
|
raise InvalidKey unless allowed_keys.include?(account_config_params[:key])
|
||||||
|
|
||||||
@account_config =
|
@account_config =
|
||||||
AccountConfig.find_or_initialize_by(account: current_account, key: account_config_params[:key])
|
AccountConfig.find_or_initialize_by(account: current_account, key: account_config_params[:key])
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ module Api
|
|||||||
SearchEntries.enqueue_reindex(@template)
|
SearchEntries.enqueue_reindex(@template)
|
||||||
|
|
||||||
WebhookUrls.enqueue_events(@template, 'template.updated')
|
WebhookUrls.enqueue_events(@template, 'template.updated')
|
||||||
|
WebhookUrls.enqueue_events(@template, 'template.archived') if archived == true
|
||||||
|
|
||||||
render json: @template.as_json(only: %i[id updated_at])
|
render json: @template.as_json(only: %i[id updated_at])
|
||||||
end
|
end
|
||||||
@@ -78,6 +79,8 @@ module Api
|
|||||||
@template.destroy!
|
@template.destroy!
|
||||||
else
|
else
|
||||||
@template.update!(archived_at: Time.current)
|
@template.update!(archived_at: Time.current)
|
||||||
|
|
||||||
|
WebhookUrls.enqueue_events(@template, 'template.archived')
|
||||||
end
|
end
|
||||||
|
|
||||||
render json: @template.as_json(only: %i[id archived_at])
|
render json: @template.as_json(only: %i[id archived_at])
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ class ErrorsController < ActionController::Base
|
|||||||
render json: { status: error_status_code, error: }.compact, status: error_status_code
|
render json: { status: error_status_code, error: }.compact, status: error_status_code
|
||||||
end
|
end
|
||||||
|
|
||||||
f.html { render error_status_code.to_s, status: error_status_code }
|
f.any { render error_status_code.to_s, status: error_status_code }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -51,7 +51,7 @@ class ErrorsController < ActionController::Base
|
|||||||
headers['Access-Control-Allow-Methods'] = 'POST, GET, PUT, PATCH, DELETE, OPTIONS'
|
headers['Access-Control-Allow-Methods'] = 'POST, GET, PUT, PATCH, DELETE, OPTIONS'
|
||||||
headers['Access-Control-Allow-Headers'] = '*'
|
headers['Access-Control-Allow-Headers'] = '*'
|
||||||
headers['Access-Control-Max-Age'] = '1728000'
|
headers['Access-Control-Max-Age'] = '1728000'
|
||||||
headers['Access-Control-Allow-Credentials'] = true
|
headers['Access-Control-Allow-Credentials'] = 'true'
|
||||||
end
|
end
|
||||||
|
|
||||||
def error_status_code
|
def error_status_code
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ class SubmissionEventsController < ApplicationController
|
|||||||
'email_verified' => 'email_check',
|
'email_verified' => 'email_check',
|
||||||
'click_sms' => 'hand_click',
|
'click_sms' => 'hand_click',
|
||||||
'decline_form' => 'x',
|
'decline_form' => 'x',
|
||||||
|
'delegate_form' => 'user_share',
|
||||||
'start_verification' => 'player_play',
|
'start_verification' => 'player_play',
|
||||||
'complete_verification' => 'check',
|
'complete_verification' => 'check',
|
||||||
'invite_party' => 'user_plus'
|
'invite_party' => 'user_plus'
|
||||||
|
|||||||
@@ -3,11 +3,12 @@
|
|||||||
class SubmitFormController < ApplicationController
|
class SubmitFormController < ApplicationController
|
||||||
layout 'form'
|
layout 'form'
|
||||||
|
|
||||||
around_action :with_browser_locale, only: %i[show completed success]
|
around_action :with_browser_locale, only: %i[show completed success delegated]
|
||||||
skip_before_action :authenticate_user!
|
skip_before_action :authenticate_user!
|
||||||
skip_authorization_check
|
skip_authorization_check
|
||||||
|
|
||||||
before_action :load_submitter, only: %i[show update completed]
|
before_action :load_submitter, only: %i[show update completed]
|
||||||
|
before_action :maybe_redirect_delegated, only: %i[show completed]
|
||||||
before_action :maybe_render_locked_page, only: :show
|
before_action :maybe_render_locked_page, only: :show
|
||||||
before_action :maybe_require_link_2fa, only: %i[show]
|
before_action :maybe_require_link_2fa, only: %i[show]
|
||||||
|
|
||||||
@@ -91,6 +92,12 @@ class SubmitFormController < ApplicationController
|
|||||||
|
|
||||||
def success; end
|
def success; end
|
||||||
|
|
||||||
|
def delegated
|
||||||
|
submitter_version = SubmitterVersion.find_by!(slug: params[:slug] || params[:submit_form_slug])
|
||||||
|
|
||||||
|
@submitter = submitter_version.submitter
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def maybe_require_link_2fa
|
def maybe_require_link_2fa
|
||||||
@@ -108,8 +115,18 @@ class SubmitFormController < ApplicationController
|
|||||||
render :declined if @submitter.declined_at?
|
render :declined if @submitter.declined_at?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def maybe_redirect_delegated
|
||||||
|
return if @submitter
|
||||||
|
|
||||||
|
submitter_version = SubmitterVersion.find_by!(slug: params[:slug] || params[:submit_form_slug])
|
||||||
|
|
||||||
|
submitter_version.submitter.submission_events.find_by!(event_type: :delegate_form)
|
||||||
|
|
||||||
|
redirect_to submit_form_delegated_path(submitter_version.slug)
|
||||||
|
end
|
||||||
|
|
||||||
def load_submitter
|
def load_submitter
|
||||||
@submitter = Submitter.find_by!(slug: params[:slug] || params[:submit_form_slug])
|
@submitter = Submitter.find_by(slug: params[:slug] || params[:submit_form_slug])
|
||||||
end
|
end
|
||||||
|
|
||||||
def build_attachments_index(submission)
|
def build_attachments_index(submission)
|
||||||
|
|||||||
@@ -4,31 +4,38 @@ class SubmitFormDeclineController < ApplicationController
|
|||||||
skip_before_action :authenticate_user!
|
skip_before_action :authenticate_user!
|
||||||
skip_authorization_check
|
skip_authorization_check
|
||||||
|
|
||||||
def create
|
before_action :load_submitter
|
||||||
submitter = Submitter.find_by!(slug: params[:submit_form_slug])
|
|
||||||
|
|
||||||
return redirect_to submit_form_path(submitter.slug) if submitter.declined_at? ||
|
def create
|
||||||
submitter.completed_at? ||
|
return redirect_to submit_form_path(@submitter.slug) if @submitter.declined_at? ||
|
||||||
submitter.submission.archived_at? ||
|
@submitter.completed_at? ||
|
||||||
submitter.submission.expired? ||
|
@submitter.submission.archived_at? ||
|
||||||
submitter.submission.template&.archived_at? ||
|
@submitter.submission.expired? ||
|
||||||
!Submitters::AuthorizedForForm.call(submitter, current_user,
|
@submitter.submission.template&.archived_at? ||
|
||||||
request)
|
!Submitters::AuthorizedForForm.call(@submitter,
|
||||||
|
current_user,
|
||||||
|
request)
|
||||||
|
|
||||||
ApplicationRecord.transaction do
|
ApplicationRecord.transaction do
|
||||||
submitter.update!(declined_at: Time.current)
|
@submitter.update!(declined_at: Time.current)
|
||||||
|
|
||||||
SubmissionEvents.create_with_tracking_data(submitter, 'decline_form', request, { reason: params[:reason] })
|
SubmissionEvents.create_with_tracking_data(@submitter, 'decline_form', request, { reason: params[:reason] })
|
||||||
end
|
end
|
||||||
|
|
||||||
user = submitter.submission.created_by_user || submitter.template.author
|
user = @submitter.submission.created_by_user || @submitter.template.author
|
||||||
|
|
||||||
if user.user_configs.find_by(key: UserConfig::RECEIVE_DECLINED_EMAIL)&.value != false
|
if user.user_configs.find_by(key: UserConfig::RECEIVE_DECLINED_EMAIL)&.value != false
|
||||||
SubmitterMailer.declined_email(submitter, user).deliver_later!
|
SubmitterMailer.declined_email(@submitter, user).deliver_later!
|
||||||
end
|
end
|
||||||
|
|
||||||
WebhookUrls.enqueue_events(submitter, 'form.declined')
|
WebhookUrls.enqueue_events(@submitter, 'form.declined')
|
||||||
|
|
||||||
redirect_to submit_form_path(submitter.slug)
|
redirect_to submit_form_path(@submitter.slug)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def load_submitter
|
||||||
|
@submitter = Submitter.find_by!(slug: params[:submit_form_slug])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class SubmitFormDelegateController < ApplicationController
|
||||||
|
skip_before_action :authenticate_user!
|
||||||
|
skip_authorization_check
|
||||||
|
|
||||||
|
before_action :load_submitter
|
||||||
|
|
||||||
|
def create
|
||||||
|
return redirect_to submit_form_path(@submitter.slug) if @submitter.declined_at? ||
|
||||||
|
@submitter.completed_at? ||
|
||||||
|
@submitter.submission.archived_at? ||
|
||||||
|
@submitter.submission.expired? ||
|
||||||
|
@submitter.submission.template&.archived_at? ||
|
||||||
|
!Submitters::AuthorizedForForm.call(@submitter,
|
||||||
|
current_user,
|
||||||
|
request)
|
||||||
|
|
||||||
|
@submitter.account.account_configs.find_by!(key: AccountConfig::ALLOW_TO_DELEGATE_KEY, value: true)
|
||||||
|
|
||||||
|
email = Submissions.normalize_email(params[:email])
|
||||||
|
|
||||||
|
return redirect_to submit_form_path(@submitter.slug) if email.blank?
|
||||||
|
|
||||||
|
old_slug = @submitter.slug
|
||||||
|
|
||||||
|
ApplicationRecord.transaction do
|
||||||
|
@submitter.submitter_versions.create!(slug: old_slug, email: @submitter.email,
|
||||||
|
name: @submitter.name, phone: @submitter.phone)
|
||||||
|
|
||||||
|
SubmissionEvents.create_with_tracking_data(@submitter, 'delegate_form', request,
|
||||||
|
{ old_email: @submitter.email, email: })
|
||||||
|
|
||||||
|
@submitter.update!(email:, phone: nil, name: nil, slug: SecureRandom.base58(14))
|
||||||
|
end
|
||||||
|
|
||||||
|
SendSubmitterInvitationEmailJob.perform_async('submitter_id' => @submitter.id)
|
||||||
|
|
||||||
|
redirect_to submit_form_delegated_path(old_slug)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def load_submitter
|
||||||
|
@submitter = Submitter.find_by!(slug: params[:submit_form_slug])
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -84,6 +84,8 @@ class TemplatesController < ApplicationController
|
|||||||
else
|
else
|
||||||
@template.update!(archived_at: Time.current)
|
@template.update!(archived_at: Time.current)
|
||||||
|
|
||||||
|
WebhookUrls.enqueue_events(@template, 'template.archived')
|
||||||
|
|
||||||
I18n.t('template_has_been_archived')
|
I18n.t('template_has_been_archived')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ class TemplatesRestoreController < ApplicationController
|
|||||||
def create
|
def create
|
||||||
@template.update!(archived_at: nil)
|
@template.update!(archived_at: nil)
|
||||||
|
|
||||||
|
WebhookUrls.enqueue_events(@template, 'template.updated')
|
||||||
|
|
||||||
redirect_to template_path(@template), notice: I18n.t('template_has_been_unarchived')
|
redirect_to template_path(@template), notice: I18n.t('template_has_been_unarchived')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -15,7 +15,7 @@ class WebhookEventsController < ApplicationController
|
|||||||
Submissions::SerializeForApi.call(@webhook_event.record)
|
Submissions::SerializeForApi.call(@webhook_event.record)
|
||||||
when 'template.created', 'template.updated'
|
when 'template.created', 'template.updated'
|
||||||
Templates::SerializeForApi.call(@webhook_event.record)
|
Templates::SerializeForApi.call(@webhook_event.record)
|
||||||
when 'submission.archived'
|
when 'submission.archived', 'template.archived'
|
||||||
@webhook_event.record.as_json(only: %i[id archived_at])
|
@webhook_event.record.as_json(only: %i[id archived_at])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ safeRegisterElement('submission-form', class extends HTMLElement {
|
|||||||
expand: ['true', 'false'].includes(this.dataset.expand) ? this.dataset.expand === 'true' : null,
|
expand: ['true', 'false'].includes(this.dataset.expand) ? this.dataset.expand === 'true' : null,
|
||||||
withSignatureId: this.dataset.withSignatureId === 'true',
|
withSignatureId: this.dataset.withSignatureId === 'true',
|
||||||
requireSigningReason: this.dataset.requireSigningReason === 'true',
|
requireSigningReason: this.dataset.requireSigningReason === 'true',
|
||||||
withConfetti: this.dataset.withConfetti !== 'false',
|
withConfetti: this.dataset.withConfetti === 'true',
|
||||||
withFieldLabels: this.dataset.withFieldLabels !== 'false',
|
withFieldLabels: this.dataset.withFieldLabels !== 'false',
|
||||||
withDisclosure: this.dataset.withDisclosure === 'true',
|
withDisclosure: this.dataset.withDisclosure === 'true',
|
||||||
reuseSignature: this.dataset.reuseSignature !== 'false',
|
reuseSignature: this.dataset.reuseSignature !== 'false',
|
||||||
|
|||||||
@@ -2735,10 +2735,13 @@ export default {
|
|||||||
} else {
|
} else {
|
||||||
this.isSaving = true
|
this.isSaving = true
|
||||||
|
|
||||||
this.documentRefs.filter((ref) => ref.update).map((ref) => ref.update())
|
const dynamicDocumentRefs = this.documentRefs.filter((ref) => ref.isDynamic)
|
||||||
|
|
||||||
|
dynamicDocumentRefs.map((ref) => ref.update())
|
||||||
|
|
||||||
this.rebuildVariablesSchema({ disable: false })
|
this.rebuildVariablesSchema({ disable: false })
|
||||||
|
|
||||||
const dynamicDocumentSaves = this.documentRefs.filter((ref) => ref.saveBody).map((ref) => ref.saveBody())
|
const dynamicDocumentSaves = dynamicDocumentRefs.map((ref) => ref.saveBody())
|
||||||
|
|
||||||
Promise.all([this.save(), ...dynamicDocumentSaves]).then(() => {
|
Promise.all([this.save(), ...dynamicDocumentSaves]).then(() => {
|
||||||
window.Turbo.visit(`/templates/${this.template.id}`)
|
window.Turbo.visit(`/templates/${this.template.id}`)
|
||||||
@@ -3028,6 +3031,8 @@ export default {
|
|||||||
} else {
|
} else {
|
||||||
dynamicDocumentRef.syncVariablesSchema(this.template.variables_schema, parsed, { disable })
|
dynamicDocumentRef.syncVariablesSchema(this.template.variables_schema, parsed, { disable })
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
this.template.variables_schema = {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class SendTemplateArchivedWebhookRequestJob
|
||||||
|
include Sidekiq::Job
|
||||||
|
|
||||||
|
sidekiq_options queue: :webhooks
|
||||||
|
|
||||||
|
MAX_ATTEMPTS = 10
|
||||||
|
|
||||||
|
def perform(params = {})
|
||||||
|
template = Template.find_by(id: params['template_id'])
|
||||||
|
|
||||||
|
return unless template
|
||||||
|
|
||||||
|
webhook_url = WebhookUrl.find_by(id: params['webhook_url_id'])
|
||||||
|
|
||||||
|
return unless webhook_url
|
||||||
|
|
||||||
|
attempt = params['attempt'].to_i
|
||||||
|
|
||||||
|
return if webhook_url.url.blank? || webhook_url.events.exclude?('template.archived')
|
||||||
|
|
||||||
|
resp = SendWebhookRequest.call(webhook_url, event_type: 'template.archived',
|
||||||
|
event_uuid: params['event_uuid'],
|
||||||
|
record: template,
|
||||||
|
attempt:,
|
||||||
|
data: template.as_json(only: %i[id archived_at]))
|
||||||
|
|
||||||
|
if (resp.nil? || resp.status.to_i >= 400) && attempt <= MAX_ATTEMPTS &&
|
||||||
|
(!Docuseal.multitenant? || template.account.account_configs.exists?(key: :plan))
|
||||||
|
SendTemplateArchivedWebhookRequestJob.perform_in((2**attempt).minutes, {
|
||||||
|
**params,
|
||||||
|
'attempt' => attempt + 1,
|
||||||
|
'last_status' => resp&.status.to_i
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -5,6 +5,8 @@ class ApplicationMailer < ActionMailer::Base
|
|||||||
layout 'mailer'
|
layout 'mailer'
|
||||||
|
|
||||||
register_interceptor ActionMailerConfigsInterceptor
|
register_interceptor ActionMailerConfigsInterceptor
|
||||||
|
register_interceptor HtmlToPlainTextInterceptor
|
||||||
|
register_preview_interceptor HtmlToPlainTextInterceptor
|
||||||
|
|
||||||
register_observer ActionMailerEventsObserver
|
register_observer ActionMailerEventsObserver
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ class AccountConfig < ApplicationRecord
|
|||||||
ALLOW_TYPED_SIGNATURE = 'allow_typed_signature'
|
ALLOW_TYPED_SIGNATURE = 'allow_typed_signature'
|
||||||
ALLOW_TO_RESUBMIT = 'allow_to_resubmit'
|
ALLOW_TO_RESUBMIT = 'allow_to_resubmit'
|
||||||
ALLOW_TO_DECLINE_KEY = 'allow_to_decline'
|
ALLOW_TO_DECLINE_KEY = 'allow_to_decline'
|
||||||
|
ALLOW_TO_DELEGATE_KEY = 'allow_to_delegate'
|
||||||
ALLOW_TO_PARTIAL_DOWNLOAD_KEY = 'allow_to_partial_download'
|
ALLOW_TO_PARTIAL_DOWNLOAD_KEY = 'allow_to_partial_download'
|
||||||
SUBMITTER_REMINDERS = 'submitter_reminders'
|
SUBMITTER_REMINDERS = 'submitter_reminders'
|
||||||
ENFORCE_SIGNING_ORDER_KEY = 'enforce_signing_order'
|
ENFORCE_SIGNING_ORDER_KEY = 'enforce_signing_order'
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ class SubmissionEvent < ApplicationRecord
|
|||||||
invite_party: 'invite_party',
|
invite_party: 'invite_party',
|
||||||
complete_form: 'complete_form',
|
complete_form: 'complete_form',
|
||||||
decline_form: 'decline_form',
|
decline_form: 'decline_form',
|
||||||
|
delegate_form: 'delegate_form',
|
||||||
api_complete_form: 'api_complete_form'
|
api_complete_form: 'api_complete_form'
|
||||||
}, scope: false
|
}, scope: false
|
||||||
|
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ class Submitter < ApplicationRecord
|
|||||||
belongs_to :account
|
belongs_to :account
|
||||||
has_one :template, through: :submission
|
has_one :template, through: :submission
|
||||||
has_one :search_entry, as: :record, inverse_of: :record, dependent: :destroy if SearchEntry.table_exists?
|
has_one :search_entry, as: :record, inverse_of: :record, dependent: :destroy if SearchEntry.table_exists?
|
||||||
|
has_many :submitter_versions, dependent: :destroy
|
||||||
|
|
||||||
attribute :values, :string, default: -> { {} }
|
attribute :values, :string, default: -> { {} }
|
||||||
attribute :preferences, :string, default: -> { {} }
|
attribute :preferences, :string, default: -> { {} }
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
# == Schema Information
|
||||||
|
#
|
||||||
|
# Table name: submitter_versions
|
||||||
|
#
|
||||||
|
# id :bigint not null, primary key
|
||||||
|
# email :string
|
||||||
|
# name :string
|
||||||
|
# phone :string
|
||||||
|
# slug :string not null
|
||||||
|
# created_at :datetime not null
|
||||||
|
# updated_at :datetime not null
|
||||||
|
# submitter_id :bigint not null
|
||||||
|
#
|
||||||
|
# Indexes
|
||||||
|
#
|
||||||
|
# index_submitter_versions_on_slug (slug)
|
||||||
|
# index_submitter_versions_on_submitter_id (submitter_id)
|
||||||
|
#
|
||||||
|
# Foreign Keys
|
||||||
|
#
|
||||||
|
# fk_rails_... (submitter_id => submitters.id)
|
||||||
|
#
|
||||||
|
class SubmitterVersion < ApplicationRecord
|
||||||
|
belongs_to :submitter
|
||||||
|
end
|
||||||
@@ -34,6 +34,7 @@ class WebhookUrl < ApplicationRecord
|
|||||||
submission.archived
|
submission.archived
|
||||||
template.created
|
template.created
|
||||||
template.updated
|
template.updated
|
||||||
|
template.archived
|
||||||
].freeze
|
].freeze
|
||||||
|
|
||||||
belongs_to :account
|
belongs_to :account
|
||||||
|
|||||||
@@ -131,23 +131,50 @@
|
|||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
<% end %>
|
<% end %>
|
||||||
<% if !Docuseal.multitenant? || can?(:manage, :disable_decline) %>
|
<% account_config = AccountConfig.find_or_initialize_by(account: current_account, key: AccountConfig::ALLOW_TO_DECLINE_KEY) %>
|
||||||
<% account_config = AccountConfig.find_or_initialize_by(account: current_account, key: AccountConfig::ALLOW_TO_DECLINE_KEY) %>
|
<% if can?(:manage, account_config) %>
|
||||||
<% if can?(:manage, account_config) %>
|
<%= form_for account_config, url: account_configs_path, method: :post do |f| %>
|
||||||
<%= form_for account_config, url: account_configs_path, method: :post do |f| %>
|
<%= f.hidden_field :key %>
|
||||||
<%= f.hidden_field :key %>
|
<div class="flex items-center justify-between gap-4 py-2.5">
|
||||||
<div class="flex items-center justify-between gap-4 py-2.5">
|
<div class="flex items-center space-x-1">
|
||||||
<div class="flex items-center space-x-1">
|
<span class="text-left"><%= t('allow_to_decline_documents') %></span>
|
||||||
<span class="text-left"><%= t('allow_to_decline_documents') %></span>
|
<span class="tooltip tooltip-top flex cursor-pointer" data-tip="<%= t('allow_recipients_to_decline_signing_a_document_the_decline_reason_notification_will_be_sent_to_the_signature_requester') %>">
|
||||||
<span class="tooltip tooltip-top flex cursor-pointer" data-tip="<%= t('allow_recipients_to_decline_signing_a_document_the_decline_reason_notification_will_be_sent_to_the_signature_requester') %>">
|
<%= svg_icon('info_circle', class: 'hidden md:inline-block w-4 h-4 shrink-0') %>
|
||||||
<%= svg_icon('info_circle', class: 'hidden md:inline-block w-4 h-4 shrink-0') %>
|
</span>
|
||||||
</span>
|
</div>
|
||||||
</div>
|
<% if !Docuseal.multitenant? || can?(:manage, :disable_decline) %>
|
||||||
<submit-form data-on="change" class="flex">
|
<submit-form data-on="change" class="flex">
|
||||||
<%= f.check_box :value, class: 'toggle', checked: account_config.value != false %>
|
<%= f.check_box :value, class: 'toggle', checked: account_config.value != false %>
|
||||||
</submit-form>
|
</submit-form>
|
||||||
|
<% else %>
|
||||||
|
<a href="<%= console_redirect_index_path(redir: "#{Docuseal::CONSOLE_URL}/plans") %>" data-turbo="false" data-tip="<%= I18n.t('unlock_with_docuseal_pro') %>" data-on="change" class="flex tooltip">
|
||||||
|
<%= f.check_box :value, class: 'toggle pointer-events-none', checked: account_config.value != false, disabled: true %>
|
||||||
|
</a>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
<% account_config = AccountConfig.find_or_initialize_by(account: current_account, key: AccountConfig::ALLOW_TO_DELEGATE_KEY) %>
|
||||||
|
<% 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 gap-4 py-2.5">
|
||||||
|
<div class="flex items-center space-x-1">
|
||||||
|
<span class="text-left"><%= t('allow_to_delegate_documents') %></span>
|
||||||
|
<span class="tooltip tooltip-top flex cursor-pointer" data-tip="<%= t('allow_recipients_to_delegate_documents') %>">
|
||||||
|
<%= svg_icon('info_circle', class: 'hidden md:inline-block w-4 h-4 shrink-0') %>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% if !Docuseal.multitenant? || can?(:manage, :delegate_form) %>
|
||||||
|
<submit-form data-on="change" class="flex">
|
||||||
|
<%= f.check_box :value, class: 'toggle', checked: account_config.value == true %>
|
||||||
|
</submit-form>
|
||||||
|
<% else %>
|
||||||
|
<a href="<%= console_redirect_index_path(redir: "#{Docuseal::CONSOLE_URL}/plans") %>" data-turbo="false" data-tip="<%= I18n.t('unlock_with_docuseal_pro') %>" class="flex tooltip">
|
||||||
|
<%= f.check_box :value, class: 'toggle pointer-events-none', checked: account_config.value == true, disabled: true %>
|
||||||
|
</a>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
<% end %>
|
<% end %>
|
||||||
<% account_config = AccountConfig.find_or_initialize_by(account: current_account, key: AccountConfig::FORM_PREFILL_SIGNATURE_KEY) %>
|
<% account_config = AccountConfig.find_or_initialize_by(account: current_account, key: AccountConfig::FORM_PREFILL_SIGNATURE_KEY) %>
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="<%= local_assigns[:class] %>"><path stroke="none" d="M0 0h24v24H0z" fill="none" /><path d="M8 7a4 4 0 1 0 8 0a4 4 0 0 0 -8 0" /><path d="M6 21v-2a4 4 0 0 1 4 -4h3" /><path d="M16 22l5 -5" /><path d="M21 21.5v-4.5h-4.5" /></svg>
|
||||||
|
After Width: | Height: | Size: 416 B |
@@ -1,4 +1,4 @@
|
|||||||
<% account_config = AccountConfig.where(account: current_account, key: AccountConfig::FORM_WITH_CONFETTI_KEY).first_or_initialize(value: true) %>
|
<% account_config = AccountConfig.where(account: current_account, key: AccountConfig::FORM_WITH_CONFETTI_KEY).first_or_initialize(value: false) %>
|
||||||
<% if can?(:manage, account_config) %>
|
<% if can?(:manage, account_config) %>
|
||||||
<div class="px-1 mt-2">
|
<div class="px-1 mt-2">
|
||||||
<%= form_for account_config, url: account_configs_path, method: :post do |f| %>
|
<%= form_for account_config, url: account_configs_path, method: :post do |f| %>
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
<%= t('show_confetti_on_successful_completion') %>
|
<%= t('show_confetti_on_successful_completion') %>
|
||||||
</span>
|
</span>
|
||||||
<submit-form data-on="change" class="flex">
|
<submit-form data-on="change" class="flex">
|
||||||
<%= f.check_box :value, { class: 'toggle', checked: account_config.value != false }, '1', '0' %>
|
<%= f.check_box :value, { class: 'toggle', checked: account_config.value == true }, '1', '0' %>
|
||||||
</submit-form>
|
</submit-form>
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|||||||
@@ -20,10 +20,13 @@
|
|||||||
<% end %>
|
<% end %>
|
||||||
</p>
|
</p>
|
||||||
</li>
|
</li>
|
||||||
|
<% submitter_versions_index = @submission.submitters.preload(:submitter_versions).each_with_object({}) { |s, h| h[s.id] = s.submitter_versions.to_a.sort_by(&:created_at) } %>
|
||||||
<% @submission.submission_events.order(:event_timestamp).each do |event| %>
|
<% @submission.submission_events.order(:event_timestamp).each do |event| %>
|
||||||
<% submitter = @submission.submitters.find { |e| e.id == event.submitter_id } %>
|
<% submitter = @submission.submitters.find { |e| e.id == event.submitter_id } %>
|
||||||
<% bg_class = event_colors[submitters_uuids.index(submitter.uuid) % event_colors.length] %>
|
<% bg_class = event_colors[submitters_uuids.index(submitter.uuid) % event_colors.length] %>
|
||||||
<% submitter_name = event.event_type.include?('sms') || event.event_type.include?('phone') ? (event.data['phone'] || submitter.phone) : (submitter.name || submitter.email || submitter.phone) %>
|
<% versions = submitter_versions_index[submitter.id] || [] %>
|
||||||
|
<% active_version = versions.find { |v| v.created_at > event.event_timestamp } %>
|
||||||
|
<% submitter_name = event.event_type.include?('sms') || event.event_type.include?('phone') ? (event.data['phone'] || active_version&.phone || submitter.phone) : (active_version&.name || active_version&.email || active_version&.phone || submitter.name || submitter.email || submitter.phone) %>
|
||||||
<li class="ml-7">
|
<li class="ml-7">
|
||||||
<span class="absolute flex items-center justify-center w-7 h-7 rounded-full -start-3.5 ring-8 ring-base-100 text-base-content <%= bg_class %>">
|
<span class="absolute flex items-center justify-center w-7 h-7 rounded-full -start-3.5 ring-8 ring-base-100 text-base-content <%= bg_class %>">
|
||||||
<%= svg_icon(SubmissionEventsController::SUBMISSION_EVENT_ICONS.fetch(event.event_type, 'circle_dot'), class: 'w-4 h-4') %>
|
<%= svg_icon(SubmissionEventsController::SUBMISSION_EVENT_ICONS.fetch(event.event_type, 'circle_dot'), class: 'w-4 h-4') %>
|
||||||
@@ -43,6 +46,9 @@
|
|||||||
<%= t('submission_event_names.complete_verification_by_html', provider: event.data['method'], submitter_name:) %>
|
<%= t('submission_event_names.complete_verification_by_html', provider: event.data['method'], submitter_name:) %>
|
||||||
<% elsif event.event_type == 'invite_party' && (invited_submitter = @submission.submitters.find { |e| e.uuid == event.data['uuid'] }) && (name = @submission.template_submitters.find { |e| e['uuid'] == event.data['uuid'] }&.dig('name')) %>
|
<% elsif event.event_type == 'invite_party' && (invited_submitter = @submission.submitters.find { |e| e.uuid == event.data['uuid'] }) && (name = @submission.template_submitters.find { |e| e['uuid'] == event.data['uuid'] }&.dig('name')) %>
|
||||||
<%= t('submission_event_names.invite_party_by_html', invited_submitter_name: [invited_submitter.name || invited_submitter.email || invited_submitter.phone, name].join(' '), submitter_name:) %>
|
<%= t('submission_event_names.invite_party_by_html', invited_submitter_name: [invited_submitter.name || invited_submitter.email || invited_submitter.phone, name].join(' '), submitter_name:) %>
|
||||||
|
<% elsif event.event_type == 'delegate_form' %>
|
||||||
|
<% delegate_from = event.data['old_email'].presence || (versions.reverse.find { |v| v.created_at <= event.event_timestamp }&.then { |v| v.name || v.phone }) %>
|
||||||
|
<%= t('submission_event_names.delegate_form_by_html', from: delegate_from, to: event.data['email']) %>
|
||||||
<% elsif event.event_type.include?('send_') %>
|
<% elsif event.event_type.include?('send_') %>
|
||||||
<%= t("submission_event_names.#{event.event_type}_to_html", submitter_name:) %>
|
<%= t("submission_event_names.#{event.event_type}_to_html", submitter_name:) %>
|
||||||
<% elsif event.event_type.start_with?('bounce_') || event.event_type.start_with?('complaint_') %>
|
<% elsif event.event_type.start_with?('bounce_') || event.event_type.start_with?('complaint_') %>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<% submitters = template.submitters.reject { |e| e['invite_by_uuid'].present? || e['optional_invite_by_uuid'].present? || e['invite_via_field_uuid'].present? } %>
|
<% submitters = template.submitters.reject { |e| e['invite_by_uuid'].present? || e['optional_invite_by_uuid'].present? || e['invite_via_field_uuid'].present? } %>
|
||||||
<dynamic-list class="space-y-4">
|
<dynamic-list class="space-y-4">
|
||||||
<div class="space-y-4">
|
<div class="space-y-4">
|
||||||
<div class="<%= 'p-4 rounded-xl bg-base-300/40' unless local_assigns[:variables_form] %>" data-targets="dynamic-list.items">
|
<div class="relative <%= 'p-4 rounded-xl bg-base-300/40' unless local_assigns[:variables_form] %>" data-targets="dynamic-list.items">
|
||||||
<div>
|
<div>
|
||||||
<div class="absolute right-4 top-5">
|
<div class="absolute right-4 top-5">
|
||||||
<a href="#" data-action="click:dynamic-list#removeItem" class="<%= submitters.size == 1 ? 'right-2 top-1' : '-top-3' %> relative block w-6 h-6 rounded-lg text-neutral-700 text-center bg-base-300 p-1 hidden hover:bg-neutral hover:text-white">
|
<a href="#" data-action="click:dynamic-list#removeItem" class="<%= submitters.size == 1 ? 'right-2 top-1' : '-top-3' %> relative block w-6 h-6 rounded-lg text-neutral-700 text-center bg-base-300 p-1 hidden hover:bg-neutral hover:text-white">
|
||||||
|
|||||||
@@ -34,7 +34,7 @@
|
|||||||
<% else %>
|
<% else %>
|
||||||
<dynamic-list class="space-y-4">
|
<dynamic-list class="space-y-4">
|
||||||
<div class="space-y-4">
|
<div class="space-y-4">
|
||||||
<div class="<%= 'p-4 rounded-xl bg-base-300/40' unless local_assigns[:variables_form] %>" data-targets="dynamic-list.items">
|
<div class="relative <%= 'p-4 rounded-xl bg-base-300/40' unless local_assigns[:variables_form] %>" data-targets="dynamic-list.items">
|
||||||
<div>
|
<div>
|
||||||
<div class="absolute right-4 top-5">
|
<div class="absolute right-4 top-5">
|
||||||
<a href="#" data-action="click:dynamic-list#removeItem" class="-top-3 relative block w-6 h-6 rounded-lg text-neutral-700 text-center bg-base-300 p-1 hidden hover:bg-neutral hover:text-white">
|
<a href="#" data-action="click:dynamic-list#removeItem" class="-top-3 relative block w-6 h-6 rounded-lg text-neutral-700 text-center bg-base-300 p-1 hidden hover:bg-neutral hover:text-white">
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<% submitters = template.submitters.reject { |e| e['invite_by_uuid'].present? || e['optional_invite_by_uuid'].present? || e['invite_via_field_uuid'].present? } %>
|
<% submitters = template.submitters.reject { |e| e['invite_by_uuid'].present? || e['optional_invite_by_uuid'].present? || e['invite_via_field_uuid'].present? } %>
|
||||||
<dynamic-list class="space-y-4">
|
<dynamic-list class="space-y-4">
|
||||||
<div class="space-y-4">
|
<div class="space-y-4">
|
||||||
<div class="<%= 'p-4 rounded-xl bg-base-300/40' unless local_assigns[:variables_form] %>" data-targets="dynamic-list.items">
|
<div class="relative <%= 'p-4 rounded-xl bg-base-300/40' unless local_assigns[:variables_form] %>" data-targets="dynamic-list.items">
|
||||||
<div>
|
<div>
|
||||||
<div class="absolute right-4 top-5">
|
<div class="absolute right-4 top-5">
|
||||||
<a href="#" data-action="click:dynamic-list#removeItem" class="<%= submitters.size == 1 ? 'right-2 top-1' : '-top-3' %> relative block w-6 h-6 rounded-lg text-neutral-700 text-center bg-base-300 p-1 hidden hover:bg-neutral hover:text-white">
|
<a href="#" data-action="click:dynamic-list#removeItem" class="<%= submitters.size == 1 ? 'right-2 top-1' : '-top-3' %> relative block w-6 h-6 rounded-lg text-neutral-700 text-center bg-base-300 p-1 hidden hover:bg-neutral hover:text-white">
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<% if template.preferences['submitters_order'] == 'preserved' || template.submitters.any? { |s| s['order'] } %>
|
<% if template.preferences['submitters_order'] == 'preserved' || template.submitters.any? { |s| s['order'] } || (template.submitters.size > 1 && template.fields.any? { |f| f['type'] == 'verification' }) %>
|
||||||
<%= f.hidden_field :preserve_order, value: '1' %>
|
<%= f.hidden_field :preserve_order, value: '1' %>
|
||||||
<% elsif template.submitters.size > 1 %>
|
<% elsif template.submitters.size > 1 %>
|
||||||
<div class="form-control">
|
<div class="form-control">
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
<%= form_for '', url: submit_form_delegate_index_path(submitter.slug), method: :post do |f| %>
|
||||||
|
<div class="form-control mt-2">
|
||||||
|
<%= f.label :email, t(:enter_the_email_address_of_the_person_you_want_to_delegate_to), class: 'label' %>
|
||||||
|
<%= f.email_field :email, required: true, class: 'base-input w-full', dir: 'auto', placeholder: t('email') %>
|
||||||
|
</div>
|
||||||
|
<toggle-submit dir="auto" class="form-control mt-4">
|
||||||
|
<%= f.button button_title(title: t(:delegate)), class: 'base-button' %>
|
||||||
|
</toggle-submit>
|
||||||
|
<% end %>
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
<div class="max-w-md mx-auto px-2 mt-12 mb-4">
|
||||||
|
<div class="space-y-6 mx-auto">
|
||||||
|
<div class="space-y-6">
|
||||||
|
<div class="flex items-center justify-center">
|
||||||
|
<%= render 'start_form/banner' %>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center bg-base-200 rounded-xl p-4 mb-4">
|
||||||
|
<div class="flex items-center">
|
||||||
|
<div class="mr-3">
|
||||||
|
<%= svg_icon('user_share', class: 'w-10 h-10') %>
|
||||||
|
</div>
|
||||||
|
<div dir="auto">
|
||||||
|
<p class="text-lg font-bold mb-1"><%= @submitter.submission.name || @submitter.submission.template.name %></p>
|
||||||
|
<p class="text-sm"><%= t('document_has_been_delegated_on_html', time: l(@submitter.submission_events.order(event_timestamp: :desc).find_by!(event_type: :delegate_form).event_timestamp, format: :long)) %></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<%= render 'shared/attribution', link_path: '/start', account: @submitter.account %>
|
||||||
@@ -9,6 +9,7 @@
|
|||||||
<% schema = Submissions.filtered_conditions_schema(@submitter.submission, values:, include_submitter_uuid: @submitter.uuid) %>
|
<% schema = Submissions.filtered_conditions_schema(@submitter.submission, values:, include_submitter_uuid: @submitter.uuid) %>
|
||||||
<% font_scale = 1000.0 / PdfUtils::US_LETTER_W %>
|
<% font_scale = 1000.0 / PdfUtils::US_LETTER_W %>
|
||||||
<% decline_modal_checkbox_uuid = nil %>
|
<% decline_modal_checkbox_uuid = nil %>
|
||||||
|
<% delegate_modal_checkbox_uuid = nil %>
|
||||||
<div style="max-height: -webkit-fill-available;">
|
<div style="max-height: -webkit-fill-available;">
|
||||||
<div id="scrollbox">
|
<div id="scrollbox">
|
||||||
<div class="mx-auto block pb-72" style="max-width: 1000px">
|
<div class="mx-auto block pb-72" style="max-width: 1000px">
|
||||||
@@ -20,42 +21,85 @@
|
|||||||
<%= @submitter.submission.name || @submitter.submission.template.name %>
|
<%= @submitter.submission.name || @submitter.submission.template.name %>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center space-x-2" style="margin-left: 20px; flex-shrink: 0">
|
<div class="flex items-center space-x-2" style="margin-left: 20px; flex-shrink: 0">
|
||||||
<% if @form_configs[:with_decline] %>
|
<% if @form_configs[:with_delegate] %>
|
||||||
<label id="decline_button" for="<%= decline_modal_checkbox_uuid = SecureRandom.uuid %>" class="btn btn-sm !px-5"><%= t(:decline) %></label>
|
<label id="delegate_button" for="<%= delegate_modal_checkbox_uuid = SecureRandom.uuid %>" class="btn btn-sm !px-5"><%= t(:delegate) %></label>
|
||||||
<% end %>
|
<% if @form_configs[:with_decline] %>
|
||||||
<% if @form_configs[:with_partial_download] %>
|
<label id="decline_button" for="<%= decline_modal_checkbox_uuid = SecureRandom.uuid %>" class="btn btn-sm px-2" title="<%= t(:decline) %>">
|
||||||
<download-button data-src="<%= submit_form_download_index_path(@submitter.slug) %>" class="btn btn-neutral text-white btn-sm !px-4">
|
<%= svg_icon('x', class: 'w-5 h-5') %>
|
||||||
<span class="flex items-center justify-center" data-target="download-button.defaultButton">
|
</label>
|
||||||
<%= svg_icon('download', class: 'w-6 h-6 inline md:hidden') %>
|
<% end %>
|
||||||
<span class="hidden md:inline"><%= t('download') %></span>
|
<% if @form_configs[:with_partial_download] %>
|
||||||
</span>
|
<download-button data-src="<%= submit_form_download_index_path(@submitter.slug) %>" class="btn btn-neutral text-white btn-sm px-2" title="<%= t('download') %>">
|
||||||
<span class="flex items-center justify-center space-x-2 hidden" data-target="download-button.loadingButton">
|
<span data-target="download-button.defaultButton">
|
||||||
<%= svg_icon('loader', class: 'w-6 h-6 animate-spin') %>
|
<%= svg_icon('download', class: 'w-5 h-5') %>
|
||||||
<span class="hidden md:inline"><%= t('downloading') %></span>
|
</span>
|
||||||
</span>
|
<span class="hidden" data-target="download-button.loadingButton">
|
||||||
</download-button>
|
<%= svg_icon('loader', class: 'w-5 h-5 animate-spin') %>
|
||||||
|
</span>
|
||||||
|
</download-button>
|
||||||
|
<% end %>
|
||||||
|
<% else %>
|
||||||
|
<% if @form_configs[:with_decline] %>
|
||||||
|
<label id="decline_button" for="<%= decline_modal_checkbox_uuid = SecureRandom.uuid %>" class="btn btn-sm !px-5"><%= t(:decline) %></label>
|
||||||
|
<% end %>
|
||||||
|
<% if @form_configs[:with_partial_download] %>
|
||||||
|
<download-button data-src="<%= submit_form_download_index_path(@submitter.slug) %>" class="btn btn-neutral text-white btn-sm !px-4">
|
||||||
|
<span class="flex items-center justify-center" data-target="download-button.defaultButton">
|
||||||
|
<%= svg_icon('download', class: 'w-6 h-6 inline md:hidden') %>
|
||||||
|
<span class="hidden md:inline"><%= t('download') %></span>
|
||||||
|
</span>
|
||||||
|
<span class="flex items-center justify-center space-x-2 hidden" data-target="download-button.loadingButton">
|
||||||
|
<%= svg_icon('loader', class: 'w-6 h-6 animate-spin') %>
|
||||||
|
<span class="hidden md:inline"><%= t('downloading') %></span>
|
||||||
|
</span>
|
||||||
|
</download-button>
|
||||||
|
<% end %>
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<scroll-buttons class="fixed right-5 top-2 hidden md:flex gap-1 z-50 ease-in-out opacity-0 -translate-y-10">
|
<scroll-buttons class="fixed right-5 top-2 hidden md:flex gap-1 z-50 ease-in-out opacity-0 -translate-y-10">
|
||||||
<% if @form_configs[:with_decline] %>
|
<% if @form_configs[:with_delegate] %>
|
||||||
<label id="decline_button" for="<%= decline_modal_checkbox_uuid %>" class="btn btn-sm px-0">
|
<label id="delegate_button" for="<%= delegate_modal_checkbox_uuid %>" class="btn btn-sm px-0">
|
||||||
<span class="min-[1366px]:inline hidden px-3">
|
<span class="min-[1366px]:inline hidden px-3">
|
||||||
<%= t(:decline) %>
|
<%= t(:delegate) %>
|
||||||
</span>
|
</span>
|
||||||
<span class="inline min-[1366px]:hidden px-2">
|
<span class="inline min-[1366px]:hidden px-2">
|
||||||
<%= svg_icon('x', class: 'w-5 h-5') %>
|
<%= svg_icon('user_share', class: 'w-5 h-5') %>
|
||||||
</span>
|
</span>
|
||||||
</label>
|
</label>
|
||||||
|
<% if @form_configs[:with_decline] %>
|
||||||
|
<label id="decline_button" for="<%= decline_modal_checkbox_uuid %>" class="btn btn-sm px-2">
|
||||||
|
<%= svg_icon('x', class: 'w-5 h-5') %>
|
||||||
|
</label>
|
||||||
|
<% end %>
|
||||||
|
<download-button data-src="<%= submit_form_download_index_path(@submitter.slug) %>" class="btn btn-neutral text-white btn-sm px-2">
|
||||||
|
<span data-target="download-button.defaultButton">
|
||||||
|
<%= svg_icon('download', class: 'w-5 h-5') %>
|
||||||
|
</span>
|
||||||
|
<span class="hidden" data-target="download-button.loadingButton">
|
||||||
|
<%= svg_icon('loader', class: 'w-5 h-5 animate-spin') %>
|
||||||
|
</span>
|
||||||
|
</download-button>
|
||||||
|
<% else %>
|
||||||
|
<% if @form_configs[:with_decline] %>
|
||||||
|
<label id="decline_button" for="<%= decline_modal_checkbox_uuid %>" class="btn btn-sm px-0">
|
||||||
|
<span class="min-[1366px]:inline hidden px-3">
|
||||||
|
<%= t(:decline) %>
|
||||||
|
</span>
|
||||||
|
<span class="inline min-[1366px]:hidden px-2">
|
||||||
|
<%= svg_icon('x', class: 'w-5 h-5') %>
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
<% end %>
|
||||||
|
<download-button data-src="<%= submit_form_download_index_path(@submitter.slug) %>" class="btn btn-neutral text-white btn-sm px-2">
|
||||||
|
<span data-target="download-button.defaultButton">
|
||||||
|
<%= svg_icon('download', class: 'w-5 h-5') %>
|
||||||
|
</span>
|
||||||
|
<span class="hidden" data-target="download-button.loadingButton">
|
||||||
|
<%= svg_icon('loader', class: 'w-5 h-5 animate-spin') %>
|
||||||
|
</span>
|
||||||
|
</download-button>
|
||||||
<% end %>
|
<% end %>
|
||||||
<download-button data-src="<%= submit_form_download_index_path(@submitter.slug) %>" class="btn btn-neutral text-white btn-sm px-2">
|
|
||||||
<span data-target="download-button.defaultButton">
|
|
||||||
<%= svg_icon('download', class: 'w-5 h-5') %>
|
|
||||||
</span>
|
|
||||||
<span class="hidden" data-target="download-button.loadingButton">
|
|
||||||
<%= svg_icon('loader', class: 'w-5 h-5 animate-spin') %>
|
|
||||||
</span>
|
|
||||||
</download-button>
|
|
||||||
</scroll-buttons>
|
</scroll-buttons>
|
||||||
<% end %>
|
<% end %>
|
||||||
<% schema.each do |item| %>
|
<% schema.each do |item| %>
|
||||||
@@ -110,4 +154,9 @@
|
|||||||
<%= render 'submit_form/decline_form', submitter: @submitter %>
|
<%= render 'submit_form/decline_form', submitter: @submitter %>
|
||||||
<% end %>
|
<% end %>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
<% if @form_configs[:with_delegate] %>
|
||||||
|
<%= render 'shared/html_modal', title: t(:delegate), uuid: delegate_modal_checkbox_uuid do %>
|
||||||
|
<%= render 'submit_form/delegate_form', submitter: @submitter %>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
<%= render 'scripts/autosize_field' %>
|
<%= render 'scripts/autosize_field' %>
|
||||||
@@ -49,7 +49,7 @@
|
|||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
<%= link_to template_share_link_path(template), class: "absolute md:relative bottom-0 right-0 btn btn-xs md:btn-sm whitespace-nowrap btn-neutral text-white mt-1 px-2 #{'btn-disabled text-base-100' if template.variables_schema.present?}", data: { turbo_frame: :modal } do %>
|
<%= link_to template_share_link_path(template), class: "absolute md:relative bottom-0 right-0 btn btn-xs md:btn-sm whitespace-nowrap btn-neutral text-white mt-1 px-2", data: { turbo_frame: :modal } do %>
|
||||||
<span class="flex items-center justify-center space-x-2">
|
<span class="flex items-center justify-center space-x-2">
|
||||||
<%= svg_icon('link', class: 'w-4 h-4 md:w-6 md:h-6') %>
|
<%= svg_icon('link', class: 'w-4 h-4 md:w-6 md:h-6') %>
|
||||||
<span><%= t('link') %></span>
|
<span><%= t('link') %></span>
|
||||||
|
|||||||
@@ -2,6 +2,12 @@
|
|||||||
<% enough_defined_submitters = Templates.filter_undefined_submitters(@template.submitters).size < 2 %>
|
<% enough_defined_submitters = Templates.filter_undefined_submitters(@template.submitters).size < 2 %>
|
||||||
<%= render 'shared/turbo_modal_large', title: t('share_link') do %>
|
<%= render 'shared/turbo_modal_large', title: t('share_link') do %>
|
||||||
<div class="mt-2 mb-4 px-5">
|
<div class="mt-2 mb-4 px-5">
|
||||||
|
<% if @template.variables_schema.present? %>
|
||||||
|
<div class="alert items-start bg-base-100 border-base-300 mt-4">
|
||||||
|
<%= svg_icon('info_circle', class: 'stroke-current shrink-0 h-6 w-6') %>
|
||||||
|
<div><%= t('dynamic_template_with_variables_cannot_be_used_via_shared_link') %></div>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
<%= form_for @template, url: template_share_link_path(@template), method: :post, html: { id: 'shared_link_form', autocomplete: 'off', class: 'mt-3' }, data: { close_on_submit: false } do |f| %>
|
<%= form_for @template, url: template_share_link_path(@template), method: :post, html: { id: 'shared_link_form', autocomplete: 'off', class: 'mt-3' }, data: { close_on_submit: false } do |f| %>
|
||||||
<% if @template.preferences&.dig('require_email_2fa') || @template.preferences&.dig('require_phone_2fa') %>
|
<% if @template.preferences&.dig('require_email_2fa') || @template.preferences&.dig('require_phone_2fa') %>
|
||||||
<label for="template_shared_link" class="tooltip tooltip-bottom flex items-center my-4 justify-between gap-1 alert bg-base-100 border-base-300" data-tip="<%= t(:templates_that_require_email_or_phone_2fa_cannot_be_used_via_a_shared_link) %>">
|
<label for="template_shared_link" class="tooltip tooltip-bottom flex items-center my-4 justify-between gap-1 alert bg-base-100 border-base-300" data-tip="<%= t(:templates_that_require_email_or_phone_2fa_cannot_be_used_via_a_shared_link) %>">
|
||||||
@@ -12,7 +18,7 @@
|
|||||||
<label for="template_shared_link" class="flex items-center my-4 justify-between gap-1 alert bg-base-100 border-base-300">
|
<label for="template_shared_link" class="flex items-center my-4 justify-between gap-1 alert bg-base-100 border-base-300">
|
||||||
<span><%= t('enable_shared_link') %></span>
|
<span><%= t('enable_shared_link') %></span>
|
||||||
<submit-form data-on="change" class="flex">
|
<submit-form data-on="change" class="flex">
|
||||||
<%= f.check_box :shared_link, { disabled: !can?(:update, @template), class: 'toggle' }, 'true', 'false' %>
|
<%= f.check_box :shared_link, { disabled: !can?(:update, @template) || @template.variables_schema.present?, class: 'toggle' }, 'true', 'false' %>
|
||||||
</submit-form>
|
</submit-form>
|
||||||
</label>
|
</label>
|
||||||
<% end %>
|
<% end %>
|
||||||
@@ -23,7 +29,7 @@
|
|||||||
</check-on-click>
|
</check-on-click>
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
<% if multiple_submitters && !enough_defined_submitters %>
|
<% if multiple_submitters && !enough_defined_submitters && @template.variables_schema.blank? %>
|
||||||
<div class="alert items-start bg-base-100 border-base-300 mt-4">
|
<div class="alert items-start bg-base-100 border-base-300 mt-4">
|
||||||
<%= svg_icon('info_circle', class: 'stroke-current shrink-0 h-6 w-6 mt-1') %>
|
<%= svg_icon('info_circle', class: 'stroke-current shrink-0 h-6 w-6 mt-1') %>
|
||||||
<div><%= t('this_template_has_multiple_parties_which_prevents_the_use_of_a_sharing_link') %></div>
|
<div><%= t('this_template_has_multiple_parties_which_prevents_the_use_of_a_sharing_link') %></div>
|
||||||
|
|||||||
@@ -88,6 +88,8 @@ Rails.application.configure do
|
|||||||
openssl_verify_mode: ENV['SMTP_SSL_VERIFY'] == 'false' ? OpenSSL::SSL::VERIFY_NONE : OpenSSL::SSL::VERIFY_PEER,
|
openssl_verify_mode: ENV['SMTP_SSL_VERIFY'] == 'false' ? OpenSSL::SSL::VERIFY_NONE : OpenSSL::SSL::VERIFY_PEER,
|
||||||
authentication: ENV.fetch('SMTP_PASSWORD', nil).present? ? ENV.fetch('SMTP_AUTHENTICATION', 'plain') : nil,
|
authentication: ENV.fetch('SMTP_PASSWORD', nil).present? ? ENV.fetch('SMTP_AUTHENTICATION', 'plain') : nil,
|
||||||
enable_starttls: ENV['SMTP_ENABLE_STARTTLS'] != 'false',
|
enable_starttls: ENV['SMTP_ENABLE_STARTTLS'] != 'false',
|
||||||
|
ssl: ENV['SMTP_ENABLE_SSL'] == 'true',
|
||||||
|
tls: ENV['SMTP_ENABLE_TLS'] == 'true',
|
||||||
open_timeout: ENV.fetch('SMTP_OPEN_TIMEOUT', '15').to_i,
|
open_timeout: ENV.fetch('SMTP_OPEN_TIMEOUT', '15').to_i,
|
||||||
read_timeout: ENV.fetch('SMTP_READ_TIMEOUT', '25').to_i
|
read_timeout: ENV.fetch('SMTP_READ_TIMEOUT', '25').to_i
|
||||||
}.compact
|
}.compact
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module SilenceErrors
|
||||||
|
def log_error(request, wrapper)
|
||||||
|
return if wrapper.status_code == 404
|
||||||
|
|
||||||
|
super
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
ActionDispatch::DebugExceptions.prepend(SilenceErrors)
|
||||||
@@ -163,10 +163,13 @@ en: &en
|
|||||||
download: Download
|
download: Download
|
||||||
decline: Decline
|
decline: Decline
|
||||||
declined: Declined
|
declined: Declined
|
||||||
|
delegate: Delegate
|
||||||
|
enter_the_email_address_of_the_person_you_want_to_delegate_to: Enter the email address of the person you want to delegate to
|
||||||
decline_reason: Decline reason
|
decline_reason: Decline reason
|
||||||
provide_a_reason: Provide a reason
|
provide_a_reason: Provide a reason
|
||||||
notify_the_sender_with_the_reason_you_declined: Notify the sender with the reason you declined
|
notify_the_sender_with_the_reason_you_declined: Notify the sender with the reason you declined
|
||||||
form_has_been_declined_on_html: 'Form has been declined on <span class="font-semibold">%{time}</span>'
|
form_has_been_declined_on_html: 'Form has been declined on <span class="font-semibold">%{time}</span>'
|
||||||
|
document_has_been_delegated_on_html: 'Document has been delegated on <span class="font-semibold">%{time}</span>'
|
||||||
name_declined_by_submitter: '"%{name}" declined by %{submitter}'
|
name_declined_by_submitter: '"%{name}" declined by %{submitter}'
|
||||||
name_declined_by_submitter_with_the_following_reason: '"%{name}" has been declined by %{submitter} with the following reason:'
|
name_declined_by_submitter_with_the_following_reason: '"%{name}" has been declined by %{submitter} with the following reason:'
|
||||||
completed_successfully: Completed Successfully
|
completed_successfully: Completed Successfully
|
||||||
@@ -201,6 +204,7 @@ en: &en
|
|||||||
allow_typed_text_signatures: Allow typed text signatures
|
allow_typed_text_signatures: Allow typed text signatures
|
||||||
allow_to_resubmit_completed_forms: Allow to resubmit completed forms
|
allow_to_resubmit_completed_forms: Allow to resubmit completed forms
|
||||||
allow_to_decline_documents: Allow to decline documents
|
allow_to_decline_documents: Allow to decline documents
|
||||||
|
allow_to_delegate_documents: Allow to delegate documents
|
||||||
remember_and_pre_fill_signatures: Remember and pre-fill signatures
|
remember_and_pre_fill_signatures: Remember and pre-fill signatures
|
||||||
require_authentication_for_file_download_links: Require authentication for file download links
|
require_authentication_for_file_download_links: Require authentication for file download links
|
||||||
combine_completed_documents_and_audit_log: Combine completed documents and Audit Log
|
combine_completed_documents_and_audit_log: Combine completed documents and Audit Log
|
||||||
@@ -787,6 +791,7 @@ en: &en
|
|||||||
share_link: Share link
|
share_link: Share link
|
||||||
enable_shared_link: Enable shared link
|
enable_shared_link: Enable shared link
|
||||||
share_link_is_currently_disabled: Share link is currently disabled
|
share_link_is_currently_disabled: Share link is currently disabled
|
||||||
|
dynamic_template_with_variables_cannot_be_used_via_shared_link: Dynamic template with variables can't be used via a shared link
|
||||||
select_data_residency: Select data residency
|
select_data_residency: Select data residency
|
||||||
account_name_has_invited_you_to_fill_and_sign_documents_online_effortlessly_with_a_secure_fast_and_user_friendly_digital_document_signing_solution: '%{account_name} has invited you to fill and sign documents online effortlessly with a secure, fast, and user-friendly digital document signing solution.'
|
account_name_has_invited_you_to_fill_and_sign_documents_online_effortlessly_with_a_secure_fast_and_user_friendly_digital_document_signing_solution: '%{account_name} has invited you to fill and sign documents online effortlessly with a secure, fast, and user-friendly digital document signing solution.'
|
||||||
review_or_download_completed_documents_fill_and_sign_documents_online_effortlessly_with_a_secure_fast_and_user_friendly_digital_document_signing_solution: Review or download completed documents. Fill and sign documents online effortlessly with a secure, fast, and user-friendly digital document signing solution.
|
review_or_download_completed_documents_fill_and_sign_documents_online_effortlessly_with_a_secure_fast_and_user_friendly_digital_document_signing_solution: Review or download completed documents. Fill and sign documents online effortlessly with a secure, fast, and user-friendly digital document signing solution.
|
||||||
@@ -841,6 +846,7 @@ en: &en
|
|||||||
allow_signers_to_create_signatures_by_typing_their_name_instead_of_drawing_or_uploading_one: Allow signers to create signatures by typing their name instead of drawing or uploading one.
|
allow_signers_to_create_signatures_by_typing_their_name_instead_of_drawing_or_uploading_one: Allow signers to create signatures by typing their name instead of drawing or uploading one.
|
||||||
allow_signers_to_resubmit_forms_after_completion_useful_when_corrections_or_multiple_submissions_are_needed: Allow signers to resubmit forms after completion, useful when corrections or multiple submissions are needed.
|
allow_signers_to_resubmit_forms_after_completion_useful_when_corrections_or_multiple_submissions_are_needed: Allow signers to resubmit forms after completion, useful when corrections or multiple submissions are needed.
|
||||||
allow_recipients_to_decline_signing_a_document_the_decline_reason_notification_will_be_sent_to_the_signature_requester: Allow recipients to decline signing a document. The decline reason notification will be sent to the signature requester.
|
allow_recipients_to_decline_signing_a_document_the_decline_reason_notification_will_be_sent_to_the_signature_requester: Allow recipients to decline signing a document. The decline reason notification will be sent to the signature requester.
|
||||||
|
allow_recipients_to_delegate_documents: Allow recipients to delegate documents to a different person via email. This can be useful when the original recipient needs to pass the document to the authorized signer.
|
||||||
save_a_users_signature_and_automatically_pre_fill_it_in_future_signing_sessions: "Save a user's signature and automatically pre-fill it in future signing sessions."
|
save_a_users_signature_and_automatically_pre_fill_it_in_future_signing_sessions: "Save a user's signature and automatically pre-fill it in future signing sessions."
|
||||||
make_document_download_links_expire_after_40_minutes_to_prevent_long_term_access_and_enhance_security: Make document download links expire after 40 minutes to prevent long-term access and enhance security.
|
make_document_download_links_expire_after_40_minutes_to_prevent_long_term_access_and_enhance_security: Make document download links expire after 40 minutes to prevent long-term access and enhance security.
|
||||||
require_authentication_with_user_login_or_api_key_to_access_the_document_download_links: Require authentication with user login or API key to access the document download links.
|
require_authentication_with_user_login_or_api_key_to_access_the_document_download_links: Require authentication with user login or API key to access the document download links.
|
||||||
@@ -914,6 +920,9 @@ en: &en
|
|||||||
connect_to_docuseal_mcp: Connect to DocuSeal MCP
|
connect_to_docuseal_mcp: Connect to DocuSeal MCP
|
||||||
add_the_following_to_your_mcp_client_configuration: Add the following to your MCP client configuration
|
add_the_following_to_your_mcp_client_configuration: Add the following to your MCP client configuration
|
||||||
works_with_claude_desktop_cursor_windsurf_vs_code_and_any_mcp_compatible_client: Works with Claude Desktop, Cursor, Windsurf, VS Code, and any MCP-compatible client.
|
works_with_claude_desktop_cursor_windsurf_vs_code_and_any_mcp_compatible_client: Works with Claude Desktop, Cursor, Windsurf, VS Code, and any MCP-compatible client.
|
||||||
|
your_email_address_has_been_changed: Your email address has been changed
|
||||||
|
the_email_address_for_your_account_has_been_changed_to_new_email: The email address for your account has been changed to %{new_email}.
|
||||||
|
if_you_did_not_make_this_change_please_contact_us_by_replying_to_this_email: If you did not make this change, please contact us by replying to this email.
|
||||||
devise:
|
devise:
|
||||||
confirmations:
|
confirmations:
|
||||||
confirmed: Your email address has been successfully confirmed.
|
confirmed: Your email address has been successfully confirmed.
|
||||||
@@ -951,6 +960,8 @@ en: &en
|
|||||||
complete_kba_by_html: '<b>KBA completed</b> by %{submitter_name}'
|
complete_kba_by_html: '<b>KBA completed</b> by %{submitter_name}'
|
||||||
fail_kba_by_html: '<b>KBA failed</b> by %{submitter_name}'
|
fail_kba_by_html: '<b>KBA failed</b> by %{submitter_name}'
|
||||||
api_complete_form_by_html: '<b>Submission completed via API</b> by %{submitter_name}'
|
api_complete_form_by_html: '<b>Submission completed via API</b> by %{submitter_name}'
|
||||||
|
decline_form_by_html: '<b>Form declined</b> by %{submitter_name}'
|
||||||
|
delegate_form_by_html: '<b>Delegated</b> from %{from} to %{to}'
|
||||||
import_list:
|
import_list:
|
||||||
select_worksheet: Select Worksheet
|
select_worksheet: Select Worksheet
|
||||||
open: Open
|
open: Open
|
||||||
@@ -1189,11 +1200,14 @@ es: &es
|
|||||||
downloading: Descargando
|
downloading: Descargando
|
||||||
download: Descargar
|
download: Descargar
|
||||||
decline: Rechazar
|
decline: Rechazar
|
||||||
|
delegate: Delegar
|
||||||
|
enter_the_email_address_of_the_person_you_want_to_delegate_to: Ingrese la dirección de correo electrónico de la persona a quien desea delegar
|
||||||
declined: Rechazado
|
declined: Rechazado
|
||||||
decline_reason: Motivo de rechazo
|
decline_reason: Motivo de rechazo
|
||||||
provide_a_reason: Proporcione un motivo
|
provide_a_reason: Proporcione un motivo
|
||||||
notify_the_sender_with_the_reason_you_declined: Notifique al remitente con el motivo por el que rechazó
|
notify_the_sender_with_the_reason_you_declined: Notifique al remitente con el motivo por el que rechazó
|
||||||
form_has_been_declined_on_html: 'El formulario ha sido rechazado el <span class="font-semibold">%{time}</span>'
|
form_has_been_declined_on_html: 'El formulario ha sido rechazado el <span class="font-semibold">%{time}</span>'
|
||||||
|
document_has_been_delegated_on_html: 'El documento ha sido delegado el <span class="font-semibold">%{time}</span>'
|
||||||
name_declined_by_submitter: '"%{name}" rechazado por %{submitter}'
|
name_declined_by_submitter: '"%{name}" rechazado por %{submitter}'
|
||||||
name_declined_by_submitter_with_the_following_reason: '"%{name}" ha sido rechazado por %{submitter} con el siguiente motivo:'
|
name_declined_by_submitter_with_the_following_reason: '"%{name}" ha sido rechazado por %{submitter} con el siguiente motivo:'
|
||||||
completed_successfully: Completado exitosamente
|
completed_successfully: Completado exitosamente
|
||||||
@@ -1228,6 +1242,7 @@ es: &es
|
|||||||
allow_typed_text_signatures: Permitir firmas de texto mecanografiadas
|
allow_typed_text_signatures: Permitir firmas de texto mecanografiadas
|
||||||
allow_to_resubmit_completed_forms: Permitir reenviar formularios completados
|
allow_to_resubmit_completed_forms: Permitir reenviar formularios completados
|
||||||
allow_to_decline_documents: Permitir rechazar documentos
|
allow_to_decline_documents: Permitir rechazar documentos
|
||||||
|
allow_to_delegate_documents: Permitir delegar documentos
|
||||||
remember_and_pre_fill_signatures: Recordar y prellenar firmas
|
remember_and_pre_fill_signatures: Recordar y prellenar firmas
|
||||||
require_authentication_for_file_download_links: Requerir autenticación para enlaces de descarga de archivos
|
require_authentication_for_file_download_links: Requerir autenticación para enlaces de descarga de archivos
|
||||||
combine_completed_documents_and_audit_log: Combinar documentos completados y Registro de Auditoría
|
combine_completed_documents_and_audit_log: Combinar documentos completados y Registro de Auditoría
|
||||||
@@ -1811,6 +1826,7 @@ es: &es
|
|||||||
share_link: Enlace para compartir
|
share_link: Enlace para compartir
|
||||||
enable_shared_link: Habilitar enlace compartido
|
enable_shared_link: Habilitar enlace compartido
|
||||||
share_link_is_currently_disabled: El enlace compartido está deshabilitado actualmente
|
share_link_is_currently_disabled: El enlace compartido está deshabilitado actualmente
|
||||||
|
dynamic_template_with_variables_cannot_be_used_via_shared_link: La plantilla dinámica con variables no se puede usar mediante un enlace compartido
|
||||||
select_data_residency: Seleccionar ubicación de datos
|
select_data_residency: Seleccionar ubicación de datos
|
||||||
account_name_has_invited_you_to_fill_and_sign_documents_online_effortlessly_with_a_secure_fast_and_user_friendly_digital_document_signing_solution: '%{account_name} te ha invitado a completar y firmar documentos en línea fácilmente con una solución de firma digital segura, rápida y fácil de usar.'
|
account_name_has_invited_you_to_fill_and_sign_documents_online_effortlessly_with_a_secure_fast_and_user_friendly_digital_document_signing_solution: '%{account_name} te ha invitado a completar y firmar documentos en línea fácilmente con una solución de firma digital segura, rápida y fácil de usar.'
|
||||||
review_or_download_completed_documents_fill_and_sign_documents_online_effortlessly_with_a_secure_fast_and_user_friendly_digital_document_signing_solution: Revisa o descarga los documentos completados. Completa y firma documentos en línea fácilmente con una solución de firma digital segura, rápida y fácil de usar.
|
review_or_download_completed_documents_fill_and_sign_documents_online_effortlessly_with_a_secure_fast_and_user_friendly_digital_document_signing_solution: Revisa o descarga los documentos completados. Completa y firma documentos en línea fácilmente con una solución de firma digital segura, rápida y fácil de usar.
|
||||||
@@ -1865,6 +1881,7 @@ es: &es
|
|||||||
allow_signers_to_create_signatures_by_typing_their_name_instead_of_drawing_or_uploading_one: Permitir que los firmantes creen firmas escribiendo su nombre en lugar de dibujar o subir una.
|
allow_signers_to_create_signatures_by_typing_their_name_instead_of_drawing_or_uploading_one: Permitir que los firmantes creen firmas escribiendo su nombre en lugar de dibujar o subir una.
|
||||||
allow_signers_to_resubmit_forms_after_completion_useful_when_corrections_or_multiple_submissions_are_needed: Permitir que los firmantes vuelvan a enviar formularios después de completarlos, útil cuando se necesitan correcciones o múltiples envíos.
|
allow_signers_to_resubmit_forms_after_completion_useful_when_corrections_or_multiple_submissions_are_needed: Permitir que los firmantes vuelvan a enviar formularios después de completarlos, útil cuando se necesitan correcciones o múltiples envíos.
|
||||||
allow_recipients_to_decline_signing_a_document_the_decline_reason_notification_will_be_sent_to_the_signature_requester: Permitir que los destinatarios rechacen firmar un documento. La notificación del motivo del rechazo se enviará al solicitante de la firma.
|
allow_recipients_to_decline_signing_a_document_the_decline_reason_notification_will_be_sent_to_the_signature_requester: Permitir que los destinatarios rechacen firmar un documento. La notificación del motivo del rechazo se enviará al solicitante de la firma.
|
||||||
|
allow_recipients_to_delegate_documents: Permitir que los destinatarios deleguen documentos a otra persona por correo electrónico. Esto puede ser útil cuando el destinatario original necesita pasar el documento al firmante autorizado.
|
||||||
save_a_users_signature_and_automatically_pre_fill_it_in_future_signing_sessions: Guardar la firma de un usuario y rellenarla automáticamente en futuras sesiones de firma.
|
save_a_users_signature_and_automatically_pre_fill_it_in_future_signing_sessions: Guardar la firma de un usuario y rellenarla automáticamente en futuras sesiones de firma.
|
||||||
make_document_download_links_expire_after_40_minutes_to_prevent_long_term_access_and_enhance_security: Hacer que los enlaces de descarga de documentos caduquen después de 40 minutos para evitar el acceso a largo plazo y mejorar la seguridad.
|
make_document_download_links_expire_after_40_minutes_to_prevent_long_term_access_and_enhance_security: Hacer que los enlaces de descarga de documentos caduquen después de 40 minutos para evitar el acceso a largo plazo y mejorar la seguridad.
|
||||||
require_authentication_with_user_login_or_api_key_to_access_the_document_download_links: Requerir autenticación con inicio de sesión de usuario o clave API para acceder a los enlaces de descarga de documentos.
|
require_authentication_with_user_login_or_api_key_to_access_the_document_download_links: Requerir autenticación con inicio de sesión de usuario o clave API para acceder a los enlaces de descarga de documentos.
|
||||||
@@ -1938,6 +1955,9 @@ es: &es
|
|||||||
connect_to_docuseal_mcp: Conectar a DocuSeal MCP
|
connect_to_docuseal_mcp: Conectar a DocuSeal MCP
|
||||||
add_the_following_to_your_mcp_client_configuration: Agregue lo siguiente a la configuración de su cliente MCP
|
add_the_following_to_your_mcp_client_configuration: Agregue lo siguiente a la configuración de su cliente MCP
|
||||||
works_with_claude_desktop_cursor_windsurf_vs_code_and_any_mcp_compatible_client: Funciona con Claude Desktop, Cursor, Windsurf, VS Code y cualquier cliente compatible con MCP.
|
works_with_claude_desktop_cursor_windsurf_vs_code_and_any_mcp_compatible_client: Funciona con Claude Desktop, Cursor, Windsurf, VS Code y cualquier cliente compatible con MCP.
|
||||||
|
your_email_address_has_been_changed: Tu dirección de correo electrónico ha sido cambiada
|
||||||
|
the_email_address_for_your_account_has_been_changed_to_new_email: La dirección de correo electrónico de tu cuenta ha sido cambiada a %{new_email}.
|
||||||
|
if_you_did_not_make_this_change_please_contact_us_by_replying_to_this_email: Si no realizaste este cambio, contáctanos respondiendo a este correo electrónico.
|
||||||
devise:
|
devise:
|
||||||
confirmations:
|
confirmations:
|
||||||
confirmed: Tu dirección de correo electrónico ha sido confirmada correctamente.
|
confirmed: Tu dirección de correo electrónico ha sido confirmada correctamente.
|
||||||
@@ -1970,6 +1990,8 @@ es: &es
|
|||||||
invite_party_by_html: '<b>Invitado</b> %{invited_submitter_name} por %{submitter_name}'
|
invite_party_by_html: '<b>Invitado</b> %{invited_submitter_name} por %{submitter_name}'
|
||||||
complete_form_by_html: '<b>Envío completado</b> por %{submitter_name}'
|
complete_form_by_html: '<b>Envío completado</b> por %{submitter_name}'
|
||||||
api_complete_form_by_html: '<b>Envío completado vía API</b> por %{submitter_name}'
|
api_complete_form_by_html: '<b>Envío completado vía API</b> por %{submitter_name}'
|
||||||
|
decline_form_by_html: '<b>Formulario rechazado</b> por %{submitter_name}'
|
||||||
|
delegate_form_by_html: '<b>Delegado</b> de %{from} a %{to}'
|
||||||
start_verification_by_html: '<b>Verificación de identidad iniciada</b> por %{submitter_name}'
|
start_verification_by_html: '<b>Verificación de identidad iniciada</b> por %{submitter_name}'
|
||||||
complete_verification_by_html: '<b>Verificación de identidad completada</b> por %{submitter_name} con %{provider}'
|
complete_verification_by_html: '<b>Verificación de identidad completada</b> por %{submitter_name} con %{provider}'
|
||||||
start_kba_by_html: '<b>KBA iniciado</b> por %{submitter_name}'
|
start_kba_by_html: '<b>KBA iniciado</b> por %{submitter_name}'
|
||||||
@@ -2213,11 +2235,14 @@ it: &it
|
|||||||
downloading: Scaricamento
|
downloading: Scaricamento
|
||||||
download: Scarica
|
download: Scarica
|
||||||
decline: Rifiuta
|
decline: Rifiuta
|
||||||
|
delegate: Delega
|
||||||
|
enter_the_email_address_of_the_person_you_want_to_delegate_to: Inserisci l'indirizzo email della persona a cui vuoi delegare
|
||||||
declined: Rifiutato
|
declined: Rifiutato
|
||||||
decline_reason: Motivo del rifiuto
|
decline_reason: Motivo del rifiuto
|
||||||
provide_a_reason: Fornisci un motivo
|
provide_a_reason: Fornisci un motivo
|
||||||
notify_the_sender_with_the_reason_you_declined: Informare il mittente del motivo per cui hai rifiutato
|
notify_the_sender_with_the_reason_you_declined: Informare il mittente del motivo per cui hai rifiutato
|
||||||
form_has_been_declined_on_html: 'Il modulo è stato rifiutato il <span class="font-semibold">%{time}</span>'
|
form_has_been_declined_on_html: 'Il modulo è stato rifiutato il <span class="font-semibold">%{time}</span>'
|
||||||
|
document_has_been_delegated_on_html: 'Il documento è stato delegato il <span class="font-semibold">%{time}</span>'
|
||||||
name_declined_by_submitter: '"%{name}" rifiutato da %{submitter}'
|
name_declined_by_submitter: '"%{name}" rifiutato da %{submitter}'
|
||||||
name_declined_by_submitter_with_the_following_reason: '"%{name}" è stato rifiutato da %{submitter} per il seguente motivo:'
|
name_declined_by_submitter_with_the_following_reason: '"%{name}" è stato rifiutato da %{submitter} per il seguente motivo:'
|
||||||
completed_successfully: Completato con successo
|
completed_successfully: Completato con successo
|
||||||
@@ -2252,6 +2277,7 @@ it: &it
|
|||||||
allow_typed_text_signatures: Permettere firme con testo digitato
|
allow_typed_text_signatures: Permettere firme con testo digitato
|
||||||
allow_to_resubmit_completed_forms: Permettere di reinviare i moduli completati
|
allow_to_resubmit_completed_forms: Permettere di reinviare i moduli completati
|
||||||
allow_to_decline_documents: Permettere di rifiutare i documenti
|
allow_to_decline_documents: Permettere di rifiutare i documenti
|
||||||
|
allow_to_delegate_documents: Permettere di delegare i documenti
|
||||||
remember_and_pre_fill_signatures: Ricordare e precompilare le firme
|
remember_and_pre_fill_signatures: Ricordare e precompilare le firme
|
||||||
require_authentication_for_file_download_links: "Richiedere l'autenticazione per i link di download dei file"
|
require_authentication_for_file_download_links: "Richiedere l'autenticazione per i link di download dei file"
|
||||||
combine_completed_documents_and_audit_log: Combinare i documenti completati e il Registro di Audit
|
combine_completed_documents_and_audit_log: Combinare i documenti completati e il Registro di Audit
|
||||||
@@ -2835,6 +2861,7 @@ it: &it
|
|||||||
share_link: Link di condivisione
|
share_link: Link di condivisione
|
||||||
enable_shared_link: Abilita link condiviso
|
enable_shared_link: Abilita link condiviso
|
||||||
share_link_is_currently_disabled: Il link condiviso è attualmente disabilitato
|
share_link_is_currently_disabled: Il link condiviso è attualmente disabilitato
|
||||||
|
dynamic_template_with_variables_cannot_be_used_via_shared_link: Il template dinamico con variabili non può essere utilizzato tramite link condiviso
|
||||||
select_data_residency: Seleziona la residenza dei dati
|
select_data_residency: Seleziona la residenza dei dati
|
||||||
account_name_has_invited_you_to_fill_and_sign_documents_online_effortlessly_with_a_secure_fast_and_user_friendly_digital_document_signing_solution: '%{account_name} ti ha invitato a compilare e firmare documenti online con facilità utilizzando una soluzione di firma digitale sicura, veloce e facile da usare.'
|
account_name_has_invited_you_to_fill_and_sign_documents_online_effortlessly_with_a_secure_fast_and_user_friendly_digital_document_signing_solution: '%{account_name} ti ha invitato a compilare e firmare documenti online con facilità utilizzando una soluzione di firma digitale sicura, veloce e facile da usare.'
|
||||||
review_or_download_completed_documents_fill_and_sign_documents_online_effortlessly_with_a_secure_fast_and_user_friendly_digital_document_signing_solution: Rivedi o scarica i documenti completati. Compila e firma documenti online facilmente con una soluzione di firma digitale sicura, veloce e facile da usare.
|
review_or_download_completed_documents_fill_and_sign_documents_online_effortlessly_with_a_secure_fast_and_user_friendly_digital_document_signing_solution: Rivedi o scarica i documenti completati. Compila e firma documenti online facilmente con una soluzione di firma digitale sicura, veloce e facile da usare.
|
||||||
@@ -2890,6 +2917,7 @@ it: &it
|
|||||||
allow_signers_to_create_signatures_by_typing_their_name_instead_of_drawing_or_uploading_one: Consentire ai firmatari di creare firme digitando il proprio nome invece di disegnarle o caricarle.
|
allow_signers_to_create_signatures_by_typing_their_name_instead_of_drawing_or_uploading_one: Consentire ai firmatari di creare firme digitando il proprio nome invece di disegnarle o caricarle.
|
||||||
allow_signers_to_resubmit_forms_after_completion_useful_when_corrections_or_multiple_submissions_are_needed: Consentire ai firmatari di reinviare i moduli dopo il completamento, utile quando sono necessarie correzioni o più invii.
|
allow_signers_to_resubmit_forms_after_completion_useful_when_corrections_or_multiple_submissions_are_needed: Consentire ai firmatari di reinviare i moduli dopo il completamento, utile quando sono necessarie correzioni o più invii.
|
||||||
allow_recipients_to_decline_signing_a_document_the_decline_reason_notification_will_be_sent_to_the_signature_requester: Consentire ai destinatari di rifiutare di firmare un documento. La notifica del motivo del rifiuto verrà inviata al richiedente della firma.
|
allow_recipients_to_decline_signing_a_document_the_decline_reason_notification_will_be_sent_to_the_signature_requester: Consentire ai destinatari di rifiutare di firmare un documento. La notifica del motivo del rifiuto verrà inviata al richiedente della firma.
|
||||||
|
allow_recipients_to_delegate_documents: Consentire ai destinatari di delegare i documenti a un'altra persona tramite e-mail. Ciò può essere utile quando il destinatario originale deve passare il documento al firmatario autorizzato.
|
||||||
save_a_users_signature_and_automatically_pre_fill_it_in_future_signing_sessions: Salvare la firma di un utente e compilarla automaticamente nelle future sessioni di firma.
|
save_a_users_signature_and_automatically_pre_fill_it_in_future_signing_sessions: Salvare la firma di un utente e compilarla automaticamente nelle future sessioni di firma.
|
||||||
make_document_download_links_expire_after_40_minutes_to_prevent_long_term_access_and_enhance_security: "Fare in modo che i link di download dei documenti scadano dopo 40 minuti per prevenire l'accesso a lungo termine e migliorare la sicurezza."
|
make_document_download_links_expire_after_40_minutes_to_prevent_long_term_access_and_enhance_security: "Fare in modo che i link di download dei documenti scadano dopo 40 minuti per prevenire l'accesso a lungo termine e migliorare la sicurezza."
|
||||||
require_authentication_with_user_login_or_api_key_to_access_the_document_download_links: "Richiedere l'autenticazione con login utente o chiave API per accedere ai link di download dei documenti."
|
require_authentication_with_user_login_or_api_key_to_access_the_document_download_links: "Richiedere l'autenticazione con login utente o chiave API per accedere ai link di download dei documenti."
|
||||||
@@ -2963,6 +2991,9 @@ it: &it
|
|||||||
connect_to_docuseal_mcp: Connetti a DocuSeal MCP
|
connect_to_docuseal_mcp: Connetti a DocuSeal MCP
|
||||||
add_the_following_to_your_mcp_client_configuration: Aggiungi quanto segue alla configurazione del tuo client MCP
|
add_the_following_to_your_mcp_client_configuration: Aggiungi quanto segue alla configurazione del tuo client MCP
|
||||||
works_with_claude_desktop_cursor_windsurf_vs_code_and_any_mcp_compatible_client: Funziona con Claude Desktop, Cursor, Windsurf, VS Code e qualsiasi client compatibile con MCP.
|
works_with_claude_desktop_cursor_windsurf_vs_code_and_any_mcp_compatible_client: Funziona con Claude Desktop, Cursor, Windsurf, VS Code e qualsiasi client compatibile con MCP.
|
||||||
|
your_email_address_has_been_changed: Il tuo indirizzo email è stato modificato
|
||||||
|
the_email_address_for_your_account_has_been_changed_to_new_email: L'indirizzo email del tuo account è stato modificato in %{new_email}.
|
||||||
|
if_you_did_not_make_this_change_please_contact_us_by_replying_to_this_email: Se non hai effettuato questa modifica, contattaci rispondendo a questa email.
|
||||||
devise:
|
devise:
|
||||||
confirmations:
|
confirmations:
|
||||||
confirmed: Il tuo indirizzo email è stato confermato con successo.
|
confirmed: Il tuo indirizzo email è stato confermato con successo.
|
||||||
@@ -2995,6 +3026,8 @@ it: &it
|
|||||||
invite_party_by_html: '<b>Invitato</b> %{invited_submitter_name} da %{submitter_name}'
|
invite_party_by_html: '<b>Invitato</b> %{invited_submitter_name} da %{submitter_name}'
|
||||||
complete_form_by_html: '<b>Invio completato</b> da %{submitter_name}'
|
complete_form_by_html: '<b>Invio completato</b> da %{submitter_name}'
|
||||||
api_complete_form_by_html: '<b>Invio completato tramite API</b> da %{submitter_name}'
|
api_complete_form_by_html: '<b>Invio completato tramite API</b> da %{submitter_name}'
|
||||||
|
decline_form_by_html: '<b>Modulo rifiutato</b> da %{submitter_name}'
|
||||||
|
delegate_form_by_html: '<b>Delegato</b> da %{from} a %{to}'
|
||||||
start_verification_by_html: "<b>Verifica dell'identità iniziata</b> da %{submitter_name}"
|
start_verification_by_html: "<b>Verifica dell'identità iniziata</b> da %{submitter_name}"
|
||||||
complete_verification_by_html: "<b>Verifica dell'identità completata</b> da %{submitter_name} con %{provider}"
|
complete_verification_by_html: "<b>Verifica dell'identità completata</b> da %{submitter_name} con %{provider}"
|
||||||
start_kba_by_html: "<b>KBA avviata</b> da %{submitter_name}"
|
start_kba_by_html: "<b>KBA avviata</b> da %{submitter_name}"
|
||||||
@@ -3238,11 +3271,14 @@ fr: &fr
|
|||||||
downloading: Téléchargement
|
downloading: Téléchargement
|
||||||
download: Télécharger
|
download: Télécharger
|
||||||
decline: Refuser
|
decline: Refuser
|
||||||
|
delegate: Déléguer
|
||||||
|
enter_the_email_address_of_the_person_you_want_to_delegate_to: Saisissez l'adresse e-mail de la personne à qui vous souhaitez déléguer
|
||||||
declined: Refusé
|
declined: Refusé
|
||||||
decline_reason: Motif du refus
|
decline_reason: Motif du refus
|
||||||
provide_a_reason: Fournissez un motif
|
provide_a_reason: Fournissez un motif
|
||||||
notify_the_sender_with_the_reason_you_declined: Notifier l’expéditeur avec le motif du refus
|
notify_the_sender_with_the_reason_you_declined: Notifier l’expéditeur avec le motif du refus
|
||||||
form_has_been_declined_on_html: Le formulaire a été refusé le <span class="font-semibold">%{time}</span>
|
form_has_been_declined_on_html: Le formulaire a été refusé le <span class="font-semibold">%{time}</span>
|
||||||
|
document_has_been_delegated_on_html: Le document a été délégué le <span class="font-semibold">%{time}</span>
|
||||||
name_declined_by_submitter: '"%{name}" refusé par %{submitter}'
|
name_declined_by_submitter: '"%{name}" refusé par %{submitter}'
|
||||||
name_declined_by_submitter_with_the_following_reason: '"%{name}" a été refusé par %{submitter} pour le motif suivant :'
|
name_declined_by_submitter_with_the_following_reason: '"%{name}" a été refusé par %{submitter} pour le motif suivant :'
|
||||||
completed_successfully: Terminé avec succès
|
completed_successfully: Terminé avec succès
|
||||||
@@ -3277,6 +3313,7 @@ fr: &fr
|
|||||||
allow_typed_text_signatures: Autoriser les signatures tapées
|
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_resubmit_completed_forms: Autoriser la nouvelle soumission des formulaires complétés
|
||||||
allow_to_decline_documents: Autoriser le refus de documents
|
allow_to_decline_documents: Autoriser le refus de documents
|
||||||
|
allow_to_delegate_documents: Autoriser la délégation de documents
|
||||||
remember_and_pre_fill_signatures: Mémoriser et pré-remplir les signatures
|
remember_and_pre_fill_signatures: Mémoriser et pré-remplir les signatures
|
||||||
require_authentication_for_file_download_links: Exiger une authentification pour les liens de téléchargement
|
require_authentication_for_file_download_links: Exiger une authentification pour les liens de téléchargement
|
||||||
combine_completed_documents_and_audit_log: Combiner les documents complétés et le journal d’audit
|
combine_completed_documents_and_audit_log: Combiner les documents complétés et le journal d’audit
|
||||||
@@ -3857,6 +3894,7 @@ fr: &fr
|
|||||||
share_link: Lien de partage
|
share_link: Lien de partage
|
||||||
enable_shared_link: Activer le lien partagé
|
enable_shared_link: Activer le lien partagé
|
||||||
share_link_is_currently_disabled: Le lien de partage est actuellement désactivé
|
share_link_is_currently_disabled: Le lien de partage est actuellement désactivé
|
||||||
|
dynamic_template_with_variables_cannot_be_used_via_shared_link: Le modèle dynamique avec des variables ne peut pas être utilisé via un lien partagé
|
||||||
select_data_residency: Sélectionner la résidence des données
|
select_data_residency: Sélectionner la résidence des données
|
||||||
account_name_has_invited_you_to_fill_and_sign_documents_online_effortlessly_with_a_secure_fast_and_user_friendly_digital_document_signing_solution: "%{account_name} vous a invité à remplir et signer des documents en ligne facilement, grâce à une solution de signature numérique sécurisée, rapide et conviviale."
|
account_name_has_invited_you_to_fill_and_sign_documents_online_effortlessly_with_a_secure_fast_and_user_friendly_digital_document_signing_solution: "%{account_name} vous a invité à remplir et signer des documents en ligne facilement, grâce à une solution de signature numérique sécurisée, rapide et conviviale."
|
||||||
review_or_download_completed_documents_fill_and_sign_documents_online_effortlessly_with_a_secure_fast_and_user_friendly_digital_document_signing_solution: Consultez ou téléchargez les documents complétés. Remplissez et signez des documents en ligne facilement, grâce à une solution de signature numérique sécurisée, rapide et conviviale.
|
review_or_download_completed_documents_fill_and_sign_documents_online_effortlessly_with_a_secure_fast_and_user_friendly_digital_document_signing_solution: Consultez ou téléchargez les documents complétés. Remplissez et signez des documents en ligne facilement, grâce à une solution de signature numérique sécurisée, rapide et conviviale.
|
||||||
@@ -3910,6 +3948,7 @@ fr: &fr
|
|||||||
allow_signers_to_create_signatures_by_typing_their_name_instead_of_drawing_or_uploading_one: Autoriser les signataires à créer des signatures en tapant leur nom au lieu de dessiner ou téléverser une signature.
|
allow_signers_to_create_signatures_by_typing_their_name_instead_of_drawing_or_uploading_one: Autoriser les signataires à créer des signatures en tapant leur nom au lieu de dessiner ou téléverser une signature.
|
||||||
allow_signers_to_resubmit_forms_after_completion_useful_when_corrections_or_multiple_submissions_are_needed: Autoriser les signataires à soumettre à nouveau les formulaires après finalisation, utile pour des corrections ou soumissions multiples.
|
allow_signers_to_resubmit_forms_after_completion_useful_when_corrections_or_multiple_submissions_are_needed: Autoriser les signataires à soumettre à nouveau les formulaires après finalisation, utile pour des corrections ou soumissions multiples.
|
||||||
allow_recipients_to_decline_signing_a_document_the_decline_reason_notification_will_be_sent_to_the_signature_requester: Autoriser les destinataires à refuser de signer un document. Le motif du refus sera notifié au demandeur de signature.
|
allow_recipients_to_decline_signing_a_document_the_decline_reason_notification_will_be_sent_to_the_signature_requester: Autoriser les destinataires à refuser de signer un document. Le motif du refus sera notifié au demandeur de signature.
|
||||||
|
allow_recipients_to_delegate_documents: Autoriser les destinataires à déléguer des documents à une autre personne par e-mail. Cela peut être utile lorsque le destinataire d'origine doit transmettre le document au signataire autorisé.
|
||||||
save_a_users_signature_and_automatically_pre_fill_it_in_future_signing_sessions: Mémoriser la signature d’un utilisateur et la pré‑remplir automatiquement lors de futures sessions de signature.
|
save_a_users_signature_and_automatically_pre_fill_it_in_future_signing_sessions: Mémoriser la signature d’un utilisateur et la pré‑remplir automatiquement lors de futures sessions de signature.
|
||||||
make_document_download_links_expire_after_40_minutes_to_prevent_long_term_access_and_enhance_security: Faire expirer les liens de téléchargement des documents après 40 minutes pour éviter un accès à long terme et renforcer la sécurité.
|
make_document_download_links_expire_after_40_minutes_to_prevent_long_term_access_and_enhance_security: Faire expirer les liens de téléchargement des documents après 40 minutes pour éviter un accès à long terme et renforcer la sécurité.
|
||||||
require_authentication_with_user_login_or_api_key_to_access_the_document_download_links: Exiger une authentification par connexion utilisateur ou clé API pour accéder aux liens de téléchargement des documents.
|
require_authentication_with_user_login_or_api_key_to_access_the_document_download_links: Exiger une authentification par connexion utilisateur ou clé API pour accéder aux liens de téléchargement des documents.
|
||||||
@@ -3984,6 +4023,9 @@ fr: &fr
|
|||||||
connect_to_docuseal_mcp: Se connecter à DocuSeal MCP
|
connect_to_docuseal_mcp: Se connecter à DocuSeal MCP
|
||||||
add_the_following_to_your_mcp_client_configuration: Ajoutez ce qui suit à la configuration de votre client MCP
|
add_the_following_to_your_mcp_client_configuration: Ajoutez ce qui suit à la configuration de votre client MCP
|
||||||
works_with_claude_desktop_cursor_windsurf_vs_code_and_any_mcp_compatible_client: Fonctionne avec Claude Desktop, Cursor, Windsurf, VS Code et tout client compatible MCP.
|
works_with_claude_desktop_cursor_windsurf_vs_code_and_any_mcp_compatible_client: Fonctionne avec Claude Desktop, Cursor, Windsurf, VS Code et tout client compatible MCP.
|
||||||
|
your_email_address_has_been_changed: Votre adresse e-mail a été modifiée
|
||||||
|
the_email_address_for_your_account_has_been_changed_to_new_email: "L'adresse e-mail de votre compte a été modifiée en %{new_email}."
|
||||||
|
if_you_did_not_make_this_change_please_contact_us_by_replying_to_this_email: Si vous n'avez pas effectué ce changement, veuillez nous contacter en répondant à cet e-mail.
|
||||||
devise:
|
devise:
|
||||||
confirmations:
|
confirmations:
|
||||||
confirmed: Votre adresse e-mail a été confirmée avec succès.
|
confirmed: Votre adresse e-mail a été confirmée avec succès.
|
||||||
@@ -4018,6 +4060,8 @@ fr: &fr
|
|||||||
start_verification_by_html: "<b>Vérification d’identité démarrée</b> par %{submitter_name}"
|
start_verification_by_html: "<b>Vérification d’identité démarrée</b> par %{submitter_name}"
|
||||||
complete_verification_by_html: "<b>Vérification d’identité terminée</b> par %{submitter_name} avec %{provider}"
|
complete_verification_by_html: "<b>Vérification d’identité terminée</b> par %{submitter_name} avec %{provider}"
|
||||||
api_complete_form_by_html: "<b>Soumission terminée via API</b> par %{submitter_name}"
|
api_complete_form_by_html: "<b>Soumission terminée via API</b> par %{submitter_name}"
|
||||||
|
decline_form_by_html: "<b>Formulaire refusé</b> par %{submitter_name}"
|
||||||
|
delegate_form_by_html: "<b>Délégué</b> de %{from} à %{to}"
|
||||||
start_kba_by_html: "<b>KBA démarré</b> par %{submitter_name}"
|
start_kba_by_html: "<b>KBA démarré</b> par %{submitter_name}"
|
||||||
complete_kba_by_html: "<b>KBA terminé</b> par %{submitter_name}"
|
complete_kba_by_html: "<b>KBA terminé</b> par %{submitter_name}"
|
||||||
fail_kba_by_html: "<b>KBA échoué</b> par %{submitter_name}"
|
fail_kba_by_html: "<b>KBA échoué</b> par %{submitter_name}"
|
||||||
@@ -4259,11 +4303,14 @@ pt: &pt
|
|||||||
downloading: Baixando
|
downloading: Baixando
|
||||||
download: Baixar
|
download: Baixar
|
||||||
decline: Recusar
|
decline: Recusar
|
||||||
|
delegate: Delegar
|
||||||
|
enter_the_email_address_of_the_person_you_want_to_delegate_to: Insira o endereço de e-mail da pessoa para quem deseja delegar
|
||||||
declined: Recusado
|
declined: Recusado
|
||||||
decline_reason: Motivo da recusa
|
decline_reason: Motivo da recusa
|
||||||
provide_a_reason: Forneça um motivo
|
provide_a_reason: Forneça um motivo
|
||||||
notify_the_sender_with_the_reason_you_declined: Notifique o remetente com o motivo da sua recusa
|
notify_the_sender_with_the_reason_you_declined: Notifique o remetente com o motivo da sua recusa
|
||||||
form_has_been_declined_on_html: "O formulário foi recusado em <span class='font-semibold'>%{time}</span>"
|
form_has_been_declined_on_html: "O formulário foi recusado em <span class='font-semibold'>%{time}</span>"
|
||||||
|
document_has_been_delegated_on_html: "O documento foi delegado em <span class='font-semibold'>%{time}</span>"
|
||||||
name_declined_by_submitter: '"%{name}" foi recusado por %{submitter}'
|
name_declined_by_submitter: '"%{name}" foi recusado por %{submitter}'
|
||||||
name_declined_by_submitter_with_the_following_reason: '"%{name}" foi recusado por %{submitter} com o seguinte motivo:'
|
name_declined_by_submitter_with_the_following_reason: '"%{name}" foi recusado por %{submitter} com o seguinte motivo:'
|
||||||
completed_successfully: Concluído com sucesso
|
completed_successfully: Concluído com sucesso
|
||||||
@@ -4298,6 +4345,7 @@ pt: &pt
|
|||||||
allow_typed_text_signatures: Permitir assinaturas digitadas
|
allow_typed_text_signatures: Permitir assinaturas digitadas
|
||||||
allow_to_resubmit_completed_forms: Permitir reenviar formulários concluídos
|
allow_to_resubmit_completed_forms: Permitir reenviar formulários concluídos
|
||||||
allow_to_decline_documents: Permitir recusar documentos
|
allow_to_decline_documents: Permitir recusar documentos
|
||||||
|
allow_to_delegate_documents: Permitir delegar documentos
|
||||||
remember_and_pre_fill_signatures: Lembrar e preencher assinaturas automaticamente
|
remember_and_pre_fill_signatures: Lembrar e preencher assinaturas automaticamente
|
||||||
require_authentication_for_file_download_links: Requerer autenticação para links de download de arquivos
|
require_authentication_for_file_download_links: Requerer autenticação para links de download de arquivos
|
||||||
combine_completed_documents_and_audit_log: Combinar documentos concluídos e log de auditoria
|
combine_completed_documents_and_audit_log: Combinar documentos concluídos e log de auditoria
|
||||||
@@ -4881,6 +4929,7 @@ pt: &pt
|
|||||||
share_link: Link de compartilhamento
|
share_link: Link de compartilhamento
|
||||||
enable_shared_link: Ativar link compartilhado
|
enable_shared_link: Ativar link compartilhado
|
||||||
share_link_is_currently_disabled: O link compartilhado está desativado no momento
|
share_link_is_currently_disabled: O link compartilhado está desativado no momento
|
||||||
|
dynamic_template_with_variables_cannot_be_used_via_shared_link: O template dinâmico com variáveis não pode ser usado por meio de link compartilhado
|
||||||
select_data_residency: Selecionar local dos dados
|
select_data_residency: Selecionar local dos dados
|
||||||
account_name_has_invited_you_to_fill_and_sign_documents_online_effortlessly_with_a_secure_fast_and_user_friendly_digital_document_signing_solution: '%{account_name} convidou você para preencher e assinar documentos online com facilidade usando uma solução de assinatura digital segura, rápida e fácil de usar.'
|
account_name_has_invited_you_to_fill_and_sign_documents_online_effortlessly_with_a_secure_fast_and_user_friendly_digital_document_signing_solution: '%{account_name} convidou você para preencher e assinar documentos online com facilidade usando uma solução de assinatura digital segura, rápida e fácil de usar.'
|
||||||
review_or_download_completed_documents_fill_and_sign_documents_online_effortlessly_with_a_secure_fast_and_user_friendly_digital_document_signing_solution: Reveja ou baixe os documentos concluídos. Preencha e assine documentos online com facilidade usando uma solução de assinatura digital segura, rápida e fácil de usar.
|
review_or_download_completed_documents_fill_and_sign_documents_online_effortlessly_with_a_secure_fast_and_user_friendly_digital_document_signing_solution: Reveja ou baixe os documentos concluídos. Preencha e assine documentos online com facilidade usando uma solução de assinatura digital segura, rápida e fácil de usar.
|
||||||
@@ -4935,6 +4984,7 @@ pt: &pt
|
|||||||
allow_signers_to_create_signatures_by_typing_their_name_instead_of_drawing_or_uploading_one: Permitir que os signatários criem assinaturas digitando seu nome em vez de desenhá-las ou carregá-las.
|
allow_signers_to_create_signatures_by_typing_their_name_instead_of_drawing_or_uploading_one: Permitir que os signatários criem assinaturas digitando seu nome em vez de desenhá-las ou carregá-las.
|
||||||
allow_signers_to_resubmit_forms_after_completion_useful_when_corrections_or_multiple_submissions_are_needed: Permitir que os signatários reenviem formulários após o término, útil quando são necessárias correções ou múltiplos envios.
|
allow_signers_to_resubmit_forms_after_completion_useful_when_corrections_or_multiple_submissions_are_needed: Permitir que os signatários reenviem formulários após o término, útil quando são necessárias correções ou múltiplos envios.
|
||||||
allow_recipients_to_decline_signing_a_document_the_decline_reason_notification_will_be_sent_to_the_signature_requester: Permitir que os destinatários recusem assinar um documento. A notificação do motivo da recusa será enviada ao solicitante da assinatura.
|
allow_recipients_to_decline_signing_a_document_the_decline_reason_notification_will_be_sent_to_the_signature_requester: Permitir que os destinatários recusem assinar um documento. A notificação do motivo da recusa será enviada ao solicitante da assinatura.
|
||||||
|
allow_recipients_to_delegate_documents: Permitir que os destinatários deleguem documentos a outra pessoa por e-mail. Isso pode ser útil quando o destinatário original precisa passar o documento ao signatário autorizado.
|
||||||
save_a_users_signature_and_automatically_pre_fill_it_in_future_signing_sessions: Salvar a assinatura de um usuário e preenchê-la automaticamente em futuras sessões de assinatura.
|
save_a_users_signature_and_automatically_pre_fill_it_in_future_signing_sessions: Salvar a assinatura de um usuário e preenchê-la automaticamente em futuras sessões de assinatura.
|
||||||
make_document_download_links_expire_after_40_minutes_to_prevent_long_term_access_and_enhance_security: Fazer os links de download de documentos expirarem após 40 minutos para evitar o acesso prolongado e aumentar a segurança.
|
make_document_download_links_expire_after_40_minutes_to_prevent_long_term_access_and_enhance_security: Fazer os links de download de documentos expirarem após 40 minutos para evitar o acesso prolongado e aumentar a segurança.
|
||||||
require_authentication_with_user_login_or_api_key_to_access_the_document_download_links: Exigir autenticação com login do usuário ou chave API para acessar os links de download de documentos.
|
require_authentication_with_user_login_or_api_key_to_access_the_document_download_links: Exigir autenticação com login do usuário ou chave API para acessar os links de download de documentos.
|
||||||
@@ -5008,6 +5058,9 @@ pt: &pt
|
|||||||
connect_to_docuseal_mcp: Conectar ao DocuSeal MCP
|
connect_to_docuseal_mcp: Conectar ao DocuSeal MCP
|
||||||
add_the_following_to_your_mcp_client_configuration: Adicione o seguinte à configuração do seu cliente MCP
|
add_the_following_to_your_mcp_client_configuration: Adicione o seguinte à configuração do seu cliente MCP
|
||||||
works_with_claude_desktop_cursor_windsurf_vs_code_and_any_mcp_compatible_client: Funciona com Claude Desktop, Cursor, Windsurf, VS Code e qualquer cliente compatível com MCP.
|
works_with_claude_desktop_cursor_windsurf_vs_code_and_any_mcp_compatible_client: Funciona com Claude Desktop, Cursor, Windsurf, VS Code e qualquer cliente compatível com MCP.
|
||||||
|
your_email_address_has_been_changed: Seu endereço de e-mail foi alterado
|
||||||
|
the_email_address_for_your_account_has_been_changed_to_new_email: O endereço de e-mail da sua conta foi alterado para %{new_email}.
|
||||||
|
if_you_did_not_make_this_change_please_contact_us_by_replying_to_this_email: Se você não fez essa alteração, entre em contato conosco respondendo a este e-mail.
|
||||||
devise:
|
devise:
|
||||||
confirmations:
|
confirmations:
|
||||||
confirmed: Seu endereço de e-mail foi confirmado com sucesso.
|
confirmed: Seu endereço de e-mail foi confirmado com sucesso.
|
||||||
@@ -5042,6 +5095,8 @@ pt: &pt
|
|||||||
start_verification_by_html: '<b>Verificação de identidade iniciada</b> por %{submitter_name}'
|
start_verification_by_html: '<b>Verificação de identidade iniciada</b> por %{submitter_name}'
|
||||||
complete_verification_by_html: '<b>Verificação de identidade concluída</b> por %{submitter_name} com %{provider}'
|
complete_verification_by_html: '<b>Verificação de identidade concluída</b> por %{submitter_name} com %{provider}'
|
||||||
api_complete_form_by_html: '<b>Submissão concluída via API</b> por %{submitter_name}'
|
api_complete_form_by_html: '<b>Submissão concluída via API</b> por %{submitter_name}'
|
||||||
|
decline_form_by_html: '<b>Formulário recusado</b> por %{submitter_name}'
|
||||||
|
delegate_form_by_html: '<b>Delegado</b> de %{from} para %{to}'
|
||||||
start_kba_by_html: '<b>KBA iniciada</b> por %{submitter_name}'
|
start_kba_by_html: '<b>KBA iniciada</b> por %{submitter_name}'
|
||||||
complete_kba_by_html: '<b>KBA concluída</b> por %{submitter_name}'
|
complete_kba_by_html: '<b>KBA concluída</b> por %{submitter_name}'
|
||||||
fail_kba_by_html: '<b>KBA reprovada</b> por %{submitter_name}'
|
fail_kba_by_html: '<b>KBA reprovada</b> por %{submitter_name}'
|
||||||
@@ -5283,11 +5338,14 @@ de: &de
|
|||||||
downloading: Wird heruntergeladen
|
downloading: Wird heruntergeladen
|
||||||
download: Download
|
download: Download
|
||||||
decline: Ablehnen
|
decline: Ablehnen
|
||||||
|
delegate: Delegieren
|
||||||
|
enter_the_email_address_of_the_person_you_want_to_delegate_to: Geben Sie die E-Mail-Adresse der Person ein, an die Sie delegieren möchten
|
||||||
declined: Abgelehnt
|
declined: Abgelehnt
|
||||||
decline_reason: Ablehnungsgrund
|
decline_reason: Ablehnungsgrund
|
||||||
provide_a_reason: Geben Sie einen Grund an
|
provide_a_reason: Geben Sie einen Grund an
|
||||||
notify_the_sender_with_the_reason_you_declined: Den Absender über den Grund Ihrer Ablehnung benachrichtigen
|
notify_the_sender_with_the_reason_you_declined: Den Absender über den Grund Ihrer Ablehnung benachrichtigen
|
||||||
form_has_been_declined_on_html: "Das Formular wurde am <span class='font-semibold'>%{time}</span> abgelehnt"
|
form_has_been_declined_on_html: "Das Formular wurde am <span class='font-semibold'>%{time}</span> abgelehnt"
|
||||||
|
document_has_been_delegated_on_html: "Das Dokument wurde am <span class='font-semibold'>%{time}</span> delegiert"
|
||||||
name_declined_by_submitter: '"%{name}" wurde von %{submitter} abgelehnt'
|
name_declined_by_submitter: '"%{name}" wurde von %{submitter} abgelehnt'
|
||||||
name_declined_by_submitter_with_the_following_reason: '"%{name}" wurde von %{submitter} mit folgendem Grund abgelehnt:'
|
name_declined_by_submitter_with_the_following_reason: '"%{name}" wurde von %{submitter} mit folgendem Grund abgelehnt:'
|
||||||
completed_successfully: Erfolgreich abgeschlossen
|
completed_successfully: Erfolgreich abgeschlossen
|
||||||
@@ -5322,6 +5380,7 @@ de: &de
|
|||||||
allow_typed_text_signatures: Getippte Unterschriften zulassen
|
allow_typed_text_signatures: Getippte Unterschriften zulassen
|
||||||
allow_to_resubmit_completed_forms: Erneutes Einreichen abgeschlossener Formulare zulassen
|
allow_to_resubmit_completed_forms: Erneutes Einreichen abgeschlossener Formulare zulassen
|
||||||
allow_to_decline_documents: Ablehnen von Dokumenten erlauben
|
allow_to_decline_documents: Ablehnen von Dokumenten erlauben
|
||||||
|
allow_to_delegate_documents: Delegieren von Dokumenten erlauben
|
||||||
remember_and_pre_fill_signatures: Signaturen merken und vorab ausfüllen
|
remember_and_pre_fill_signatures: Signaturen merken und vorab ausfüllen
|
||||||
require_authentication_for_file_download_links: Authentifizierung für Dateidownload-Links erforderlich
|
require_authentication_for_file_download_links: Authentifizierung für Dateidownload-Links erforderlich
|
||||||
combine_completed_documents_and_audit_log: Abgeschlossene Dokumente und Prüfprotokoll kombinieren
|
combine_completed_documents_and_audit_log: Abgeschlossene Dokumente und Prüfprotokoll kombinieren
|
||||||
@@ -5905,6 +5964,7 @@ de: &de
|
|||||||
share_link: Freigabelink
|
share_link: Freigabelink
|
||||||
enable_shared_link: Freigabelink aktivieren
|
enable_shared_link: Freigabelink aktivieren
|
||||||
share_link_is_currently_disabled: Freigabelink ist derzeit deaktiviert
|
share_link_is_currently_disabled: Freigabelink ist derzeit deaktiviert
|
||||||
|
dynamic_template_with_variables_cannot_be_used_via_shared_link: Dynamische Vorlage mit Variablen kann nicht über einen Freigabelink verwendet werden
|
||||||
select_data_residency: Datenstandort auswählen
|
select_data_residency: Datenstandort auswählen
|
||||||
account_name_has_invited_you_to_fill_and_sign_documents_online_effortlessly_with_a_secure_fast_and_user_friendly_digital_document_signing_solution: '%{account_name} hat Sie eingeladen, Dokumente mühelos online mit einer sicheren, schnellen und benutzerfreundlichen digitalen Signaturlösung auszufüllen und zu unterschreiben.'
|
account_name_has_invited_you_to_fill_and_sign_documents_online_effortlessly_with_a_secure_fast_and_user_friendly_digital_document_signing_solution: '%{account_name} hat Sie eingeladen, Dokumente mühelos online mit einer sicheren, schnellen und benutzerfreundlichen digitalen Signaturlösung auszufüllen und zu unterschreiben.'
|
||||||
review_or_download_completed_documents_fill_and_sign_documents_online_effortlessly_with_a_secure_fast_and_user_friendly_digital_document_signing_solution: Überprüfen oder laden Sie abgeschlossene Dokumente herunter. Füllen und unterschreiben Sie Dokumente mühelos online mit einer sicheren, schnellen und benutzerfreundlichen digitalen Signaturlösung.
|
review_or_download_completed_documents_fill_and_sign_documents_online_effortlessly_with_a_secure_fast_and_user_friendly_digital_document_signing_solution: Überprüfen oder laden Sie abgeschlossene Dokumente herunter. Füllen und unterschreiben Sie Dokumente mühelos online mit einer sicheren, schnellen und benutzerfreundlichen digitalen Signaturlösung.
|
||||||
@@ -5959,6 +6019,7 @@ de: &de
|
|||||||
allow_signers_to_create_signatures_by_typing_their_name_instead_of_drawing_or_uploading_one: Unterzeichner dürfen Signaturen erstellen, indem sie ihren Namen eingeben, statt eine Signatur zu zeichnen oder hochzuladen.
|
allow_signers_to_create_signatures_by_typing_their_name_instead_of_drawing_or_uploading_one: Unterzeichner dürfen Signaturen erstellen, indem sie ihren Namen eingeben, statt eine Signatur zu zeichnen oder hochzuladen.
|
||||||
allow_signers_to_resubmit_forms_after_completion_useful_when_corrections_or_multiple_submissions_are_needed: Unterzeichner dürfen Formulare nach Abschluss erneut einreichen – nützlich für Korrekturen oder mehrere Einreichungen.
|
allow_signers_to_resubmit_forms_after_completion_useful_when_corrections_or_multiple_submissions_are_needed: Unterzeichner dürfen Formulare nach Abschluss erneut einreichen – nützlich für Korrekturen oder mehrere Einreichungen.
|
||||||
allow_recipients_to_decline_signing_a_document_the_decline_reason_notification_will_be_sent_to_the_signature_requester: Empfänger dürfen die Unterzeichnung eines Dokuments ablehnen. Die Benachrichtigung mit dem Ablehnungsgrund wird an den Anforderer der Signatur gesendet.
|
allow_recipients_to_decline_signing_a_document_the_decline_reason_notification_will_be_sent_to_the_signature_requester: Empfänger dürfen die Unterzeichnung eines Dokuments ablehnen. Die Benachrichtigung mit dem Ablehnungsgrund wird an den Anforderer der Signatur gesendet.
|
||||||
|
allow_recipients_to_delegate_documents: Empfängern erlauben, Dokumente per E-Mail an eine andere Person weiterzuleiten. Dies kann nützlich sein, wenn der ursprüngliche Empfänger das Dokument an den autorisierten Unterzeichner weiterleiten muss.
|
||||||
save_a_users_signature_and_automatically_pre_fill_it_in_future_signing_sessions: Die Signatur eines Benutzers speichern und sie in zukünftigen Signatursitzungen automatisch vorausfüllen.
|
save_a_users_signature_and_automatically_pre_fill_it_in_future_signing_sessions: Die Signatur eines Benutzers speichern und sie in zukünftigen Signatursitzungen automatisch vorausfüllen.
|
||||||
make_document_download_links_expire_after_40_minutes_to_prevent_long_term_access_and_enhance_security: Download-Links für Dokumente nach 40 Minuten ablaufen lassen, um langfristigen Zugriff zu verhindern und die Sicherheit zu erhöhen.
|
make_document_download_links_expire_after_40_minutes_to_prevent_long_term_access_and_enhance_security: Download-Links für Dokumente nach 40 Minuten ablaufen lassen, um langfristigen Zugriff zu verhindern und die Sicherheit zu erhöhen.
|
||||||
require_authentication_with_user_login_or_api_key_to_access_the_document_download_links: Authentifizierung mit Benutzeranmeldung oder API-Schlüssel erforderlich, um auf die Download-Links für Dokumente zuzugreifen.
|
require_authentication_with_user_login_or_api_key_to_access_the_document_download_links: Authentifizierung mit Benutzeranmeldung oder API-Schlüssel erforderlich, um auf die Download-Links für Dokumente zuzugreifen.
|
||||||
@@ -6032,6 +6093,9 @@ de: &de
|
|||||||
connect_to_docuseal_mcp: Mit DocuSeal MCP verbinden
|
connect_to_docuseal_mcp: Mit DocuSeal MCP verbinden
|
||||||
add_the_following_to_your_mcp_client_configuration: Fügen Sie Folgendes zu Ihrer MCP-Client-Konfiguration hinzu
|
add_the_following_to_your_mcp_client_configuration: Fügen Sie Folgendes zu Ihrer MCP-Client-Konfiguration hinzu
|
||||||
works_with_claude_desktop_cursor_windsurf_vs_code_and_any_mcp_compatible_client: Funktioniert mit Claude Desktop, Cursor, Windsurf, VS Code und jedem MCP-kompatiblen Client.
|
works_with_claude_desktop_cursor_windsurf_vs_code_and_any_mcp_compatible_client: Funktioniert mit Claude Desktop, Cursor, Windsurf, VS Code und jedem MCP-kompatiblen Client.
|
||||||
|
your_email_address_has_been_changed: Ihre E-Mail-Adresse wurde geändert
|
||||||
|
the_email_address_for_your_account_has_been_changed_to_new_email: Die E-Mail-Adresse Ihres Kontos wurde in %{new_email} geändert.
|
||||||
|
if_you_did_not_make_this_change_please_contact_us_by_replying_to_this_email: Wenn Sie diese Änderung nicht vorgenommen haben, kontaktieren Sie uns bitte, indem Sie auf diese E-Mail antworten.
|
||||||
devise:
|
devise:
|
||||||
confirmations:
|
confirmations:
|
||||||
confirmed: Ihre E-Mail-Adresse wurde erfolgreich bestätigt.
|
confirmed: Ihre E-Mail-Adresse wurde erfolgreich bestätigt.
|
||||||
@@ -6066,6 +6130,8 @@ de: &de
|
|||||||
start_verification_by_html: '<b>Identitätsüberprüfung gestartet</b> von %{submitter_name}'
|
start_verification_by_html: '<b>Identitätsüberprüfung gestartet</b> von %{submitter_name}'
|
||||||
complete_verification_by_html: '<b>Identitätsüberprüfung abgeschlossen</b> von %{submitter_name} mit %{provider}'
|
complete_verification_by_html: '<b>Identitätsüberprüfung abgeschlossen</b> von %{submitter_name} mit %{provider}'
|
||||||
api_complete_form_by_html: '<b>Einreichung über API abgeschlossen</b> von %{submitter_name}'
|
api_complete_form_by_html: '<b>Einreichung über API abgeschlossen</b> von %{submitter_name}'
|
||||||
|
decline_form_by_html: '<b>Formular abgelehnt</b> von %{submitter_name}'
|
||||||
|
delegate_form_by_html: '<b>Delegiert</b> von %{from} an %{to}'
|
||||||
start_kba_by_html: '<b>KBA gestartet</b> von %{submitter_name}'
|
start_kba_by_html: '<b>KBA gestartet</b> von %{submitter_name}'
|
||||||
complete_kba_by_html: '<b>KBA abgeschlossen</b> von %{submitter_name}'
|
complete_kba_by_html: '<b>KBA abgeschlossen</b> von %{submitter_name}'
|
||||||
fail_kba_by_html: '<b>KBA fehlgeschlagen</b> von %{submitter_name}'
|
fail_kba_by_html: '<b>KBA fehlgeschlagen</b> von %{submitter_name}'
|
||||||
@@ -6172,11 +6238,14 @@ pl:
|
|||||||
hi_there: Cześć,
|
hi_there: Cześć,
|
||||||
download: Pobierz
|
download: Pobierz
|
||||||
decline: Odrzuć
|
decline: Odrzuć
|
||||||
|
delegate: Deleguj
|
||||||
|
enter_the_email_address_of_the_person_you_want_to_delegate_to: Wprowadź adres e-mail osoby, do której chcesz delegować
|
||||||
declined: Odrzucono
|
declined: Odrzucono
|
||||||
decline_reason: Powód odrzucenia
|
decline_reason: Powód odrzucenia
|
||||||
provide_a_reason: Podaj powód
|
provide_a_reason: Podaj powód
|
||||||
notify_the_sender_with_the_reason_you_declined: Powiadom nadawcę o powodzie, dla którego odrzuciłeś
|
notify_the_sender_with_the_reason_you_declined: Powiadom nadawcę o powodzie, dla którego odrzuciłeś
|
||||||
form_has_been_declined_on_html: 'Formularz został odrzucony o <span class="font-semibold">%{time}</span>'
|
form_has_been_declined_on_html: 'Formularz został odrzucony o <span class="font-semibold">%{time}</span>'
|
||||||
|
document_has_been_delegated_on_html: 'Dokument został oddelegowany o <span class="font-semibold">%{time}</span>'
|
||||||
name_declined_by_submitter: '"%{name}" odrzucono przez %{submitter}'
|
name_declined_by_submitter: '"%{name}" odrzucono przez %{submitter}'
|
||||||
name_declined_by_submitter_with_the_following_reason: '"%{name}" został odrzucony przez %{submitter} z następującym powodem:'
|
name_declined_by_submitter_with_the_following_reason: '"%{name}" został odrzucony przez %{submitter} z następującym powodem:'
|
||||||
email: E-mail
|
email: E-mail
|
||||||
@@ -6269,11 +6338,14 @@ uk:
|
|||||||
hi_there: Привіт,
|
hi_there: Привіт,
|
||||||
download: Завантажити
|
download: Завантажити
|
||||||
decline: Відхилити
|
decline: Відхилити
|
||||||
|
delegate: Делегувати
|
||||||
|
enter_the_email_address_of_the_person_you_want_to_delegate_to: Введіть адресу електронної пошти особи, якій ви хочете делегувати
|
||||||
declined: Відхилено
|
declined: Відхилено
|
||||||
decline_reason: Причина відхилення
|
decline_reason: Причина відхилення
|
||||||
provide_a_reason: Надайте причину
|
provide_a_reason: Надайте причину
|
||||||
notify_the_sender_with_the_reason_you_declined: Повідомте відправника про причину, з якої ви відхилили
|
notify_the_sender_with_the_reason_you_declined: Повідомте відправника про причину, з якої ви відхилили
|
||||||
form_has_been_declined_on_html: 'Форму було відхилено о <span class="font-semibold">%{time}</span>'
|
form_has_been_declined_on_html: 'Форму було відхилено о <span class="font-semibold">%{time}</span>'
|
||||||
|
document_has_been_delegated_on_html: 'Документ було делеговано о <span class="font-semibold">%{time}</span>'
|
||||||
name_declined_by_submitter: '"%{name}" відхилено %{submitter}'
|
name_declined_by_submitter: '"%{name}" відхилено %{submitter}'
|
||||||
name_declined_by_submitter_with_the_following_reason: '"%{name}" було відхилено %{submitter} з такою причиною:'
|
name_declined_by_submitter_with_the_following_reason: '"%{name}" було відхилено %{submitter} з такою причиною:'
|
||||||
email: E-mail
|
email: E-mail
|
||||||
@@ -6366,11 +6438,14 @@ cs:
|
|||||||
hi_there: Ahoj,
|
hi_there: Ahoj,
|
||||||
download: Stáhnout
|
download: Stáhnout
|
||||||
decline: Odmítnout
|
decline: Odmítnout
|
||||||
|
delegate: Delegovat
|
||||||
|
enter_the_email_address_of_the_person_you_want_to_delegate_to: Zadejte e-mailovou adresu osoby, na kterou chcete delegovat
|
||||||
declined: Odmítnuto
|
declined: Odmítnuto
|
||||||
decline_reason: Důvod odmítnutí
|
decline_reason: Důvod odmítnutí
|
||||||
provide_a_reason: Uveďte důvod
|
provide_a_reason: Uveďte důvod
|
||||||
notify_the_sender_with_the_reason_you_declined: Informujte odesílatele o důvodu odmítnutí
|
notify_the_sender_with_the_reason_you_declined: Informujte odesílatele o důvodu odmítnutí
|
||||||
form_has_been_declined_on_html: 'Formulář byl odmítnut dne <span class="font-semibold">%{time}</span>'
|
form_has_been_declined_on_html: 'Formulář byl odmítnut dne <span class="font-semibold">%{time}</span>'
|
||||||
|
document_has_been_delegated_on_html: 'Dokument byl delegován dne <span class="font-semibold">%{time}</span>'
|
||||||
name_declined_by_submitter: '"%{name}" odmítnuto %{submitter}'
|
name_declined_by_submitter: '"%{name}" odmítnuto %{submitter}'
|
||||||
name_declined_by_submitter_with_the_following_reason: '"%{name}" bylo odmítnuto %{submitter} s následujícím důvodem:'
|
name_declined_by_submitter_with_the_following_reason: '"%{name}" bylo odmítnuto %{submitter} s následujícím důvodem:'
|
||||||
email: E-mail
|
email: E-mail
|
||||||
@@ -6463,11 +6538,14 @@ he:
|
|||||||
hi_there: שלום,
|
hi_there: שלום,
|
||||||
download: הורד
|
download: הורד
|
||||||
decline: דחייה
|
decline: דחייה
|
||||||
|
delegate: הואלה
|
||||||
|
enter_the_email_address_of_the_person_you_want_to_delegate_to: הזן את כתובת הדוא"ל של האדם שברצונך להאציל אליו
|
||||||
declined: דחוי
|
declined: דחוי
|
||||||
decline_reason: סיבת דחייה
|
decline_reason: סיבת דחייה
|
||||||
provide_a_reason: אנא ספק סיבה
|
provide_a_reason: אנא ספק סיבה
|
||||||
notify_the_sender_with_the_reason_you_declined: הודע לשולח על הסיבה לדחייה
|
notify_the_sender_with_the_reason_you_declined: הודע לשולח על הסיבה לדחייה
|
||||||
form_has_been_declined_on_html: 'הטופס נדחה בתאריך <span class="font-semibold">%{time}</span>'
|
form_has_been_declined_on_html: 'הטופס נדחה בתאריך <span class="font-semibold">%{time}</span>'
|
||||||
|
document_has_been_delegated_on_html: 'המסמך הועבר בתאריך <span class="font-semibold">%{time}</span>'
|
||||||
name_declined_by_submitter: '"%{name}" נדחה על ידי %{submitter}'
|
name_declined_by_submitter: '"%{name}" נדחה על ידי %{submitter}'
|
||||||
name_declined_by_submitter_with_the_following_reason: '"%{name}" נדחה על ידי %{submitter} עם הסיבה הבאה:'
|
name_declined_by_submitter_with_the_following_reason: '"%{name}" נדחה על ידי %{submitter} עם הסיבה הבאה:'
|
||||||
email: דוא"ל
|
email: דוא"ל
|
||||||
@@ -6696,11 +6774,14 @@ nl: &nl
|
|||||||
downloading: Downloaden
|
downloading: Downloaden
|
||||||
download: Downloaden
|
download: Downloaden
|
||||||
decline: Weigeren
|
decline: Weigeren
|
||||||
|
delegate: Delegeren
|
||||||
|
enter_the_email_address_of_the_person_you_want_to_delegate_to: Voer het e-mailadres in van de persoon aan wie u wilt delegeren
|
||||||
declined: Geweigerd
|
declined: Geweigerd
|
||||||
decline_reason: Reden van weigering
|
decline_reason: Reden van weigering
|
||||||
provide_a_reason: Geef een reden op
|
provide_a_reason: Geef een reden op
|
||||||
notify_the_sender_with_the_reason_you_declined: Informeer de verzender over de reden van uw weigering
|
notify_the_sender_with_the_reason_you_declined: Informeer de verzender over de reden van uw weigering
|
||||||
form_has_been_declined_on_html: Formulier is geweigerd op <span class="font-semibold">%{time}</span>
|
form_has_been_declined_on_html: Formulier is geweigerd op <span class="font-semibold">%{time}</span>
|
||||||
|
document_has_been_delegated_on_html: Document is gedelegeerd op <span class="font-semibold">%{time}</span>
|
||||||
name_declined_by_submitter: '"%{name}" geweigerd door %{submitter}'
|
name_declined_by_submitter: '"%{name}" geweigerd door %{submitter}'
|
||||||
name_declined_by_submitter_with_the_following_reason: '"%{name}" is geweigerd door %{submitter} met de volgende reden:'
|
name_declined_by_submitter_with_the_following_reason: '"%{name}" is geweigerd door %{submitter} met de volgende reden:'
|
||||||
completed_successfully: Succesvol voltooid
|
completed_successfully: Succesvol voltooid
|
||||||
@@ -6735,6 +6816,7 @@ nl: &nl
|
|||||||
allow_typed_text_signatures: Handtekeningen met getypte tekst toestaan
|
allow_typed_text_signatures: Handtekeningen met getypte tekst toestaan
|
||||||
allow_to_resubmit_completed_forms: Opnieuw indienen van voltooide formulieren toestaan
|
allow_to_resubmit_completed_forms: Opnieuw indienen van voltooide formulieren toestaan
|
||||||
allow_to_decline_documents: Weigeren van documenten toestaan
|
allow_to_decline_documents: Weigeren van documenten toestaan
|
||||||
|
allow_to_delegate_documents: Delegeren van documenten toestaan
|
||||||
remember_and_pre_fill_signatures: Handtekeningen onthouden en vooraf invullen
|
remember_and_pre_fill_signatures: Handtekeningen onthouden en vooraf invullen
|
||||||
require_authentication_for_file_download_links: Authenticatie vereisen voor links naar bestandsdownloads
|
require_authentication_for_file_download_links: Authenticatie vereisen voor links naar bestandsdownloads
|
||||||
combine_completed_documents_and_audit_log: Voltooide documenten en auditlogboek combineren
|
combine_completed_documents_and_audit_log: Voltooide documenten en auditlogboek combineren
|
||||||
@@ -7315,6 +7397,7 @@ nl: &nl
|
|||||||
share_link: Deellink
|
share_link: Deellink
|
||||||
enable_shared_link: Deellink inschakelen
|
enable_shared_link: Deellink inschakelen
|
||||||
share_link_is_currently_disabled: Deellink is momenteel uitgeschakeld
|
share_link_is_currently_disabled: Deellink is momenteel uitgeschakeld
|
||||||
|
dynamic_template_with_variables_cannot_be_used_via_shared_link: Dynamisch sjabloon met variabelen kan niet worden gebruikt via een deellink
|
||||||
select_data_residency: Gegevensresidentie selecteren
|
select_data_residency: Gegevensresidentie selecteren
|
||||||
account_name_has_invited_you_to_fill_and_sign_documents_online_effortlessly_with_a_secure_fast_and_user_friendly_digital_document_signing_solution: "%{account_name} heeft u uitgenodigd om documenten online moeiteloos in te vullen en te ondertekenen met een veilige, snelle en gebruiksvriendelijke digitale ondertekenoplossing."
|
account_name_has_invited_you_to_fill_and_sign_documents_online_effortlessly_with_a_secure_fast_and_user_friendly_digital_document_signing_solution: "%{account_name} heeft u uitgenodigd om documenten online moeiteloos in te vullen en te ondertekenen met een veilige, snelle en gebruiksvriendelijke digitale ondertekenoplossing."
|
||||||
review_or_download_completed_documents_fill_and_sign_documents_online_effortlessly_with_a_secure_fast_and_user_friendly_digital_document_signing_solution: Bekijk of download voltooide documenten. Vul en onderteken documenten online moeiteloos met een veilige, snelle en gebruiksvriendelijke digitale ondertekenoplossing.
|
review_or_download_completed_documents_fill_and_sign_documents_online_effortlessly_with_a_secure_fast_and_user_friendly_digital_document_signing_solution: Bekijk of download voltooide documenten. Vul en onderteken documenten online moeiteloos met een veilige, snelle en gebruiksvriendelijke digitale ondertekenoplossing.
|
||||||
@@ -7368,6 +7451,7 @@ nl: &nl
|
|||||||
allow_signers_to_create_signatures_by_typing_their_name_instead_of_drawing_or_uploading_one: Sta ondertekenaars toe handtekeningen te maken door hun naam te typen in plaats van te tekenen of te uploaden.
|
allow_signers_to_create_signatures_by_typing_their_name_instead_of_drawing_or_uploading_one: Sta ondertekenaars toe handtekeningen te maken door hun naam te typen in plaats van te tekenen of te uploaden.
|
||||||
allow_signers_to_resubmit_forms_after_completion_useful_when_corrections_or_multiple_submissions_are_needed: Sta ondertekenaars toe formulieren na voltooiing opnieuw in te dienen; nuttig wanneer correcties of meerdere inzendingen nodig zijn.
|
allow_signers_to_resubmit_forms_after_completion_useful_when_corrections_or_multiple_submissions_are_needed: Sta ondertekenaars toe formulieren na voltooiing opnieuw in te dienen; nuttig wanneer correcties of meerdere inzendingen nodig zijn.
|
||||||
allow_recipients_to_decline_signing_a_document_the_decline_reason_notification_will_be_sent_to_the_signature_requester: Sta ontvangers toe het ondertekenen van een document te weigeren. De melding met de reden van weigering wordt naar de aanvrager van de handtekening gestuurd.
|
allow_recipients_to_decline_signing_a_document_the_decline_reason_notification_will_be_sent_to_the_signature_requester: Sta ontvangers toe het ondertekenen van een document te weigeren. De melding met de reden van weigering wordt naar de aanvrager van de handtekening gestuurd.
|
||||||
|
allow_recipients_to_delegate_documents: Sta ontvangers toe documenten per e-mail te delegeren aan een andere persoon. Dit kan handig zijn wanneer de oorspronkelijke ontvanger het document moet doorgeven aan de gemachtigde ondertekenaar.
|
||||||
save_a_users_signature_and_automatically_pre_fill_it_in_future_signing_sessions: Sla de handtekening van een gebruiker op en vul deze automatisch vooraf in bij toekomstige ondertekeningssessies.
|
save_a_users_signature_and_automatically_pre_fill_it_in_future_signing_sessions: Sla de handtekening van een gebruiker op en vul deze automatisch vooraf in bij toekomstige ondertekeningssessies.
|
||||||
make_document_download_links_expire_after_40_minutes_to_prevent_long_term_access_and_enhance_security: Laat links voor het downloaden van documenten na 40 minuten verlopen om langdurige toegang te voorkomen en de beveiliging te verbeteren.
|
make_document_download_links_expire_after_40_minutes_to_prevent_long_term_access_and_enhance_security: Laat links voor het downloaden van documenten na 40 minuten verlopen om langdurige toegang te voorkomen en de beveiliging te verbeteren.
|
||||||
require_authentication_with_user_login_or_api_key_to_access_the_document_download_links: Authenticatie met gebruikerslogin of API-sleutel vereisen om toegang te krijgen tot de documentdownloadlinks.
|
require_authentication_with_user_login_or_api_key_to_access_the_document_download_links: Authenticatie met gebruikerslogin of API-sleutel vereisen om toegang te krijgen tot de documentdownloadlinks.
|
||||||
@@ -7441,6 +7525,9 @@ nl: &nl
|
|||||||
connect_to_docuseal_mcp: Verbinden met DocuSeal MCP
|
connect_to_docuseal_mcp: Verbinden met DocuSeal MCP
|
||||||
add_the_following_to_your_mcp_client_configuration: Voeg het volgende toe aan uw MCP-clientconfiguratie
|
add_the_following_to_your_mcp_client_configuration: Voeg het volgende toe aan uw MCP-clientconfiguratie
|
||||||
works_with_claude_desktop_cursor_windsurf_vs_code_and_any_mcp_compatible_client: Werkt met Claude Desktop, Cursor, Windsurf, VS Code en elke MCP-compatibele client.
|
works_with_claude_desktop_cursor_windsurf_vs_code_and_any_mcp_compatible_client: Werkt met Claude Desktop, Cursor, Windsurf, VS Code en elke MCP-compatibele client.
|
||||||
|
your_email_address_has_been_changed: Je e-mailadres is gewijzigd
|
||||||
|
the_email_address_for_your_account_has_been_changed_to_new_email: Het e-mailadres van je account is gewijzigd naar %{new_email}.
|
||||||
|
if_you_did_not_make_this_change_please_contact_us_by_replying_to_this_email: Als je deze wijziging niet hebt aangebracht, neem dan contact met ons op door op deze e-mail te antwoorden.
|
||||||
devise:
|
devise:
|
||||||
confirmations:
|
confirmations:
|
||||||
confirmed: Je e-mailadres is succesvol bevestigd.
|
confirmed: Je e-mailadres is succesvol bevestigd.
|
||||||
@@ -7475,6 +7562,8 @@ nl: &nl
|
|||||||
start_verification_by_html: "<b>Identiteitsverificatie gestart</b> door %{submitter_name}"
|
start_verification_by_html: "<b>Identiteitsverificatie gestart</b> door %{submitter_name}"
|
||||||
complete_verification_by_html: "<b>Identiteitsverificatie voltooid</b> door %{submitter_name} met %{provider}"
|
complete_verification_by_html: "<b>Identiteitsverificatie voltooid</b> door %{submitter_name} met %{provider}"
|
||||||
api_complete_form_by_html: "<b>Inzending via API voltooid</b> door %{submitter_name}"
|
api_complete_form_by_html: "<b>Inzending via API voltooid</b> door %{submitter_name}"
|
||||||
|
decline_form_by_html: "<b>Formulier geweigerd</b> door %{submitter_name}"
|
||||||
|
delegate_form_by_html: "<b>Gedelegeerd</b> van %{from} naar %{to}"
|
||||||
start_kba_by_html: "<b>KBA gestart</b> door %{submitter_name}"
|
start_kba_by_html: "<b>KBA gestart</b> door %{submitter_name}"
|
||||||
complete_kba_by_html: "<b>KBA voltooid</b> door %{submitter_name}"
|
complete_kba_by_html: "<b>KBA voltooid</b> door %{submitter_name}"
|
||||||
fail_kba_by_html: "<b>KBA mislukt</b> door %{submitter_name}"
|
fail_kba_by_html: "<b>KBA mislukt</b> door %{submitter_name}"
|
||||||
@@ -7581,11 +7670,14 @@ ar:
|
|||||||
hi_there: مرحبا,
|
hi_there: مرحبا,
|
||||||
download: تحميل
|
download: تحميل
|
||||||
decline: رفض
|
decline: رفض
|
||||||
|
delegate: تفويض
|
||||||
|
enter_the_email_address_of_the_person_you_want_to_delegate_to: أدخل عنوان البريد الإلكتروني للشخص الذي تريد التفويض إليه
|
||||||
declined: مرفوض
|
declined: مرفوض
|
||||||
decline_reason: سبب الرفض
|
decline_reason: سبب الرفض
|
||||||
provide_a_reason: قدم سببًا
|
provide_a_reason: قدم سببًا
|
||||||
notify_the_sender_with_the_reason_you_declined: أخطر المرسل بسبب الرفض
|
notify_the_sender_with_the_reason_you_declined: أخطر المرسل بسبب الرفض
|
||||||
form_has_been_declined_on_html: 'تم رفض النموذج في <span class="font-semibold">%{time}</span>'
|
form_has_been_declined_on_html: 'تم رفض النموذج في <span class="font-semibold">%{time}</span>'
|
||||||
|
document_has_been_delegated_on_html: 'تم تفويض المستند في <span class="font-semibold">%{time}</span>'
|
||||||
name_declined_by_submitter: '"%{name}" مرفوض بواسطة %{submitter}'
|
name_declined_by_submitter: '"%{name}" مرفوض بواسطة %{submitter}'
|
||||||
name_declined_by_submitter_with_the_following_reason: '"%{name}" تم رفضه بواسطة %{submitter} مع السبب التالي:'
|
name_declined_by_submitter_with_the_following_reason: '"%{name}" تم رفضه بواسطة %{submitter} مع السبب التالي:'
|
||||||
email: البريد الإلكتروني
|
email: البريد الإلكتروني
|
||||||
@@ -7678,11 +7770,14 @@ ko:
|
|||||||
hi_there: 안녕하세요,
|
hi_there: 안녕하세요,
|
||||||
download: 다운로드
|
download: 다운로드
|
||||||
decline: 거절
|
decline: 거절
|
||||||
|
delegate: 위임
|
||||||
|
enter_the_email_address_of_the_person_you_want_to_delegate_to: 위임할 사람의 이메일 주소를 입력하세요
|
||||||
declined: 거절됨
|
declined: 거절됨
|
||||||
decline_reason: 거절 사유
|
decline_reason: 거절 사유
|
||||||
provide_a_reason: 사유를 제공하세요
|
provide_a_reason: 사유를 제공하세요
|
||||||
notify_the_sender_with_the_reason_you_declined: 거절한 이유로 발신자에게 알리기
|
notify_the_sender_with_the_reason_you_declined: 거절한 이유로 발신자에게 알리기
|
||||||
form_has_been_declined_on_html: '양식이 <span class="font-semibold">%{time}</span>에 거절되었습니다.'
|
form_has_been_declined_on_html: '양식이 <span class="font-semibold">%{time}</span>에 거절되었습니다.'
|
||||||
|
document_has_been_delegated_on_html: '문서가 <span class="font-semibold">%{time}</span>에 위임되었습니다.'
|
||||||
name_declined_by_submitter: '"%{name}"이(가) %{submitter}에 의해 거절되었습니다.'
|
name_declined_by_submitter: '"%{name}"이(가) %{submitter}에 의해 거절되었습니다.'
|
||||||
name_declined_by_submitter_with_the_following_reason: '"%{name}"이(가) %{submitter}에 의해 다음과 같은 사유로 거절되었습니다:'
|
name_declined_by_submitter_with_the_following_reason: '"%{name}"이(가) %{submitter}에 의해 다음과 같은 사유로 거절되었습니다:'
|
||||||
email: 이메일
|
email: 이메일
|
||||||
@@ -7775,11 +7870,14 @@ ja:
|
|||||||
hi_there: こんにちは
|
hi_there: こんにちは
|
||||||
download: ダウンロード
|
download: ダウンロード
|
||||||
decline: 辞退
|
decline: 辞退
|
||||||
|
delegate: 委任
|
||||||
|
enter_the_email_address_of_the_person_you_want_to_delegate_to: 委任したい人のメールアドレスを入力してください
|
||||||
declined: 辞退済み
|
declined: 辞退済み
|
||||||
decline_reason: 辞退の理由
|
decline_reason: 辞退の理由
|
||||||
provide_a_reason: 理由を入力してください
|
provide_a_reason: 理由を入力してください
|
||||||
notify_the_sender_with_the_reason_you_declined: 辞退理由を送信者に通知してください
|
notify_the_sender_with_the_reason_you_declined: 辞退理由を送信者に通知してください
|
||||||
form_has_been_declined_on_html: '<span class="font-semibold">%{time}</span> にフォームが辞退されました'
|
form_has_been_declined_on_html: '<span class="font-semibold">%{time}</span> にフォームが辞退されました'
|
||||||
|
document_has_been_delegated_on_html: '<span class="font-semibold">%{time}</span> にドキュメントが委任されました'
|
||||||
name_declined_by_submitter: '"%{name}" は %{submitter} により辞退されました'
|
name_declined_by_submitter: '"%{name}" は %{submitter} により辞退されました'
|
||||||
name_declined_by_submitter_with_the_following_reason: '"%{name}" は %{submitter} により次の理由で辞退されました:'
|
name_declined_by_submitter_with_the_following_reason: '"%{name}" は %{submitter} により次の理由で辞退されました:'
|
||||||
email: メール
|
email: メール
|
||||||
|
|||||||
@@ -145,8 +145,10 @@ Rails.application.routes.draw do
|
|||||||
resources :values, only: %i[index], controller: 'submit_form_values'
|
resources :values, only: %i[index], controller: 'submit_form_values'
|
||||||
resources :download, only: %i[index], controller: 'submit_form_download'
|
resources :download, only: %i[index], controller: 'submit_form_download'
|
||||||
resources :decline, only: %i[create], controller: 'submit_form_decline'
|
resources :decline, only: %i[create], controller: 'submit_form_decline'
|
||||||
|
resources :delegate, only: %i[create], controller: 'submit_form_delegate'
|
||||||
resources :invite, only: %i[create], controller: 'submit_form_invite'
|
resources :invite, only: %i[create], controller: 'submit_form_invite'
|
||||||
get :completed
|
get :completed
|
||||||
|
get :delegated
|
||||||
end
|
end
|
||||||
|
|
||||||
resources :submit_form_draw_signature, only: %i[show], path: 'p', param: 'slug'
|
resources :submit_form_draw_signature, only: %i[show], path: 'p', param: 'slug'
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class CreateSubmitterVersions < ActiveRecord::Migration[8.1]
|
||||||
|
def change
|
||||||
|
create_table :submitter_versions do |t|
|
||||||
|
t.references :submitter, null: false, foreign_key: true
|
||||||
|
t.string :slug, null: false
|
||||||
|
t.string :email
|
||||||
|
t.string :name
|
||||||
|
t.string :phone
|
||||||
|
|
||||||
|
t.timestamps
|
||||||
|
end
|
||||||
|
|
||||||
|
add_index :submitter_versions, :slug
|
||||||
|
end
|
||||||
|
end
|
||||||
+16
-1
@@ -10,7 +10,7 @@
|
|||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema[8.1].define(version: 2026_02_26_193537) do
|
ActiveRecord::Schema[8.1].define(version: 2026_03_27_100000) do
|
||||||
# These are extensions that must be enabled in order to support this database
|
# These are extensions that must be enabled in order to support this database
|
||||||
enable_extension "btree_gin"
|
enable_extension "btree_gin"
|
||||||
enable_extension "plpgsql"
|
enable_extension "plpgsql"
|
||||||
@@ -364,6 +364,18 @@ ActiveRecord::Schema[8.1].define(version: 2026_02_26_193537) do
|
|||||||
t.index ["template_id"], name: "index_submissions_on_template_id"
|
t.index ["template_id"], name: "index_submissions_on_template_id"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
create_table "submitter_versions", force: :cascade do |t|
|
||||||
|
t.datetime "created_at", null: false
|
||||||
|
t.string "email"
|
||||||
|
t.string "name"
|
||||||
|
t.string "phone"
|
||||||
|
t.string "slug", null: false
|
||||||
|
t.bigint "submitter_id", null: false
|
||||||
|
t.datetime "updated_at", null: false
|
||||||
|
t.index ["slug"], name: "index_submitter_versions_on_slug"
|
||||||
|
t.index ["submitter_id"], name: "index_submitter_versions_on_submitter_id"
|
||||||
|
end
|
||||||
|
|
||||||
create_table "submitters", force: :cascade do |t|
|
create_table "submitters", force: :cascade do |t|
|
||||||
t.bigint "submission_id", null: false
|
t.bigint "submission_id", null: false
|
||||||
t.string "uuid", null: false
|
t.string "uuid", null: false
|
||||||
@@ -541,12 +553,14 @@ ActiveRecord::Schema[8.1].define(version: 2026_02_26_193537) do
|
|||||||
add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id"
|
add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id"
|
||||||
add_foreign_key "active_storage_variant_records", "active_storage_blobs", column: "blob_id"
|
add_foreign_key "active_storage_variant_records", "active_storage_blobs", column: "blob_id"
|
||||||
add_foreign_key "document_generation_events", "submitters"
|
add_foreign_key "document_generation_events", "submitters"
|
||||||
|
add_foreign_key "dynamic_document_versions", "dynamic_documents"
|
||||||
add_foreign_key "dynamic_documents", "templates"
|
add_foreign_key "dynamic_documents", "templates"
|
||||||
add_foreign_key "email_events", "accounts"
|
add_foreign_key "email_events", "accounts"
|
||||||
add_foreign_key "email_messages", "accounts"
|
add_foreign_key "email_messages", "accounts"
|
||||||
add_foreign_key "email_messages", "users", column: "author_id"
|
add_foreign_key "email_messages", "users", column: "author_id"
|
||||||
add_foreign_key "encrypted_configs", "accounts"
|
add_foreign_key "encrypted_configs", "accounts"
|
||||||
add_foreign_key "encrypted_user_configs", "users"
|
add_foreign_key "encrypted_user_configs", "users"
|
||||||
|
add_foreign_key "mcp_tokens", "users"
|
||||||
add_foreign_key "oauth_access_grants", "oauth_applications", column: "application_id"
|
add_foreign_key "oauth_access_grants", "oauth_applications", column: "application_id"
|
||||||
add_foreign_key "oauth_access_grants", "users", column: "resource_owner_id"
|
add_foreign_key "oauth_access_grants", "users", column: "resource_owner_id"
|
||||||
add_foreign_key "oauth_access_tokens", "oauth_applications", column: "application_id"
|
add_foreign_key "oauth_access_tokens", "oauth_applications", column: "application_id"
|
||||||
@@ -556,6 +570,7 @@ ActiveRecord::Schema[8.1].define(version: 2026_02_26_193537) do
|
|||||||
add_foreign_key "submission_events", "submitters"
|
add_foreign_key "submission_events", "submitters"
|
||||||
add_foreign_key "submissions", "templates"
|
add_foreign_key "submissions", "templates"
|
||||||
add_foreign_key "submissions", "users", column: "created_by_user_id"
|
add_foreign_key "submissions", "users", column: "created_by_user_id"
|
||||||
|
add_foreign_key "submitter_versions", "submitters"
|
||||||
add_foreign_key "submitters", "submissions"
|
add_foreign_key "submitters", "submissions"
|
||||||
add_foreign_key "template_accesses", "templates"
|
add_foreign_key "template_accesses", "templates"
|
||||||
add_foreign_key "template_folders", "accounts"
|
add_foreign_key "template_folders", "accounts"
|
||||||
|
|||||||
@@ -175,6 +175,7 @@ module Accounts
|
|||||||
|
|
||||||
def can_send_emails?(_account, **_params)
|
def can_send_emails?(_account, **_params)
|
||||||
return true if Docuseal.multitenant?
|
return true if Docuseal.multitenant?
|
||||||
|
return true if Rails.env.development?
|
||||||
return true if ENV['SMTP_ADDRESS'].present?
|
return true if ENV['SMTP_ADDRESS'].present?
|
||||||
|
|
||||||
EncryptedConfig.exists?(key: EncryptedConfig::EMAIL_SMTP_KEY)
|
EncryptedConfig.exists?(key: EncryptedConfig::EMAIL_SMTP_KEY)
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ module EmailVerificationCodes
|
|||||||
def build_totp_secret(value)
|
def build_totp_secret(value)
|
||||||
ROTP::Base32.encode(
|
ROTP::Base32.encode(
|
||||||
Digest::SHA1.digest(
|
Digest::SHA1.digest(
|
||||||
[Rails.application.secret_key_base, value].join(':')
|
[Rails.application.secret_key_base, 'form_email_2fa', value].join(':')
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -0,0 +1,119 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module HtmlToPlainText
|
||||||
|
module_function
|
||||||
|
|
||||||
|
def call(html, line_length = 65)
|
||||||
|
return '' if html.nil? || html.strip.empty?
|
||||||
|
|
||||||
|
cleaned = html.gsub(%r{<!-- start text/html -->.*?<!-- end text/html -->}m, '')
|
||||||
|
|
||||||
|
doc = Nokogiri::HTML.fragment(cleaned)
|
||||||
|
|
||||||
|
doc.css('script').each(&:remove)
|
||||||
|
|
||||||
|
result = process_nodes(doc, line_length)
|
||||||
|
|
||||||
|
result.gsub!(/\r\n?/, "\n")
|
||||||
|
result.gsub!(/[ \t]*\u00A0+[ \t]*/, ' ')
|
||||||
|
result.gsub!(/\n[ \t]+/, "\n")
|
||||||
|
result.gsub!(/[ \t]+\n/, "\n")
|
||||||
|
result.gsub!(/\n{3,}/, "\n\n")
|
||||||
|
|
||||||
|
result = word_wrap(result, line_length)
|
||||||
|
|
||||||
|
result.gsub!(/\(([ \n])(http[^)]+)([\n ])\)/) do
|
||||||
|
"#{"\n" if ::Regexp.last_match(1) == "\n"}( #{::Regexp.last_match(2)} )#{"\n" if ::Regexp.last_match(3) == "\n"}"
|
||||||
|
end
|
||||||
|
|
||||||
|
result.strip
|
||||||
|
end
|
||||||
|
|
||||||
|
def process_nodes(node, line_length)
|
||||||
|
result = +''
|
||||||
|
|
||||||
|
node.children.each do |child|
|
||||||
|
case child
|
||||||
|
when Nokogiri::XML::Text
|
||||||
|
result << child.text
|
||||||
|
when Nokogiri::XML::Comment
|
||||||
|
next
|
||||||
|
when Nokogiri::XML::Element
|
||||||
|
result << process_element(child, line_length)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
result
|
||||||
|
end
|
||||||
|
|
||||||
|
def process_element(node, line_length)
|
||||||
|
case node.name
|
||||||
|
when 'br'
|
||||||
|
"\n"
|
||||||
|
when 'p', 'div'
|
||||||
|
inner = process_nodes(node, line_length)
|
||||||
|
inner.strip.empty? ? '' : "#{inner}\n\n"
|
||||||
|
when 'img'
|
||||||
|
node['alt'] || ''
|
||||||
|
when 'a'
|
||||||
|
process_link(node, line_length)
|
||||||
|
when /\Ah([1-6])\z/
|
||||||
|
process_heading(node, ::Regexp.last_match(1).to_i, line_length)
|
||||||
|
when 'li'
|
||||||
|
inner = process_nodes(node, line_length)
|
||||||
|
"* #{inner.strip}\n"
|
||||||
|
else
|
||||||
|
process_nodes(node, line_length)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def process_link(node, line_length)
|
||||||
|
text = process_nodes(node, line_length).strip
|
||||||
|
return '' if text.empty?
|
||||||
|
|
||||||
|
href = node['href']
|
||||||
|
href = href.sub(/\Amailto:/i, '') if href
|
||||||
|
|
||||||
|
if href.nil? || text.casecmp(href.strip) == 0
|
||||||
|
text
|
||||||
|
else
|
||||||
|
"#{text} ( #{href.strip} )"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def process_heading(node, level, line_length)
|
||||||
|
text = +''
|
||||||
|
node.children.each do |child|
|
||||||
|
text << if child.name == 'br'
|
||||||
|
"\n"
|
||||||
|
else
|
||||||
|
child.text
|
||||||
|
end
|
||||||
|
end
|
||||||
|
text.strip!
|
||||||
|
|
||||||
|
hlength = text.each_line.map { |l| l.strip.length }.max || 0
|
||||||
|
hlength = line_length if hlength > line_length
|
||||||
|
|
||||||
|
decorated = case level
|
||||||
|
when 1
|
||||||
|
"#{'*' * hlength}\n#{text}\n#{'*' * hlength}"
|
||||||
|
when 2
|
||||||
|
"#{'-' * hlength}\n#{text}\n#{'-' * hlength}"
|
||||||
|
else
|
||||||
|
"#{text}\n#{'-' * hlength}"
|
||||||
|
end
|
||||||
|
|
||||||
|
"\n\n#{decorated}\n\n"
|
||||||
|
end
|
||||||
|
|
||||||
|
def word_wrap(txt, line_length)
|
||||||
|
txt.split("\n").map do |line|
|
||||||
|
if line.length > line_length
|
||||||
|
line.gsub(/(.{1,#{line_length}})(\s+|$)/, "\\1\n").strip
|
||||||
|
else
|
||||||
|
line
|
||||||
|
end
|
||||||
|
end.join("\n")
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module HtmlToPlainTextInterceptor
|
||||||
|
module_function
|
||||||
|
|
||||||
|
def delivering_email(message)
|
||||||
|
process(message)
|
||||||
|
end
|
||||||
|
|
||||||
|
def previewing_email(message)
|
||||||
|
process(message)
|
||||||
|
end
|
||||||
|
|
||||||
|
def process(message)
|
||||||
|
return message unless html_part(message)
|
||||||
|
return message if message.text_part
|
||||||
|
|
||||||
|
add_text_part(message)
|
||||||
|
|
||||||
|
message
|
||||||
|
end
|
||||||
|
|
||||||
|
def add_text_part(message)
|
||||||
|
html = html_part(message).decoded
|
||||||
|
text = HtmlToPlainText.call(html)
|
||||||
|
|
||||||
|
text_part = Mail::Part.new do
|
||||||
|
content_type 'text/plain; charset=UTF-8'
|
||||||
|
body text
|
||||||
|
end
|
||||||
|
|
||||||
|
if pure_html_message?(message)
|
||||||
|
message.body = nil
|
||||||
|
message.content_type = 'multipart/alternative'
|
||||||
|
message.add_part(text_part)
|
||||||
|
message.add_part(Mail::Part.new do
|
||||||
|
content_type 'text/html; charset=UTF-8'
|
||||||
|
body html
|
||||||
|
end)
|
||||||
|
else
|
||||||
|
alternative = Mail::Part.new(content_type: 'multipart/alternative')
|
||||||
|
alternative.add_part(text_part)
|
||||||
|
alternative.add_part(message.html_part)
|
||||||
|
replace_part(message.parts, message.html_part, alternative)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def pure_html_message?(message)
|
||||||
|
message.content_type.to_s.include?('text/html')
|
||||||
|
end
|
||||||
|
|
||||||
|
def html_part(message)
|
||||||
|
pure_html_message?(message) ? message : message.html_part
|
||||||
|
end
|
||||||
|
|
||||||
|
def replace_part(parts, old_part, new_part)
|
||||||
|
if (index = parts.index(old_part))
|
||||||
|
parts[index] = new_part
|
||||||
|
else
|
||||||
|
parts.each do |part|
|
||||||
|
replace_part(part.parts, old_part, new_part) if part.respond_to?(:parts)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
module LoadIco
|
module LoadIco
|
||||||
BI_RGB = 0
|
BI_RGB = 0
|
||||||
|
PNG_SIGNATURE = "\x89PNG".b
|
||||||
|
|
||||||
module_function
|
module_function
|
||||||
|
|
||||||
@@ -42,6 +43,8 @@ module LoadIco
|
|||||||
|
|
||||||
raise ArgumentError, 'Unable to load' unless image_data_bytes && image_data_bytes.bytesize == best_entry[:size]
|
raise ArgumentError, 'Unable to load' unless image_data_bytes && image_data_bytes.bytesize == best_entry[:size]
|
||||||
|
|
||||||
|
return Vips::Image.new_from_buffer(image_data_bytes, '') if image_data_bytes.start_with?(PNG_SIGNATURE)
|
||||||
|
|
||||||
image = load_image_entry(image_data_bytes, best_entry[:width], best_entry[:height])
|
image = load_image_entry(image_data_bytes, best_entry[:width], best_entry[:height])
|
||||||
|
|
||||||
raise ArgumentError, 'Unable to load' unless image
|
raise ArgumentError, 'Unable to load' unless image
|
||||||
|
|||||||
@@ -246,33 +246,25 @@ module Submissions
|
|||||||
|
|
||||||
next if submitter.blank?
|
next if submitter.blank?
|
||||||
|
|
||||||
completed_event =
|
submission_events = submission.submission_events.select { |e| e.submitter_id == submitter.id }
|
||||||
submission.submission_events.find { |e| e.submitter_id == submitter.id && e.complete_form? } ||
|
|
||||||
SubmissionEvent.new
|
|
||||||
|
|
||||||
click_email_event =
|
delegated_event = submission_events.select(&:delegate_form?).max_by(&:event_timestamp)
|
||||||
submission.submission_events.find { |e| e.submitter_id == submitter.id && e.click_email? }
|
|
||||||
|
|
||||||
verify_email_event =
|
if delegated_event
|
||||||
submission.submission_events.find { |e| e.submitter_id == submitter.id && e.email_verified? }
|
submission_events = submission_events.select { |e| e.event_timestamp > delegated_event.event_timestamp }
|
||||||
|
end
|
||||||
|
|
||||||
is_phone_verified =
|
completed_event = submission_events.find(&:complete_form?) || SubmissionEvent.new
|
||||||
submission.template_fields.any? do |e|
|
|
||||||
e['type'] == 'phone' && e['submitter_uuid'] == submitter.uuid && submitter.values[e['uuid']].present?
|
|
||||||
end
|
|
||||||
|
|
||||||
verify_phone_event =
|
click_email_event = submission_events.find(&:click_email?)
|
||||||
submission.submission_events.find { |e| e.submitter_id == submitter.id && e.phone_verified? }
|
|
||||||
|
|
||||||
is_id_verified =
|
verify_email_event = submission_events.find(&:email_verified?)
|
||||||
submission.template_fields.any? do |e|
|
|
||||||
e['type'] == 'verification' && e['submitter_uuid'] == submitter.uuid && submitter.values[e['uuid']].present?
|
|
||||||
end
|
|
||||||
|
|
||||||
is_kba_passed =
|
verify_phone_event = submission_events.find(&:phone_verified?)
|
||||||
submission.template_fields.any? do |e|
|
|
||||||
e['type'] == 'kba' && e['submitter_uuid'] == submitter.uuid && submitter.values[e['uuid']].present?
|
is_id_verified = submission_events.any?(&:complete_verification?)
|
||||||
end
|
|
||||||
|
is_kba_passed = submission_events.any?(&:complete_kba?)
|
||||||
|
|
||||||
info_rows = [
|
info_rows = [
|
||||||
[
|
[
|
||||||
@@ -291,7 +283,7 @@ module Submissions
|
|||||||
submitter.email && (click_email_event || verify_email_event) && {
|
submitter.email && (click_email_event || verify_email_event) && {
|
||||||
text: "#{I18n.t('email_verification')}: #{I18n.t('verified')}\n"
|
text: "#{I18n.t('email_verification')}: #{I18n.t('verified')}\n"
|
||||||
},
|
},
|
||||||
submitter.phone && (is_phone_verified || verify_phone_event) && {
|
submitter.phone && verify_phone_event && {
|
||||||
text: "#{I18n.t('phone_verification')}: #{I18n.t('verified')}\n"
|
text: "#{I18n.t('phone_verification')}: #{I18n.t('verified')}\n"
|
||||||
},
|
},
|
||||||
is_id_verified && {
|
is_id_verified && {
|
||||||
@@ -446,15 +438,23 @@ module Submissions
|
|||||||
|
|
||||||
composer.text(I18n.t('event_log'), font_size: 12, padding: [10, 0, 20, 0])
|
composer.text(I18n.t('event_log'), font_size: 12, padding: [10, 0, 20, 0])
|
||||||
|
|
||||||
|
submitter_versions_index = submission.submitters.preload(:submitter_versions).each_with_object({}) do |s, h|
|
||||||
|
h[s.id] = s.submitter_versions.to_a.sort_by(&:created_at)
|
||||||
|
end
|
||||||
|
|
||||||
events_data = submission.submission_events.sort_by(&:event_timestamp).filter_map do |event|
|
events_data = submission.submission_events.sort_by(&:event_timestamp).filter_map do |event|
|
||||||
next if event.event_type.in?(%w[bounce_email complaint_email])
|
next if event.event_type.in?(%w[bounce_email complaint_email])
|
||||||
|
|
||||||
submitter = submission.submitters.find { |e| e.id == event.submitter_id }
|
submitter = submission.submitters.find { |e| e.id == event.submitter_id }
|
||||||
|
versions = submitter_versions_index[submitter.id] || []
|
||||||
|
active_version = versions.find { |v| v.created_at > event.event_timestamp }
|
||||||
|
|
||||||
submitter_name =
|
submitter_name =
|
||||||
if event.event_type.include?('sms') || event.event_type.include?('phone')
|
if event.event_type.include?('sms') || event.event_type.include?('phone')
|
||||||
event.data['phone'] || submitter.phone
|
event.data['phone'] || active_version&.phone || submitter.phone
|
||||||
else
|
else
|
||||||
submitter.name || submitter.email || submitter.phone
|
active_version&.name || active_version&.email || active_version&.phone ||
|
||||||
|
submitter.name || submitter.email || submitter.phone
|
||||||
end
|
end
|
||||||
|
|
||||||
text =
|
text =
|
||||||
@@ -473,6 +473,10 @@ module Submissions
|
|||||||
I18n.t("submission_event_names.#{event.event_type}_to_html", submitter_name:),
|
I18n.t("submission_event_names.#{event.event_type}_to_html", submitter_name:),
|
||||||
"<b>#{I18n.t(:from)}</b> #{submission.created_by_user.full_name} #{submission.created_by_user.email}"
|
"<b>#{I18n.t(:from)}</b> #{submission.created_by_user.full_name} #{submission.created_by_user.email}"
|
||||||
].join("\n")
|
].join("\n")
|
||||||
|
elsif event.event_type == 'delegate_form'
|
||||||
|
from = event.data['old_email'].presence ||
|
||||||
|
versions.reverse.find { |v| v.created_at <= event.event_timestamp }&.then { |v| v.name || v.phone }
|
||||||
|
I18n.t('submission_event_names.delegate_form_by_html', from:, to: event.data['email'])
|
||||||
elsif event.event_type.include?('send_')
|
elsif event.event_type.include?('send_')
|
||||||
I18n.t("submission_event_names.#{event.event_type}_to_html", submitter_name:)
|
I18n.t("submission_event_names.#{event.event_type}_to_html", submitter_name:)
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -236,9 +236,10 @@ module Submissions
|
|||||||
|
|
||||||
page[:Annots] ||= []
|
page[:Annots] ||= []
|
||||||
page[:Annots] = page[:Annots].try(:reject) do |e|
|
page[:Annots] = page[:Annots].try(:reject) do |e|
|
||||||
next if e.is_a?(Integer) || e.is_a?(Symbol)
|
next if e.is_a?(Integer) || e.is_a?(Symbol) || e.is_a?(HexaPDF::PDFArray)
|
||||||
|
|
||||||
e.present? && e[:A] && e[:A][:URI].to_s.starts_with?('file:///docuseal_field')
|
e.present? && e[:A] && !e[:A].is_a?(HexaPDF::PDFArray) &&
|
||||||
|
e[:A][:URI].to_s.starts_with?('file:///docuseal_field')
|
||||||
end || page[:Annots]
|
end || page[:Annots]
|
||||||
|
|
||||||
width = page.box.width
|
width = page.box.width
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ module Submitters
|
|||||||
AccountConfig::FORM_PREFILL_SIGNATURE_KEY,
|
AccountConfig::FORM_PREFILL_SIGNATURE_KEY,
|
||||||
AccountConfig::WITH_SIGNATURE_ID,
|
AccountConfig::WITH_SIGNATURE_ID,
|
||||||
AccountConfig::ALLOW_TO_DECLINE_KEY,
|
AccountConfig::ALLOW_TO_DECLINE_KEY,
|
||||||
|
AccountConfig::ALLOW_TO_DELEGATE_KEY,
|
||||||
AccountConfig::ENFORCE_SIGNING_ORDER_KEY,
|
AccountConfig::ENFORCE_SIGNING_ORDER_KEY,
|
||||||
AccountConfig::REQUIRE_SIGNING_REASON_KEY,
|
AccountConfig::REQUIRE_SIGNING_REASON_KEY,
|
||||||
AccountConfig::REUSE_SIGNATURE_KEY,
|
AccountConfig::REUSE_SIGNATURE_KEY,
|
||||||
@@ -27,10 +28,11 @@ module Submitters
|
|||||||
completed_button = find_safe_value(configs, AccountConfig::FORM_COMPLETED_BUTTON_KEY) || {}
|
completed_button = find_safe_value(configs, AccountConfig::FORM_COMPLETED_BUTTON_KEY) || {}
|
||||||
completed_message = find_safe_value(configs, AccountConfig::FORM_COMPLETED_MESSAGE_KEY) || {}
|
completed_message = find_safe_value(configs, AccountConfig::FORM_COMPLETED_MESSAGE_KEY) || {}
|
||||||
with_typed_signature = find_safe_value(configs, AccountConfig::ALLOW_TYPED_SIGNATURE) != false
|
with_typed_signature = find_safe_value(configs, AccountConfig::ALLOW_TYPED_SIGNATURE) != false
|
||||||
with_confetti = find_safe_value(configs, AccountConfig::FORM_WITH_CONFETTI_KEY) != false
|
with_confetti = find_safe_value(configs, AccountConfig::FORM_WITH_CONFETTI_KEY) == true
|
||||||
prefill_signature = find_safe_value(configs, AccountConfig::FORM_PREFILL_SIGNATURE_KEY) != false
|
prefill_signature = find_safe_value(configs, AccountConfig::FORM_PREFILL_SIGNATURE_KEY) != false
|
||||||
reuse_signature = find_safe_value(configs, AccountConfig::REUSE_SIGNATURE_KEY) != false
|
reuse_signature = find_safe_value(configs, AccountConfig::REUSE_SIGNATURE_KEY) != false
|
||||||
with_decline = find_safe_value(configs, AccountConfig::ALLOW_TO_DECLINE_KEY) != false
|
with_decline = find_safe_value(configs, AccountConfig::ALLOW_TO_DECLINE_KEY) != false
|
||||||
|
with_delegate = find_safe_value(configs, AccountConfig::ALLOW_TO_DELEGATE_KEY) == true
|
||||||
with_partial_download = find_safe_value(configs, AccountConfig::ALLOW_TO_PARTIAL_DOWNLOAD_KEY) != false
|
with_partial_download = find_safe_value(configs, AccountConfig::ALLOW_TO_PARTIAL_DOWNLOAD_KEY) != false
|
||||||
with_signature_id = find_safe_value(configs, AccountConfig::WITH_SIGNATURE_ID) == true
|
with_signature_id = find_safe_value(configs, AccountConfig::WITH_SIGNATURE_ID) == true
|
||||||
require_signing_reason = find_safe_value(configs, AccountConfig::REQUIRE_SIGNING_REASON_KEY) == true
|
require_signing_reason = find_safe_value(configs, AccountConfig::REQUIRE_SIGNING_REASON_KEY) == true
|
||||||
@@ -42,7 +44,7 @@ module Submitters
|
|||||||
policy_links = find_safe_value(configs, AccountConfig::POLICY_LINKS_KEY)
|
policy_links = find_safe_value(configs, AccountConfig::POLICY_LINKS_KEY)
|
||||||
|
|
||||||
attrs = { completed_button:, with_typed_signature:, with_confetti:,
|
attrs = { completed_button:, with_typed_signature:, with_confetti:,
|
||||||
reuse_signature:, with_decline:, with_partial_download:,
|
reuse_signature:, with_decline:, with_delegate:, with_partial_download:,
|
||||||
policy_links:, enforce_signing_order:, completed_message:,
|
policy_links:, enforce_signing_order:, completed_message:,
|
||||||
require_signing_reason:, prefill_signature:, with_submitter_timezone:,
|
require_signing_reason:, prefill_signature:, with_submitter_timezone:,
|
||||||
with_signature_id_reason:, with_signature_id:, with_field_labels:, with_timestamp_seconds: }
|
with_signature_id_reason:, with_signature_id:, with_field_labels:, with_timestamp_seconds: }
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ module Templates
|
|||||||
pdf.pages.flat_map.with_index do |page, index|
|
pdf.pages.flat_map.with_index do |page, index|
|
||||||
(page[:Annots] || []).filter_map do |annot|
|
(page[:Annots] || []).filter_map do |annot|
|
||||||
next if annot.blank?
|
next if annot.blank?
|
||||||
next if annot.is_a?(Integer) || annot.is_a?(Symbol)
|
next if annot.is_a?(Integer) || annot.is_a?(Symbol) || annot.is_a?(HexaPDF::PDFArray)
|
||||||
next if annot[:A].blank? || annot[:A][:URI].blank?
|
next if annot[:A].blank? || annot[:A][:URI].blank?
|
||||||
next unless annot[:Subtype] == :Link
|
next unless annot[:Subtype] == :Link
|
||||||
next if !annot[:A][:URI].starts_with?('https://') && !annot[:A][:URI].starts_with?('http://')
|
next if !annot[:A][:URI].starts_with?('https://') && !annot[:A][:URI].starts_with?('http://')
|
||||||
|
|||||||
+2
-1
@@ -11,7 +11,8 @@ module WebhookUrls
|
|||||||
'submission.expired' => SendSubmissionExpiredWebhookRequestJob,
|
'submission.expired' => SendSubmissionExpiredWebhookRequestJob,
|
||||||
'submission.archived' => SendSubmissionArchivedWebhookRequestJob,
|
'submission.archived' => SendSubmissionArchivedWebhookRequestJob,
|
||||||
'template.created' => SendTemplateCreatedWebhookRequestJob,
|
'template.created' => SendTemplateCreatedWebhookRequestJob,
|
||||||
'template.updated' => SendTemplateUpdatedWebhookRequestJob
|
'template.updated' => SendTemplateUpdatedWebhookRequestJob,
|
||||||
|
'template.archived' => SendTemplateArchivedWebhookRequestJob
|
||||||
}.freeze
|
}.freeze
|
||||||
|
|
||||||
EVENT_TYPE_ID_KEYS = {
|
EVENT_TYPE_ID_KEYS = {
|
||||||
|
|||||||
@@ -0,0 +1,100 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
RSpec.describe SendTemplateArchivedWebhookRequestJob do
|
||||||
|
let(:account) { create(:account) }
|
||||||
|
let(:user) { create(:user, account:) }
|
||||||
|
let(:template) { create(:template, account:, author: user) }
|
||||||
|
let(:webhook_url) { create(:webhook_url, account:, events: ['template.archived']) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
create(:encrypted_config, key: EncryptedConfig::ESIGN_CERTS_KEY,
|
||||||
|
value: GenerateCertificate.call.transform_values(&:to_pem))
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#perform' do
|
||||||
|
around do |example|
|
||||||
|
freeze_time { example.run }
|
||||||
|
end
|
||||||
|
|
||||||
|
before do
|
||||||
|
stub_request(:post, webhook_url.url).to_return(status: 200)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'sends a webhook request' do
|
||||||
|
described_class.new.perform('template_id' => template.id, 'webhook_url_id' => webhook_url.id,
|
||||||
|
'event_uuid' => SecureRandom.uuid)
|
||||||
|
|
||||||
|
expect(WebMock).to have_requested(:post, webhook_url.url).with(
|
||||||
|
body: {
|
||||||
|
'event_type' => 'template.archived',
|
||||||
|
'timestamp' => /.*/,
|
||||||
|
'data' => template.reload.as_json(only: %i[id archived_at])
|
||||||
|
},
|
||||||
|
headers: {
|
||||||
|
'Content-Type' => 'application/json',
|
||||||
|
'User-Agent' => 'DocuSeal.com Webhook'
|
||||||
|
}
|
||||||
|
).once
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'sends a webhook request with the secret' do
|
||||||
|
webhook_url.update(secret: { 'X-Secret-Header' => 'secret_value' })
|
||||||
|
described_class.new.perform('template_id' => template.id, 'webhook_url_id' => webhook_url.id,
|
||||||
|
'event_uuid' => SecureRandom.uuid)
|
||||||
|
|
||||||
|
expect(WebMock).to have_requested(:post, webhook_url.url).with(
|
||||||
|
body: {
|
||||||
|
'event_type' => 'template.archived',
|
||||||
|
'timestamp' => /.*/,
|
||||||
|
'data' => template.reload.as_json(only: %i[id archived_at])
|
||||||
|
},
|
||||||
|
headers: {
|
||||||
|
'Content-Type' => 'application/json',
|
||||||
|
'User-Agent' => 'DocuSeal.com Webhook',
|
||||||
|
'X-Secret-Header' => 'secret_value'
|
||||||
|
}
|
||||||
|
).once
|
||||||
|
end
|
||||||
|
|
||||||
|
it "doesn't send a webhook request if the event is not in the webhook's events" do
|
||||||
|
webhook_url.update!(events: ['template.updated'])
|
||||||
|
|
||||||
|
described_class.new.perform('template_id' => template.id, 'webhook_url_id' => webhook_url.id,
|
||||||
|
'event_uuid' => SecureRandom.uuid)
|
||||||
|
|
||||||
|
expect(WebMock).not_to have_requested(:post, webhook_url.url)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'sends again if the response status is 400 or higher' do
|
||||||
|
stub_request(:post, webhook_url.url).to_return(status: 401)
|
||||||
|
|
||||||
|
event_uuid = SecureRandom.uuid
|
||||||
|
|
||||||
|
expect do
|
||||||
|
described_class.new.perform('template_id' => template.id, 'webhook_url_id' => webhook_url.id,
|
||||||
|
'event_uuid' => event_uuid)
|
||||||
|
end.to change(described_class.jobs, :size).by(1)
|
||||||
|
|
||||||
|
expect(WebMock).to have_requested(:post, webhook_url.url).once
|
||||||
|
|
||||||
|
args = described_class.jobs.last['args'].first
|
||||||
|
|
||||||
|
expect(args['attempt']).to eq(1)
|
||||||
|
expect(args['last_status']).to eq(401)
|
||||||
|
expect(args['event_uuid']).to eq(event_uuid)
|
||||||
|
expect(args['webhook_url_id']).to eq(webhook_url.id)
|
||||||
|
expect(args['template_id']).to eq(template.id)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "doesn't send again if the max attempts is reached" do
|
||||||
|
stub_request(:post, webhook_url.url).to_return(status: 401)
|
||||||
|
|
||||||
|
expect do
|
||||||
|
described_class.new.perform('template_id' => template.id, 'webhook_url_id' => webhook_url.id,
|
||||||
|
'event_uuid' => SecureRandom.uuid, 'attempt' => 11)
|
||||||
|
end.not_to change(described_class.jobs, :size)
|
||||||
|
|
||||||
|
expect(WebMock).to have_requested(:post, webhook_url.url).once
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -23,7 +23,7 @@ RSpec.describe 'Sign In' do
|
|||||||
fill_in 'Password', with: 'wrong_password'
|
fill_in 'Password', with: 'wrong_password'
|
||||||
click_button 'Sign In'
|
click_button 'Sign In'
|
||||||
|
|
||||||
expect(page).to have_content('Invalid Email or password')
|
expect(page).to have_content('Invalid email or password')
|
||||||
expect(page).not_to have_content('Document Templates')
|
expect(page).not_to have_content('Document Templates')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -51,7 +51,7 @@ RSpec.describe 'Sign In' do
|
|||||||
fill_in 'Two-Factor Code from Authenticator App', with: '123456'
|
fill_in 'Two-Factor Code from Authenticator App', with: '123456'
|
||||||
click_button 'Sign In'
|
click_button 'Sign In'
|
||||||
|
|
||||||
expect(page).to have_content('Invalid Email or password')
|
expect(page).to have_content('Invalid email or password')
|
||||||
expect(page).not_to have_content('Document Templates')
|
expect(page).not_to have_content('Document Templates')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1159,6 +1159,50 @@ RSpec.describe 'Signing Form' do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'when decline is enabled' do
|
||||||
|
let(:template) { create(:template, account:, author:, only_field_types: %w[text]) }
|
||||||
|
let(:submission) { create(:submission, template:) }
|
||||||
|
let(:submitter) { create(:submitter, submission:, uuid: template.submitters.first['uuid'], account:) }
|
||||||
|
|
||||||
|
it 'declines the form and shows the declined page' do
|
||||||
|
visit submit_form_path(slug: submitter.slug)
|
||||||
|
|
||||||
|
find('#decline_button').click
|
||||||
|
fill_in 'reason', with: 'I do not agree with the terms'
|
||||||
|
click_button 'Decline'
|
||||||
|
|
||||||
|
expect(page).to have_content('Form has been declined')
|
||||||
|
|
||||||
|
submitter.reload
|
||||||
|
|
||||||
|
expect(submitter.declined_at).to be_present
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when delegate is enabled' do
|
||||||
|
let(:template) { create(:template, account:, author:, only_field_types: %w[text]) }
|
||||||
|
let(:submission) { create(:submission, template:) }
|
||||||
|
let(:submitter) { create(:submitter, submission:, uuid: template.submitters.first['uuid'], account:) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
create(:account_config, account:, key: AccountConfig::ALLOW_TO_DELEGATE_KEY, value: true)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'delegates the form to another email and shows the delegated page' do
|
||||||
|
visit submit_form_path(slug: submitter.slug)
|
||||||
|
|
||||||
|
find('#delegate_button').click
|
||||||
|
fill_in 'email', with: 'delegate@example.com'
|
||||||
|
click_button 'Delegate'
|
||||||
|
|
||||||
|
expect(page).to have_content('Document has been delegated')
|
||||||
|
|
||||||
|
submitter.reload
|
||||||
|
|
||||||
|
expect(submitter.email).to eq('delegate@example.com')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
context 'when the 2FA email verification is enabled', sidekiq: :inline do
|
context 'when the 2FA email verification is enabled', sidekiq: :inline do
|
||||||
let(:template) { create(:template, account:, author:, only_field_types: %w[text]) }
|
let(:template) { create(:template, account:, author:, only_field_types: %w[text]) }
|
||||||
let(:submission) { create(:submission, template:) }
|
let(:submission) { create(:submission, template:) }
|
||||||
|
|||||||
Reference in new issue
Block a user