diff --git a/.rubocop.yml b/.rubocop.yml
index ca7a3de9a..9b9a9089a 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -11,7 +11,7 @@ inherit_mode:
- Include
AllCops:
- TargetRubyVersion: 3.1
+ TargetRubyVersion: 3.2
DisabledByDefault: true
SuggestExtensions: false
NewCops: enable
diff --git a/.ruby-version b/.ruby-version
index ef538c281..be94e6f53 100644
--- a/.ruby-version
+++ b/.ruby-version
@@ -1 +1 @@
-3.1.2
+3.2.2
diff --git a/Gemfile b/Gemfile
index e03fc22c8..74571dd79 100644
--- a/Gemfile
+++ b/Gemfile
@@ -1,5 +1,7 @@
source 'https://rubygems.org'
+gem 'rails', '~> 7.0.4' # allows update to security fixes at any time
+
gem 'aasm'
gem 'acsv'
gem 'active_link_to' # Automatically set a class on active links
@@ -67,7 +69,6 @@ gem 'premailer-rails'
gem 'puma' # Use Puma as the app server
gem 'pundit'
gem 'rack-attack'
-gem 'rails'
gem 'rails-i18n' # Locales par défaut
gem 'rake-progressbar', require: false
gem 'redcarpet'
diff --git a/Gemfile.lock b/Gemfile.lock
index 64ec024eb..5ba9cb14b 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -4,40 +4,47 @@ GEM
aasm (5.2.0)
concurrent-ruby (~> 1.0)
acsv (0.0.1)
- actioncable (6.1.7.1)
- actionpack (= 6.1.7.1)
- activesupport (= 6.1.7.1)
+ actioncable (7.0.4.3)
+ actionpack (= 7.0.4.3)
+ activesupport (= 7.0.4.3)
nio4r (~> 2.0)
websocket-driver (>= 0.6.1)
- actionmailbox (6.1.7.1)
- actionpack (= 6.1.7.1)
- activejob (= 6.1.7.1)
- activerecord (= 6.1.7.1)
- activestorage (= 6.1.7.1)
- activesupport (= 6.1.7.1)
+ actionmailbox (7.0.4.3)
+ actionpack (= 7.0.4.3)
+ activejob (= 7.0.4.3)
+ activerecord (= 7.0.4.3)
+ activestorage (= 7.0.4.3)
+ activesupport (= 7.0.4.3)
mail (>= 2.7.1)
- actionmailer (6.1.7.1)
- actionpack (= 6.1.7.1)
- actionview (= 6.1.7.1)
- activejob (= 6.1.7.1)
- activesupport (= 6.1.7.1)
+ net-imap
+ net-pop
+ net-smtp
+ actionmailer (7.0.4.3)
+ actionpack (= 7.0.4.3)
+ actionview (= 7.0.4.3)
+ activejob (= 7.0.4.3)
+ activesupport (= 7.0.4.3)
mail (~> 2.5, >= 2.5.4)
+ net-imap
+ net-pop
+ net-smtp
rails-dom-testing (~> 2.0)
- actionpack (6.1.7.1)
- actionview (= 6.1.7.1)
- activesupport (= 6.1.7.1)
- rack (~> 2.0, >= 2.0.9)
+ actionpack (7.0.4.3)
+ actionview (= 7.0.4.3)
+ activesupport (= 7.0.4.3)
+ rack (~> 2.0, >= 2.2.0)
rack-test (>= 0.6.3)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.2.0)
- actiontext (6.1.7.1)
- actionpack (= 6.1.7.1)
- activerecord (= 6.1.7.1)
- activestorage (= 6.1.7.1)
- activesupport (= 6.1.7.1)
+ actiontext (7.0.4.3)
+ actionpack (= 7.0.4.3)
+ activerecord (= 7.0.4.3)
+ activestorage (= 7.0.4.3)
+ activesupport (= 7.0.4.3)
+ globalid (>= 0.6.0)
nokogiri (>= 1.8.5)
- actionview (6.1.7.1)
- activesupport (= 6.1.7.1)
+ actionview (7.0.4.3)
+ activesupport (= 7.0.4.3)
builder (~> 3.1)
erubi (~> 1.4)
rails-dom-testing (~> 2.0)
@@ -45,9 +52,9 @@ GEM
active_link_to (1.0.5)
actionpack
addressable
- active_model_serializers (0.10.12)
- actionpack (>= 4.1, < 6.2)
- activemodel (>= 4.1, < 6.2)
+ active_model_serializers (0.10.13)
+ actionpack (>= 4.1, < 7.1)
+ activemodel (>= 4.1, < 7.1)
case_transform (>= 0.2)
jsonapi-renderer (>= 0.1.1.beta1, < 0.3)
active_storage_validations (0.9.6)
@@ -55,31 +62,30 @@ GEM
activemodel (>= 5.2.0)
activestorage (>= 5.2.0)
activesupport (>= 5.2.0)
- activejob (6.1.7.1)
- activesupport (= 6.1.7.1)
+ activejob (7.0.4.3)
+ activesupport (= 7.0.4.3)
globalid (>= 0.3.6)
- activemodel (6.1.7.1)
- activesupport (= 6.1.7.1)
- activerecord (6.1.7.1)
- activemodel (= 6.1.7.1)
- activesupport (= 6.1.7.1)
- activestorage (6.1.7.1)
- actionpack (= 6.1.7.1)
- activejob (= 6.1.7.1)
- activerecord (= 6.1.7.1)
- activesupport (= 6.1.7.1)
+ activemodel (7.0.4.3)
+ activesupport (= 7.0.4.3)
+ activerecord (7.0.4.3)
+ activemodel (= 7.0.4.3)
+ activesupport (= 7.0.4.3)
+ activestorage (7.0.4.3)
+ actionpack (= 7.0.4.3)
+ activejob (= 7.0.4.3)
+ activerecord (= 7.0.4.3)
+ activesupport (= 7.0.4.3)
marcel (~> 1.0)
mini_mime (>= 1.1.0)
activestorage-openstack (1.5.1)
fog-openstack (~> 1.0)
marcel
rails (>= 5.2.2)
- activesupport (6.1.7.1)
+ activesupport (7.0.4.3)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 1.6, < 2)
minitest (>= 5.1)
tzinfo (~> 2.0)
- zeitwerk (~> 2.3)
addressable (2.8.1)
public_suffix (>= 2.0.2, < 6.0)
administrate (0.18.0)
@@ -95,12 +101,10 @@ GEM
aes_key_wrap (1.1.0)
after_party (1.11.2)
anchored (1.1.0)
- annotate (3.1.1)
- activerecord (>= 3.2, < 7.0)
+ annotate (3.2.0)
+ activerecord (>= 3.2, < 8.0)
rake (>= 10.4, < 14.0)
ast (2.4.2)
- attr_encrypted (3.1.0)
- encryptor (~> 3.0.0)
attr_required (1.0.1)
axe-core-api (4.2.1)
capybara
@@ -119,7 +123,7 @@ GEM
axlsx_styler (1.1.0)
activesupport (>= 3.1)
caxlsx (>= 2.0.2)
- bcrypt (3.1.16)
+ bcrypt (3.1.18)
better_html (1.0.16)
actionview (>= 4.0)
activesupport (>= 4.0)
@@ -175,14 +179,15 @@ GEM
css_parser (1.9.0)
addressable
daemons (1.3.1)
- deep_cloneable (3.0.0)
- activerecord (>= 3.1.0, < 7)
+ date (3.3.3)
+ deep_cloneable (3.2.0)
+ activerecord (>= 3.1.0, < 8)
delayed_cron_job (0.7.4)
delayed_job (>= 4.1)
delayed_job (4.1.11)
activesupport (>= 3.0, < 8.0)
- delayed_job_active_record (4.1.5)
- activerecord (>= 3.0, < 6.2)
+ delayed_job_active_record (4.1.7)
+ activerecord (>= 3.0, < 8.0)
delayed_job (>= 3.0, < 5)
delayed_job_web (1.4.4)
activerecord (> 3.0.0)
@@ -191,7 +196,7 @@ GEM
sinatra (>= 1.4.4)
descendants_tracker (0.0.4)
thread_safe (~> 0.3, >= 0.3.1)
- devise (4.7.3)
+ devise (4.9.2)
bcrypt (~> 3.0)
orm_adapter (~> 0.1)
railties (>= 4.1.0)
@@ -199,16 +204,14 @@ GEM
warden (~> 1.2.3)
devise-i18n (1.9.2)
devise (>= 4.7.1)
- devise-two-factor (4.0.2)
- activesupport (< 7.1)
- attr_encrypted (>= 1.3, < 4, != 2)
+ devise-two-factor (5.0.0)
+ activesupport (~> 7.0)
devise (~> 4.0)
- railties (< 7.1)
+ railties (~> 7.0)
rotp (~> 6.0)
- diff-lcs (1.4.4)
- digest (3.1.0)
- discard (1.2.0)
- activerecord (>= 4.2, < 7)
+ diff-lcs (1.5.0)
+ discard (1.2.1)
+ activerecord (>= 4.2, < 8)
domain_name (0.5.20190701)
unf (>= 0.0.5, < 1.0.0)
dotenv (2.7.6)
@@ -224,7 +227,6 @@ GEM
concurrent-ruby (~> 1.0)
http (>= 3.0)
ruby2_keywords
- encryptor (3.0.0)
erubi (1.12.0)
et-orbi (1.2.4)
tzinfo
@@ -285,7 +287,7 @@ GEM
raabro (~> 1.4)
geo_coord (0.2.0)
geocoder (1.6.5)
- globalid (1.0.1)
+ globalid (1.1.0)
activesupport (>= 5.0)
gon (6.4.0)
actionpack (>= 3.0.20)
@@ -341,7 +343,7 @@ GEM
http-form_data (2.3.0)
http_accept_language (2.1.1)
httpclient (2.8.3)
- i18n (1.12.0)
+ i18n (1.13.0)
concurrent-ruby (~> 1.0)
i18n-tasks (1.0.9)
activesupport (>= 4.0.2)
@@ -362,7 +364,6 @@ GEM
ruby-vips (>= 2.0.17, < 3)
invisible_captcha (2.0.0)
rails (>= 5.0)
- io-wait (0.2.1)
ipaddress (0.8.3)
jquery-rails (4.5.1)
rails-dom-testing (>= 1, < 3)
@@ -412,10 +413,10 @@ GEM
railties (>= 4)
request_store (~> 1.0)
logstash-event (1.2.02)
- loofah (2.19.1)
+ loofah (2.20.0)
crass (~> 1.0.2)
nokogiri (>= 1.5.9)
- mail (2.8.0.1)
+ mail (2.8.1)
mini_mime (>= 0.1.1)
net-imap
net-pop
@@ -436,28 +437,24 @@ GEM
rake
mini_magick (4.11.0)
mini_mime (1.1.2)
- mini_portile2 (2.8.1)
+ mini_portile2 (2.8.2)
minitest (5.18.0)
msgpack (1.4.2)
multi_json (1.15.0)
multipart-post (2.1.1)
mustermann (3.0.0)
ruby2_keywords (~> 0.0.1)
- net-imap (0.2.3)
- digest
+ net-imap (0.3.4)
+ date
net-protocol
- strscan
- net-pop (0.1.1)
- digest
+ net-pop (0.1.2)
net-protocol
+ net-protocol (0.2.1)
timeout
- net-protocol (0.1.1)
- io-wait
- timeout
- net-smtp (0.2.1)
+ net-smtp (0.3.3)
net-protocol
netrc (0.11.0)
- nio4r (2.5.8)
+ nio4r (2.5.9)
nokogiri (1.14.3)
mini_portile2 (~> 2.8.0)
racc (~> 1.4)
@@ -478,7 +475,7 @@ GEM
parser (3.2.2.0)
ast (~> 2.4.1)
pdf-core (0.9.0)
- pg (1.2.3)
+ pg (1.4.6)
phonelib (0.6.53)
prawn (2.4.0)
pdf-core (~> 0.9.0)
@@ -497,12 +494,12 @@ GEM
actionmailer (>= 3)
premailer (~> 1.7, >= 1.7.9)
promise.rb (0.7.4)
- pry (0.13.1)
+ pry (0.14.2)
coderay (~> 1.1)
method_source (~> 1.0)
- pry-byebug (3.9.0)
+ pry-byebug (3.10.1)
byebug (~> 11.0)
- pry (~> 0.13.0)
+ pry (>= 0.13, < 0.15)
pry-rails (0.3.9)
pry (>= 0.10.4)
public_suffix (5.0.1)
@@ -512,7 +509,7 @@ GEM
activesupport (>= 3.0.0)
raabro (1.4.0)
racc (1.6.2)
- rack (2.2.6.4)
+ rack (2.2.7)
rack-attack (6.5.0)
rack (>= 1.0, < 3)
rack-mini-profiler (3.0.0)
@@ -532,21 +529,20 @@ GEM
rack_session_access (0.2.0)
builder (>= 2.0.0)
rack (>= 1.0.0)
- rails (6.1.7.1)
- actioncable (= 6.1.7.1)
- actionmailbox (= 6.1.7.1)
- actionmailer (= 6.1.7.1)
- actionpack (= 6.1.7.1)
- actiontext (= 6.1.7.1)
- actionview (= 6.1.7.1)
- activejob (= 6.1.7.1)
- activemodel (= 6.1.7.1)
- activerecord (= 6.1.7.1)
- activestorage (= 6.1.7.1)
- activesupport (= 6.1.7.1)
+ rails (7.0.4.3)
+ actioncable (= 7.0.4.3)
+ actionmailbox (= 7.0.4.3)
+ actionmailer (= 7.0.4.3)
+ actionpack (= 7.0.4.3)
+ actiontext (= 7.0.4.3)
+ actionview (= 7.0.4.3)
+ activejob (= 7.0.4.3)
+ activemodel (= 7.0.4.3)
+ activerecord (= 7.0.4.3)
+ activestorage (= 7.0.4.3)
+ activesupport (= 7.0.4.3)
bundler (>= 1.15.0)
- railties (= 6.1.7.1)
- sprockets-rails (>= 2.0.0)
+ railties (= 7.0.4.3)
rails-controller-testing (1.0.5)
actionpack (>= 5.0.1.rc1)
actionview (>= 5.0.1.rc1)
@@ -564,12 +560,13 @@ GEM
rails-i18n (7.0.3)
i18n (>= 0.7, < 2)
railties (>= 6.0.0, < 8)
- railties (6.1.7.1)
- actionpack (= 6.1.7.1)
- activesupport (= 6.1.7.1)
+ railties (7.0.4.3)
+ actionpack (= 7.0.4.3)
+ activesupport (= 7.0.4.3)
method_source
rake (>= 12.2)
thor (~> 1.0)
+ zeitwerk (~> 2.5)
rainbow (3.1.1)
rake (13.0.6)
rake-progressbar (0.0.5)
@@ -580,9 +577,9 @@ GEM
regexp_parser (2.8.0)
request_store (1.5.0)
rack (>= 1.4)
- responders (3.0.1)
- actionpack (>= 5.0)
- railties (>= 5.0)
+ responders (3.1.0)
+ actionpack (>= 5.2)
+ railties (>= 5.2)
rest-client (2.1.0)
http-accept (>= 1.7.0, < 2.0)
http-cookie (>= 1.0.2, < 2.0)
@@ -596,29 +593,29 @@ GEM
builder (>= 3.0)
dry-inflector (~> 0.1)
rubyzip (>= 1.0)
- rotp (6.2.0)
+ rotp (6.2.2)
rouge (3.30.0)
rqrcode (1.2.0)
chunky_png (~> 1.0)
rqrcode_core (~> 0.2)
rqrcode_core (0.2.0)
- rspec-core (3.10.1)
- rspec-support (~> 3.10.0)
- rspec-expectations (3.10.1)
+ rspec-core (3.12.2)
+ rspec-support (~> 3.12.0)
+ rspec-expectations (3.12.3)
diff-lcs (>= 1.2.0, < 2.0)
- rspec-support (~> 3.10.0)
- rspec-mocks (3.10.2)
+ rspec-support (~> 3.12.0)
+ rspec-mocks (3.12.5)
diff-lcs (>= 1.2.0, < 2.0)
- rspec-support (~> 3.10.0)
- rspec-rails (5.0.0)
- actionpack (>= 5.2)
- activesupport (>= 5.2)
- railties (>= 5.2)
- rspec-core (~> 3.10)
- rspec-expectations (~> 3.10)
- rspec-mocks (~> 3.10)
- rspec-support (~> 3.10)
- rspec-support (3.10.2)
+ rspec-support (~> 3.12.0)
+ rspec-rails (6.0.1)
+ actionpack (>= 6.1)
+ activesupport (>= 6.1)
+ railties (>= 6.1)
+ rspec-core (~> 3.11)
+ rspec-expectations (~> 3.11)
+ rspec-mocks (~> 3.11)
+ rspec-support (~> 3.11)
+ rspec-support (3.12.0)
rspec_junit_formatter (0.4.1)
rspec-core (>= 2, < 4, != 2.12.0)
rubocop (1.50.2)
@@ -718,7 +715,7 @@ GEM
axlsx_styler (>= 1.0.0, < 2)
caxlsx (>= 2.0.2, < 4)
rodf (>= 1.0.0, < 2)
- spring (2.1.1)
+ spring (4.1.1)
spring-commands-rspec (1.0.4)
spring (>= 0.9.1)
sprockets (4.2.0)
@@ -731,7 +728,6 @@ GEM
stackprof (0.2.21)
strong_migrations (0.8.0)
activerecord (>= 5.2)
- strscan (3.0.4)
swd (1.3.0)
activesupport (>= 3)
attr_required (>= 0.0.5)
@@ -744,7 +740,7 @@ GEM
thread_safe (0.3.6)
tilt (2.0.11)
timecop (0.9.4)
- timeout (0.1.1)
+ timeout (0.3.2)
ttfunk (1.7.0)
turbo-rails (1.3.2)
actionpack (>= 6.0.0)
@@ -767,8 +763,9 @@ GEM
activemodel (>= 3.0.0)
public_suffix
vcr (6.1.0)
- view_component (2.63.0)
- activesupport (>= 5.0.0, < 8.0)
+ view_component (2.82.0)
+ activesupport (>= 5.2.0, < 8.0)
+ concurrent-ruby (~> 1.0)
method_source (~> 1.0)
virtus (2.0.0)
axiom-types (~> 0.1)
@@ -815,7 +812,7 @@ GEM
nokogiri (~> 1.11)
xpath (3.2.0)
nokogiri (~> 1.8)
- zeitwerk (2.6.7)
+ zeitwerk (2.6.8)
zip_tricks (5.6.0)
zipline (1.4.1)
actionpack (>= 6.0, < 8.0)
@@ -911,7 +908,7 @@ DEPENDENCIES
rack-attack
rack-mini-profiler
rack_session_access
- rails
+ rails (~> 7.0.4)
rails-controller-testing
rails-erd
rails-i18n
diff --git a/app/components/attachment/edit_component.rb b/app/components/attachment/edit_component.rb
index d21199de5..37d6ffe62 100644
--- a/app/components/attachment/edit_component.rb
+++ b/app/components/attachment/edit_component.rb
@@ -93,7 +93,7 @@ class Attachment::EditComponent < ApplicationComponent
nil
end
- def field_name
+ def field_name(object_name = nil, method_name = nil, *method_names, multiple: false, index: nil)
helpers.field_name(@form_object_name || ActiveModel::Naming.param_key(@attached_file.record), attribute_name)
end
diff --git a/app/components/dossiers/export_component/export_component.html.haml b/app/components/dossiers/export_component/export_component.html.haml
index 12bc03cd7..d60b6b490 100644
--- a/app/components/dossiers/export_component/export_component.html.haml
+++ b/app/components/dossiers/export_component/export_component.html.haml
@@ -11,7 +11,7 @@
- elsif export.available?
- menu.with_item do
%div
- = link_to ready_link_label(export), export.file.service_url, target: "_blank", rel: "noopener", role: 'menuitem'
+ = link_to ready_link_label(export), export.file.url, target: "_blank", rel: "noopener", role: 'menuitem'
- if export.old?
= button_to download_export_path(export_format: export.format, force_export: true), refresh_button_options(export).merge(role: 'menuitem') do
.icon.retry
diff --git a/app/controllers/administrateurs/exports_controller.rb b/app/controllers/administrateurs/exports_controller.rb
index 44d953356..c8e105db1 100644
--- a/app/controllers/administrateurs/exports_controller.rb
+++ b/app/controllers/administrateurs/exports_controller.rb
@@ -15,7 +15,7 @@ module Administrateurs
end
format.html do
- redirect_to export.file.service_url
+ redirect_to url_from(export.file.url)
end
end
else
diff --git a/app/controllers/agent_connect/agent_controller.rb b/app/controllers/agent_connect/agent_controller.rb
index 18a781235..15d9f16d1 100644
--- a/app/controllers/agent_connect/agent_controller.rb
+++ b/app/controllers/agent_connect/agent_controller.rb
@@ -15,7 +15,7 @@ class AgentConnect::AgentController < ApplicationController
cookies.encrypted[STATE_COOKIE_NAME] = state
cookies.encrypted[NONCE_COOKIE_NAME] = nonce
- redirect_to uri
+ redirect_to uri, allow_other_host: true
end
def callback
diff --git a/app/controllers/france_connect/particulier_controller.rb b/app/controllers/france_connect/particulier_controller.rb
index 5817a3185..92ae65efa 100644
--- a/app/controllers/france_connect/particulier_controller.rb
+++ b/app/controllers/france_connect/particulier_controller.rb
@@ -4,7 +4,7 @@ class FranceConnect::ParticulierController < ApplicationController
def login
if FranceConnectService.enabled?
- redirect_to FranceConnectService.authorization_uri
+ redirect_to FranceConnectService.authorization_uri, allow_other_host: true
else
redirect_to new_user_session_path
end
diff --git a/app/controllers/instructeurs/dossiers_controller.rb b/app/controllers/instructeurs/dossiers_controller.rb
index 47c930eae..2f3ec8a82 100644
--- a/app/controllers/instructeurs/dossiers_controller.rb
+++ b/app/controllers/instructeurs/dossiers_controller.rb
@@ -19,7 +19,7 @@ module Instructeurs
def attestation
if dossier.attestation.pdf.attached?
- redirect_to dossier.attestation.pdf.service_url
+ redirect_to dossier.attestation.pdf.url
end
end
diff --git a/app/controllers/instructeurs/procedures_controller.rb b/app/controllers/instructeurs/procedures_controller.rb
index 5e497ddc6..74f46a0cd 100644
--- a/app/controllers/instructeurs/procedures_controller.rb
+++ b/app/controllers/instructeurs/procedures_controller.rb
@@ -175,7 +175,7 @@ module Instructeurs
end
format.html do
- redirect_to export.file.service_url
+ redirect_to url_from(export.file.url)
end
end
else
diff --git a/app/controllers/users/dossiers_controller.rb b/app/controllers/users/dossiers_controller.rb
index 022f79bee..96a67addc 100644
--- a/app/controllers/users/dossiers_controller.rb
+++ b/app/controllers/users/dossiers_controller.rb
@@ -73,7 +73,7 @@ module Users
def attestation
if dossier.attestation&.pdf&.attached?
- redirect_to dossier.attestation.pdf.service_url
+ redirect_to dossier.attestation.pdf.url
else
flash.notice = t('.no_longer_available')
redirect_to dossier_path(dossier)
diff --git a/app/controllers/users/sessions_controller.rb b/app/controllers/users/sessions_controller.rb
index 276a3e716..41cbb9254 100644
--- a/app/controllers/users/sessions_controller.rb
+++ b/app/controllers/users/sessions_controller.rb
@@ -36,7 +36,7 @@ class Users::SessionsController < Devise::SessionsController
case connected_with_france_connect
when User.loged_in_with_france_connects.fetch(:particulier)
- redirect_to FRANCE_CONNECT[:particulier][:logout_endpoint]
+ redirect_to FRANCE_CONNECT[:particulier][:logout_endpoint], allow_other_host: true
return
end
end
diff --git a/app/graphql/loaders/association.rb b/app/graphql/loaders/association.rb
index 693bc9b58..cf7257a6a 100644
--- a/app/graphql/loaders/association.rb
+++ b/app/graphql/loaders/association.rb
@@ -42,7 +42,10 @@ module Loaders
end
def preload_association(records)
- ::ActiveRecord::Associations::Preloader.new.preload(records, @association_schema)
+ ::ActiveRecord::Associations::Preloader.new(
+ records: records,
+ associations: @association_schema
+ ).call
end
def read_association(record)
diff --git a/app/graphql/types/file.rb b/app/graphql/types/file.rb
index 22a8e1afd..9845a92ee 100644
--- a/app/graphql/types/file.rb
+++ b/app/graphql/types/file.rb
@@ -11,7 +11,7 @@ module Types
if object.is_a?(Hash)
object[:url]
else
- object.service_url
+ object.url
end
end
end
diff --git a/app/helpers/form_tag_helper.rb b/app/helpers/form_tag_helper.rb
deleted file mode 100644
index 68971b454..000000000
--- a/app/helpers/form_tag_helper.rb
+++ /dev/null
@@ -1,39 +0,0 @@
-module FormTagHelper
- # from Rails 7 ActionView::Helpers::FormTagHelper
- # https://api.rubyonrails.org/classes/ActionView/Helpers/FormTagHelper.html#method-i-field_id
- # Should be removed when we upgrade to Rails 7
- def field_id(object_name, method_name, *suffixes, index: nil, namespace: nil)
- if object_name.respond_to?(:model_name)
- object_name = object_name.model_name.singular
- end
-
- sanitized_object_name = object_name.to_s.gsub(/\]\[|[^-a-zA-Z0-9:.]/, "_").delete_suffix("_")
-
- sanitized_method_name = method_name.to_s.delete_suffix("?")
-
- [
- namespace,
- sanitized_object_name.presence,
- (index unless sanitized_object_name.empty?),
- sanitized_method_name,
- *suffixes
- ].tap(&:compact!).join("_")
- end
-
- # from Rails 7 ActionView::Helpers::FormTagHelper
- # https://api.rubyonrails.org/classes/ActionView/Helpers/FormTagHelper.html#method-i-field_name
- # Should be removed when we upgrade to Rails 7
- def field_name(object_name, method_name, *method_names, multiple: false, index: nil)
- names = method_names.map! { |name| "[#{name}]" }.join
-
- # a little duplication to construct fewer strings
- case
- when object_name.blank?
- "#{method_name}#{names}#{multiple ? "[]" : ""}"
- when index
- "#{object_name}[#{index}][#{method_name}]#{names}#{multiple ? "[]" : ""}"
- else
- "#{object_name}[#{method_name}]#{names}#{multiple ? "[]" : ""}"
- end
- end
-end
diff --git a/app/jobs/cron/datagouv/export_and_publish_demarches_publiques_job.rb b/app/jobs/cron/datagouv/export_and_publish_demarches_publiques_job.rb
index 095e9b1bd..c11b8eec4 100644
--- a/app/jobs/cron/datagouv/export_and_publish_demarches_publiques_job.rb
+++ b/app/jobs/cron/datagouv/export_and_publish_demarches_publiques_job.rb
@@ -5,7 +5,7 @@ class Cron::Datagouv::ExportAndPublishDemarchesPubliquesJob < Cron::CronJob
def perform(*args)
gzip_filepath = [
'tmp/',
- Time.zone.now.to_formatted_s(:number),
+ Time.zone.now.to_fs(:number),
'-demarches.json.gz'
].join
diff --git a/app/models/champs/boolean_champ.rb b/app/models/champs/boolean_champ.rb
index 562fc3dee..5539369dc 100644
--- a/app/models/champs/boolean_champ.rb
+++ b/app/models/champs/boolean_champ.rb
@@ -17,6 +17,7 @@
# etablissement_id :integer
# external_id :string
# parent_id :bigint
+# row_id :string
# type_de_champ_id :integer
#
class Champs::BooleanChamp < Champ
diff --git a/app/models/champs/piece_justificative_champ.rb b/app/models/champs/piece_justificative_champ.rb
index 6ac018a07..f7e7a878b 100644
--- a/app/models/champs/piece_justificative_champ.rb
+++ b/app/models/champs/piece_justificative_champ.rb
@@ -55,7 +55,7 @@ class Champs::PieceJustificativeChamp < Champ
return nil if attachment.nil?
if attachment.virus_scanner.safe? || attachment.virus_scanner.pending?
- attachment.service_url
+ attachment.url
end
end
end
diff --git a/app/models/champs/rna_champ.rb b/app/models/champs/rna_champ.rb
index 781e21014..5bf7c78f0 100644
--- a/app/models/champs/rna_champ.rb
+++ b/app/models/champs/rna_champ.rb
@@ -13,12 +13,12 @@
# value_json :jsonb
# created_at :datetime
# updated_at :datetime
-# dossier_id :integer not null
+# dossier_id :integer
# etablissement_id :integer
# external_id :string
# parent_id :bigint
-# type_de_champ_id :integer not null
# row_id :string
+# type_de_champ_id :integer
#
class Champs::RNAChamp < Champ
include RNAChampAssociationFetchableConcern
diff --git a/app/models/concerns/blob_signed_id_concern.rb b/app/models/concerns/blob_signed_id_concern.rb
index 8e7d1e09b..f12b2616d 100644
--- a/app/models/concerns/blob_signed_id_concern.rb
+++ b/app/models/concerns/blob_signed_id_concern.rb
@@ -5,8 +5,8 @@ module BlobSignedIdConcern
# We override signed_id to add `expires_in` option to generated hash.
# This is a measure to ensure that we never under any circumstance
# expose permanent attachment url
- def signed_id
- ActiveStorage.verifier.generate(id, purpose: :blob_id, expires_in: Rails.application.config.active_storage.service_urls_expire_in)
+ def signed_id(**options)
+ ActiveStorage.verifier.generate(id, **options, purpose: :blob_id, expires_in: Rails.application.config.active_storage.service_urls_expire_in)
end
end
end
diff --git a/app/models/dossier.rb b/app/models/dossier.rb
index 8eb6e95b5..7ad38bb52 100644
--- a/app/models/dossier.rb
+++ b/app/models/dossier.rb
@@ -31,9 +31,9 @@
# motivation :text
# prefill_token :string
# prefilled :boolean
-# private_search_terms :text
+# private_search_terms :string
# processed_at :datetime
-# search_terms :text
+# search_terms :string
# state :string
# termine_close_to_expiration_notice_sent_at :datetime
# created_at :datetime
diff --git a/app/models/export.rb b/app/models/export.rb
index fa8c6910e..d9f3b4c8d 100644
--- a/app/models/export.rb
+++ b/app/models/export.rb
@@ -86,7 +86,7 @@ class Export < ApplicationRecord
def flash_message
if available?
- "L’export au format \"#{format}\" est prêt. Vous pouvez le télécharger"
+ "L’export au format \"#{format}\" est prêt. Vous pouvez le télécharger"
else
"Nous générons cet export. Veuillez revenir dans quelques minutes pour le télécharger."
end
diff --git a/app/models/procedure.rb b/app/models/procedure.rb
index 019c0cd09..b40c8080f 100644
--- a/app/models/procedure.rb
+++ b/app/models/procedure.rb
@@ -4,6 +4,7 @@
#
# id :integer not null, primary key
# aasm_state :string default("brouillon")
+# allow_expert_messaging :boolean default(TRUE), not null
# allow_expert_review :boolean default(TRUE), not null
# api_entreprise_token :string
# api_particulier_scopes :text default([]), is an Array
@@ -17,10 +18,10 @@
# description :string
# dossiers_count_computed_at :datetime
# duree_conservation_dossiers_dans_ds :integer
-# duree_conservation_etendue_par_ds :boolean default(FALSE)
+# duree_conservation_etendue_par_ds :boolean default(FALSE), not null
# encrypted_api_particulier_token :string
-# estimated_duration_visible :boolean default(TRUE), not null
# estimated_dossiers_count :integer
+# estimated_duration_visible :boolean default(TRUE), not null
# euro_flag :boolean default(FALSE)
# experts_require_administrateur_invitation :boolean default(FALSE)
# for_individual :boolean default(FALSE)
@@ -28,11 +29,10 @@
# instructeurs_self_management_enabled :boolean
# juridique_required :boolean default(TRUE)
# libelle :string
-# lien_demarche :string
# lien_dpo :string
# lien_notice :string
# lien_site_web :string
-# max_duree_conservation_dossiers_dans_ds :integer default(12)
+# max_duree_conservation_dossiers_dans_ds :integer default(12), not null
# migrated_champ_routage :boolean
# monavis_embed :text
# opendata :boolean default(TRUE)
diff --git a/app/models/super_admin.rb b/app/models/super_admin.rb
index 9fe9b4590..c7a1f9926 100644
--- a/app/models/super_admin.rb
+++ b/app/models/super_admin.rb
@@ -16,6 +16,7 @@
# last_sign_in_ip :string
# locked_at :datetime
# otp_required_for_login :boolean
+# otp_secret :string
# remember_created_at :datetime
# reset_password_sent_at :datetime
# reset_password_token :string
@@ -43,6 +44,7 @@ class SuperAdmin < ApplicationRecord
def disable_otp!
self.assign_attributes(
{
+ otp_secret: nil,
encrypted_otp_secret: nil,
encrypted_otp_secret_iv: nil,
encrypted_otp_secret_salt: nil,
@@ -66,4 +68,75 @@ class SuperAdmin < ApplicationRecord
def send_devise_notification(notification, *args)
devise_mailer.send(notification, self, *args).deliver_later
end
+
+ private
+
+ # From https://github.com/tinfoil/devise-two-factor/blob/main/UPGRADING.md
+ # Remove me after super admin have been migrated to the new OTP system.
+ # Decrypt and return the `encrypted_otp_secret` attribute which was used in
+ # prior versions of devise-two-factor
+ # @return [String] The decrypted OTP secret
+ def legacy_otp_secret
+ return nil unless self[:encrypted_otp_secret]
+ return nil unless self.class.otp_secret_encryption_key
+
+ hmac_iterations = 2000 # a default set by the Encryptor gem
+ key = self.class.otp_secret_encryption_key
+ salt = Base64.decode64(encrypted_otp_secret_salt)
+ iv = Base64.decode64(encrypted_otp_secret_iv)
+
+ raw_cipher_text = Base64.decode64(encrypted_otp_secret)
+ # The last 16 bytes of the ciphertext are the authentication tag - we use
+ # Galois Counter Mode which is an authenticated encryption mode
+ cipher_text = raw_cipher_text[0..-17]
+ auth_tag = raw_cipher_text[-16..-1]
+
+ # this alrorithm lifted from
+ # https://github.com/attr-encrypted/encryptor/blob/master/lib/encryptor.rb#L54
+
+ # create an OpenSSL object which will decrypt the AES cipher with 256 bit
+ # keys in Galois Counter Mode (GCM). See
+ # https://ruby.github.io/openssl/OpenSSL/Cipher.html
+ cipher = OpenSSL::Cipher.new('aes-256-gcm')
+
+ # tell the cipher we want to decrypt. Symmetric algorithms use a very
+ # similar process for encryption and decryption, hence the same object can
+ # do both.
+ cipher.decrypt
+
+ # Use a Password-Based Key Derivation Function to generate the key actually
+ # used for encryptoin from the key we got as input.
+ cipher.key = OpenSSL::PKCS5.pbkdf2_hmac_sha1(key, salt, hmac_iterations, cipher.key_len)
+
+ # set the Initialization Vector (IV)
+ cipher.iv = iv
+
+ # The tag must be set after calling Cipher#decrypt, Cipher#key= and
+ # Cipher#iv=, but before calling Cipher#final. After all decryption is
+ # performed, the tag is verified automatically in the call to Cipher#final.
+ #
+ # If the auth_tag does not verify, then #final will raise OpenSSL::Cipher::CipherError
+ cipher.auth_tag = auth_tag
+
+ # auth_data must be set after auth_tag has been set when decrypting See
+ # http://ruby-doc.org/stdlib-2.0.0/libdoc/openssl/rdoc/OpenSSL/Cipher.html#method-i-auth_data-3D
+ # we are not adding any authenticated data but OpenSSL docs say this should
+ # still be called.
+ cipher.auth_data = ''
+
+ # #update is (somewhat confusingly named) the method which actually
+ # performs the decryption on the given chunk of data. Our OTP secret is
+ # short so we only need to call it once.
+ #
+ # It is very important that we call #final because:
+ #
+ # 1. The authentication tag is checked during the call to #final
+ # 2. Block based cipher modes (e.g. CBC) work on fixed size chunks. We need
+ # to call #final to get it to process the last chunk properly. The output
+ # of #final should be appended to the decrypted value. This isn't
+ # required for streaming cipher modes but including it is a best practice
+ # so that your code will continue to function correctly even if you later
+ # change to a block cipher mode.
+ cipher.update(cipher_text) + cipher.final
+ end
end
diff --git a/app/models/trusted_device_token.rb b/app/models/trusted_device_token.rb
index 06d84a4a9..53ba9fa9c 100644
--- a/app/models/trusted_device_token.rb
+++ b/app/models/trusted_device_token.rb
@@ -3,7 +3,7 @@
# Table name: trusted_device_tokens
#
# id :bigint not null, primary key
-# token :string not null
+# token :string
# created_at :datetime not null
# updated_at :datetime not null
# instructeur_id :bigint
diff --git a/app/validators/jwt_token_validator.rb b/app/validators/jwt_token_validator.rb
index ec1ca427d..031a9d1ab 100644
--- a/app/validators/jwt_token_validator.rb
+++ b/app/validators/jwt_token_validator.rb
@@ -3,7 +3,7 @@ class JwtTokenValidator < ActiveModel::EachValidator
begin
JWT.decode value, nil, false
rescue
- record.errors[attribute] << (options[:message] || "n'est pas un jeton valide")
+ record.errors.add attribute, :invalid, message: (options[:message] || "n'est pas un jeton valide")
end
end
end
diff --git a/app/validators/mon_avis_embed_validator.rb b/app/validators/mon_avis_embed_validator.rb
index 4e4483988..b4fb33f59 100644
--- a/app/validators/mon_avis_embed_validator.rb
+++ b/app/validators/mon_avis_embed_validator.rb
@@ -3,7 +3,7 @@ class MonAvisEmbedValidator < ActiveModel::Validator
# We need to ensure the embed code is not any random string in order to avoid injections
r = Regexp.new('\s*
\s*', Regexp::MULTILINE)
if record.monavis_embed.present? && !r.match?(record.monavis_embed)
- record.errors[:base] << "Le code fourni ne correspond pas au format des codes MonAvis reconnus par la plateforme."
+ record.errors.add :base, :invalid, message: "Le code fourni ne correspond pas au format des codes MonAvis reconnus par la plateforme."
end
end
end
diff --git a/bin/rake b/bin/rake
index 7327f471e..4fbf10b96 100755
--- a/bin/rake
+++ b/bin/rake
@@ -1,5 +1,4 @@
#!/usr/bin/env ruby
-load File.expand_path("spring", __dir__)
require_relative "../config/boot"
require "rake"
Rake.application.run
diff --git a/bin/setup b/bin/setup
index f07a41744..0d283a126 100755
--- a/bin/setup
+++ b/bin/setup
@@ -2,7 +2,7 @@
require "fileutils"
# path to your application root.
-APP_ROOT = File.expand_path('..', __dir__)
+APP_ROOT = File.expand_path("..", __dir__)
def system!(*args)
system(*args) || abort("\n== Command #{args} failed ==")
@@ -13,9 +13,9 @@ FileUtils.chdir APP_ROOT do
# This script is idempotent, so that you can run it at any time and get an expectable outcome.
# Add necessary setup steps to this file.
- puts '== Installing dependencies =='
- system! 'gem install bundler --conservative'
- system('bundle check') || system!('bundle install')
+ puts "== Installing dependencies =="
+ system! "gem install bundler --conservative"
+ system("bundle check") || system!("bundle install")
# Install JavaScript dependencies
system! 'node --version'
@@ -29,13 +29,17 @@ FileUtils.chdir APP_ROOT do
FileUtils.cp 'config/env.example', '.env'
end
- # Create the database, load the schema, and initialize it with the seed data
+ # puts "\n== Copying sample files =="
+ # unless File.exist?("config/database.yml")
+ # FileUtils.cp "config/database.yml.sample", "config/database.yml"
+ # end
+
puts "\n== Preparing database =="
- system! 'bin/rails db:prepare'
+ system! "bin/rails db:prepare"
puts "\n== Removing old logs and tempfiles =="
- system! 'bin/rails log:clear tmp:clear'
+ system! "bin/rails log:clear tmp:clear"
puts "\n== Restarting application server =="
- system! 'bin/rails restart'
+ system! "bin/rails restart"
end
diff --git a/config/application.rb b/config/application.rb
index cf437e1c9..cf264ec08 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -98,5 +98,9 @@ module TPS
html_tag.html_safe # this is generated by rails
end
# rubocop:enable Rails/OutputSafety
+ #
+
+ config.active_record.encryption.primary_key = Rails.application.secrets.active_record_encryption.fetch(:primary_key)
+ config.active_record.encryption.key_derivation_salt = Rails.application.secrets.active_record_encryption.fetch(:key_derivation_salt)
end
end
diff --git a/config/env.example b/config/env.example
index 978dfd183..a3624b572 100644
--- a/config/env.example
+++ b/config/env.example
@@ -142,6 +142,10 @@ API_EDUCATION_URL="https://data.education.gouv.fr/api/records/1.0"
# Encryption key for sensitive columns in the database
ENCRYPTION_SERVICE_SALT=""
+# ActiveRecord encryption keys. Generate them with bin/rails db:encryption:init (you can omit deterministic_key)
+AR_ENCRYPTION_PRIMARY_KEY=""
+AR_ENCRYPTION_KEY_DERIVATION_SALT=""
+
# Salt for invisible_captcha session data.
# Must be the same value for all app instances behind a load-balancer.
INVISIBLE_CAPTCHA_SECRET="kikooloool"
diff --git a/config/initializers/cookie_rotator.rb b/config/initializers/cookie_rotator.rb
new file mode 100644
index 000000000..63d4fabe5
--- /dev/null
+++ b/config/initializers/cookie_rotator.rb
@@ -0,0 +1,18 @@
+# TODO: Enable cookies rotation when new SHA256 will be enforced
+# See new_framework_defaults_7.0.rb
+# key_generator_hash_digest_class = OpenSSL::Digest::SHA256 will be
+#
+# Rails.application.config.after_initialize do
+# Rails.application.config.action_dispatch.cookies_rotations.tap do |cookies|
+# salt = Rails.application.config.action_dispatch.authenticated_encrypted_cookie_salt
+# secret_key_base = Rails.application.secret_key_base
+
+# key_generator = ActiveSupport::KeyGenerator.new(
+# secret_key_base, iterations: 1000, hash_digest_class: OpenSSL::Digest::SHA1
+# )
+# key_len = ActiveSupport::MessageEncryptor.key_len
+# secret = key_generator.generate_key(salt, key_len)
+
+# cookies.rotate :encrypted, secret
+# end
+# end
diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb
index 18349e833..83c408320 100644
--- a/config/initializers/devise.rb
+++ b/config/initializers/devise.rb
@@ -227,7 +227,7 @@ Devise.setup do |config|
# should add them to the navigational formats lists.
#
# The "*/*" below is required to match Internet Explorer requests.
- # config.navigational_formats = ['*/*', :html]
+ # config.navigational_formats = ['*/*', :html, :turbo_stream]
# The default HTTP method used to sign out a resource. Default is :delete.
config.sign_out_via = :delete
@@ -253,4 +253,12 @@ Devise.setup do |config|
# When using omniauth, Devise cannot automatically set Omniauth path,
# so you need to do it manually. For the users scope, it would be:
# config.omniauth_path_prefix = '/my_engine/users/auth'
+
+ # When using Devise with Hotwire/Turbo, the http status for error responses
+ # and some redirects must match the following. The default in Devise for existing
+ # apps is `200 OK` and `302 Found respectively`, but new apps are generated with
+ # these new defaults that match Hotwire/Turbo behavior.
+ # Note: These might become the new default in future versions of Devise.
+ config.responder.error_status = :unprocessable_entity
+ config.responder.redirect_status = :see_other
end
diff --git a/config/initializers/dolist.rb b/config/initializers/dolist.rb
index b38a97e2c..7835b532a 100644
--- a/config/initializers/dolist.rb
+++ b/config/initializers/dolist.rb
@@ -1,3 +1,5 @@
ActiveSupport.on_load(:action_mailer) do
+ require "dolist/api_sender"
+
ActionMailer::Base.add_delivery_method :dolist_api, Dolist::APISender
end
diff --git a/config/initializers/lograge.rb b/config/initializers/lograge.rb
index 422c6906d..3a80f22af 100644
--- a/config/initializers/lograge.rb
+++ b/config/initializers/lograge.rb
@@ -40,8 +40,10 @@ Rails.application.configure do
config.lograge.keep_original_rails_log = true
config.lograge.logger = ActiveSupport::Logger.new(Rails.root.join('log', "logstash_#{Rails.env}.log"))
+end
- if config.lograge.enabled
+Rails.application.config.after_initialize do |app|
+ if app.config.lograge.enabled
ActiveJob::ApplicationLogSubscriber.attach_to(:active_job)
end
end
diff --git a/config/initializers/mail_observers.rb b/config/initializers/mail_observers.rb
index 513d7cd1c..985682909 100644
--- a/config/initializers/mail_observers.rb
+++ b/config/initializers/mail_observers.rb
@@ -1,6 +1,8 @@
# Must be registered *before* loading custom delivery methods
# otherwise the observer won't be invoked.
#
+require_relative "../../app/services/email_delivery_observer"
+
ActiveSupport.on_load(:action_mailer) do |mailer|
mailer.register_observer EmailDeliveryObserver
end
diff --git a/config/initializers/new_framework_defaults_7_0.rb b/config/initializers/new_framework_defaults_7_0.rb
new file mode 100644
index 000000000..b90fb14e4
--- /dev/null
+++ b/config/initializers/new_framework_defaults_7_0.rb
@@ -0,0 +1,133 @@
+# Be sure to restart your server when you modify this file.
+#
+# This file eases your Rails 7.0 framework defaults upgrade.
+#
+# Uncomment each configuration one by one to switch to the new default.
+# Once your application is ready to run with all new defaults, you can remove
+# this file and set the `config.load_defaults` to `7.0`.
+#
+# Read the Guide for Upgrading Ruby on Rails for more info on each option.
+# https://guides.rubyonrails.org/upgrading_ruby_on_rails.html
+
+# `button_to` view helper will render `