mirror of
https://github.com/docusealco/docuseal
synced 2026-11-04 14:42:32 -05:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8f8f69f0bc | ||
|
|
04663d55eb | ||
|
|
93d0b935e2 | ||
|
|
829b2b2855 | ||
|
|
cf6de444f4 | ||
|
|
126f5d58a2 | ||
|
|
09b93067f4 | ||
|
|
f14458f238 | ||
|
|
445139f05c | ||
|
|
e5e4965f05 | ||
|
|
1c8f7b0316 | ||
|
|
9fe3656652 | ||
|
|
17ae46bd61 | ||
|
|
a036483938 |
No files matched your search
+4
-2
@@ -52,7 +52,7 @@ ENV OPENSSL_CONF=/etc/openssl_legacy.cnf
|
|||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
RUN apk add --no-cache libpq vips redis onnxruntime leptonica && \
|
RUN apk add --no-cache libpq vips redis onnxruntime leptonica jemalloc font-liberation font-carlito && \
|
||||||
rm -f /usr/bin/onnx_test_runner /usr/bin/onnxruntime_test
|
rm -f /usr/bin/onnx_test_runner /usr/bin/onnxruntime_test
|
||||||
|
|
||||||
RUN addgroup -g 2000 docuseal && adduser -u 2000 -G docuseal -s /bin/sh -D -h /home/docuseal docuseal
|
RUN addgroup -g 2000 docuseal && adduser -u 2000 -G docuseal -s /bin/sh -D -h /home/docuseal docuseal
|
||||||
@@ -91,7 +91,7 @@ COPY --chown=docuseal:docuseal --from=download /model.onnx /app/tmp/model.onnx
|
|||||||
COPY --chown=docuseal:docuseal --from=webpack /app/public/packs ./public/packs
|
COPY --chown=docuseal:docuseal --from=webpack /app/public/packs ./public/packs
|
||||||
|
|
||||||
RUN mkdir -p /app/public/fonts && ln -s /fonts/DancingScript-Regular.otf /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 && \
|
mkdir -p /usr/share/fonts/noto/bold && ln -s /fonts/GoNotoKurrent-Regular.ttf /usr/share/fonts/noto/ && ln -s /fonts/GoNotoKurrent-Bold.ttf /usr/share/fonts/noto/bold/ && fc-cache -f && \
|
||||||
bundle exec bootsnap precompile -j 1 --gemfile app/ lib/ && \
|
bundle exec bootsnap precompile -j 1 --gemfile app/ lib/ && \
|
||||||
chown -R docuseal:docuseal /app/tmp/cache
|
chown -R docuseal:docuseal /app/tmp/cache
|
||||||
|
|
||||||
@@ -100,6 +100,8 @@ ENV HOME=/home/docuseal
|
|||||||
ENV WORKDIR=/data/docuseal
|
ENV WORKDIR=/data/docuseal
|
||||||
ENV VIPS_MAX_COORD=17000
|
ENV VIPS_MAX_COORD=17000
|
||||||
ENV VIPS_BLOCK_UNTRUSTED=1
|
ENV VIPS_BLOCK_UNTRUSTED=1
|
||||||
|
# ENV LD_PRELOAD=/usr/lib/libjemalloc.so.2
|
||||||
|
ENV MALLOC_CONF=dirty_decay_ms:1000,narenas:2,background_thread:true
|
||||||
|
|
||||||
EXPOSE 3000
|
EXPOSE 3000
|
||||||
CMD ["/app/bin/bundle", "exec", "puma", "-C", "/app/config/puma.rb", "--dir", "/app"]
|
CMD ["/app/bin/bundle", "exec", "puma", "-C", "/app/config/puma.rb", "--dir", "/app"]
|
||||||
@@ -45,6 +45,7 @@ gem 'trilogy', require: false
|
|||||||
gem 'turbo-rails'
|
gem 'turbo-rails'
|
||||||
gem 'twitter_cldr', require: false
|
gem 'twitter_cldr', require: false
|
||||||
gem 'tzinfo-data'
|
gem 'tzinfo-data'
|
||||||
|
gem 'wordcraft', require: false, group: :ce
|
||||||
gem 'xlsxtream', require: false
|
gem 'xlsxtream', require: false
|
||||||
|
|
||||||
group :development, :test do
|
group :development, :test do
|
||||||
|
|||||||
@@ -572,6 +572,16 @@ GEM
|
|||||||
base64
|
base64
|
||||||
websocket-extensions (>= 0.1.0)
|
websocket-extensions (>= 0.1.0)
|
||||||
websocket-extensions (0.1.5)
|
websocket-extensions (0.1.5)
|
||||||
|
wordcraft (0.8.0-aarch64-linux-gnu)
|
||||||
|
ffi (>= 1.15)
|
||||||
|
wordcraft (0.8.0-aarch64-linux-musl)
|
||||||
|
ffi (>= 1.15)
|
||||||
|
wordcraft (0.8.0-arm64-darwin)
|
||||||
|
ffi (>= 1.15)
|
||||||
|
wordcraft (0.8.0-x86_64-linux-gnu)
|
||||||
|
ffi (>= 1.15)
|
||||||
|
wordcraft (0.8.0-x86_64-linux-musl)
|
||||||
|
ffi (>= 1.15)
|
||||||
xlsxtream (3.1.0)
|
xlsxtream (3.1.0)
|
||||||
zip_kit (>= 6.2, < 7)
|
zip_kit (>= 6.2, < 7)
|
||||||
xpath (3.2.0)
|
xpath (3.2.0)
|
||||||
@@ -650,6 +660,7 @@ DEPENDENCIES
|
|||||||
tzinfo-data
|
tzinfo-data
|
||||||
web-console
|
web-console
|
||||||
webmock
|
webmock
|
||||||
|
wordcraft
|
||||||
xlsxtream
|
xlsxtream
|
||||||
|
|
||||||
RUBY VERSION
|
RUBY VERSION
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ module Api
|
|||||||
attachment = Submitters.create_attachment!(@submitter, file, metadata:)
|
attachment = Submitters.create_attachment!(@submitter, file, metadata:)
|
||||||
|
|
||||||
if params[:remember_signature] == 'true' && @submitter.email.present?
|
if params[:remember_signature] == 'true' && @submitter.email.present?
|
||||||
cookies.encrypted[:signature_uuids] = build_new_cookie_signatures_json(@submitter, attachment)
|
cookies.permanent.encrypted[:signature_uuids] = build_new_cookie_signatures_json(@submitter, attachment)
|
||||||
end
|
end
|
||||||
|
|
||||||
render json: attachment.as_json(only: %i[uuid created_at], methods: %i[url filename content_type])
|
render json: attachment.as_json(only: %i[uuid created_at], methods: %i[url filename content_type])
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ class SubmitFormUploadController < ActionController::API
|
|||||||
attachment = Submitters.create_attachment!(@submitter, file, metadata:)
|
attachment = Submitters.create_attachment!(@submitter, file, metadata:)
|
||||||
|
|
||||||
if params[:remember_signature] == 'true' && @submitter.email.present?
|
if params[:remember_signature] == 'true' && @submitter.email.present?
|
||||||
cookies.encrypted[:signature_uuids] = build_new_cookie_signatures_json(@submitter, attachment)
|
cookies.permanent.encrypted[:signature_uuids] = build_new_cookie_signatures_json(@submitter, attachment)
|
||||||
end
|
end
|
||||||
|
|
||||||
render json: attachment.as_json(only: %i[uuid created_at], methods: %i[url filename content_type])
|
render json: attachment.as_json(only: %i[uuid created_at], methods: %i[url filename content_type])
|
||||||
|
|||||||
@@ -8,7 +8,9 @@ class TemplateSharingsTestingController < ApplicationController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
testing_account = Accounts.find_or_create_testing_user(true_user.account).account
|
account = can?(:manage, :tenants_test) ? current_account : true_user.account
|
||||||
|
|
||||||
|
testing_account = Accounts.find_or_create_testing_user(account).account
|
||||||
|
|
||||||
if params[:value] == '1'
|
if params[:value] == '1'
|
||||||
TemplateSharing.create!(ability: :manage, account: testing_account, template: @template)
|
TemplateSharing.create!(ability: :manage, account: testing_account, template: @template)
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ export default class extends HTMLElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async flashFrom (fetchResponse) {
|
async flashFrom (fetchResponse) {
|
||||||
const html = await fetchResponse?.responseHTML
|
const html = await fetchResponse?.responseHTML.catch(() => null)
|
||||||
const flash = html && new DOMParser().parseFromString(html, 'text/html').getElementById('native_flash')
|
const flash = html && new DOMParser().parseFromString(html, 'text/html').getElementById('native_flash')
|
||||||
|
|
||||||
if (flash?.dataset.alert) return { alert: flash.dataset.alert }
|
if (flash?.dataset.alert) return { alert: flash.dataset.alert }
|
||||||
|
|||||||
@@ -3,11 +3,19 @@
|
|||||||
v-if="!error"
|
v-if="!error"
|
||||||
class="label text-xl sm:text-2xl py-0 mb-2 sm:mb-3.5 field-name-label"
|
class="label text-xl sm:text-2xl py-0 mb-2 sm:mb-3.5 field-name-label"
|
||||||
>
|
>
|
||||||
<MarkdownContent
|
<span class="flex items-end">
|
||||||
v-if="field.title"
|
<MarkdownContent
|
||||||
:string="field.title"
|
v-if="field.title"
|
||||||
/>
|
:string="field.title"
|
||||||
<template v-else>{{ field.name || 'Knowledge Based Authentication' }}</template>
|
/>
|
||||||
|
<template v-else>{{ field.name || 'Knowledge Based Authentication' }}</template>
|
||||||
|
<span
|
||||||
|
class="tooltip tooltip-bottom ml-2 mb-1"
|
||||||
|
data-tip="To verify your identity, the details you enter are checked against third-party records, which may include credit bureau data, and used to generate questions based on those records. Only these identity details are shared with the identity verification provider; this document and your tax return information are not shared with it or with any credit reporting company. If the check is recorded on your credit report, it appears as a soft inquiry, which does not affect your credit score and is not shown to lenders. This check does not give the sender of this document or the IRS access to your credit report."
|
||||||
|
>
|
||||||
|
<IconInfoCircle class="w-4 h-4 text-neutral-500" />
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
<span
|
<span
|
||||||
v-if="questions"
|
v-if="questions"
|
||||||
class="float-right font-normal text-neutral-500 mt-1 whitespace-nowrap text-right text-sm"
|
class="float-right font-normal text-neutral-500 mt-1 whitespace-nowrap text-right text-sm"
|
||||||
@@ -282,13 +290,14 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import MarkdownContent from './markdown_content'
|
import MarkdownContent from './markdown_content'
|
||||||
import { IconInnerShadowTop } from '@tabler/icons-vue'
|
import { IconInnerShadowTop, IconInfoCircle } from '@tabler/icons-vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'KbaStep',
|
name: 'KbaStep',
|
||||||
components: {
|
components: {
|
||||||
MarkdownContent,
|
MarkdownContent,
|
||||||
IconInnerShadowTop
|
IconInnerShadowTop,
|
||||||
|
IconInfoCircle
|
||||||
},
|
},
|
||||||
inject: ['baseUrl', 't'],
|
inject: ['baseUrl', 't'],
|
||||||
props: {
|
props: {
|
||||||
|
|||||||
@@ -27,13 +27,17 @@ tiptapStylesheet.replaceSync(
|
|||||||
font-feature-settings: "liga" 0;
|
font-feature-settings: "liga" 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-flow: column nowrap;
|
flex-flow: column nowrap;
|
||||||
min-height: inherit;
|
flex-grow: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ProseMirror > article {
|
.ProseMirror > article:last-of-type {
|
||||||
margin-bottom: auto;
|
margin-bottom: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ProseMirror p.doc-trailing-break::after {
|
||||||
|
content: none;
|
||||||
|
}
|
||||||
|
|
||||||
.ProseMirror [contenteditable="false"] {
|
.ProseMirror [contenteditable="false"] {
|
||||||
white-space: normal;
|
white-space: normal;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,13 +22,13 @@
|
|||||||
<% end %>
|
<% end %>
|
||||||
<% if can?(:create, ::Template) && controller_name.in?(%w[templates_dashboard submissions_dashboard template_folders templates_archived submissions_archived]) %>
|
<% if can?(:create, ::Template) && controller_name.in?(%w[templates_dashboard submissions_dashboard template_folders templates_archived submissions_archived]) %>
|
||||||
<% folder_name = @template_folder&.full_name %>
|
<% folder_name = @template_folder&.full_name %>
|
||||||
<native-action data-placement="create" data-icon="upload" data-native="upload" data-label="<%= t('upload') %>" data-url="<%= templates_upload_path(folder_name: folder_name) %>" data-accept="image/*, application/pdf, application/zip, application/json<%= ", #{Templates::CreateAttachments::DOCUMENT_EXTENSIONS.join(', ')}" if Docuseal.advanced_formats? %>"></native-action>
|
<native-action data-placement="create" data-icon="upload" data-native="upload" data-label="<%= t('upload') %>" data-url="<%= templates_upload_path(folder_name: folder_name) %>" data-accept="image/*, application/pdf, application/zip, application/json, <%= Templates::CreateAttachments.document_extensions.join(', ') %>"></native-action>
|
||||||
<native-action data-placement="create" data-icon="scan" data-native="scan" data-label="<%= t('scan') %>" data-url="<%= templates_upload_path(folder_name: folder_name) %>"></native-action>
|
<native-action data-placement="create" data-icon="scan" data-native="scan" data-label="<%= t('scan') %>" data-url="<%= templates_upload_path(folder_name: folder_name) %>"></native-action>
|
||||||
<native-action data-placement="create" data-icon="pencil_plus">
|
<native-action data-placement="create" data-icon="pencil_plus">
|
||||||
<%= link_to t('create'), new_template_path(folder_name: folder_name), data: { turbo_frame: :modal, native_modal: :medium } %>
|
<%= link_to t('create'), new_template_path(folder_name: folder_name), data: { turbo_frame: :modal, native_modal: :medium } %>
|
||||||
</native-action>
|
</native-action>
|
||||||
<% unless controller_name.in?(%w[templates_archived submissions_archived]) %>
|
<% unless controller_name.in?(%w[templates_archived submissions_archived]) %>
|
||||||
<native-action data-placement="menu" data-menu="<%= t('new') %>" data-menu-icon="pencil_plus" data-icon="upload" data-native="upload" data-label="<%= t('upload') %>" data-url="<%= templates_upload_path(folder_name: folder_name) %>" data-accept="image/*, application/pdf, application/zip, application/json<%= ", #{Templates::CreateAttachments::DOCUMENT_EXTENSIONS.join(', ')}" if Docuseal.advanced_formats? %>"></native-action>
|
<native-action data-placement="menu" data-menu="<%= t('new') %>" data-menu-icon="pencil_plus" data-icon="upload" data-native="upload" data-label="<%= t('upload') %>" data-url="<%= templates_upload_path(folder_name: folder_name) %>" data-accept="image/*, application/pdf, application/zip, application/json, <%= Templates::CreateAttachments.document_extensions.join(', ') %>"></native-action>
|
||||||
<native-action data-placement="menu" data-menu="<%= t('new') %>" data-menu-icon="pencil_plus" data-icon="scan" data-native="scan" data-label="<%= t('scan') %>" data-url="<%= templates_upload_path(folder_name: folder_name) %>"></native-action>
|
<native-action data-placement="menu" data-menu="<%= t('new') %>" data-menu-icon="pencil_plus" data-icon="scan" data-native="scan" data-label="<%= t('scan') %>" data-url="<%= templates_upload_path(folder_name: folder_name) %>"></native-action>
|
||||||
<native-action data-placement="menu" data-menu="<%= t('new') %>" data-menu-icon="pencil_plus" data-icon="pencil_plus">
|
<native-action data-placement="menu" data-menu="<%= t('new') %>" data-menu-icon="pencil_plus" data-icon="pencil_plus">
|
||||||
<%= link_to t('create'), new_template_path(folder_name: folder_name), data: { turbo_frame: :modal, native_modal: :medium } %>
|
<%= link_to t('create'), new_template_path(folder_name: folder_name), data: { turbo_frame: :modal, native_modal: :medium } %>
|
||||||
|
|||||||
@@ -93,14 +93,14 @@
|
|||||||
</li>
|
</li>
|
||||||
<% end %>
|
<% end %>
|
||||||
<% if !Docuseal.demo? && can?(:manage, EncryptedConfig) && (current_user == true_user || current_account.testing?) %>
|
<% if !Docuseal.demo? && can?(:manage, EncryptedConfig) && (current_user == true_user || current_account.testing?) %>
|
||||||
<% if Docuseal.multitenant? || !turbo_native_ios? %>
|
<% unless turbo_native_app? %>
|
||||||
<li>
|
<li>
|
||||||
<%= link_to Docuseal.multitenant? ? console_redirect_index_path(redir: "#{Docuseal::CONSOLE_URL}#{'/test' if current_account.testing?}/api") : "#{Docuseal::CONSOLE_URL}/on_premises", class: 'text-base hover:bg-base-300', data: { turbo: false } do %>
|
<%= link_to Docuseal.multitenant? ? console_redirect_index_path(redir: "#{Docuseal::CONSOLE_URL}#{'/test' if current_account.testing?}/api") : "#{Docuseal::CONSOLE_URL}/on_premises", class: 'text-base hover:bg-base-300', data: { turbo: false } do %>
|
||||||
<% if Docuseal.multitenant? %> API <% else %> <%= t('console') %> <% end %>
|
<% if Docuseal.multitenant? %> API <% else %> <%= t('console') %> <% end %>
|
||||||
<% end %>
|
<% end %>
|
||||||
</li>
|
</li>
|
||||||
<% end %>
|
<% end %>
|
||||||
<% if Docuseal.multitenant? %>
|
<% if Docuseal.multitenant? && !turbo_native_app? %>
|
||||||
<li>
|
<li>
|
||||||
<%= link_to console_redirect_index_path(redir: "#{Docuseal::CONSOLE_URL}#{'/test' if current_account.testing?}/embedding/form"), class: 'text-base hover:bg-base-300', data: { turbo: false } do %>
|
<%= link_to console_redirect_index_path(redir: "#{Docuseal::CONSOLE_URL}#{'/test' if current_account.testing?}/embedding/form"), class: 'text-base hover:bg-base-300', data: { turbo: false } do %>
|
||||||
<%= t('embedding') %>
|
<%= t('embedding') %>
|
||||||
|
|||||||
@@ -227,39 +227,39 @@
|
|||||||
</div>
|
</div>
|
||||||
<% if submitter&.name.present? %>
|
<% if submitter&.name.present? %>
|
||||||
<div class="flex items-center space-x-1 mt-1">
|
<div class="flex items-center space-x-1 mt-1">
|
||||||
<%= svg_icon('user', class: 'w-5 h-5') %>
|
<%= svg_icon('user', class: 'w-5 h-5 shrink-0') %>
|
||||||
<span>
|
<span class="truncate">
|
||||||
<%= submitter&.name %>
|
<%= submitter&.name %>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
<% if submitter&.email.present? %>
|
<% if submitter&.email.present? %>
|
||||||
<div class="flex items-center space-x-1 mt-1">
|
<div class="flex items-center space-x-1 mt-1">
|
||||||
<%= svg_icon('mail', class: 'w-5 h-5') %>
|
<%= svg_icon('mail', class: 'w-5 h-5 shrink-0') %>
|
||||||
<span>
|
<span class="truncate">
|
||||||
<%= submitter.email || 'N/A' %>
|
<%= submitter.email || 'N/A' %>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
<% if submitter&.phone.present? %>
|
<% if submitter&.phone.present? %>
|
||||||
<div class="flex items-center space-x-1 mt-1">
|
<div class="flex items-center space-x-1 mt-1">
|
||||||
<%= svg_icon('phone', class: 'w-5 h-5') %>
|
<%= svg_icon('phone', class: 'w-5 h-5 shrink-0') %>
|
||||||
<span>
|
<span class="truncate">
|
||||||
<%= submitter.phone %>
|
<%= submitter.phone %>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
<div class="flex items-center space-x-1 mt-1">
|
<div class="flex items-center space-x-1 mt-1">
|
||||||
<% if submitter&.viewer? %>
|
<% if submitter&.viewer? %>
|
||||||
<%= svg_icon(submitter.opened_at? ? 'file_check' : 'file_unknown', class: 'w-5 h-5') %>
|
<%= svg_icon(submitter.opened_at? ? 'file_check' : 'file_unknown', class: 'w-5 h-5 shrink-0') %>
|
||||||
<% elsif submitter && !submitter.completed_at? && @submission.completed_at? %>
|
<% elsif submitter && !submitter.completed_at? && @submission.completed_at? %>
|
||||||
<%= svg_icon('writing_off', class: 'w-5 h-5') %>
|
<%= svg_icon('writing_off', class: 'w-5 h-5 shrink-0') %>
|
||||||
<% elsif @submission.expire_at? && submitter && !submitter.completed_at? %>
|
<% elsif @submission.expire_at? && submitter && !submitter.completed_at? %>
|
||||||
<%= svg_icon('clock_exclamation', class: 'w-5 h-5') %>
|
<%= svg_icon('clock_exclamation', class: 'w-5 h-5 shrink-0') %>
|
||||||
<% else %>
|
<% else %>
|
||||||
<%= svg_icon('writing', class: 'w-5 h-5') %>
|
<%= svg_icon('writing', class: 'w-5 h-5 shrink-0') %>
|
||||||
<% end %>
|
<% end %>
|
||||||
<span>
|
<span class="truncate">
|
||||||
<% if submitter&.declined_at? %>
|
<% if submitter&.declined_at? %>
|
||||||
<%= t('declined_on_time', time: l(submitter.declined_at.in_time_zone(@submission.account.timezone), format: :short, locale: @submission.account.locale)) %>
|
<%= t('declined_on_time', time: l(submitter.declined_at.in_time_zone(@submission.account.timezone), format: :short, locale: @submission.account.locale)) %>
|
||||||
<% elsif submitter&.viewer? %>
|
<% elsif submitter&.viewer? %>
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<input id="file_dropzone_input" name="files[]" class="hidden" data-action="change:file-dropzone#onSelectFiles" data-target="file-dropzone.input" type="file" accept="image/*, application/pdf, application/zip, application/json<%= ", #{Templates::CreateAttachments::DOCUMENT_EXTENSIONS.join(', ')}" if Docuseal.advanced_formats? %>" multiple>
|
<input id="file_dropzone_input" name="files[]" class="hidden" data-action="change:file-dropzone#onSelectFiles" data-target="file-dropzone.input" type="file" accept="image/*, application/pdf, application/zip, application/json, <%= Templates::CreateAttachments.document_extensions.join(', ') %>" multiple>
|
||||||
</div>
|
</div>
|
||||||
</label>
|
</label>
|
||||||
</file-dropzone>
|
</file-dropzone>
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
</label>
|
</label>
|
||||||
<input type="hidden" name="form_id" value="<%= form_id %>">
|
<input type="hidden" name="form_id" value="<%= form_id %>">
|
||||||
<convert-upload>
|
<convert-upload>
|
||||||
<input id="upload_template" name="files[]" class="hidden" type="file" accept="image/*, application/pdf, application/zip, application/json<%= ", #{Templates::CreateAttachments::DOCUMENT_EXTENSIONS.join(', ')}" if Docuseal.advanced_formats? %>" multiple>
|
<input id="upload_template" name="files[]" class="hidden" type="file" accept="image/*, application/pdf, application/zip, application/json, <%= Templates::CreateAttachments.document_extensions.join(', ') %>" multiple>
|
||||||
</convert-upload>
|
</convert-upload>
|
||||||
<input hidden name="folder_name" value="<%= local_assigns[:folder_name] %>">
|
<input hidden name="folder_name" value="<%= local_assigns[:folder_name] %>">
|
||||||
<% end %>
|
<% end %>
|
||||||
@@ -10,4 +10,4 @@
|
|||||||
<% account_configs = current_account.account_configs.where(key: [AccountConfig::TEMPLATE_CUSTOM_FIELDS_KEY, AccountConfig::TEMPLATE_DATE_FORMATS_KEY]).to_a %>
|
<% account_configs = current_account.account_configs.where(key: [AccountConfig::TEMPLATE_CUSTOM_FIELDS_KEY, AccountConfig::TEMPLATE_DATE_FORMATS_KEY]).to_a %>
|
||||||
<% custom_fields = account_configs.find { |e| e.key == AccountConfig::TEMPLATE_CUSTOM_FIELDS_KEY }&.value || [] %>
|
<% custom_fields = account_configs.find { |e| e.key == AccountConfig::TEMPLATE_CUSTOM_FIELDS_KEY }&.value || [] %>
|
||||||
<% date_formats = account_configs.find { |e| e.key == AccountConfig::TEMPLATE_DATE_FORMATS_KEY }&.value || [] %>
|
<% date_formats = account_configs.find { |e| e.key == AccountConfig::TEMPLATE_DATE_FORMATS_KEY }&.value || [] %>
|
||||||
<template-builder data-native-platform="<%= turbo_native_ios? ? 'ios' : (turbo_native_android? ? 'android' : '') %>" class="grid" data-template="<%= @template_data.to_json %>" data-custom-fields="<%= custom_fields.to_json %>" data-date-formats="<%= date_formats.to_json %>" data-with-sign-yourself-button="<%= !@template.archived_at? %>" data-with-fields-detection="true" data-with-send-button="<%= !@template.archived_at? && can?(:create, @template.submissions.new(account: current_account)) %>" data-with-revisions-menu="<%= @template.template_versions.exists? %>" data-locale="<%= I18n.locale %>" data-show-tour-start-form="<%= @show_tour_start_form %>"></template-builder>
|
<template-builder data-native-platform="<%= turbo_native_ios? ? 'ios' : (turbo_native_android? ? 'android' : '') %>" data-accept-file-types="image/*, application/pdf, application/zip, application/json, <%= Templates::CreateAttachments.document_extensions.join(', ') %>" class="grid" data-template="<%= @template_data.to_json %>" data-custom-fields="<%= custom_fields.to_json %>" data-date-formats="<%= date_formats.to_json %>" data-with-sign-yourself-button="<%= !@template.archived_at? %>" data-with-fields-detection="true" data-with-send-button="<%= !@template.archived_at? && can?(:create, @template.submissions.new(account: current_account)) %>" data-with-revisions-menu="<%= @template.template_versions.exists? %>" data-locale="<%= I18n.locale %>" data-show-tour-start-form="<%= @show_tour_start_form %>"></template-builder>
|
||||||
@@ -26,7 +26,7 @@
|
|||||||
<%= t('share_template_with_test_mode') %>
|
<%= t('share_template_with_test_mode') %>
|
||||||
</span>
|
</span>
|
||||||
<submit-form data-on="change">
|
<submit-form data-on="change">
|
||||||
<%= f.check_box :value, class: 'toggle', checked: @template.template_sharings.exists?(account_id: true_user.account.testing_accounts) %>
|
<%= f.check_box :value, class: 'toggle', checked: @template.template_sharings.exists?(account_id: (can?(:manage, :tenants_test) ? current_account : true_user.account).testing_accounts) %>
|
||||||
</submit-form>
|
</submit-form>
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|||||||
@@ -127,4 +127,4 @@
|
|||||||
<%= render 'shared/pagination', pagy: @related_submissions_pagy, items_name: 'submissions', next_page_path: submissions_path(q: params[:q]) %>
|
<%= render 'shared/pagination', pagy: @related_submissions_pagy, items_name: 'submissions', next_page_path: submissions_path(q: params[:q]) %>
|
||||||
<% end %>
|
<% end %>
|
||||||
<% end %>
|
<% end %>
|
||||||
<%= render 'shared/review_form' %>
|
<%= render 'shared/review_form' unless turbo_native_app? %>
|
||||||
@@ -194,7 +194,7 @@
|
|||||||
<%= t('share_template_with_test_mode') %>
|
<%= t('share_template_with_test_mode') %>
|
||||||
</span>
|
</span>
|
||||||
<submit-form data-on="change" class="flex">
|
<submit-form data-on="change" class="flex">
|
||||||
<%= f.check_box :value, class: 'toggle', checked: @template.template_sharings.exists?(account_id: true_user.account.testing_accounts) %>
|
<%= f.check_box :value, class: 'toggle', checked: @template.template_sharings.exists?(account_id: (can?(:manage, :tenants_test) ? current_account : true_user.account).testing_accounts) %>
|
||||||
</submit-form>
|
</submit-form>
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|||||||
@@ -9,3 +9,4 @@ autoload :OnnxRuntime, 'onnxruntime'
|
|||||||
autoload :RQRCode, 'rqrcode'
|
autoload :RQRCode, 'rqrcode'
|
||||||
autoload :ArabicLetterConnector, 'arabic-letter-connector/logic'
|
autoload :ArabicLetterConnector, 'arabic-letter-connector/logic'
|
||||||
autoload :JWT, 'jwt'
|
autoload :JWT, 'jwt'
|
||||||
|
autoload :WordCraft, 'wordcraft'
|
||||||
@@ -267,7 +267,10 @@ module Submissions
|
|||||||
|
|
||||||
is_id_verified = submission_events.any?(&:complete_verification?)
|
is_id_verified = submission_events.any?(&:complete_verification?)
|
||||||
|
|
||||||
is_kba_passed = submission_events.any?(&:complete_kba?)
|
complete_kba_event = submission_events.find(&:complete_kba?) || SubmissionEvent.new
|
||||||
|
|
||||||
|
kba_answers = complete_kba_event.data['answers']
|
||||||
|
kba_score = " (#{kba_answers['correct']}/#{kba_answers['asked']})" if kba_answers
|
||||||
|
|
||||||
info_rows = [
|
info_rows = [
|
||||||
[
|
[
|
||||||
@@ -297,8 +300,8 @@ module Submissions
|
|||||||
is_id_verified && {
|
is_id_verified && {
|
||||||
text: "#{I18n.t('identity_verification')}: #{I18n.t('verified')}\n"
|
text: "#{I18n.t('identity_verification')}: #{I18n.t('verified')}\n"
|
||||||
},
|
},
|
||||||
is_kba_passed && {
|
complete_kba_event.persisted? && {
|
||||||
text: "#{I18n.t('knowledge_based_authentication')}: #{I18n.t('passed')}\n"
|
text: "#{I18n.t('knowledge_based_authentication')}: #{I18n.t('passed')}#{kba_score}\n"
|
||||||
},
|
},
|
||||||
completed_event.data['ip'] && { text: "IP: #{completed_event.data['ip']}\n" },
|
completed_event.data['ip'] && { text: "IP: #{completed_event.data['ip']}\n" },
|
||||||
completed_event.data['sid'] && { text: "#{I18n.t('session_id')}: #{completed_event.data['sid']}\n" },
|
completed_event.data['sid'] && { text: "#{I18n.t('session_id')}: #{completed_event.data['sid']}\n" },
|
||||||
|
|||||||
@@ -602,6 +602,8 @@ module Submissions
|
|||||||
cell_valign = field.dig('preferences', 'valign').to_s.presence_in(TEXT_VALIGNS) || 'center'
|
cell_valign = field.dig('preferences', 'valign').to_s.presence_in(TEXT_VALIGNS) || 'center'
|
||||||
cell_layouter = cell_layouters[cell_valign]
|
cell_layouter = cell_layouters[cell_valign]
|
||||||
|
|
||||||
|
value = value.to_s
|
||||||
|
|
||||||
if (mask = field.dig('preferences', 'mask').presence)
|
if (mask = field.dig('preferences', 'mask').presence)
|
||||||
value = TextUtils.mask_value(value, mask)
|
value = TextUtils.mask_value(value, mask)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ module Templates
|
|||||||
ZIP_CONTENT_TYPE = 'application/zip'
|
ZIP_CONTENT_TYPE = 'application/zip'
|
||||||
X_ZIP_CONTENT_TYPE = 'application/x-zip-compressed'
|
X_ZIP_CONTENT_TYPE = 'application/x-zip-compressed'
|
||||||
JSON_CONTENT_TYPE = 'application/json'
|
JSON_CONTENT_TYPE = 'application/json'
|
||||||
|
WORD_EXTENSIONS = %w[.docx .doc .rtf].freeze
|
||||||
DOCUMENT_EXTENSIONS = %w[.docx .doc .xlsx .xls .odt .rtf].freeze
|
DOCUMENT_EXTENSIONS = %w[.docx .doc .xlsx .xls .odt .rtf].freeze
|
||||||
|
|
||||||
DOCUMENT_CONTENT_TYPES = %w[
|
DOCUMENT_CONTENT_TYPES = %w[
|
||||||
@@ -134,7 +135,27 @@ module Templates
|
|||||||
return [handle_pdf_or_image(template, file, file.read, params, extract_fields:), []]
|
return [handle_pdf_or_image(template, file, file.read, params, extract_fields:), []]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if File.extname(file.original_filename.to_s).downcase.in?(WORD_EXTENSIONS)
|
||||||
|
return [handle_word_document(template, file, params), []]
|
||||||
|
end
|
||||||
|
|
||||||
raise InvalidFileType, "#{file.content_type}/#{dynamic}"
|
raise InvalidFileType, "#{file.content_type}/#{dynamic}"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def handle_word_document(template, file, params)
|
||||||
|
pdf = WordCraft.open_buffer(file, &:to_pdf)
|
||||||
|
|
||||||
|
pdf_file = ActionDispatch::Http::UploadedFile.new(
|
||||||
|
tempfile: StringIO.new(pdf),
|
||||||
|
filename: "#{File.basename(file.original_filename, '.*')}.pdf",
|
||||||
|
type: PDF_CONTENT_TYPE
|
||||||
|
)
|
||||||
|
|
||||||
|
handle_pdf_or_image(template, pdf_file, pdf, params)
|
||||||
|
end
|
||||||
|
|
||||||
|
def document_extensions
|
||||||
|
Docuseal.advanced_formats? ? DOCUMENT_EXTENSIONS : WORD_EXTENSIONS
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
Reference in new issue
Block a user