mirror of
https://github.com/docusealco/docuseal.git
synced 2026-08-07 07:14:43 +00:00
Compare commits
25 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8c4cbd86f7 | |||
| eaedaa96bb | |||
| bd7ad5fce8 | |||
| 759dac1b70 | |||
| 38577c6235 | |||
| b24fff0f55 | |||
| 9e0efeb092 | |||
| 41152f90fc | |||
| 4486f8040e | |||
| a98caad968 | |||
| ffb75238b4 | |||
| cba3e74f3a | |||
| 8d3f0b5b98 | |||
| a2598b30f7 | |||
| 8d11f5ddae | |||
| 6ffc88b4ed | |||
| 640b451727 | |||
| db6e2eb7ca | |||
| 407816b576 | |||
| 486cc493e6 | |||
| 3eb0b8a89f | |||
| c23eca0ade | |||
| 67de153016 | |||
| ba2da69a67 | |||
| 111bef14e1 |
@@ -51,6 +51,15 @@ Style/NumericPredicate:
|
||||
Style/MinMaxComparison:
|
||||
Enabled: false
|
||||
|
||||
Style/EmptyClassDefinition:
|
||||
Enabled: false
|
||||
|
||||
Style/OneClassPerFile:
|
||||
Enabled: false
|
||||
|
||||
Layout/MultilineMethodCallIndentation:
|
||||
Enabled: false
|
||||
|
||||
Naming/PredicateMethod:
|
||||
Enabled: false
|
||||
|
||||
|
||||
+10
-14
@@ -2,20 +2,17 @@ FROM ruby:4.0.1-alpine AS download
|
||||
|
||||
WORKDIR /fonts
|
||||
|
||||
RUN apk --no-cache add fontforge wget && \
|
||||
RUN apk --no-cache add wget && \
|
||||
wget https://github.com/satbyy/go-noto-universal/releases/download/v7.0/GoNotoKurrent-Regular.ttf && \
|
||||
wget https://github.com/satbyy/go-noto-universal/releases/download/v7.0/GoNotoKurrent-Bold.ttf && \
|
||||
wget https://github.com/impallari/DancingScript/raw/master/fonts/DancingScript-Regular.otf && \
|
||||
wget https://cdn.jsdelivr.net/gh/notofonts/notofonts.github.io/fonts/NotoSansSymbols2/hinted/ttf/NotoSansSymbols2-Regular.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://raw.githubusercontent.com/impallari/DancingScript/master/OFL.txt && \
|
||||
wget https://raw.githubusercontent.com/notofonts/noto-fonts/refs/heads/main/LICENSE && \
|
||||
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 && \
|
||||
tar -xzf pdfium-linux.tgz -C /pdfium-linux
|
||||
|
||||
RUN fontforge -lang=py -c 'font1 = fontforge.open("FreeSans.ttf"); font2 = fontforge.open("NotoSansSymbols2-Regular.ttf"); font1.mergeFonts(font2); font1.generate("FreeSans.ttf")'
|
||||
|
||||
FROM ruby:4.0.1-alpine AS webpack
|
||||
|
||||
ENV RAILS_ENV=production
|
||||
@@ -47,13 +44,11 @@ FROM ruby:4.0.1-alpine AS app
|
||||
|
||||
ENV RAILS_ENV=production
|
||||
ENV BUNDLE_WITHOUT="development:test"
|
||||
ENV LD_PRELOAD=/lib/libgcompat.so.0
|
||||
ENV OPENSSL_CONF=/etc/openssl_legacy.cnf
|
||||
ENV VIPS_MAX_COORD=15000
|
||||
|
||||
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 fontconfig onnxruntime
|
||||
|
||||
RUN addgroup -g 2000 docuseal && adduser -u 2000 -G docuseal -s /bin/sh -D -h /home/docuseal docuseal
|
||||
|
||||
@@ -71,7 +66,7 @@ activate = 1' >> /etc/openssl_legacy.cnf
|
||||
|
||||
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 ./app ./app
|
||||
@@ -84,20 +79,21 @@ COPY --chown=docuseal:docuseal ./tmp ./tmp
|
||||
COPY --chown=docuseal:docuseal LICENSE LICENSE_ADDITIONAL_TERMS README.md Rakefile config.ru .version ./
|
||||
COPY --chown=docuseal:docuseal .version ./public/version
|
||||
|
||||
COPY --chown=docuseal:docuseal --from=download /fonts/GoNotoKurrent-Regular.ttf /fonts/GoNotoKurrent-Bold.ttf /fonts/DancingScript-Regular.otf /fonts/OFL.txt /fonts
|
||||
COPY --from=download /fonts/FreeSans.ttf /usr/share/fonts/freefont
|
||||
COPY --chown=docuseal:docuseal --from=download /fonts/GoNotoKurrent-Regular.ttf /fonts/GoNotoKurrent-Bold.ttf /fonts/DancingScript-Regular.otf /fonts/OFL.txt /fonts/LICENSE /fonts/
|
||||
COPY --from=download /pdfium-linux/lib/libpdfium.so /usr/lib/libpdfium.so
|
||||
COPY --from=download /pdfium-linux/licenses/pdfium.txt /usr/lib/libpdfium-LICENSE.txt
|
||||
COPY --chown=docuseal:docuseal --from=download /model.onnx /app/tmp/model.onnx
|
||||
COPY --chown=docuseal:docuseal --from=webpack /app/public/packs ./public/packs
|
||||
|
||||
RUN ln -s /fonts /app/public/fonts && \
|
||||
RUN mkdir -p /app/public/fonts && ln -s /fonts/DancingScript-Regular.otf /app/public/fonts/ && \
|
||||
mkdir -p /usr/share/fonts/noto && ln -s /fonts/GoNotoKurrent-Regular.ttf /usr/share/fonts/noto/ && ln -s /fonts/GoNotoKurrent-Bold.ttf /usr/share/fonts/noto/ && fc-cache -f && \
|
||||
bundle exec bootsnap precompile -j 1 --gemfile app/ lib/ && \
|
||||
chown -R docuseal:docuseal /app/tmp/cache
|
||||
|
||||
WORKDIR /data/docuseal
|
||||
ENV HOME=/home/docuseal
|
||||
ENV WORKDIR=/data/docuseal
|
||||
ENV VIPS_MAX_COORD=17000
|
||||
|
||||
EXPOSE 3000
|
||||
CMD ["/app/bin/bundle", "exec", "puma", "-C", "/app/config/puma.rb", "--dir", "/app"]
|
||||
|
||||
+121
-121
@@ -1,31 +1,31 @@
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
action_text-trix (2.1.16)
|
||||
action_text-trix (2.1.18)
|
||||
railties
|
||||
actioncable (8.1.2)
|
||||
actionpack (= 8.1.2)
|
||||
activesupport (= 8.1.2)
|
||||
actioncable (8.1.3)
|
||||
actionpack (= 8.1.3)
|
||||
activesupport (= 8.1.3)
|
||||
nio4r (~> 2.0)
|
||||
websocket-driver (>= 0.6.1)
|
||||
zeitwerk (~> 2.6)
|
||||
actionmailbox (8.1.2)
|
||||
actionpack (= 8.1.2)
|
||||
activejob (= 8.1.2)
|
||||
activerecord (= 8.1.2)
|
||||
activestorage (= 8.1.2)
|
||||
activesupport (= 8.1.2)
|
||||
actionmailbox (8.1.3)
|
||||
actionpack (= 8.1.3)
|
||||
activejob (= 8.1.3)
|
||||
activerecord (= 8.1.3)
|
||||
activestorage (= 8.1.3)
|
||||
activesupport (= 8.1.3)
|
||||
mail (>= 2.8.0)
|
||||
actionmailer (8.1.2)
|
||||
actionpack (= 8.1.2)
|
||||
actionview (= 8.1.2)
|
||||
activejob (= 8.1.2)
|
||||
activesupport (= 8.1.2)
|
||||
actionmailer (8.1.3)
|
||||
actionpack (= 8.1.3)
|
||||
actionview (= 8.1.3)
|
||||
activejob (= 8.1.3)
|
||||
activesupport (= 8.1.3)
|
||||
mail (>= 2.8.0)
|
||||
rails-dom-testing (~> 2.2)
|
||||
actionpack (8.1.2)
|
||||
actionview (= 8.1.2)
|
||||
activesupport (= 8.1.2)
|
||||
actionpack (8.1.3)
|
||||
actionview (= 8.1.3)
|
||||
activesupport (= 8.1.3)
|
||||
nokogiri (>= 1.8.5)
|
||||
rack (>= 2.2.4)
|
||||
rack-session (>= 1.0.1)
|
||||
@@ -33,36 +33,36 @@ GEM
|
||||
rails-dom-testing (~> 2.2)
|
||||
rails-html-sanitizer (~> 1.6)
|
||||
useragent (~> 0.16)
|
||||
actiontext (8.1.2)
|
||||
actiontext (8.1.3)
|
||||
action_text-trix (~> 2.1.15)
|
||||
actionpack (= 8.1.2)
|
||||
activerecord (= 8.1.2)
|
||||
activestorage (= 8.1.2)
|
||||
activesupport (= 8.1.2)
|
||||
actionpack (= 8.1.3)
|
||||
activerecord (= 8.1.3)
|
||||
activestorage (= 8.1.3)
|
||||
activesupport (= 8.1.3)
|
||||
globalid (>= 0.6.0)
|
||||
nokogiri (>= 1.8.5)
|
||||
actionview (8.1.2)
|
||||
activesupport (= 8.1.2)
|
||||
actionview (8.1.3)
|
||||
activesupport (= 8.1.3)
|
||||
builder (~> 3.1)
|
||||
erubi (~> 1.11)
|
||||
rails-dom-testing (~> 2.2)
|
||||
rails-html-sanitizer (~> 1.6)
|
||||
activejob (8.1.2)
|
||||
activesupport (= 8.1.2)
|
||||
activejob (8.1.3)
|
||||
activesupport (= 8.1.3)
|
||||
globalid (>= 0.3.6)
|
||||
activemodel (8.1.2)
|
||||
activesupport (= 8.1.2)
|
||||
activerecord (8.1.2)
|
||||
activemodel (= 8.1.2)
|
||||
activesupport (= 8.1.2)
|
||||
activemodel (8.1.3)
|
||||
activesupport (= 8.1.3)
|
||||
activerecord (8.1.3)
|
||||
activemodel (= 8.1.3)
|
||||
activesupport (= 8.1.3)
|
||||
timeout (>= 0.4.0)
|
||||
activestorage (8.1.2)
|
||||
actionpack (= 8.1.2)
|
||||
activejob (= 8.1.2)
|
||||
activerecord (= 8.1.2)
|
||||
activesupport (= 8.1.2)
|
||||
activestorage (8.1.3)
|
||||
actionpack (= 8.1.3)
|
||||
activejob (= 8.1.3)
|
||||
activerecord (= 8.1.3)
|
||||
activesupport (= 8.1.3)
|
||||
marcel (~> 1.0)
|
||||
activesupport (8.1.2)
|
||||
activesupport (8.1.3)
|
||||
base64
|
||||
bigdecimal
|
||||
concurrent-ruby (~> 1.0, >= 1.3.1)
|
||||
@@ -75,16 +75,16 @@ GEM
|
||||
securerandom (>= 0.3)
|
||||
tzinfo (~> 2.0, >= 2.0.5)
|
||||
uri (>= 0.13.1)
|
||||
addressable (2.8.8)
|
||||
addressable (2.8.9)
|
||||
public_suffix (>= 2.0.2, < 8.0)
|
||||
annotaterb (4.20.0)
|
||||
annotaterb (4.22.0)
|
||||
activerecord (>= 6.0.0)
|
||||
activesupport (>= 6.0.0)
|
||||
arabic-letter-connector (0.1.1)
|
||||
ast (2.4.3)
|
||||
aws-eventstream (1.4.0)
|
||||
aws-partitions (1.1209.0)
|
||||
aws-sdk-core (3.241.4)
|
||||
aws-partitions (1.1233.0)
|
||||
aws-sdk-core (3.244.0)
|
||||
aws-eventstream (~> 1, >= 1.3.0)
|
||||
aws-partitions (~> 1, >= 1.992.0)
|
||||
aws-sigv4 (~> 1.9)
|
||||
@@ -92,15 +92,15 @@ GEM
|
||||
bigdecimal
|
||||
jmespath (~> 1, >= 1.6.1)
|
||||
logger
|
||||
aws-sdk-kms (1.121.0)
|
||||
aws-sdk-core (~> 3, >= 3.241.4)
|
||||
aws-sdk-kms (1.123.0)
|
||||
aws-sdk-core (~> 3, >= 3.244.0)
|
||||
aws-sigv4 (~> 1.5)
|
||||
aws-sdk-s3 (1.212.0)
|
||||
aws-sdk-core (~> 3, >= 3.241.4)
|
||||
aws-sdk-s3 (1.218.0)
|
||||
aws-sdk-core (~> 3, >= 3.244.0)
|
||||
aws-sdk-kms (~> 1)
|
||||
aws-sigv4 (~> 1.5)
|
||||
aws-sdk-secretsmanager (1.128.0)
|
||||
aws-sdk-core (~> 3, >= 3.241.4)
|
||||
aws-sdk-secretsmanager (1.129.0)
|
||||
aws-sdk-core (~> 3, >= 3.244.0)
|
||||
aws-sigv4 (~> 1.5)
|
||||
aws-sigv4 (1.12.1)
|
||||
aws-eventstream (~> 1, >= 1.0.2)
|
||||
@@ -116,11 +116,11 @@ GEM
|
||||
erubi (~> 1.4)
|
||||
parser (>= 2.4)
|
||||
smart_properties
|
||||
bigdecimal (4.0.1)
|
||||
bigdecimal (4.1.0)
|
||||
bindex (0.8.1)
|
||||
bootsnap (1.21.1)
|
||||
bootsnap (1.23.0)
|
||||
msgpack (~> 1.2)
|
||||
brakeman (7.1.2)
|
||||
brakeman (8.0.4)
|
||||
racc
|
||||
builder (3.3.0)
|
||||
bullet (8.1.0)
|
||||
@@ -193,7 +193,7 @@ GEM
|
||||
factory_bot_rails (6.5.1)
|
||||
factory_bot (~> 6.5)
|
||||
railties (>= 6.1.0)
|
||||
faker (3.6.0)
|
||||
faker (3.6.1)
|
||||
i18n (>= 1.8.11, < 2)
|
||||
faraday (2.14.1)
|
||||
faraday-net_http (>= 2.0, < 3.5)
|
||||
@@ -203,17 +203,17 @@ GEM
|
||||
faraday (>= 1, < 3)
|
||||
faraday-net_http (3.4.2)
|
||||
net-http (~> 0.5)
|
||||
ferrum (0.17.1)
|
||||
ferrum (0.17.2)
|
||||
addressable (~> 2.5)
|
||||
base64 (~> 0.2)
|
||||
concurrent-ruby (~> 1.1)
|
||||
webrick (~> 1.7)
|
||||
websocket-driver (~> 0.7)
|
||||
ffi (1.17.3-aarch64-linux-gnu)
|
||||
ffi (1.17.3-aarch64-linux-musl)
|
||||
ffi (1.17.3-arm64-darwin)
|
||||
ffi (1.17.3-x86_64-linux-gnu)
|
||||
ffi (1.17.3-x86_64-linux-musl)
|
||||
ffi (1.17.4-aarch64-linux-gnu)
|
||||
ffi (1.17.4-aarch64-linux-musl)
|
||||
ffi (1.17.4-arm64-darwin)
|
||||
ffi (1.17.4-x86_64-linux-gnu)
|
||||
ffi (1.17.4-x86_64-linux-musl)
|
||||
foreman (0.90.0)
|
||||
thor (~> 1.4)
|
||||
geom2d (0.4.1)
|
||||
@@ -229,7 +229,7 @@ GEM
|
||||
retriable (~> 3.1)
|
||||
google-apis-iamcredentials_v1 (0.26.0)
|
||||
google-apis-core (>= 0.15.0, < 2.a)
|
||||
google-apis-storage_v1 (0.59.0)
|
||||
google-apis-storage_v1 (0.61.0)
|
||||
google-apis-core (>= 0.15.0, < 2.a)
|
||||
google-cloud-core (1.8.0)
|
||||
google-cloud-env (>= 1.0, < 3.a)
|
||||
@@ -237,8 +237,8 @@ GEM
|
||||
google-cloud-env (2.3.1)
|
||||
base64 (~> 0.2)
|
||||
faraday (>= 1.0, < 3.a)
|
||||
google-cloud-errors (1.5.0)
|
||||
google-cloud-storage (1.58.0)
|
||||
google-cloud-errors (1.6.0)
|
||||
google-cloud-storage (1.59.0)
|
||||
addressable (~> 2.8)
|
||||
digest-crc (~> 0.4)
|
||||
google-apis-core (>= 0.18, < 2)
|
||||
@@ -248,7 +248,7 @@ GEM
|
||||
googleauth (~> 1.9)
|
||||
mini_mime (~> 1.0)
|
||||
google-logging-utils (0.2.0)
|
||||
googleauth (1.16.1)
|
||||
googleauth (1.16.2)
|
||||
faraday (>= 1.0, < 3.a)
|
||||
google-cloud-env (~> 2.2)
|
||||
google-logging-utils (~> 0.1)
|
||||
@@ -257,7 +257,7 @@ GEM
|
||||
os (>= 0.9, < 2.0)
|
||||
signet (>= 0.16, < 2.a)
|
||||
hashdiff (1.2.1)
|
||||
hexapdf (1.5.0)
|
||||
hexapdf (1.6.0)
|
||||
cmdparse (~> 3.0, >= 3.0.3)
|
||||
geom2d (~> 0.4, >= 0.4.1)
|
||||
openssl (>= 2.2.1)
|
||||
@@ -274,7 +274,7 @@ GEM
|
||||
rdoc (>= 4.0.0)
|
||||
reline (>= 0.4.2)
|
||||
jmespath (1.6.2)
|
||||
json (2.19.2)
|
||||
json (2.19.3)
|
||||
jwt (3.1.2)
|
||||
base64
|
||||
language_server-protocol (3.17.0.5)
|
||||
@@ -311,14 +311,14 @@ GEM
|
||||
mini_magick (5.3.1)
|
||||
logger
|
||||
mini_mime (1.1.5)
|
||||
minitest (6.0.2)
|
||||
minitest (6.0.3)
|
||||
drb (~> 2.0)
|
||||
prism (~> 1.5)
|
||||
msgpack (1.8.0)
|
||||
multi_json (1.19.1)
|
||||
net-http (0.9.1)
|
||||
uri (>= 0.11.1)
|
||||
net-imap (0.6.2)
|
||||
net-imap (0.6.3)
|
||||
date
|
||||
net-protocol
|
||||
net-pop (0.1.2)
|
||||
@@ -339,7 +339,7 @@ GEM
|
||||
nokogiri (1.19.2-x86_64-linux-musl)
|
||||
racc (~> 1.4)
|
||||
numo-narray-alt (0.10.3)
|
||||
oj (3.16.13)
|
||||
oj (3.16.16)
|
||||
bigdecimal (>= 3.0)
|
||||
ostruct (>= 0.2)
|
||||
onnxruntime (0.10.1-aarch64-linux)
|
||||
@@ -348,16 +348,17 @@ GEM
|
||||
ffi
|
||||
onnxruntime (0.10.1-x86_64-linux)
|
||||
ffi
|
||||
openssl (4.0.0)
|
||||
openssl (4.0.1)
|
||||
orm_adapter (0.5.0)
|
||||
os (1.1.4)
|
||||
ostruct (0.6.3)
|
||||
package_json (0.2.0)
|
||||
pagy (43.2.8)
|
||||
pagy (43.4.4)
|
||||
json
|
||||
uri
|
||||
yaml
|
||||
parallel (1.27.0)
|
||||
parser (3.3.10.1)
|
||||
parallel (1.28.0)
|
||||
parser (3.3.11.1)
|
||||
ast (~> 2.4.1)
|
||||
racc
|
||||
pg (1.6.3-aarch64-linux)
|
||||
@@ -367,8 +368,8 @@ GEM
|
||||
pg (1.6.3-x86_64-linux-musl)
|
||||
pp (0.6.3)
|
||||
prettyprint
|
||||
pretender (0.6.0)
|
||||
actionpack (>= 7.1)
|
||||
pretender (1.0.0)
|
||||
actionpack (>= 7.2)
|
||||
prettyprint (0.2.0)
|
||||
prism (1.9.0)
|
||||
pry (0.16.0)
|
||||
@@ -380,11 +381,11 @@ GEM
|
||||
psych (5.3.1)
|
||||
date
|
||||
stringio
|
||||
public_suffix (7.0.2)
|
||||
public_suffix (7.0.5)
|
||||
puma (7.2.0)
|
||||
nio4r (~> 2.0)
|
||||
racc (1.8.1)
|
||||
rack (3.2.5)
|
||||
rack (3.2.6)
|
||||
rack-proxy (0.7.7)
|
||||
rack
|
||||
rack-session (2.1.1)
|
||||
@@ -394,20 +395,20 @@ GEM
|
||||
rack (>= 1.3)
|
||||
rackup (2.3.1)
|
||||
rack (>= 3)
|
||||
rails (8.1.2)
|
||||
actioncable (= 8.1.2)
|
||||
actionmailbox (= 8.1.2)
|
||||
actionmailer (= 8.1.2)
|
||||
actionpack (= 8.1.2)
|
||||
actiontext (= 8.1.2)
|
||||
actionview (= 8.1.2)
|
||||
activejob (= 8.1.2)
|
||||
activemodel (= 8.1.2)
|
||||
activerecord (= 8.1.2)
|
||||
activestorage (= 8.1.2)
|
||||
activesupport (= 8.1.2)
|
||||
rails (8.1.3)
|
||||
actioncable (= 8.1.3)
|
||||
actionmailbox (= 8.1.3)
|
||||
actionmailer (= 8.1.3)
|
||||
actionpack (= 8.1.3)
|
||||
actiontext (= 8.1.3)
|
||||
actionview (= 8.1.3)
|
||||
activejob (= 8.1.3)
|
||||
activemodel (= 8.1.3)
|
||||
activerecord (= 8.1.3)
|
||||
activestorage (= 8.1.3)
|
||||
activesupport (= 8.1.3)
|
||||
bundler (>= 1.15.0)
|
||||
railties (= 8.1.2)
|
||||
railties (= 8.1.3)
|
||||
rails-dom-testing (2.3.0)
|
||||
activesupport (>= 5.0.0)
|
||||
minitest
|
||||
@@ -418,9 +419,9 @@ GEM
|
||||
rails-i18n (8.1.0)
|
||||
i18n (>= 0.7, < 2)
|
||||
railties (>= 8.0.0, < 9)
|
||||
railties (8.1.2)
|
||||
actionpack (= 8.1.2)
|
||||
activesupport (= 8.1.2)
|
||||
railties (8.1.3)
|
||||
actionpack (= 8.1.3)
|
||||
activesupport (= 8.1.3)
|
||||
irb (~> 1.13)
|
||||
rackup (>= 1.0.0)
|
||||
rake (>= 12.2)
|
||||
@@ -433,7 +434,7 @@ GEM
|
||||
erb
|
||||
psych (>= 4.0.0)
|
||||
tsort
|
||||
redis-client (0.26.4)
|
||||
redis-client (0.28.0)
|
||||
connection_pool
|
||||
regexp_parser (2.11.3)
|
||||
reline (0.6.3)
|
||||
@@ -447,7 +448,7 @@ GEM
|
||||
responders (3.2.0)
|
||||
actionpack (>= 7.0)
|
||||
railties (>= 7.0)
|
||||
retriable (3.1.2)
|
||||
retriable (3.4.1)
|
||||
rexml (3.4.4)
|
||||
rotp (6.3.0)
|
||||
rouge (4.7.0)
|
||||
@@ -460,19 +461,19 @@ GEM
|
||||
rspec-expectations (3.13.5)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.13.0)
|
||||
rspec-mocks (3.13.7)
|
||||
rspec-mocks (3.13.8)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.13.0)
|
||||
rspec-rails (8.0.2)
|
||||
rspec-rails (8.0.4)
|
||||
actionpack (>= 7.2)
|
||||
activesupport (>= 7.2)
|
||||
railties (>= 7.2)
|
||||
rspec-core (~> 3.13)
|
||||
rspec-expectations (~> 3.13)
|
||||
rspec-mocks (~> 3.13)
|
||||
rspec-support (~> 3.13)
|
||||
rspec-support (3.13.6)
|
||||
rubocop (1.82.1)
|
||||
rspec-core (>= 3.13.0, < 5.0.0)
|
||||
rspec-expectations (>= 3.13.0, < 5.0.0)
|
||||
rspec-mocks (>= 3.13.0, < 5.0.0)
|
||||
rspec-support (>= 3.13.0, < 5.0.0)
|
||||
rspec-support (3.13.7)
|
||||
rubocop (1.86.0)
|
||||
json (~> 2.3)
|
||||
language_server-protocol (~> 3.17.0.2)
|
||||
lint_roller (~> 1.1.0)
|
||||
@@ -480,10 +481,10 @@ GEM
|
||||
parser (>= 3.3.0.2)
|
||||
rainbow (>= 2.2.2, < 4.0)
|
||||
regexp_parser (>= 2.9.3, < 3.0)
|
||||
rubocop-ast (>= 1.48.0, < 2.0)
|
||||
rubocop-ast (>= 1.49.0, < 2.0)
|
||||
ruby-progressbar (~> 1.7)
|
||||
unicode-display_width (>= 2.4.0, < 4.0)
|
||||
rubocop-ast (1.49.0)
|
||||
rubocop-ast (1.49.1)
|
||||
parser (>= 3.3.7.2)
|
||||
prism (~> 1.7)
|
||||
rubocop-performance (1.26.1)
|
||||
@@ -508,14 +509,14 @@ GEM
|
||||
rubyzip (>= 3.2.2)
|
||||
rubyzip (3.2.2)
|
||||
securerandom (0.4.1)
|
||||
semantic_range (3.1.0)
|
||||
shakapacker (9.5.0)
|
||||
semantic_range (3.1.1)
|
||||
shakapacker (9.7.0)
|
||||
activesupport (>= 5.2)
|
||||
package_json
|
||||
rack-proxy (>= 0.6.1)
|
||||
railties (>= 5.2)
|
||||
semantic_range (>= 2.3.0)
|
||||
sidekiq (8.1.0)
|
||||
sidekiq (8.1.2)
|
||||
connection_pool (>= 3.0.0)
|
||||
json (>= 2.16.0)
|
||||
logger (>= 1.7.0)
|
||||
@@ -533,22 +534,22 @@ GEM
|
||||
simplecov-html (0.13.2)
|
||||
simplecov_json_formatter (0.1.4)
|
||||
smart_properties (1.17.0)
|
||||
sqlite3 (2.9.0-aarch64-linux-gnu)
|
||||
sqlite3 (2.9.0-aarch64-linux-musl)
|
||||
sqlite3 (2.9.0-arm64-darwin)
|
||||
sqlite3 (2.9.0-x86_64-linux-gnu)
|
||||
sqlite3 (2.9.0-x86_64-linux-musl)
|
||||
sqlite3 (2.9.2-aarch64-linux-gnu)
|
||||
sqlite3 (2.9.2-aarch64-linux-musl)
|
||||
sqlite3 (2.9.2-arm64-darwin)
|
||||
sqlite3 (2.9.2-x86_64-linux-gnu)
|
||||
sqlite3 (2.9.2-x86_64-linux-musl)
|
||||
stringio (3.2.0)
|
||||
strip_attributes (2.0.1)
|
||||
activemodel (>= 3.0, < 9.0)
|
||||
strscan (3.1.7)
|
||||
strscan (3.1.8)
|
||||
thor (1.5.0)
|
||||
timeout (0.6.0)
|
||||
timeout (0.6.1)
|
||||
trailblazer-option (0.1.2)
|
||||
trilogy (2.10.0)
|
||||
trilogy (2.12.2)
|
||||
bigdecimal
|
||||
tsort (0.2.0)
|
||||
turbo-rails (2.0.21)
|
||||
turbo-rails (2.0.23)
|
||||
actionpack (>= 7.1.0)
|
||||
railties (>= 7.1.0)
|
||||
twitter_cldr (6.14.0)
|
||||
@@ -558,7 +559,7 @@ GEM
|
||||
tzinfo
|
||||
tzinfo (2.0.6)
|
||||
concurrent-ruby (~> 1.0)
|
||||
tzinfo-data (1.2025.3)
|
||||
tzinfo-data (1.2026.1)
|
||||
tzinfo (>= 1.0.0)
|
||||
uber (0.1.0)
|
||||
unicode-display_width (3.2.0)
|
||||
@@ -569,12 +570,11 @@ GEM
|
||||
useragent (0.16.11)
|
||||
warden (1.2.9)
|
||||
rack (>= 2.0.9)
|
||||
web-console (4.2.1)
|
||||
actionview (>= 6.0.0)
|
||||
activemodel (>= 6.0.0)
|
||||
web-console (4.3.0)
|
||||
actionview (>= 8.0.0)
|
||||
bindex (>= 0.4.0)
|
||||
railties (>= 6.0.0)
|
||||
webmock (3.26.1)
|
||||
railties (>= 8.0.0)
|
||||
webmock (3.26.2)
|
||||
addressable (>= 2.8.0)
|
||||
crack (>= 0.3.2)
|
||||
hashdiff (>= 0.4.0, < 2.0.0)
|
||||
|
||||
@@ -11,6 +11,7 @@ class AccountConfigsController < ApplicationController
|
||||
AccountConfig::FORCE_MFA,
|
||||
AccountConfig::ALLOW_TO_RESUBMIT,
|
||||
AccountConfig::ALLOW_TO_DECLINE_KEY,
|
||||
AccountConfig::ALLOW_TO_DELEGATE_KEY,
|
||||
AccountConfig::FORM_PREFILL_SIGNATURE_KEY,
|
||||
AccountConfig::ESIGNING_PREFERENCE_KEY,
|
||||
AccountConfig::FORM_WITH_CONFETTI_KEY,
|
||||
@@ -36,7 +37,7 @@ class AccountConfigsController < ApplicationController
|
||||
end
|
||||
|
||||
def destroy
|
||||
raise InvalidKey unless ALLOWED_KEYS.include?(@account_config.key)
|
||||
raise InvalidKey unless allowed_keys.include?(@account_config.key)
|
||||
|
||||
@account_config.destroy!
|
||||
|
||||
@@ -45,8 +46,12 @@ class AccountConfigsController < ApplicationController
|
||||
|
||||
private
|
||||
|
||||
def allowed_keys
|
||||
ALLOWED_KEYS
|
||||
end
|
||||
|
||||
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 =
|
||||
AccountConfig.find_or_initialize_by(account: current_account, key: account_config_params[:key])
|
||||
|
||||
@@ -9,7 +9,7 @@ module Api
|
||||
|
||||
ActiveRecord::Associations::Preloader.new(
|
||||
records: [@template],
|
||||
associations: [schema_documents: :preview_images_attachments]
|
||||
associations: [{ schema_documents: :preview_images_attachments }]
|
||||
).call
|
||||
|
||||
cloned_template = Templates::Clone.call(
|
||||
|
||||
@@ -40,7 +40,7 @@ class ErrorsController < ActionController::Base
|
||||
render json: { status: error_status_code, error: }.compact, status: error_status_code
|
||||
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
|
||||
|
||||
@@ -51,7 +51,7 @@ class ErrorsController < ActionController::Base
|
||||
headers['Access-Control-Allow-Methods'] = 'POST, GET, PUT, PATCH, DELETE, OPTIONS'
|
||||
headers['Access-Control-Allow-Headers'] = '*'
|
||||
headers['Access-Control-Max-Age'] = '1728000'
|
||||
headers['Access-Control-Allow-Credentials'] = true
|
||||
headers['Access-Control-Allow-Credentials'] = 'true'
|
||||
end
|
||||
|
||||
def error_status_code
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
class EsignSettingsController < ApplicationController
|
||||
DEFAULT_CERT_NAME = 'DocuSeal Self-Host Autogenerated'
|
||||
|
||||
CertFormRecord = Struct.new(:name, :file, :password, keyword_init: true) do
|
||||
CertFormRecord = Struct.new(:name, :file, :password) do
|
||||
include ActiveModel::Validations
|
||||
|
||||
def to_key
|
||||
|
||||
@@ -16,6 +16,7 @@ class SubmissionEventsController < ApplicationController
|
||||
'email_verified' => 'email_check',
|
||||
'click_sms' => 'hand_click',
|
||||
'decline_form' => 'x',
|
||||
'delegate_form' => 'user_share',
|
||||
'start_verification' => 'player_play',
|
||||
'complete_verification' => 'check',
|
||||
'invite_party' => 'user_plus'
|
||||
|
||||
@@ -26,7 +26,7 @@ class SubmissionsController < ApplicationController
|
||||
unless @submission.submitters.all?(&:completed_at?)
|
||||
ActiveRecord::Associations::Preloader.new(
|
||||
records: [@submission],
|
||||
associations: [submitters: :start_form_submission_events]
|
||||
associations: [{ submitters: :start_form_submission_events }]
|
||||
).call
|
||||
end
|
||||
|
||||
|
||||
@@ -3,11 +3,12 @@
|
||||
class SubmitFormController < ApplicationController
|
||||
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_authorization_check
|
||||
|
||||
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_require_link_2fa, only: %i[show]
|
||||
|
||||
@@ -91,6 +92,12 @@ class SubmitFormController < ApplicationController
|
||||
|
||||
def success; end
|
||||
|
||||
def delegated
|
||||
submitter_version = SubmitterVersion.find_by!(slug: params[:slug] || params[:submit_form_slug])
|
||||
|
||||
@submitter = submitter_version.submitter
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def maybe_require_link_2fa
|
||||
@@ -108,8 +115,18 @@ class SubmitFormController < ApplicationController
|
||||
render :declined if @submitter.declined_at?
|
||||
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
|
||||
@submitter = Submitter.find_by!(slug: params[:slug] || params[:submit_form_slug])
|
||||
@submitter = Submitter.find_by(slug: params[:slug] || params[:submit_form_slug])
|
||||
end
|
||||
|
||||
def build_attachments_index(submission)
|
||||
|
||||
@@ -4,31 +4,38 @@ class SubmitFormDeclineController < ApplicationController
|
||||
skip_before_action :authenticate_user!
|
||||
skip_authorization_check
|
||||
|
||||
def create
|
||||
submitter = Submitter.find_by!(slug: params[:submit_form_slug])
|
||||
before_action :load_submitter
|
||||
|
||||
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)
|
||||
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)
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
SubmitterMailer.declined_email(submitter, user).deliver_later!
|
||||
SubmitterMailer.declined_email(@submitter, user).deliver_later!
|
||||
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
|
||||
|
||||
@@ -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
|
||||
@@ -8,7 +8,7 @@ class TemplatesCloneAndReplaceController < ApplicationController
|
||||
|
||||
ActiveRecord::Associations::Preloader.new(
|
||||
records: [@template],
|
||||
associations: [schema_documents: :preview_images_attachments]
|
||||
associations: [{ schema_documents: :preview_images_attachments }]
|
||||
).call
|
||||
|
||||
cloned_template = Templates::Clone.call(@template, author: current_user)
|
||||
|
||||
@@ -12,7 +12,7 @@ class TemplatesCloneController < ApplicationController
|
||||
def create
|
||||
ActiveRecord::Associations::Preloader.new(
|
||||
records: [@base_template],
|
||||
associations: [schema_documents: :preview_images_attachments]
|
||||
associations: [{ schema_documents: :preview_images_attachments }]
|
||||
).call
|
||||
|
||||
@template = Templates::Clone.call(@base_template, author: current_user,
|
||||
|
||||
@@ -29,7 +29,7 @@ class TemplatesController < ApplicationController
|
||||
def edit
|
||||
ActiveRecord::Associations::Preloader.new(
|
||||
records: [@template],
|
||||
associations: [schema_documents: [:blob, { preview_images_attachments: :blob }]]
|
||||
associations: [{ schema_documents: [:blob, { preview_images_attachments: :blob }] }]
|
||||
).call
|
||||
|
||||
@template_data =
|
||||
|
||||
@@ -30,7 +30,7 @@ class TemplatesDebugController < ApplicationController
|
||||
|
||||
ActiveRecord::Associations::Preloader.new(
|
||||
records: [@template],
|
||||
associations: [schema_documents: { preview_images_attachments: :blob }]
|
||||
associations: [{ schema_documents: { preview_images_attachments: :blob } }]
|
||||
).call
|
||||
|
||||
@template_data =
|
||||
|
||||
@@ -58,8 +58,8 @@ class TemplatesPreferencesController < ApplicationController
|
||||
default_expire_at_duration shared_link_2fa default_expire_at request_email_enabled
|
||||
completed_notification_email_subject completed_notification_email_body
|
||||
completed_notification_email_enabled completed_notification_email_attach_audit] +
|
||||
[completed_message: %i[title body],
|
||||
submitters: [%i[uuid request_email_subject request_email_body]], link_form_fields: []]
|
||||
[{ completed_message: %i[title body],
|
||||
submitters: [%i[uuid request_email_subject request_email_body]], link_form_fields: [] }]
|
||||
).tap do |attrs|
|
||||
attrs[:preferences].delete(:submitters) if params[:request_email_per_submitter] != '1'
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ class TemplatesPreviewController < ApplicationController
|
||||
def show
|
||||
ActiveRecord::Associations::Preloader.new(
|
||||
records: [@template],
|
||||
associations: [schema_documents: { preview_images_attachments: :blob }]
|
||||
associations: [{ schema_documents: { preview_images_attachments: :blob } }]
|
||||
).call
|
||||
|
||||
@template_data =
|
||||
|
||||
@@ -36,7 +36,7 @@ safeRegisterElement('submission-form', class extends HTMLElement {
|
||||
expand: ['true', 'false'].includes(this.dataset.expand) ? this.dataset.expand === 'true' : null,
|
||||
withSignatureId: this.dataset.withSignatureId === 'true',
|
||||
requireSigningReason: this.dataset.requireSigningReason === 'true',
|
||||
withConfetti: this.dataset.withConfetti !== 'false',
|
||||
withConfetti: this.dataset.withConfetti === 'true',
|
||||
withFieldLabels: this.dataset.withFieldLabels !== 'false',
|
||||
withDisclosure: this.dataset.withDisclosure === 'true',
|
||||
reuseSignature: this.dataset.reuseSignature !== 'false',
|
||||
|
||||
@@ -30,6 +30,7 @@ class AccountConfig < ApplicationRecord
|
||||
ALLOW_TYPED_SIGNATURE = 'allow_typed_signature'
|
||||
ALLOW_TO_RESUBMIT = 'allow_to_resubmit'
|
||||
ALLOW_TO_DECLINE_KEY = 'allow_to_decline'
|
||||
ALLOW_TO_DELEGATE_KEY = 'allow_to_delegate'
|
||||
ALLOW_TO_PARTIAL_DOWNLOAD_KEY = 'allow_to_partial_download'
|
||||
SUBMITTER_REMINDERS = 'submitter_reminders'
|
||||
ENFORCE_SIGNING_ORDER_KEY = 'enforce_signing_order'
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
# id :bigint not null, primary key
|
||||
# body :text not null
|
||||
# head :text
|
||||
# sha1 :text not null
|
||||
# uuid :uuid not null
|
||||
# sha1 :string not null
|
||||
# uuid :string not null
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# template_id :bigint not null
|
||||
|
||||
@@ -64,6 +64,7 @@ class SubmissionEvent < ApplicationRecord
|
||||
invite_party: 'invite_party',
|
||||
complete_form: 'complete_form',
|
||||
decline_form: 'decline_form',
|
||||
delegate_form: 'delegate_form',
|
||||
api_complete_form: 'api_complete_form'
|
||||
}, scope: false
|
||||
|
||||
|
||||
@@ -44,6 +44,7 @@ class Submitter < ApplicationRecord
|
||||
belongs_to :account
|
||||
has_one :template, through: :submission
|
||||
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 :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
|
||||
@@ -131,23 +131,50 @@
|
||||
</div>
|
||||
<% 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) %>
|
||||
<% 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_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') %>">
|
||||
<%= svg_icon('info_circle', class: 'hidden md:inline-block w-4 h-4 shrink-0') %>
|
||||
</span>
|
||||
</div>
|
||||
<% account_config = AccountConfig.find_or_initialize_by(account: current_account, key: AccountConfig::ALLOW_TO_DECLINE_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_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') %>">
|
||||
<%= svg_icon('info_circle', class: 'hidden md:inline-block w-4 h-4 shrink-0') %>
|
||||
</span>
|
||||
</div>
|
||||
<% if !Docuseal.multitenant? || can?(:manage, :disable_decline) %>
|
||||
<submit-form data-on="change" class="flex">
|
||||
<%= f.check_box :value, class: 'toggle', checked: account_config.value != false %>
|
||||
</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>
|
||||
<% 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 %>
|
||||
<% 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) %>
|
||||
<div class="px-1 mt-2">
|
||||
<%= form_for account_config, url: account_configs_path, method: :post do |f| %>
|
||||
@@ -8,7 +8,7 @@
|
||||
<%= t('show_confetti_on_successful_completion') %>
|
||||
</span>
|
||||
<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>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
@@ -20,10 +20,13 @@
|
||||
<% end %>
|
||||
</p>
|
||||
</li>
|
||||
<% submitter_versions_index = @submission.submitters.preload(:submitter_versions).to_h { |s| [s.id, s.submitter_versions.to_a.sort_by(&:created_at)] } %>
|
||||
<% @submission.submission_events.order(:event_timestamp).each do |event| %>
|
||||
<% submitter = @submission.submitters.find { |e| e.id == event.submitter_id } %>
|
||||
<% 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">
|
||||
<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') %>
|
||||
@@ -43,6 +46,9 @@
|
||||
<%= 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')) %>
|
||||
<%= 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.rfind { |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_') %>
|
||||
<%= t("submission_event_names.#{event.event_type}_to_html", submitter_name:) %>
|
||||
<% 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? } %>
|
||||
<dynamic-list 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 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">
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
<% else %>
|
||||
<dynamic-list 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 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">
|
||||
|
||||
@@ -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? } %>
|
||||
<dynamic-list 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 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">
|
||||
|
||||
@@ -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' %>
|
||||
<% elsif template.submitters.size > 1 %>
|
||||
<div class="form-control">
|
||||
|
||||
@@ -96,7 +96,7 @@
|
||||
<% submitters_index = @submission.submitters.index_by(&:uuid) %>
|
||||
<% submitters_order_index = nil %>
|
||||
<% attachments_index = ActiveStorage::Attachment.where(record: @submission.submitters, name: :attachments).preload(:blob).index_by(&:uuid) %>
|
||||
<% page_blob_struct = Struct.new(:url, :metadata, keyword_init: true) %>
|
||||
<% page_blob_struct = Struct.new(:url, :metadata) %>
|
||||
<% bg_classes = %w[bg-red-100 bg-sky-100 bg-emerald-100 bg-yellow-100 bg-purple-100 bg-pink-100 bg-cyan-100 bg-orange-100 bg-lime-100 bg-indigo-100] %>
|
||||
<% schema.each do |item| %>
|
||||
<% document = @submission.schema_documents.find { |e| e.uuid == item['attachment_uuid'] } %>
|
||||
|
||||
@@ -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 %>
|
||||
@@ -5,10 +5,11 @@
|
||||
<% fields_index = Templates.build_field_areas_index(@submitter.submission.template_fields || @submitter.submission.template.fields) %>
|
||||
<% values = @submitter.submission.submitters.reduce({}) { |acc, sub| acc.merge(sub.values) } %>
|
||||
<% submitters_index = @submitter.submission.submitters.index_by(&:uuid) %>
|
||||
<% page_blob_struct = Struct.new(:url, :metadata, keyword_init: true) %>
|
||||
<% page_blob_struct = Struct.new(:url, :metadata) %>
|
||||
<% schema = Submissions.filtered_conditions_schema(@submitter.submission, values:, include_submitter_uuid: @submitter.uuid) %>
|
||||
<% font_scale = 1000.0 / PdfUtils::US_LETTER_W %>
|
||||
<% decline_modal_checkbox_uuid = nil %>
|
||||
<% delegate_modal_checkbox_uuid = nil %>
|
||||
<div style="max-height: -webkit-fill-available;">
|
||||
<div id="scrollbox">
|
||||
<div class="mx-auto block pb-72" style="max-width: 1000px">
|
||||
@@ -20,42 +21,85 @@
|
||||
<%= @submitter.submission.name || @submitter.submission.template.name %>
|
||||
</div>
|
||||
<div class="flex items-center space-x-2" style="margin-left: 20px; flex-shrink: 0">
|
||||
<% 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>
|
||||
<% if @form_configs[:with_delegate] %>
|
||||
<label id="delegate_button" for="<%= delegate_modal_checkbox_uuid = SecureRandom.uuid %>" class="btn btn-sm !px-5"><%= t(:delegate) %></label>
|
||||
<% if @form_configs[:with_decline] %>
|
||||
<label id="decline_button" for="<%= decline_modal_checkbox_uuid = SecureRandom.uuid %>" class="btn btn-sm px-2" title="<%= t(:decline) %>">
|
||||
<%= svg_icon('x', class: 'w-5 h-5') %>
|
||||
</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-2" title="<%= t('download') %>">
|
||||
<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 %>
|
||||
<% 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 %>
|
||||
</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">
|
||||
<% if @form_configs[:with_decline] %>
|
||||
<label id="decline_button" for="<%= decline_modal_checkbox_uuid %>" class="btn btn-sm px-0">
|
||||
<% if @form_configs[:with_delegate] %>
|
||||
<label id="delegate_button" for="<%= delegate_modal_checkbox_uuid %>" class="btn btn-sm px-0">
|
||||
<span class="min-[1366px]:inline hidden px-3">
|
||||
<%= t(:decline) %>
|
||||
<%= t(:delegate) %>
|
||||
</span>
|
||||
<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>
|
||||
</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 %>
|
||||
<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>
|
||||
<% end %>
|
||||
<% schema.each do |item| %>
|
||||
@@ -110,4 +154,9 @@
|
||||
<%= render 'submit_form/decline_form', submitter: @submitter %>
|
||||
<% 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' %>
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
<% end %>
|
||||
</div>
|
||||
<% 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">
|
||||
<%= svg_icon('link', class: 'w-4 h-4 md:w-6 md:h-6') %>
|
||||
<span><%= t('link') %></span>
|
||||
|
||||
@@ -2,6 +2,12 @@
|
||||
<% enough_defined_submitters = Templates.filter_undefined_submitters(@template.submitters).size < 2 %>
|
||||
<%= render 'shared/turbo_modal_large', title: t('share_link') do %>
|
||||
<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| %>
|
||||
<% 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) %>">
|
||||
@@ -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">
|
||||
<span><%= t('enable_shared_link') %></span>
|
||||
<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>
|
||||
</label>
|
||||
<% end %>
|
||||
@@ -23,7 +29,7 @@
|
||||
</check-on-click>
|
||||
</div>
|
||||
<% 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">
|
||||
<%= 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>
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
Pagy.options[:limit] = 10
|
||||
Pagy::OPTIONS[:limit] = 10
|
||||
|
||||
@@ -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
|
||||
decline: Decline
|
||||
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
|
||||
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: '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_with_the_following_reason: '"%{name}" has been declined by %{submitter} with the following reason:'
|
||||
completed_successfully: Completed Successfully
|
||||
@@ -201,6 +204,7 @@ en: &en
|
||||
allow_typed_text_signatures: Allow typed text signatures
|
||||
allow_to_resubmit_completed_forms: Allow to resubmit completed forms
|
||||
allow_to_decline_documents: Allow to decline documents
|
||||
allow_to_delegate_documents: Allow to delegate documents
|
||||
remember_and_pre_fill_signatures: Remember and pre-fill signatures
|
||||
require_authentication_for_file_download_links: Require authentication for file download links
|
||||
combine_completed_documents_and_audit_log: Combine completed documents and Audit Log
|
||||
@@ -787,6 +791,7 @@ en: &en
|
||||
share_link: Share link
|
||||
enable_shared_link: Enable shared link
|
||||
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
|
||||
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.
|
||||
@@ -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_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_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."
|
||||
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.
|
||||
@@ -954,6 +960,8 @@ en: &en
|
||||
complete_kba_by_html: '<b>KBA completed</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}'
|
||||
decline_form_by_html: '<b>Form declined</b> by %{submitter_name}'
|
||||
delegate_form_by_html: '<b>Delegated</b> from %{from} to %{to}'
|
||||
import_list:
|
||||
select_worksheet: Select Worksheet
|
||||
open: Open
|
||||
@@ -1192,11 +1200,14 @@ es: &es
|
||||
downloading: Descargando
|
||||
download: Descargar
|
||||
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
|
||||
decline_reason: Motivo de rechazo
|
||||
provide_a_reason: Proporcione un motivo
|
||||
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>'
|
||||
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_with_the_following_reason: '"%{name}" ha sido rechazado por %{submitter} con el siguiente motivo:'
|
||||
completed_successfully: Completado exitosamente
|
||||
@@ -1231,6 +1242,7 @@ es: &es
|
||||
allow_typed_text_signatures: Permitir firmas de texto mecanografiadas
|
||||
allow_to_resubmit_completed_forms: Permitir reenviar formularios completados
|
||||
allow_to_decline_documents: Permitir rechazar documentos
|
||||
allow_to_delegate_documents: Permitir delegar documentos
|
||||
remember_and_pre_fill_signatures: Recordar y prellenar firmas
|
||||
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
|
||||
@@ -1814,6 +1826,7 @@ es: &es
|
||||
share_link: Enlace para compartir
|
||||
enable_shared_link: Habilitar enlace compartido
|
||||
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
|
||||
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.
|
||||
@@ -1868,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_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_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.
|
||||
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.
|
||||
@@ -1976,6 +1990,8 @@ es: &es
|
||||
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}'
|
||||
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}'
|
||||
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}'
|
||||
@@ -2219,11 +2235,14 @@ it: &it
|
||||
downloading: Scaricamento
|
||||
download: Scarica
|
||||
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
|
||||
decline_reason: Motivo del rifiuto
|
||||
provide_a_reason: Fornisci un motivo
|
||||
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>'
|
||||
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_with_the_following_reason: '"%{name}" è stato rifiutato da %{submitter} per il seguente motivo:'
|
||||
completed_successfully: Completato con successo
|
||||
@@ -2258,6 +2277,7 @@ it: &it
|
||||
allow_typed_text_signatures: Permettere firme con testo digitato
|
||||
allow_to_resubmit_completed_forms: Permettere di reinviare i moduli completati
|
||||
allow_to_decline_documents: Permettere di rifiutare i documenti
|
||||
allow_to_delegate_documents: Permettere di delegare i documenti
|
||||
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"
|
||||
combine_completed_documents_and_audit_log: Combinare i documenti completati e il Registro di Audit
|
||||
@@ -2841,6 +2861,7 @@ it: &it
|
||||
share_link: Link di condivisione
|
||||
enable_shared_link: Abilita link condiviso
|
||||
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
|
||||
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.
|
||||
@@ -2896,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_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_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.
|
||||
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."
|
||||
@@ -3004,6 +3026,8 @@ it: &it
|
||||
invite_party_by_html: '<b>Invitato</b> %{invited_submitter_name} 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}'
|
||||
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}"
|
||||
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}"
|
||||
@@ -3247,11 +3271,14 @@ fr: &fr
|
||||
downloading: Téléchargement
|
||||
download: Télécharger
|
||||
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é
|
||||
decline_reason: Motif du refus
|
||||
provide_a_reason: Fournissez un motif
|
||||
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>
|
||||
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_with_the_following_reason: '"%{name}" a été refusé par %{submitter} pour le motif suivant :'
|
||||
completed_successfully: Terminé avec succès
|
||||
@@ -3286,6 +3313,7 @@ fr: &fr
|
||||
allow_typed_text_signatures: Autoriser les signatures tapées
|
||||
allow_to_resubmit_completed_forms: Autoriser la nouvelle soumission des formulaires complétés
|
||||
allow_to_decline_documents: Autoriser le refus de documents
|
||||
allow_to_delegate_documents: Autoriser la délégation de documents
|
||||
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
|
||||
combine_completed_documents_and_audit_log: Combiner les documents complétés et le journal d’audit
|
||||
@@ -3866,6 +3894,7 @@ fr: &fr
|
||||
share_link: Lien de partage
|
||||
enable_shared_link: Activer le lien partagé
|
||||
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
|
||||
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.
|
||||
@@ -3919,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_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_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.
|
||||
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.
|
||||
@@ -4030,6 +4060,8 @@ fr: &fr
|
||||
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}"
|
||||
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}"
|
||||
complete_kba_by_html: "<b>KBA terminé</b> par %{submitter_name}"
|
||||
fail_kba_by_html: "<b>KBA échoué</b> par %{submitter_name}"
|
||||
@@ -4271,11 +4303,14 @@ pt: &pt
|
||||
downloading: Baixando
|
||||
download: Baixar
|
||||
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
|
||||
decline_reason: Motivo da recusa
|
||||
provide_a_reason: Forneça um motivo
|
||||
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>"
|
||||
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_with_the_following_reason: '"%{name}" foi recusado por %{submitter} com o seguinte motivo:'
|
||||
completed_successfully: Concluído com sucesso
|
||||
@@ -4310,6 +4345,7 @@ pt: &pt
|
||||
allow_typed_text_signatures: Permitir assinaturas digitadas
|
||||
allow_to_resubmit_completed_forms: Permitir reenviar formulários concluídos
|
||||
allow_to_decline_documents: Permitir recusar documentos
|
||||
allow_to_delegate_documents: Permitir delegar documentos
|
||||
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
|
||||
combine_completed_documents_and_audit_log: Combinar documentos concluídos e log de auditoria
|
||||
@@ -4893,6 +4929,7 @@ pt: &pt
|
||||
share_link: Link de compartilhamento
|
||||
enable_shared_link: Ativar link compartilhado
|
||||
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
|
||||
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.
|
||||
@@ -4947,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_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_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.
|
||||
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.
|
||||
@@ -5057,6 +5095,8 @@ pt: &pt
|
||||
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}'
|
||||
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}'
|
||||
complete_kba_by_html: '<b>KBA concluída</b> por %{submitter_name}'
|
||||
fail_kba_by_html: '<b>KBA reprovada</b> por %{submitter_name}'
|
||||
@@ -5298,11 +5338,14 @@ de: &de
|
||||
downloading: Wird heruntergeladen
|
||||
download: Download
|
||||
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
|
||||
decline_reason: Ablehnungsgrund
|
||||
provide_a_reason: Geben Sie einen Grund an
|
||||
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"
|
||||
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_with_the_following_reason: '"%{name}" wurde von %{submitter} mit folgendem Grund abgelehnt:'
|
||||
completed_successfully: Erfolgreich abgeschlossen
|
||||
@@ -5337,6 +5380,7 @@ de: &de
|
||||
allow_typed_text_signatures: Getippte Unterschriften zulassen
|
||||
allow_to_resubmit_completed_forms: Erneutes Einreichen abgeschlossener Formulare zulassen
|
||||
allow_to_decline_documents: Ablehnen von Dokumenten erlauben
|
||||
allow_to_delegate_documents: Delegieren von Dokumenten erlauben
|
||||
remember_and_pre_fill_signatures: Signaturen merken und vorab ausfüllen
|
||||
require_authentication_for_file_download_links: Authentifizierung für Dateidownload-Links erforderlich
|
||||
combine_completed_documents_and_audit_log: Abgeschlossene Dokumente und Prüfprotokoll kombinieren
|
||||
@@ -5920,6 +5964,7 @@ de: &de
|
||||
share_link: Freigabelink
|
||||
enable_shared_link: Freigabelink aktivieren
|
||||
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
|
||||
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.
|
||||
@@ -5974,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_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_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.
|
||||
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.
|
||||
@@ -6084,6 +6130,8 @@ de: &de
|
||||
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}'
|
||||
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}'
|
||||
complete_kba_by_html: '<b>KBA abgeschlossen</b> von %{submitter_name}'
|
||||
fail_kba_by_html: '<b>KBA fehlgeschlagen</b> von %{submitter_name}'
|
||||
@@ -6190,11 +6238,14 @@ pl:
|
||||
hi_there: Cześć,
|
||||
download: Pobierz
|
||||
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
|
||||
decline_reason: Powód odrzucenia
|
||||
provide_a_reason: Podaj powód
|
||||
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>'
|
||||
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_with_the_following_reason: '"%{name}" został odrzucony przez %{submitter} z następującym powodem:'
|
||||
email: E-mail
|
||||
@@ -6287,11 +6338,14 @@ uk:
|
||||
hi_there: Привіт,
|
||||
download: Завантажити
|
||||
decline: Відхилити
|
||||
delegate: Делегувати
|
||||
enter_the_email_address_of_the_person_you_want_to_delegate_to: Введіть адресу електронної пошти особи, якій ви хочете делегувати
|
||||
declined: Відхилено
|
||||
decline_reason: Причина відхилення
|
||||
provide_a_reason: Надайте причину
|
||||
notify_the_sender_with_the_reason_you_declined: Повідомте відправника про причину, з якої ви відхилили
|
||||
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_with_the_following_reason: '"%{name}" було відхилено %{submitter} з такою причиною:'
|
||||
email: E-mail
|
||||
@@ -6384,11 +6438,14 @@ cs:
|
||||
hi_there: Ahoj,
|
||||
download: Stáhnout
|
||||
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
|
||||
decline_reason: Důvod odmítnutí
|
||||
provide_a_reason: Uveďte důvod
|
||||
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>'
|
||||
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_with_the_following_reason: '"%{name}" bylo odmítnuto %{submitter} s následujícím důvodem:'
|
||||
email: E-mail
|
||||
@@ -6481,11 +6538,14 @@ he:
|
||||
hi_there: שלום,
|
||||
download: הורד
|
||||
decline: דחייה
|
||||
delegate: הואלה
|
||||
enter_the_email_address_of_the_person_you_want_to_delegate_to: הזן את כתובת הדוא"ל של האדם שברצונך להאציל אליו
|
||||
declined: דחוי
|
||||
decline_reason: סיבת דחייה
|
||||
provide_a_reason: אנא ספק סיבה
|
||||
notify_the_sender_with_the_reason_you_declined: הודע לשולח על הסיבה לדחייה
|
||||
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_with_the_following_reason: '"%{name}" נדחה על ידי %{submitter} עם הסיבה הבאה:'
|
||||
email: דוא"ל
|
||||
@@ -6714,11 +6774,14 @@ nl: &nl
|
||||
downloading: Downloaden
|
||||
download: Downloaden
|
||||
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
|
||||
decline_reason: Reden van weigering
|
||||
provide_a_reason: Geef een reden op
|
||||
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>
|
||||
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_with_the_following_reason: '"%{name}" is geweigerd door %{submitter} met de volgende reden:'
|
||||
completed_successfully: Succesvol voltooid
|
||||
@@ -6753,6 +6816,7 @@ nl: &nl
|
||||
allow_typed_text_signatures: Handtekeningen met getypte tekst toestaan
|
||||
allow_to_resubmit_completed_forms: Opnieuw indienen van voltooide formulieren toestaan
|
||||
allow_to_decline_documents: Weigeren van documenten toestaan
|
||||
allow_to_delegate_documents: Delegeren van documenten toestaan
|
||||
remember_and_pre_fill_signatures: Handtekeningen onthouden en vooraf invullen
|
||||
require_authentication_for_file_download_links: Authenticatie vereisen voor links naar bestandsdownloads
|
||||
combine_completed_documents_and_audit_log: Voltooide documenten en auditlogboek combineren
|
||||
@@ -7333,6 +7397,7 @@ nl: &nl
|
||||
share_link: Deellink
|
||||
enable_shared_link: Deellink inschakelen
|
||||
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
|
||||
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.
|
||||
@@ -7386,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_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_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.
|
||||
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.
|
||||
@@ -7496,6 +7562,8 @@ nl: &nl
|
||||
start_verification_by_html: "<b>Identiteitsverificatie gestart</b> door %{submitter_name}"
|
||||
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}"
|
||||
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}"
|
||||
complete_kba_by_html: "<b>KBA voltooid</b> door %{submitter_name}"
|
||||
fail_kba_by_html: "<b>KBA mislukt</b> door %{submitter_name}"
|
||||
@@ -7602,11 +7670,14 @@ ar:
|
||||
hi_there: مرحبا,
|
||||
download: تحميل
|
||||
decline: رفض
|
||||
delegate: تفويض
|
||||
enter_the_email_address_of_the_person_you_want_to_delegate_to: أدخل عنوان البريد الإلكتروني للشخص الذي تريد التفويض إليه
|
||||
declined: مرفوض
|
||||
decline_reason: سبب الرفض
|
||||
provide_a_reason: قدم سببًا
|
||||
notify_the_sender_with_the_reason_you_declined: أخطر المرسل بسبب الرفض
|
||||
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_with_the_following_reason: '"%{name}" تم رفضه بواسطة %{submitter} مع السبب التالي:'
|
||||
email: البريد الإلكتروني
|
||||
@@ -7699,11 +7770,14 @@ ko:
|
||||
hi_there: 안녕하세요,
|
||||
download: 다운로드
|
||||
decline: 거절
|
||||
delegate: 위임
|
||||
enter_the_email_address_of_the_person_you_want_to_delegate_to: 위임할 사람의 이메일 주소를 입력하세요
|
||||
declined: 거절됨
|
||||
decline_reason: 거절 사유
|
||||
provide_a_reason: 사유를 제공하세요
|
||||
notify_the_sender_with_the_reason_you_declined: 거절한 이유로 발신자에게 알리기
|
||||
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_with_the_following_reason: '"%{name}"이(가) %{submitter}에 의해 다음과 같은 사유로 거절되었습니다:'
|
||||
email: 이메일
|
||||
@@ -7796,11 +7870,14 @@ ja:
|
||||
hi_there: こんにちは
|
||||
download: ダウンロード
|
||||
decline: 辞退
|
||||
delegate: 委任
|
||||
enter_the_email_address_of_the_person_you_want_to_delegate_to: 委任したい人のメールアドレスを入力してください
|
||||
declined: 辞退済み
|
||||
decline_reason: 辞退の理由
|
||||
provide_a_reason: 理由を入力してください
|
||||
notify_the_sender_with_the_reason_you_declined: 辞退理由を送信者に通知してください
|
||||
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_with_the_following_reason: '"%{name}" は %{submitter} により次の理由で辞退されました:'
|
||||
email: メール
|
||||
|
||||
@@ -145,8 +145,10 @@ Rails.application.routes.draw do
|
||||
resources :values, only: %i[index], controller: 'submit_form_values'
|
||||
resources :download, only: %i[index], controller: 'submit_form_download'
|
||||
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'
|
||||
get :completed
|
||||
get :delegated
|
||||
end
|
||||
|
||||
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
|
||||
+180
-165
@@ -10,44 +10,44 @@
|
||||
#
|
||||
# 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
|
||||
enable_extension "btree_gin"
|
||||
enable_extension "plpgsql"
|
||||
enable_extension "pg_catalog.plpgsql"
|
||||
|
||||
create_table "access_tokens", force: :cascade do |t|
|
||||
t.bigint "user_id", null: false
|
||||
t.text "token", null: false
|
||||
t.text "sha256", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.text "sha256", null: false
|
||||
t.text "token", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.bigint "user_id", null: false
|
||||
t.index ["sha256"], name: "index_access_tokens_on_sha256", unique: true
|
||||
t.index ["user_id"], name: "index_access_tokens_on_user_id"
|
||||
end
|
||||
|
||||
create_table "account_accesses", force: :cascade do |t|
|
||||
t.bigint "account_id", null: false
|
||||
t.bigint "user_id", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.bigint "user_id", null: false
|
||||
t.index ["account_id", "user_id"], name: "index_account_accesses_on_account_id_and_user_id", unique: true
|
||||
end
|
||||
|
||||
create_table "account_configs", force: :cascade do |t|
|
||||
t.bigint "account_id", null: false
|
||||
t.string "key", null: false
|
||||
t.text "value", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.string "key", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.text "value", null: false
|
||||
t.index ["account_id", "key"], name: "index_account_configs_on_account_id_and_key", unique: true
|
||||
t.index ["account_id"], name: "index_account_configs_on_account_id"
|
||||
end
|
||||
|
||||
create_table "account_linked_accounts", force: :cascade do |t|
|
||||
t.bigint "account_id", null: false
|
||||
t.bigint "linked_account_id", null: false
|
||||
t.text "account_type", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.bigint "linked_account_id", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["account_id", "linked_account_id"], name: "idx_on_account_id_linked_account_id_48ab9f79d2", unique: true
|
||||
t.index ["account_id"], name: "index_account_linked_accounts_on_account_id"
|
||||
@@ -55,37 +55,37 @@ ActiveRecord::Schema[8.1].define(version: 2026_02_26_193537) do
|
||||
end
|
||||
|
||||
create_table "accounts", force: :cascade do |t|
|
||||
t.datetime "archived_at"
|
||||
t.datetime "created_at", null: false
|
||||
t.string "locale", null: false
|
||||
t.string "name", null: false
|
||||
t.string "timezone", null: false
|
||||
t.string "locale", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.string "uuid", null: false
|
||||
t.datetime "archived_at"
|
||||
t.index ["uuid"], name: "index_accounts_on_uuid", unique: true
|
||||
end
|
||||
|
||||
create_table "active_storage_attachments", force: :cascade do |t|
|
||||
t.string "name", null: false
|
||||
t.string "uuid", null: false
|
||||
t.string "record_type", null: false
|
||||
t.bigint "record_id", null: false
|
||||
t.bigint "blob_id", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.string "name", null: false
|
||||
t.bigint "record_id", null: false
|
||||
t.string "record_type", null: false
|
||||
t.string "uuid", null: false
|
||||
t.index ["blob_id"], name: "index_active_storage_attachments_on_blob_id"
|
||||
t.index ["record_type", "record_id", "name", "blob_id"], name: "idx_on_record_type_record_id_name_blob_id_0be5805727"
|
||||
t.index ["uuid"], name: "index_active_storage_attachments_on_uuid"
|
||||
end
|
||||
|
||||
create_table "active_storage_blobs", force: :cascade do |t|
|
||||
t.string "key", null: false
|
||||
t.string "filename", null: false
|
||||
t.string "content_type"
|
||||
t.text "metadata"
|
||||
t.string "service_name", null: false
|
||||
t.bigint "byte_size", null: false
|
||||
t.string "checksum"
|
||||
t.string "content_type"
|
||||
t.datetime "created_at", null: false
|
||||
t.string "filename", null: false
|
||||
t.string "key", null: false
|
||||
t.text "metadata"
|
||||
t.string "service_name", null: false
|
||||
t.string "uuid"
|
||||
t.index ["checksum"], name: "index_active_storage_blobs_on_checksum"
|
||||
t.index ["key"], name: "index_active_storage_blobs_on_key", unique: true
|
||||
@@ -99,26 +99,26 @@ ActiveRecord::Schema[8.1].define(version: 2026_02_26_193537) do
|
||||
end
|
||||
|
||||
create_table "completed_documents", force: :cascade do |t|
|
||||
t.bigint "submitter_id", null: false
|
||||
t.string "sha256", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.string "sha256", null: false
|
||||
t.bigint "submitter_id", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["sha256"], name: "index_completed_documents_on_sha256"
|
||||
t.index ["submitter_id"], name: "index_completed_documents_on_submitter_id"
|
||||
end
|
||||
|
||||
create_table "completed_submitters", force: :cascade do |t|
|
||||
t.bigint "submitter_id", null: false
|
||||
t.bigint "submission_id", null: false
|
||||
t.bigint "account_id", null: false
|
||||
t.bigint "template_id"
|
||||
t.string "source", null: false
|
||||
t.integer "sms_count", null: false
|
||||
t.datetime "completed_at", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.boolean "is_first"
|
||||
t.integer "sms_count", null: false
|
||||
t.string "source", null: false
|
||||
t.bigint "submission_id", null: false
|
||||
t.bigint "submitter_id", null: false
|
||||
t.bigint "template_id"
|
||||
t.datetime "updated_at", null: false
|
||||
t.string "verification_method"
|
||||
t.boolean "is_first"
|
||||
t.index ["account_id", "completed_at"], name: "index_completed_submitters_account_id_completed_at_is_first", where: "(is_first = true)"
|
||||
t.index ["account_id", "completed_at"], name: "index_completed_submitters_on_account_id_and_completed_at"
|
||||
t.index ["submission_id"], name: "index_completed_submitters_on_submission_id", unique: true, where: "(is_first = true)"
|
||||
@@ -126,45 +126,45 @@ ActiveRecord::Schema[8.1].define(version: 2026_02_26_193537) do
|
||||
end
|
||||
|
||||
create_table "console1984_commands", force: :cascade do |t|
|
||||
t.text "statements"
|
||||
t.datetime "created_at", null: false
|
||||
t.bigint "sensitive_access_id"
|
||||
t.bigint "session_id", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.text "statements"
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["sensitive_access_id"], name: "index_console1984_commands_on_sensitive_access_id"
|
||||
t.index ["session_id", "created_at", "sensitive_access_id"], name: "on_session_and_sensitive_chronologically"
|
||||
end
|
||||
|
||||
create_table "console1984_sensitive_accesses", force: :cascade do |t|
|
||||
t.datetime "created_at", null: false
|
||||
t.text "justification"
|
||||
t.bigint "session_id", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["session_id"], name: "index_console1984_sensitive_accesses_on_session_id"
|
||||
end
|
||||
|
||||
create_table "console1984_sessions", force: :cascade do |t|
|
||||
t.text "reason"
|
||||
t.bigint "user_id", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.text "reason"
|
||||
t.datetime "updated_at", null: false
|
||||
t.bigint "user_id", null: false
|
||||
t.index ["created_at"], name: "index_console1984_sessions_on_created_at"
|
||||
t.index ["user_id", "created_at"], name: "index_console1984_sessions_on_user_id_and_created_at"
|
||||
end
|
||||
|
||||
create_table "console1984_users", force: :cascade do |t|
|
||||
t.string "username", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.string "username", null: false
|
||||
t.index ["username"], name: "index_console1984_users_on_username"
|
||||
end
|
||||
|
||||
create_table "document_generation_events", force: :cascade do |t|
|
||||
t.bigint "submitter_id", null: false
|
||||
t.string "event_name", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.string "event_name", null: false
|
||||
t.bigint "submitter_id", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["submitter_id", "event_name"], name: "index_document_generation_events_on_submitter_id_and_event_name", unique: true, where: "((event_name)::text = ANY ((ARRAY['start'::character varying, 'complete'::character varying])::text[]))"
|
||||
t.index ["submitter_id", "event_name"], name: "index_document_generation_events_on_submitter_id_and_event_name", unique: true, where: "((event_name)::text = ANY (ARRAY[('start'::character varying)::text, ('complete'::character varying)::text]))"
|
||||
t.index ["submitter_id"], name: "index_document_generation_events_on_submitter_id"
|
||||
end
|
||||
|
||||
@@ -190,31 +190,31 @@ ActiveRecord::Schema[8.1].define(version: 2026_02_26_193537) do
|
||||
|
||||
create_table "email_events", force: :cascade do |t|
|
||||
t.bigint "account_id", null: false
|
||||
t.string "emailable_type", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.text "data", null: false
|
||||
t.string "email", null: false
|
||||
t.bigint "emailable_id", null: false
|
||||
t.string "emailable_type", null: false
|
||||
t.datetime "event_datetime", null: false
|
||||
t.string "event_type", null: false
|
||||
t.string "message_id", null: false
|
||||
t.string "tag", null: false
|
||||
t.string "event_type", null: false
|
||||
t.string "email", null: false
|
||||
t.text "data", null: false
|
||||
t.datetime "event_datetime", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.index ["account_id", "event_datetime"], name: "index_email_events_on_account_id_and_event_datetime"
|
||||
t.index ["email"], name: "index_email_events_on_email"
|
||||
t.index ["email"], name: "index_email_events_on_email_event_types", where: "((event_type)::text = ANY ((ARRAY['bounce'::character varying, 'soft_bounce'::character varying, 'permanent_bounce'::character varying, 'complaint'::character varying, 'soft_complaint'::character varying])::text[]))"
|
||||
t.index ["email"], name: "index_email_events_on_email_event_types", where: "((event_type)::text = ANY (ARRAY[('bounce'::character varying)::text, ('soft_bounce'::character varying)::text, ('permanent_bounce'::character varying)::text, ('complaint'::character varying)::text, ('soft_complaint'::character varying)::text]))"
|
||||
t.index ["emailable_type", "emailable_id"], name: "index_email_events_on_emailable"
|
||||
t.index ["message_id"], name: "index_email_events_on_message_id"
|
||||
end
|
||||
|
||||
create_table "email_messages", force: :cascade do |t|
|
||||
t.string "uuid", null: false
|
||||
t.bigint "author_id", null: false
|
||||
t.bigint "account_id", null: false
|
||||
t.text "subject", null: false
|
||||
t.bigint "author_id", null: false
|
||||
t.text "body", null: false
|
||||
t.string "sha1", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.string "sha1", null: false
|
||||
t.text "subject", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.string "uuid", null: false
|
||||
t.index ["account_id"], name: "index_email_messages_on_account_id"
|
||||
t.index ["sha1"], name: "index_email_messages_on_sha1"
|
||||
t.index ["uuid"], name: "index_email_messages_on_uuid"
|
||||
@@ -222,30 +222,30 @@ ActiveRecord::Schema[8.1].define(version: 2026_02_26_193537) do
|
||||
|
||||
create_table "encrypted_configs", force: :cascade do |t|
|
||||
t.bigint "account_id", null: false
|
||||
t.string "key", null: false
|
||||
t.text "value", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.string "key", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.text "value", null: false
|
||||
t.index ["account_id", "key"], name: "index_encrypted_configs_on_account_id_and_key", unique: true
|
||||
t.index ["account_id"], name: "index_encrypted_configs_on_account_id"
|
||||
end
|
||||
|
||||
create_table "encrypted_user_configs", force: :cascade do |t|
|
||||
t.bigint "user_id", null: false
|
||||
t.string "key", null: false
|
||||
t.text "value", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.string "key", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.bigint "user_id", null: false
|
||||
t.text "value", null: false
|
||||
t.index ["user_id", "key"], name: "index_encrypted_user_configs_on_user_id_and_key", unique: true
|
||||
t.index ["user_id"], name: "index_encrypted_user_configs_on_user_id"
|
||||
end
|
||||
|
||||
create_table "lock_events", force: :cascade do |t|
|
||||
t.string "key", null: false
|
||||
t.string "event_name", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.string "event_name", null: false
|
||||
t.string "key", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["event_name", "key"], name: "index_lock_events_on_event_name_and_key", unique: true, where: "((event_name)::text = ANY ((ARRAY['start'::character varying, 'complete'::character varying])::text[]))"
|
||||
t.index ["event_name", "key"], name: "index_lock_events_on_event_name_and_key", unique: true, where: "((event_name)::text = ANY (ARRAY[('start'::character varying)::text, ('complete'::character varying)::text]))"
|
||||
t.index ["key"], name: "index_lock_events_on_key"
|
||||
end
|
||||
|
||||
@@ -262,31 +262,31 @@ ActiveRecord::Schema[8.1].define(version: 2026_02_26_193537) do
|
||||
end
|
||||
|
||||
create_table "oauth_access_grants", force: :cascade do |t|
|
||||
t.bigint "resource_owner_id", null: false
|
||||
t.bigint "application_id", null: false
|
||||
t.string "token", null: false
|
||||
t.integer "expires_in", null: false
|
||||
t.text "redirect_uri", null: false
|
||||
t.string "scopes", default: "", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "revoked_at"
|
||||
t.string "code_challenge"
|
||||
t.string "code_challenge_method"
|
||||
t.datetime "created_at", null: false
|
||||
t.integer "expires_in", null: false
|
||||
t.text "redirect_uri", null: false
|
||||
t.bigint "resource_owner_id", null: false
|
||||
t.datetime "revoked_at"
|
||||
t.string "scopes", default: "", null: false
|
||||
t.string "token", null: false
|
||||
t.index ["application_id"], name: "index_oauth_access_grants_on_application_id"
|
||||
t.index ["resource_owner_id"], name: "index_oauth_access_grants_on_resource_owner_id"
|
||||
t.index ["token"], name: "index_oauth_access_grants_on_token", unique: true
|
||||
end
|
||||
|
||||
create_table "oauth_access_tokens", force: :cascade do |t|
|
||||
t.bigint "resource_owner_id"
|
||||
t.bigint "application_id", null: false
|
||||
t.string "token", null: false
|
||||
t.string "refresh_token"
|
||||
t.integer "expires_in"
|
||||
t.string "scopes"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "revoked_at"
|
||||
t.integer "expires_in"
|
||||
t.string "previous_refresh_token", default: "", null: false
|
||||
t.string "refresh_token"
|
||||
t.bigint "resource_owner_id"
|
||||
t.datetime "revoked_at"
|
||||
t.string "scopes"
|
||||
t.string "token", null: false
|
||||
t.index ["application_id"], name: "index_oauth_access_tokens_on_application_id"
|
||||
t.index ["refresh_token"], name: "index_oauth_access_tokens_on_refresh_token", unique: true
|
||||
t.index ["resource_owner_id"], name: "index_oauth_access_tokens_on_resource_owner_id"
|
||||
@@ -294,25 +294,25 @@ ActiveRecord::Schema[8.1].define(version: 2026_02_26_193537) do
|
||||
end
|
||||
|
||||
create_table "oauth_applications", force: :cascade do |t|
|
||||
t.string "name", null: false
|
||||
t.string "uid", null: false
|
||||
t.string "secret", null: false
|
||||
t.text "redirect_uri"
|
||||
t.string "scopes", default: "", null: false
|
||||
t.boolean "confidential", default: true, null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.string "name", null: false
|
||||
t.text "redirect_uri"
|
||||
t.string "scopes", default: "", null: false
|
||||
t.string "secret", null: false
|
||||
t.string "uid", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["uid"], name: "index_oauth_applications_on_uid", unique: true
|
||||
end
|
||||
|
||||
create_table "search_entries", force: :cascade do |t|
|
||||
t.string "record_type", null: false
|
||||
t.bigint "record_id", null: false
|
||||
t.bigint "account_id", null: false
|
||||
t.tsvector "tsvector", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.tsvector "ngram"
|
||||
t.bigint "record_id", null: false
|
||||
t.string "record_type", null: false
|
||||
t.tsvector "tsvector", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["account_id", "ngram"], name: "index_search_entries_on_account_id_ngram_submission", where: "((record_type)::text = 'Submission'::text)", using: :gin
|
||||
t.index ["account_id", "ngram"], name: "index_search_entries_on_account_id_ngram_submitter", where: "((record_type)::text = 'Submitter'::text)", using: :gin
|
||||
t.index ["account_id", "ngram"], name: "index_search_entries_on_account_id_ngram_template", where: "((record_type)::text = 'Template'::text)", using: :gin
|
||||
@@ -323,15 +323,15 @@ ActiveRecord::Schema[8.1].define(version: 2026_02_26_193537) do
|
||||
end
|
||||
|
||||
create_table "submission_events", force: :cascade do |t|
|
||||
t.bigint "account_id"
|
||||
t.datetime "created_at", null: false
|
||||
t.text "data", null: false
|
||||
t.datetime "event_timestamp", null: false
|
||||
t.string "event_type", null: false
|
||||
t.bigint "submission_id", null: false
|
||||
t.bigint "submitter_id"
|
||||
t.text "data", null: false
|
||||
t.string "event_type", null: false
|
||||
t.datetime "event_timestamp", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.bigint "account_id"
|
||||
t.index ["account_id", "created_at"], name: "index_submissions_events_on_sms_event_types", where: "((event_type)::text = ANY ((ARRAY['send_sms'::character varying, 'send_2fa_sms'::character varying])::text[]))"
|
||||
t.index ["account_id", "created_at"], name: "index_submissions_events_on_sms_event_types", where: "((event_type)::text = ANY (ARRAY[('send_sms'::character varying)::text, ('send_2fa_sms'::character varying)::text]))"
|
||||
t.index ["account_id"], name: "index_submission_events_on_account_id"
|
||||
t.index ["created_at"], name: "index_submission_events_on_created_at"
|
||||
t.index ["submission_id"], name: "index_submission_events_on_submission_id"
|
||||
@@ -339,23 +339,23 @@ ActiveRecord::Schema[8.1].define(version: 2026_02_26_193537) do
|
||||
end
|
||||
|
||||
create_table "submissions", force: :cascade do |t|
|
||||
t.bigint "template_id"
|
||||
t.bigint "created_by_user_id"
|
||||
t.bigint "account_id", null: false
|
||||
t.datetime "archived_at"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.text "template_fields"
|
||||
t.text "template_schema"
|
||||
t.text "template_submitters"
|
||||
t.string "source", null: false
|
||||
t.string "submitters_order", null: false
|
||||
t.string "slug", null: false
|
||||
t.text "preferences", null: false
|
||||
t.bigint "account_id", null: false
|
||||
t.bigint "created_by_user_id"
|
||||
t.datetime "expire_at"
|
||||
t.text "name"
|
||||
t.text "variables_schema"
|
||||
t.text "preferences", null: false
|
||||
t.string "slug", null: false
|
||||
t.string "source", null: false
|
||||
t.string "submitters_order", null: false
|
||||
t.text "template_fields"
|
||||
t.bigint "template_id"
|
||||
t.text "template_schema"
|
||||
t.text "template_submitters"
|
||||
t.datetime "updated_at", null: false
|
||||
t.text "variables"
|
||||
t.text "variables_schema"
|
||||
t.index ["account_id", "id"], name: "index_submissions_on_account_id_and_id"
|
||||
t.index ["account_id", "template_id", "id"], name: "index_submissions_on_account_id_and_template_id_and_id", where: "(archived_at IS NULL)"
|
||||
t.index ["account_id", "template_id", "id"], name: "index_submissions_on_account_id_and_template_id_and_id_archived", where: "(archived_at IS NOT NULL)"
|
||||
@@ -364,27 +364,39 @@ ActiveRecord::Schema[8.1].define(version: 2026_02_26_193537) do
|
||||
t.index ["template_id"], name: "index_submissions_on_template_id"
|
||||
end
|
||||
|
||||
create_table "submitters", force: :cascade do |t|
|
||||
t.bigint "submission_id", null: false
|
||||
t.string "uuid", null: false
|
||||
t.string "email"
|
||||
t.string "slug", null: false
|
||||
t.text "values", null: false
|
||||
t.string "ua"
|
||||
t.string "ip"
|
||||
t.datetime "sent_at"
|
||||
t.datetime "opened_at"
|
||||
t.datetime "completed_at"
|
||||
create_table "submitter_versions", force: :cascade do |t|
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.string "email"
|
||||
t.string "name"
|
||||
t.string "phone"
|
||||
t.string "external_id"
|
||||
t.text "preferences", null: false
|
||||
t.text "metadata", null: false
|
||||
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|
|
||||
t.bigint "account_id", null: false
|
||||
t.datetime "completed_at"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "declined_at"
|
||||
t.string "email"
|
||||
t.string "external_id"
|
||||
t.string "ip"
|
||||
t.text "metadata", null: false
|
||||
t.string "name"
|
||||
t.datetime "opened_at"
|
||||
t.string "phone"
|
||||
t.text "preferences", null: false
|
||||
t.datetime "sent_at"
|
||||
t.string "slug", null: false
|
||||
t.bigint "submission_id", null: false
|
||||
t.string "timezone"
|
||||
t.string "ua"
|
||||
t.datetime "updated_at", null: false
|
||||
t.string "uuid", null: false
|
||||
t.text "values", null: false
|
||||
t.index ["account_id", "id"], name: "index_submitters_on_account_id_and_id"
|
||||
t.index ["completed_at", "account_id"], name: "index_submitters_on_completed_at_and_account_id"
|
||||
t.index ["email"], name: "index_submitters_on_email"
|
||||
@@ -394,52 +406,52 @@ ActiveRecord::Schema[8.1].define(version: 2026_02_26_193537) do
|
||||
end
|
||||
|
||||
create_table "template_accesses", force: :cascade do |t|
|
||||
t.bigint "template_id", null: false
|
||||
t.bigint "user_id", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.bigint "template_id", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.bigint "user_id", null: false
|
||||
t.index ["template_id", "user_id"], name: "index_template_accesses_on_template_id_and_user_id", unique: true
|
||||
end
|
||||
|
||||
create_table "template_folders", force: :cascade do |t|
|
||||
t.string "name", null: false
|
||||
t.bigint "author_id", null: false
|
||||
t.bigint "account_id", null: false
|
||||
t.datetime "archived_at"
|
||||
t.bigint "author_id", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.string "name", null: false
|
||||
t.bigint "parent_folder_id"
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["account_id"], name: "index_template_folders_on_account_id"
|
||||
t.index ["author_id"], name: "index_template_folders_on_author_id"
|
||||
t.index ["parent_folder_id"], name: "index_template_folders_on_parent_folder_id"
|
||||
end
|
||||
|
||||
create_table "template_sharings", force: :cascade do |t|
|
||||
t.bigint "template_id", null: false
|
||||
t.bigint "account_id", null: false
|
||||
t.string "ability", null: false
|
||||
t.bigint "account_id", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.bigint "template_id", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["account_id", "template_id"], name: "index_template_sharings_on_account_id_and_template_id", unique: true
|
||||
t.index ["template_id"], name: "index_template_sharings_on_template_id"
|
||||
end
|
||||
|
||||
create_table "templates", force: :cascade do |t|
|
||||
t.string "slug", null: false
|
||||
t.string "name", null: false
|
||||
t.text "schema", null: false
|
||||
t.text "fields", null: false
|
||||
t.text "submitters", null: false
|
||||
t.bigint "author_id", null: false
|
||||
t.bigint "account_id", null: false
|
||||
t.datetime "archived_at"
|
||||
t.bigint "author_id", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.text "source", null: false
|
||||
t.bigint "folder_id", null: false
|
||||
t.string "external_id"
|
||||
t.text "fields", null: false
|
||||
t.bigint "folder_id", null: false
|
||||
t.string "name", null: false
|
||||
t.text "preferences", null: false
|
||||
t.text "schema", null: false
|
||||
t.boolean "shared_link", default: false, null: false
|
||||
t.string "slug", null: false
|
||||
t.text "source", null: false
|
||||
t.text "submitters", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.text "variables_schema"
|
||||
t.index ["account_id", "folder_id", "id"], name: "index_templates_on_account_id_and_folder_id_and_id", where: "(archived_at IS NULL)"
|
||||
t.index ["account_id", "id"], name: "index_templates_on_account_id_and_id_archived", where: "(archived_at IS NOT NULL)"
|
||||
@@ -451,44 +463,44 @@ ActiveRecord::Schema[8.1].define(version: 2026_02_26_193537) do
|
||||
end
|
||||
|
||||
create_table "user_configs", force: :cascade do |t|
|
||||
t.bigint "user_id", null: false
|
||||
t.string "key", null: false
|
||||
t.text "value", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.string "key", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.bigint "user_id", null: false
|
||||
t.text "value", null: false
|
||||
t.index ["user_id", "key"], name: "index_user_configs_on_user_id_and_key", unique: true
|
||||
t.index ["user_id"], name: "index_user_configs_on_user_id"
|
||||
end
|
||||
|
||||
create_table "users", force: :cascade do |t|
|
||||
t.string "first_name"
|
||||
t.string "last_name"
|
||||
t.string "email", null: false
|
||||
t.string "role", null: false
|
||||
t.string "encrypted_password", null: false
|
||||
t.bigint "account_id", null: false
|
||||
t.string "reset_password_token"
|
||||
t.datetime "reset_password_sent_at"
|
||||
t.datetime "remember_created_at"
|
||||
t.integer "sign_in_count", default: 0, null: false
|
||||
t.datetime "current_sign_in_at"
|
||||
t.datetime "last_sign_in_at"
|
||||
t.string "current_sign_in_ip"
|
||||
t.string "last_sign_in_ip"
|
||||
t.integer "failed_attempts", default: 0, null: false
|
||||
t.string "unlock_token"
|
||||
t.datetime "locked_at"
|
||||
t.datetime "archived_at"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.string "uuid", null: false
|
||||
t.string "otp_secret"
|
||||
t.integer "consumed_timestep"
|
||||
t.boolean "otp_required_for_login", default: false, null: false
|
||||
t.datetime "confirmation_sent_at"
|
||||
t.string "confirmation_token"
|
||||
t.datetime "confirmed_at"
|
||||
t.datetime "confirmation_sent_at"
|
||||
t.integer "consumed_timestep"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "current_sign_in_at"
|
||||
t.string "current_sign_in_ip"
|
||||
t.string "email", null: false
|
||||
t.string "encrypted_password", null: false
|
||||
t.integer "failed_attempts", default: 0, null: false
|
||||
t.string "first_name"
|
||||
t.string "last_name"
|
||||
t.datetime "last_sign_in_at"
|
||||
t.string "last_sign_in_ip"
|
||||
t.datetime "locked_at"
|
||||
t.boolean "otp_required_for_login", default: false, null: false
|
||||
t.string "otp_secret"
|
||||
t.datetime "remember_created_at"
|
||||
t.datetime "reset_password_sent_at"
|
||||
t.string "reset_password_token"
|
||||
t.string "role", null: false
|
||||
t.integer "sign_in_count", default: 0, null: false
|
||||
t.string "unconfirmed_email"
|
||||
t.string "unlock_token"
|
||||
t.datetime "updated_at", null: false
|
||||
t.string "uuid", null: false
|
||||
t.index ["account_id"], name: "index_users_on_account_id"
|
||||
t.index ["email"], name: "index_users_on_email", unique: true
|
||||
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
|
||||
@@ -497,25 +509,25 @@ ActiveRecord::Schema[8.1].define(version: 2026_02_26_193537) do
|
||||
end
|
||||
|
||||
create_table "webhook_attempts", force: :cascade do |t|
|
||||
t.bigint "webhook_event_id", null: false
|
||||
t.text "response_body"
|
||||
t.integer "response_status_code", null: false
|
||||
t.integer "attempt", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.text "response_body"
|
||||
t.integer "response_status_code", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.bigint "webhook_event_id", null: false
|
||||
t.index ["webhook_event_id"], name: "index_webhook_attempts_on_webhook_event_id"
|
||||
end
|
||||
|
||||
create_table "webhook_events", force: :cascade do |t|
|
||||
t.string "uuid", null: false
|
||||
t.bigint "webhook_url_id", null: false
|
||||
t.bigint "account_id", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.string "event_type", null: false
|
||||
t.bigint "record_id", null: false
|
||||
t.string "record_type", null: false
|
||||
t.string "event_type", null: false
|
||||
t.string "status", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.string "uuid", null: false
|
||||
t.bigint "webhook_url_id", null: false
|
||||
t.index ["uuid", "webhook_url_id"], name: "index_webhook_events_on_uuid_and_webhook_url_id", unique: true
|
||||
t.index ["webhook_url_id", "id"], name: "index_webhook_events_error", where: "((status)::text = 'error'::text)"
|
||||
t.index ["webhook_url_id", "id"], name: "index_webhook_events_on_webhook_url_id_and_id"
|
||||
@@ -523,12 +535,12 @@ ActiveRecord::Schema[8.1].define(version: 2026_02_26_193537) do
|
||||
|
||||
create_table "webhook_urls", force: :cascade do |t|
|
||||
t.bigint "account_id", null: false
|
||||
t.text "url", null: false
|
||||
t.text "events", null: false
|
||||
t.string "sha1", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.text "events", null: false
|
||||
t.text "secret", null: false
|
||||
t.string "sha1", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.text "url", null: false
|
||||
t.index ["account_id"], name: "index_webhook_urls_on_account_id"
|
||||
t.index ["sha1"], name: "index_webhook_urls_on_sha1"
|
||||
end
|
||||
@@ -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_variant_records", "active_storage_blobs", column: "blob_id"
|
||||
add_foreign_key "document_generation_events", "submitters"
|
||||
add_foreign_key "dynamic_document_versions", "dynamic_documents"
|
||||
add_foreign_key "dynamic_documents", "templates"
|
||||
add_foreign_key "email_events", "accounts"
|
||||
add_foreign_key "email_messages", "accounts"
|
||||
add_foreign_key "email_messages", "users", column: "author_id"
|
||||
add_foreign_key "encrypted_configs", "accounts"
|
||||
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", "users", column: "resource_owner_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 "submissions", "templates"
|
||||
add_foreign_key "submissions", "users", column: "created_by_user_id"
|
||||
add_foreign_key "submitter_versions", "submitters"
|
||||
add_foreign_key "submitters", "submissions"
|
||||
add_foreign_key "template_accesses", "templates"
|
||||
add_foreign_key "template_folders", "accounts"
|
||||
|
||||
@@ -175,6 +175,7 @@ module Accounts
|
||||
|
||||
def can_send_emails?(_account, **_params)
|
||||
return true if Docuseal.multitenant?
|
||||
return true if Rails.env.development?
|
||||
return true if ENV['SMTP_ADDRESS'].present?
|
||||
|
||||
EncryptedConfig.exists?(key: EncryptedConfig::EMAIL_SMTP_KEY)
|
||||
|
||||
@@ -20,7 +20,7 @@ module EmailVerificationCodes
|
||||
def build_totp_secret(value)
|
||||
ROTP::Base32.encode(
|
||||
Digest::SHA1.digest(
|
||||
[Rails.application.secret_key_base, value].join(':')
|
||||
[Rails.application.secret_key_base, 'form_email_2fa', value].join(':')
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
module GenerateCertificate
|
||||
SIZE = 2**11
|
||||
|
||||
Pkcs12Struct = Struct.new(:certificate, :ca_certs, keyword_init: true)
|
||||
Pkcs12Struct = Struct.new(:certificate, :ca_certs)
|
||||
|
||||
module_function
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
module LoadIco
|
||||
BI_RGB = 0
|
||||
PNG_SIGNATURE = "\x89PNG".b
|
||||
|
||||
module_function
|
||||
|
||||
@@ -42,6 +43,8 @@ module LoadIco
|
||||
|
||||
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])
|
||||
|
||||
raise ArgumentError, 'Unable to load' unless image
|
||||
|
||||
@@ -92,7 +92,7 @@ module Params
|
||||
def in_path(params, path = [], skip_blank: false)
|
||||
old_path = @current_path
|
||||
|
||||
@current_path = [old_path, *path].compact_blank.map(&:to_s).join('.')
|
||||
@current_path = [old_path, *path].compact_blank.join('.')
|
||||
|
||||
param = params.dig(*path)
|
||||
param = nil if skip_blank && param.blank?
|
||||
@@ -106,7 +106,7 @@ module Params
|
||||
old_path = @current_path
|
||||
|
||||
params.dig(*path)&.each_with_index do |item, index|
|
||||
@current_path = [old_path, [*path].map(&:to_s).join('.') + "[#{index}]"].compact_blank.join('.')
|
||||
@current_path = [old_path, [*path].join('.') + "[#{index}]"].compact_blank.join('.')
|
||||
|
||||
yield item if item
|
||||
end
|
||||
|
||||
@@ -106,6 +106,8 @@ module Submissions
|
||||
return submission if template.variables_schema.present? ||
|
||||
submission.variables_schema.present?
|
||||
|
||||
return submission if template.schema.none? { |e| e['dynamic'] }
|
||||
|
||||
areas_index = {}
|
||||
submission.template_schema = []
|
||||
|
||||
|
||||
@@ -246,33 +246,25 @@ module Submissions
|
||||
|
||||
next if submitter.blank?
|
||||
|
||||
completed_event =
|
||||
submission.submission_events.find { |e| e.submitter_id == submitter.id && e.complete_form? } ||
|
||||
SubmissionEvent.new
|
||||
submission_events = submission.submission_events.select { |e| e.submitter_id == submitter.id }
|
||||
|
||||
click_email_event =
|
||||
submission.submission_events.find { |e| e.submitter_id == submitter.id && e.click_email? }
|
||||
delegated_event = submission_events.select(&:delegate_form?).max_by(&:event_timestamp)
|
||||
|
||||
verify_email_event =
|
||||
submission.submission_events.find { |e| e.submitter_id == submitter.id && e.email_verified? }
|
||||
if delegated_event
|
||||
submission_events = submission_events.select { |e| e.event_timestamp > delegated_event.event_timestamp }
|
||||
end
|
||||
|
||||
is_phone_verified =
|
||||
submission.template_fields.any? do |e|
|
||||
e['type'] == 'phone' && e['submitter_uuid'] == submitter.uuid && submitter.values[e['uuid']].present?
|
||||
end
|
||||
completed_event = submission_events.find(&:complete_form?) || SubmissionEvent.new
|
||||
|
||||
verify_phone_event =
|
||||
submission.submission_events.find { |e| e.submitter_id == submitter.id && e.phone_verified? }
|
||||
click_email_event = submission_events.find(&:click_email?)
|
||||
|
||||
is_id_verified =
|
||||
submission.template_fields.any? do |e|
|
||||
e['type'] == 'verification' && e['submitter_uuid'] == submitter.uuid && submitter.values[e['uuid']].present?
|
||||
end
|
||||
verify_email_event = submission_events.find(&:email_verified?)
|
||||
|
||||
is_kba_passed =
|
||||
submission.template_fields.any? do |e|
|
||||
e['type'] == 'kba' && e['submitter_uuid'] == submitter.uuid && submitter.values[e['uuid']].present?
|
||||
end
|
||||
verify_phone_event = submission_events.find(&:phone_verified?)
|
||||
|
||||
is_id_verified = submission_events.any?(&:complete_verification?)
|
||||
|
||||
is_kba_passed = submission_events.any?(&:complete_kba?)
|
||||
|
||||
info_rows = [
|
||||
[
|
||||
@@ -291,7 +283,7 @@ module Submissions
|
||||
submitter.email && (click_email_event || verify_email_event) && {
|
||||
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"
|
||||
},
|
||||
is_id_verified && {
|
||||
@@ -446,15 +438,23 @@ module Submissions
|
||||
|
||||
composer.text(I18n.t('event_log'), font_size: 12, padding: [10, 0, 20, 0])
|
||||
|
||||
submitter_versions_index = submission.submitters.preload(:submitter_versions).to_h do |s|
|
||||
[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|
|
||||
next if event.event_type.in?(%w[bounce_email complaint_email])
|
||||
|
||||
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 =
|
||||
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
|
||||
submitter.name || submitter.email || submitter.phone
|
||||
active_version&.name || active_version&.email || active_version&.phone ||
|
||||
submitter.name || submitter.email || submitter.phone
|
||||
end
|
||||
|
||||
text =
|
||||
@@ -473,6 +473,10 @@ module Submissions
|
||||
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}"
|
||||
].join("\n")
|
||||
elsif event.event_type == 'delegate_form'
|
||||
from = event.data['old_email'].presence ||
|
||||
versions.rfind { |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_')
|
||||
I18n.t("submission_event_names.#{event.event_type}_to_html", submitter_name:)
|
||||
else
|
||||
|
||||
@@ -58,7 +58,7 @@ module Submissions
|
||||
end
|
||||
|
||||
def build_table_rows(submissions, expires_at: nil)
|
||||
submissions.preload(submitters: [attachments_attachments: :blob, documents_attachments: :blob])
|
||||
submissions.preload(submitters: [{ attachments_attachments: :blob, documents_attachments: :blob }])
|
||||
.find_each.map do |submission|
|
||||
submission_data = []
|
||||
submitters_count = submission.submitters.size
|
||||
|
||||
@@ -4,6 +4,7 @@ module Submitters
|
||||
module CreateStampAttachment
|
||||
WIDTH = 400
|
||||
HEIGHT = 200
|
||||
LRM = "\u200E"
|
||||
|
||||
TRANSPARENT_PIXEL = "\x89PNG\r\n\u001A\n\u0000\u0000\u0000\rIHDR\u0000" \
|
||||
"\u0000\u0000\u0001\u0000\u0000\u0000\u0001\b\u0004" \
|
||||
@@ -83,7 +84,8 @@ module Submitters
|
||||
name = ERB::Util.html_escape(name)
|
||||
role = ERB::Util.html_escape(role)
|
||||
|
||||
text = %(<span size="90">#{digitally_signed_by}:\n<b>#{name}</b>\n#{role}#{time} #{timezone}</span>)
|
||||
text =
|
||||
%(<span size="90">#{LRM}#{digitally_signed_by}:\n#{LRM}<b>#{name}</b>\n#{LRM}#{role}#{time} #{timezone}</span>)
|
||||
|
||||
Vips::Image.text(text, width: WIDTH, height: HEIGHT, wrap: :'word-char')
|
||||
end
|
||||
|
||||
@@ -8,6 +8,7 @@ module Submitters
|
||||
AccountConfig::FORM_PREFILL_SIGNATURE_KEY,
|
||||
AccountConfig::WITH_SIGNATURE_ID,
|
||||
AccountConfig::ALLOW_TO_DECLINE_KEY,
|
||||
AccountConfig::ALLOW_TO_DELEGATE_KEY,
|
||||
AccountConfig::ENFORCE_SIGNING_ORDER_KEY,
|
||||
AccountConfig::REQUIRE_SIGNING_REASON_KEY,
|
||||
AccountConfig::REUSE_SIGNATURE_KEY,
|
||||
@@ -27,10 +28,11 @@ module Submitters
|
||||
completed_button = find_safe_value(configs, AccountConfig::FORM_COMPLETED_BUTTON_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_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
|
||||
reuse_signature = find_safe_value(configs, AccountConfig::REUSE_SIGNATURE_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_signature_id = find_safe_value(configs, AccountConfig::WITH_SIGNATURE_ID) == 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)
|
||||
|
||||
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:,
|
||||
require_signing_reason:, prefill_signature:, with_submitter_timezone:,
|
||||
with_signature_id_reason:, with_signature_id:, with_field_labels:, with_timestamp_seconds: }
|
||||
|
||||
@@ -15,9 +15,9 @@ module Submitters
|
||||
ActiveRecord::Associations::Preloader.new(
|
||||
records: [submitter],
|
||||
associations: if with_documents
|
||||
[documents_attachments: :blob, attachments_attachments: :blob]
|
||||
[{ documents_attachments: :blob, attachments_attachments: :blob }]
|
||||
elsif with_values
|
||||
[attachments_attachments: :blob]
|
||||
[{ attachments_attachments: :blob }]
|
||||
end
|
||||
).call
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ module Submitters
|
||||
|
||||
def call(submitter, expires_at: Accounts.link_expires_at(Account.new(id: submitter.account_id)))
|
||||
ActiveRecord::Associations::Preloader.new(
|
||||
records: [submitter], associations: [documents_attachments: :blob, attachments_attachments: :blob]
|
||||
records: [submitter], associations: [{ documents_attachments: :blob, attachments_attachments: :blob }]
|
||||
).call
|
||||
|
||||
values = build_values_array(submitter, expires_at:)
|
||||
|
||||
@@ -4,7 +4,7 @@ module Templates
|
||||
module DetectFields
|
||||
module_function
|
||||
|
||||
TextFieldBox = Struct.new(:x, :y, :w, :h, keyword_init: true) do
|
||||
TextFieldBox = Struct.new(:x, :y, :w, :h) do
|
||||
def endy
|
||||
@endy ||= y + h
|
||||
end
|
||||
@@ -14,7 +14,7 @@ module Templates
|
||||
end
|
||||
end
|
||||
|
||||
PageNode = Struct.new(:prev, :next, :elem, :page, :attachment_uuid, keyword_init: true)
|
||||
PageNode = Struct.new(:prev, :next, :elem, :page, :attachment_uuid)
|
||||
|
||||
DATE_REGEXP = /
|
||||
(?:
|
||||
|
||||
@@ -4,7 +4,7 @@ module Templates
|
||||
module ImageToFields
|
||||
module_function
|
||||
|
||||
Field = Struct.new(:type, :x, :y, :w, :h, :confidence, keyword_init: true) do
|
||||
Field = Struct.new(:type, :x, :y, :w, :h, :confidence) do
|
||||
def endy
|
||||
@endy ||= y + h
|
||||
end
|
||||
|
||||
@@ -34,7 +34,7 @@ module Templates
|
||||
|
||||
if index.positive? && pdf_fields.present?
|
||||
preview_document = template.schema[index - 1]
|
||||
preview_document_last_field = template.fields.reverse.find do |f|
|
||||
preview_document_last_field = template.fields.rfind do |f|
|
||||
f['areas']&.any? do |a|
|
||||
a['attachment_uuid'] == preview_document[:attachment_uuid]
|
||||
end
|
||||
|
||||
@@ -9,10 +9,9 @@ require 'rspec/rails'
|
||||
require 'capybara/cuprite'
|
||||
require 'capybara/rspec'
|
||||
require 'webmock/rspec'
|
||||
require 'sidekiq/testing'
|
||||
require 'signing_form_helper'
|
||||
|
||||
Sidekiq::Testing.fake!
|
||||
Sidekiq.testing!(:fake)
|
||||
|
||||
WebMock.disable_net_connect!(allow_localhost: true)
|
||||
|
||||
@@ -69,11 +68,11 @@ RSpec.configure do |config|
|
||||
end
|
||||
|
||||
config.before do |example|
|
||||
Sidekiq::Testing.inline! if example.metadata[:sidekiq] == :inline
|
||||
Sidekiq.testing!(:inline) if example.metadata[:sidekiq] == :inline
|
||||
end
|
||||
|
||||
config.after do |example|
|
||||
Sidekiq::Testing.fake! if example.metadata[:sidekiq] == :inline
|
||||
Sidekiq.testing!(:fake) if example.metadata[:sidekiq] == :inline
|
||||
end
|
||||
|
||||
config.before(multitenant: true) do
|
||||
|
||||
@@ -1159,6 +1159,50 @@ RSpec.describe 'Signing Form' do
|
||||
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
|
||||
let(:template) { create(:template, account:, author:, only_field_types: %w[text]) }
|
||||
let(:submission) { create(:submission, template:) }
|
||||
|
||||
Reference in New Issue
Block a user