pull/627/head^2
ChapsJust 2 months ago
parent 3eb1142afe
commit 121a722be7

1
.gitattributes vendored

@ -1 +1,2 @@
*.html linguist-detectable=false
bin/* text eol=lf

@ -40,7 +40,7 @@ COPY ./tailwind.application.config.js ./tailwind.application.config.js
COPY ./app/javascript ./app/javascript
COPY ./app/views ./app/views
RUN echo "gem 'shakapacker'" > Gemfile && ./bin/shakapacker
RUN echo "gem 'shakapacker'" > Gemfile && sed -i 's/\r$//' bin/shakapacker && ./bin/shakapacker
FROM ruby:4.0.1-alpine AS app

@ -39,7 +39,7 @@ class ApplicationController < ActionController::Base
rescue_from CanCan::AccessDenied do |e|
Rollbar.warning(e) if defined?(Rollbar)
redirect_to root_path, alert: e.message
redirect_to root_path, alert: I18n.t('unauthorized.default', locale: current_account&.locale)
end
end
@ -67,12 +67,13 @@ class ApplicationController < ActionController::Base
private
def with_locale(&)
return yield unless current_account
locale = if current_account
(params[:lang].presence if Rails.env.development?) || current_account.locale
else
request.env['HTTP_ACCEPT_LANGUAGE'].to_s[BROWSER_LOCALE_REGEXP].to_s.split('-').first.presence
end
locale = params[:lang].presence if Rails.env.development?
locale ||= current_account.locale
I18n.with_locale(locale, &)
I18n.with_locale(locale || I18n.default_locale, &)
end
def with_browser_locale(&)

@ -119,7 +119,7 @@ export default {
docId: this.eidEasyData.doc_id,
language: this.locale,
countryCode: this.countryCode,
sandbox: ['demo.docuseal.tech'].includes(location.host),
sandbox: false,
enabledMethods: {
signature: this.eidEasyData.available_methods
},

@ -1,20 +1,13 @@
<template>
<svg
height="40"
width="40"
style="color: #e0753f"
viewBox="0 0 180 180"
width="37"
viewBox="0 0 819 897"
xmlns="http://www.w3.org/2000/svg"
>
<path
fill="currentColor"
d="M 178.224 72.09 c -0.296 -1.463 -0.627 -2.919 -0.996 -4.364 -0.293 -1.151 -0.616 -2.293 -0.956 -3.433 -0.301 -1.008 -0.612 -2.014 -0.95 -3.012 -0.531 -1.578 -1.113 -3.142 -1.735 -4.694 -0.216 -0.54 -0.433 -1.082 -0.661 -1.618 -0.195 -0.462 -0.399 -0.917 -0.601 -1.375 -0.262 -0.591 -0.53 -1.177 -0.804 -1.762 -0.074 -0.159 -0.151 -0.315 -0.226 -0.474 -0.209 -0.441 -0.422 -0.881 -0.638 -1.318 -0.076 -0.154 -0.153 -0.306 -0.229 -0.459 -0.236 -0.471 -0.477 -0.939 -0.721 -1.406 -0.053 -0.101 -0.105 -0.201 -0.158 -0.302 -1.143 -2.16 -2.367 -4.269 -3.68 -6.322 -0.116 -0.181 -0.237 -0.359 -0.355 -0.539 -0.094 -0.144 -0.189 -0.288 -0.284 -0.432 -0.284 -0.431 -0.57 -0.861 -0.862 -1.287 -0.112 -0.164 -0.225 -0.326 -0.338 -0.489 -0.193 -0.279 -0.382 -0.56 -0.579 -0.836 -0.089 -0.125 -0.182 -0.249 -0.273 -0.374 -0.13 -0.182 -0.264 -0.362 -0.395 -0.542 -0.277 -0.38 -0.556 -0.76 -0.838 -1.135 -0.15 -0.199 -0.303 -0.395 -0.454 -0.593 -0.21 -0.274 -0.417 -0.552 -0.63 -0.823 -0.055 -0.069 -0.111 -0.136 -0.166 -0.205 -0.482 -0.61 -0.971 -1.216 -1.47 -1.814 -0.129 -0.155 -0.262 -0.306 -0.392 -0.461 -0.402 -0.476 -0.808 -0.95 -1.22 -1.417 -0.186 -0.212 -0.375 -0.422 -0.563 -0.631 -0.384 -0.428 -0.773 -0.854 -1.167 -1.276 -0.176 -0.189 -0.351 -0.379 -0.529 -0.567 -0.564 -0.595 -1.134 -1.186 -1.716 -1.768 -1.091 -1.091 -2.207 -2.15 -3.346 -3.178 -1.016 -0.919 -2.05 -1.815 -3.103 -2.684 -0.772 -0.636 -1.557 -1.255 -2.348 -1.864 -3.465 -2.67 -7.112 -5.075 -10.927 -7.209 -2.869 -1.604 -5.83 -3.06 -8.883 -4.351 -2.443 -1.033 -4.922 -1.948 -7.428 -2.756 -8.879 -2.863 -18.13 -4.318 -27.605 -4.318 -3.19 0 -6.354 0.169 -9.488 0.496 -4.036 0.421 -8.019 1.114 -11.94 2.073 -1.732 0.423 -3.452 0.892 -5.157 1.42 -2.856 0.883 -5.673 1.912 -8.447 3.085 -2.645 1.118 -5.222 2.357 -7.729 3.711 -2.574 1.39 -5.073 2.901 -7.494 4.533 -1.195 0.805 -2.37 1.64 -3.527 2.503 -1.156 0.864 -2.292 1.756 -3.408 2.676 -0.553 0.456 -1.1 0.919 -1.643 1.389 -1.649 1.427 -3.252 2.92 -4.806 4.473 -2.582 2.582 -4.991 5.299 -7.222 8.138 -0.892 1.135 -1.756 2.292 -2.59 3.467 -0.417 0.588 -0.827 1.18 -1.23 1.778 -0.403 0.597 -0.798 1.199 -1.186 1.806 -0.388 0.607 -0.769 1.218 -1.143 1.835 -2.241 3.697 -4.216 7.562 -5.916 11.582 -1.095 2.589 -2.059 5.217 -2.901 7.877 -0.153 0.482 -0.3 0.965 -0.444 1.449 -0.339 1.14 -0.663 2.282 -0.956 3.433 -0.369 1.446 -0.7 2.901 -0.996 4.364 -1.034 5.121 -1.618 10.343 -1.749 15.637 -0.018 0.757 -0.028 1.514 -0.028 2.274 0 1.123 0.02 2.244 0.062 3.361 0.285 7.82 1.568 15.475 3.825 22.879 0.044 0.147 0.088 0.295 0.133 0.441 0.877 2.823 1.894 5.608 3.054 8.35 0.85 2.009 1.769 3.98 2.755 5.912 0.539 1.057 1.105 2.099 1.685 3.132 4.013 7.142 8.98 13.698 14.846 19.564 7.713 7.713 16.611 13.878 26.477 18.352 0.705 0.32 1.415 0.632 2.131 0.935 2.081 0.88 4.185 1.679 6.313 2.396 9.217 3.106 18.85 4.677 28.719 4.677 8.031 0 15.902 -1.047 23.522 -3.107 0.633 -0.172 1.266 -0.35 1.895 -0.535 0.757 -0.222 1.509 -0.456 2.26 -0.698 0.717 -0.232 1.431 -0.474 2.145 -0.723 1.752 -0.616 3.49 -1.281 5.211 -2.009 0.755 -0.319 1.503 -0.651 2.247 -0.989 1.237 -0.563 2.459 -1.15 3.664 -1.766 0.644 -0.328 1.283 -0.665 1.917 -1.009 1.654 -0.896 3.274 -1.848 4.865 -2.844 5.736 -3.591 11.06 -7.827 15.912 -12.679 0.775 -0.775 1.534 -1.562 2.278 -2.36 5.204 -5.59 9.636 -11.754 13.246 -18.417 0.343 -0.634 0.68 -1.274 1.009 -1.917 0.482 -0.944 0.943 -1.9 1.392 -2.863 0.471 -1.007 0.928 -2.021 1.364 -3.049 1.22 -2.886 2.281 -5.82 3.187 -8.793 0.559 -1.833 1.056 -3.68 1.494 -5.542 0.108 -0.458 0.211 -0.916 0.312 -1.376 0.194 -0.883 0.373 -1.77 0.539 -2.659 1.02 -5.455 1.542 -11.02 1.542 -16.663 0 -6.074 -0.595 -12.058 -1.776 -17.911 z m -161.733 19.614 c -1.118 -56.662 44.604 -74.877 60.998 -67.647 2.187 0.965 4.732 2.431 7.042 2.96 5.295 1.213 13.432 -3.113 13.521 6.273 0.078 8.156 -3.389 13.108 -10.797 16.177 -7.539 3.124 -14.777 9.181 -19.95 15.493 -21.487 26.216 -31.231 68.556 -7.565 94.296 -13.679 -5.545 -42.418 -25.467 -43.248 -67.552 z m 91.109 72.619 c -0.053 0.008 -4.171 0.775 -4.171 0.775 0 0 -15.862 -22.957 -23.509 -21.719 11.291 16.04 12.649 22.625 12.649 22.625 -0.053 0.001 -0.107 0.001 -0.161 0.003 -51.831 2.131 -42.785 -64.026 -28.246 -86.502 -1.555 13.073 8.878 39.992 39.034 44.1 9.495 1.293 32.302 -3.275 41.015 -11.38 0.098 1.825 0.163 3.85 0.159 6.013 -0.046 23.538 -13.47 42.743 -36.77 46.085 z m 30.575 -15.708 c 9.647 -9.263 12.869 -27.779 9.103 -44.137 -4.608 -20.011 -28.861 -32.383 -40.744 -35.564 5.766 -8.089 27.908 -14.274 39.567 5.363 -5.172 -10.519 -13.556 -23.023 -1.732 -33.128 12.411 13.329 19.411 29.94 20.161 48.7 0.75 18.753 -6.64 41.768 -26.355 58.765 z"
/>
<circle
fill="currentColor"
cx="71.927"
cy="32.004"
r="2.829"
fill="rgb(77,138,225)"
d="M 441.00 718.00 L 441.00 831.00 L 62.07 831.00 L 62.29 772.25 L 62.50 713.50 L 85.25 713.23 L 108.00 712.96 L 108.00 186.00 L 63.26 186.00 L 62.64 182.25 C61.82,177.29 61.82,78.61 62.64,72.64 L 63.27 68.00 L 226.00 68.00 L 226.25 392.75 L 226.50 717.50 L 248.93 717.81 C261.27,717.99 272.40,717.86 273.68,717.54 L 276.00 716.96 L 276.00 68.00 L 441.00 68.00 L 441.00 180.74 L 436.84 181.41 C434.55,181.78 424.53,182.04 414.59,182.00 C404.64,181.95 395.94,181.94 395.25,181.96 C394.26,181.99 394.00,202.90 394.00,283.07 L 394.00 384.15 L 450.25 383.73 C511.08,383.28 511.26,383.26 528.95,377.36 C562.24,366.27 587.29,341.03 595.99,309.83 C602.17,287.70 600.18,258.96 591.08,238.67 C577.56,208.56 547.01,189.15 504.20,183.49 C497.98,182.67 490.90,182.00 488.45,182.00 L 484.00 182.00 L 484.00 68.00 L 497.85 68.00 C529.54,68.00 565.68,72.85 590.87,80.49 C661.51,101.91 703.26,148.71 714.44,219.00 C720.04,254.19 717.89,290.64 708.58,318.48 C700.93,341.33 688.25,361.76 671.00,379.00 C658.27,391.72 650.19,397.88 634.74,406.64 C628.27,410.31 623.09,413.42 623.24,413.57 C623.38,413.71 627.10,415.25 631.50,417.00 C663.91,429.86 696.53,454.01 716.42,479.89 C744.77,516.76 757.99,557.53 757.99,608.00 C757.99,635.30 753.16,668.04 746.04,689.00 C740.09,706.53 735.88,715.82 727.50,729.91 C701.08,774.35 654.97,805.82 594.20,820.90 C567.64,827.49 547.18,829.92 511.75,830.68 L 484.00 831.29 L 484.00 718.27 L 500.75 717.58 C509.96,717.20 521.55,716.42 526.50,715.86 C592.96,708.22 632.14,672.78 637.21,615.70 C640.68,576.72 626.22,544.52 596.05,524.03 C577.26,511.27 550.10,502.25 520.93,499.07 C513.92,498.31 428.28,497.57 395.25,497.98 C394.26,498.00 394.00,520.68 394.00,608.00 L 394.00 718.00 Z"
/>
</svg>
</template>

@ -48,7 +48,9 @@
#
class User < ApplicationRecord
ROLES = [
ADMIN_ROLE = 'admin'
ADMIN_ROLE = 'admin',
GESTIONNAIRE_ROLE = 'gestionnaire',
USER_ROLE = 'user'
].freeze
EMAIL_REGEXP = /[^@;,<>\s]+@[^@;,<>\s]+/

@ -1,3 +1,4 @@
<% return unless Whitelabel.show_pro_upsells? %>
<tr scope="row" class="group">
<td class="flex items-center space-x-1">
<%= svg_icon('discount_check_filled', class: 'w-6 h-6 text-green-500') %>

@ -21,7 +21,7 @@
<% end %>
<%= stylesheet_pack_tag 'application', media: 'all' %>
</head>
<body>
<body class="min-h-screen">
<% if params[:modal].present? %>
<% url_params = Rails.application.routes.recognize_path(params[:modal], method: :get) %>
<% if url_params[:action] == 'new' %>

@ -1,3 +1,4 @@
<% return unless Whitelabel.show_pro_upsells? %>
<div class="alert my-4">
<%= svg_icon('info_circle', class: 'w-6 h-6') %>
<div>

@ -1,3 +1,4 @@
<% return unless Whitelabel.show_pro_upsells? %>
<div class="alert my-4">
<%= svg_icon('info_circle', class: 'w-6 h-6') %>
<div>

@ -46,7 +46,7 @@
<% end %>
<%= render 'shared/settings_nav_extra' %>
<% if Docuseal.demo? || !Docuseal.multitenant? %>
<% if can?(:read, AccessToken) %>
<% if can?(:read, AccessToken) && current_user.role != User::USER_ROLE %>
<li>
<%= link_to 'API', settings_api_index_path, class: 'text-base hover:bg-base-300' %>
</li>

@ -1,3 +1,4 @@
<% return unless Whitelabel.show_pro_upsells? %>
<div class="alert">
<%= svg_icon('info_circle', class: 'w-6 h-6') %>
<div>

@ -1,3 +1,4 @@
<% return unless Whitelabel.show_pro_upsells? %>
<div class="alert">
<%= svg_icon('info_circle', class: 'w-6 h-6') %>
<div>

@ -1,3 +1,4 @@
<% return unless Whitelabel.show_pro_upsells? %>
<div class="alert">
<%= svg_icon('info_circle', class: 'w-6 h-6') %>
<div>

@ -1,3 +1,4 @@
<% return unless Whitelabel.show_pro_upsells? %>
<div class="mt-2 mb-1">
<div class="tooltip w-full" data-tip="<%= t('unlock_with_docuseal_pro') %>">
<%= link_to submitter.sent_at? ? t('re_send_sms') : t('send_sms'), Docuseal.multitenant? ? console_redirect_index_path(redir: "#{Docuseal::CONSOLE_URL}/plans") : "#{Docuseal::CLOUD_URL}/sign_up?#{{ redir: "#{Docuseal::CONSOLE_URL}/on_premises" }.to_query}", class: 'btn btn-sm btn-primary text-gray-400 w-full' %>

@ -1,3 +1,4 @@
<% return unless Whitelabel.show_pro_upsells? %>
<div class="alert">
<%= svg_icon('info_circle', class: 'w-6 h-6') %>
<div>

@ -1,9 +1,9 @@
<div class="form-control">
<%= f.label :role, class: 'label' %>
<%= f.select :role, nil, {}, class: 'base-select' do %>
<option value="admin"><%= t('admin') %></option>
<option value="editor" disabled><%= t('editor') %></option>
<option value="viewer" disabled><%= t('viewer') %></option>
<option value="admin"><%= t('role_admin') %></option>
<option value="gestionnaire"><%= t('role_gestionnaire') %></option>
<option value="user"><%= t('role_user') %></option>
<% end %>
<% if Docuseal.multitenant? %>
<label class="label">
@ -12,9 +12,11 @@
</span>
</label>
<% end %>
<a class="text-sm mt-3 px-4 py-2 bg-base-300 rounded-full block" target="_blank" href="<%= Docuseal.multitenant? ? console_redirect_index_path(redir: "#{Docuseal::CONSOLE_URL}/plans") : "#{Docuseal::CLOUD_URL}/sign_up?#{{ redir: "#{Docuseal::CONSOLE_URL}/on_premises" }.to_query}" %>">
<%= svg_icon('info_circle', class: 'w-4 h-4 inline align-text-bottom') %>
<%= t('unlock_more_user_roles_with_docuseal_pro') %>
<span class="link font-medium"><%= t('learn_more') %></span>
</a>
<% if Whitelabel.show_pro_upsells? %>
<a class="text-sm mt-3 px-4 py-2 bg-base-300 rounded-full block" target="_blank" href="<%= Docuseal.multitenant? ? console_redirect_index_path(redir: "#{Docuseal::CONSOLE_URL}/plans") : "#{Docuseal::CLOUD_URL}/sign_up?#{{ redir: "#{Docuseal::CONSOLE_URL}/on_premises" }.to_query}" %>">
<%= svg_icon('info_circle', class: 'w-4 h-4 inline align-text-bottom') %>
<%= t('unlock_more_user_roles_with_docuseal_pro') %>
<span class="link font-medium"><%= t('learn_more') %></span>
</a>
<% end %>
</div>

@ -10,7 +10,7 @@
# Languages: English (en) + French (fr)
# =============================================================================
en:
en: &en_wl
docuseal_trusted_signature: "Intébec Trusted Signature"
sent_with_docuseal_pro_html: 'Sent with <a href="%{product_url}">Intébec Pro</a>'
show_send_with_docuseal_pro_attribution_in_emails_html: 'Show "Sent with <span class="link">Intébec Pro</span>" attribution in emails'
@ -28,13 +28,21 @@ en:
your_pro_plan_has_been_suspended_due_to_unpaid_invoices_you_can_update_your_payment_details_to_settle_the_invoice_and_continue_using_docuseal_or_cancel_your_subscription: "Your Pro Plan has been suspended due to unpaid invoices. You can update your payment details to settle the invoice and continue using Intébec or cancel your subscription."
this_submission_has_multiple_signers_which_prevents_the_use_of_a_sharing_link_html: 'This submission has multiple signers, which prevents the use of a sharing link as it''s unclear which signer is responsible for specific fields. To resolve this, follow this <a href="https://intebec.ca/resources/pre-filling-recipients" class="link font-bold" rel="noopener noreferrer nofollow" target="_blank">guide</a> to define the default signer details.'
welcome_to_docuseal: "Welcome to Intébec"
start_a_quick_tour_to_learn_how_to_create_an_send_your_first_document: "Start a quick tour to learn how to create and send your first document with Intébec."
your_email_could_not_be_reached_this_may_happen_if_there_was_a_typo_in_your_address_or_if_your_mailbox_is_not_available_please_contact_support_email_to_log_in: "Your email could not be reached. This may happen if there was a typo in your address or if your mailbox is not available. Please contact support@intebec.ca to log in."
add_a_unique_signature_id_and_timestamp_to_each_signature_for_audit_and_traceability_purposes_along_with_the_timestamp_part_of_docuseals_21_cfr_part_11_compliance_settings: "Add a unique Signature ID and timestamp to each signature for audit and traceability purposes along with the timestamp. Part of Intébec's 21 CFR Part 11 compliance settings."
require_signer_to_provide_a_reason_for_signing_before_completing_their_signature_e_g_approvals_certifications_part_of_docuseals_21_cfr_part_11_compliance_settings: "Require signers to provide a reason for signing before completing their signature (e.g., approvals, certifications). Part of Intébec's 21 CFR Part 11 compliance settings."
role_admin: "Administrator"
role_gestionnaire: "Manager"
role_user: "User"
unauthorized:
default: "You are not authorized to access this page."
manage:
all: "You are not authorized to perform this action."
onboarding:
support_description: "You can use our self-service AI assistant or email us at support@intebec.ca if you have any questions."
fr:
fr: &fr_wl
docuseal_trusted_signature: "Signature de confiance Intébec"
sent_with_docuseal_pro_html: 'Envoyé avec <a href="%{product_url}">Intébec Pro</a>'
show_send_with_docuseal_pro_attribution_in_emails_html: 'Afficher l''attribution « Envoyé avec <span class="link">Intébec Pro</span> » dans les courriels'
@ -52,9 +60,13 @@ fr:
your_pro_plan_has_been_suspended_due_to_unpaid_invoices_you_can_update_your_payment_details_to_settle_the_invoice_and_continue_using_docuseal_or_cancel_your_subscription: "Votre plan Pro a été suspendu en raison de factures impayées. Vous pouvez mettre à jour vos informations de paiement pour régler la facture et continuer à utiliser Intébec ou annuler votre abonnement."
this_submission_has_multiple_signers_which_prevents_the_use_of_a_sharing_link_html: 'Cette soumission comporte plusieurs signataires, ce qui empêche l''utilisation d''un lien de partage car on ne sait pas quel signataire est responsable de quels champs. Pour résoudre ce problème, suivez ce <a href="https://intebec.ca/resources/pre-filling-recipients" class="link font-bold" rel="noopener noreferrer nofollow" target="_blank">guide</a> pour définir les détails du signataire par défaut.'
welcome_to_docuseal: "Bienvenue sur Intébec"
start_a_quick_tour_to_learn_how_to_create_an_send_your_first_document: "Lancez une visite rapide pour apprendre à créer et envoyer votre premier document avec Intébec."
your_email_could_not_be_reached_this_may_happen_if_there_was_a_typo_in_your_address_or_if_your_mailbox_is_not_available_please_contact_support_email_to_log_in: "Votre courriel n'a pas pu être atteint. Cela peut arriver s'il y a une faute de frappe dans votre adresse ou si votre boîte de réception n'est pas disponible. Veuillez contacter support@intebec.ca pour vous connecter."
add_a_unique_signature_id_and_timestamp_to_each_signature_for_audit_and_traceability_purposes_along_with_the_timestamp_part_of_docuseals_21_cfr_part_11_compliance_settings: "Ajoutez un identifiant de signature unique et un horodatage à chaque signature à des fins d'audit et de traçabilité, ainsi que l'horodatage. Fait partie des paramètres de conformité 21 CFR Part 11 d'Intébec."
require_signer_to_provide_a_reason_for_signing_before_completing_their_signature_e_g_approvals_certifications_part_of_docuseals_21_cfr_part_11_compliance_settings: "Exiger que le signataire fournisse une raison de signature avant de terminer sa signature (ex. : approbations, certifications). Fait partie des paramètres de conformité 21 CFR Part 11 d'Intébec."
role_admin: "Administrateur"
role_gestionnaire: "Gestionnaire"
role_user: "Utilisateur"
onboarding:
support_description: "Vous pouvez utiliser notre assistant IA en libre-service ou nous écrire à support@intebec.ca si vous avez des questions."
# -------------------------------------------------------------------------
@ -75,3 +87,42 @@ fr:
download: "Télécharger"
powered_by: "Propulsé par"
open_source_documents_software: "logiciel de signature de documents"
unauthorized:
default: "Vous n'êtes pas autorisé à accéder à cette page."
manage:
all: "Vous n'êtes pas autorisé à effectuer cette action."
devise:
sessions:
signed_in: "Connexion réussie."
signed_out: "Déconnexion réussie."
already_signed_in: "Vous êtes déjà connecté."
failure:
already_authenticated: "Vous êtes déjà connecté."
unauthenticated: "Vous devez vous connecter pour accéder à cette page."
locked: "Votre compte est verrouillé."
invalid: "Adresse courriel ou mot de passe invalide."
last_attempt: "Il vous reste une tentative avant que votre compte soit verrouillé."
not_found_in_database: "Adresse courriel ou mot de passe invalide."
timeout: "Votre session a expiré. Veuillez vous reconnecter."
inactive: "Votre compte n'est pas encore activé."
passwords:
send_instructions: "Vous recevrez un courriel avec les instructions pour réinitialiser votre mot de passe."
send_paranoid_instructions: "Si votre courriel est dans notre base de données, vous recevrez un lien pour réinitialiser votre mot de passe."
updated: "Votre mot de passe a été modifié. Vous êtes maintenant connecté."
updated_not_active: "Votre mot de passe a été modifié avec succès."
mailer:
reset_password_instructions:
subject: "Réinitialisation de votre mot de passe"
# ---------------------------------------------------------------------------
# Regional locale aliases — inherit all overrides from the base locales above
# (mirrors the YAML anchor pattern used in i18n.yml)
# ---------------------------------------------------------------------------
en-US:
<<: *en_wl
en-GB:
<<: *en_wl
fr-FR:
<<: *fr_wl

@ -175,3 +175,14 @@ features:
# Show the Discord link
show_discord_link: false
# Show "Upgrade to Pro" upsell banners/buttons throughout the app
# Set to false to hide all Pro upgrade prompts (recommended for self-hosted)
show_pro_upsells: false
# ---------------------------------------------------------------------------
# Internal / technical settings
# ---------------------------------------------------------------------------
internal:
# Domain used for auto-generated duplicate/test account emails (never real addresses)
temp_email_domain: "intebec.ca"

@ -4,6 +4,20 @@ class Ability
include CanCan::Ability
def initialize(user)
case user.role
when User::ADMIN_ROLE
admin_abilities(user)
when User::GESTIONNAIRE_ROLE
gestionnaire_abilities(user)
when User::USER_ROLE
user_abilities(user)
end
end
private
# Accès complet à tout le compte
def admin_abilities(user)
can %i[read create update], Template, Abilities::TemplateConditions.collection(user) do |template|
Abilities::TemplateConditions.entity(template, user:, ability: 'manage')
end
@ -22,4 +36,38 @@ class Ability
can :manage, AccessToken, user_id: user.id
can :manage, WebhookUrl, account_id: user.account_id
end
# Peut créer/gérer documents et envois — pas les paramètres ni les utilisateurs
def gestionnaire_abilities(user)
can %i[read create update], Template, Abilities::TemplateConditions.collection(user) do |template|
Abilities::TemplateConditions.entity(template, user:, ability: 'manage')
end
can :destroy, Template, account_id: user.account_id
can :manage, TemplateFolder, account_id: user.account_id
can :manage, TemplateSharing, template: { account_id: user.account_id }
can :manage, Submission, account_id: user.account_id
can :manage, Submitter, account_id: user.account_id
can :manage, EncryptedUserConfig, user_id: user.id
can :manage, UserConfig, user_id: user.id
can :manage, User, id: user.id
can :read, Account, id: user.account_id
can :manage, AccessToken, user_id: user.id
end
# Lecture seule — ne peut pas créer ni modifier
def user_abilities(user)
can :read, Template, Abilities::TemplateConditions.collection(user) do |template|
Abilities::TemplateConditions.entity(template, user:)
end
can :read, TemplateFolder, account_id: user.account_id
can :read, Submission, account_id: user.account_id
can :read, Submitter, account_id: user.account_id
can :manage, EncryptedUserConfig, user_id: user.id
can :manage, UserConfig, user_id: user.id
can :manage, User, id: user.id
can :read, Account, id: user.account_id
can :manage, AccessToken, user_id: user.id
end
end

@ -13,7 +13,7 @@ module Accounts
new_user.uuid = SecureRandom.uuid
new_user.account = new_account
new_user.encrypted_password = SecureRandom.hex
new_user.email = "#{SecureRandom.hex}@docuseal.com"
new_user.email = "#{SecureRandom.hex}@#{Whitelabel.temp_email_domain}"
account.templates.each do |template|
new_template = template.dup

@ -233,6 +233,18 @@ module Whitelabel
config.dig('features', 'show_discord_link') == true
end
def show_pro_upsells?
config.dig('features', 'show_pro_upsells') == true
end
# -----------------------------------------------------------------------
# Internal / technical
# -----------------------------------------------------------------------
def temp_email_domain
config.dig('internal', 'temp_email_domain') || 'example.com'
end
private
def load_config

Loading…
Cancel
Save