beautiful_scaffold 2.0.0.pre → 2.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -1
  3. data/CHANGELOG +45 -0
  4. data/Gemfile +5 -4
  5. data/README.rdoc +22 -4
  6. data/Rakefile +0 -3
  7. data/beautiful_scaffold.gemspec +0 -2
  8. data/lib/beautiful_scaffold/version.rb +1 -1
  9. data/lib/generators/USAGE +25 -11
  10. data/lib/generators/beautiful_cancancan_generator.rb +51 -0
  11. data/lib/generators/beautiful_jointable_generator.rb +3 -5
  12. data/lib/generators/beautiful_locale_generator.rb +15 -13
  13. data/lib/generators/beautiful_migration_generator.rb +3 -1
  14. data/lib/generators/beautiful_scaffold_common_methods.rb +10 -2
  15. data/lib/generators/beautiful_scaffold_generator.rb +2 -10
  16. data/lib/generators/beautiful_sorcery_generator.rb +137 -0
  17. data/lib/generators/beautiful_storage_generator.rb +61 -0
  18. data/lib/generators/templates/app/assets/javascripts/application-bs.js +0 -2
  19. data/lib/generators/templates/app/assets/javascripts/beautiful_scaffold.js +15 -30
  20. data/lib/generators/templates/app/assets/javascripts/bootstrap-datetimepicker-for-beautiful-scaffold.js +16 -15
  21. data/lib/generators/templates/app/assets/stylesheets/application-bs.css +0 -2
  22. data/lib/generators/templates/app/assets/stylesheets/beautiful-scaffold.css.scss +9 -1
  23. data/lib/generators/templates/app/controllers/user_sessions_controller.rb +20 -0
  24. data/lib/generators/templates/app/helpers/beautiful_helper.rb +19 -5
  25. data/lib/generators/templates/app/locales/beautiful_scaffold.en.yml +8 -0
  26. data/lib/generators/templates/app/locales/beautiful_scaffold.fr.yml +9 -1
  27. data/lib/generators/templates/app/locales/beautiful_scaffold.ja.yml +9 -2
  28. data/lib/generators/templates/app/mailers/user_mailer.rb +13 -0
  29. data/lib/generators/templates/app/models/ability.rb +39 -0
  30. data/lib/generators/templates/app/models/concerns/caption_concern.rb +1 -1
  31. data/lib/generators/templates/app/models/user.rb +11 -0
  32. data/lib/generators/templates/app/views/_form_habtm_tag.html.erb +3 -3
  33. data/lib/generators/templates/app/views/layout.html.erb +12 -2
  34. data/lib/generators/templates/app/views/login_logout/user_mailer/activation_needed_email.en.html.erb +16 -0
  35. data/lib/generators/templates/app/views/login_logout/user_mailer/activation_needed_email.en.text.erb +9 -0
  36. data/lib/generators/templates/app/views/login_logout/user_mailer/activation_needed_email.fr.html.erb +16 -0
  37. data/lib/generators/templates/app/views/login_logout/user_mailer/activation_needed_email.fr.text.erb +8 -0
  38. data/lib/generators/templates/app/views/login_logout/user_mailer/activation_success_email.en.html.erb +19 -0
  39. data/lib/generators/templates/app/views/login_logout/user_mailer/activation_success_email.en.text.erb +8 -0
  40. data/lib/generators/templates/app/views/login_logout/user_mailer/activation_success_email.fr.html.erb +19 -0
  41. data/lib/generators/templates/app/views/login_logout/user_mailer/activation_success_email.fr.text.erb +8 -0
  42. data/lib/generators/templates/app/views/login_logout/user_sessions/_form.html.erb +15 -0
  43. data/lib/generators/templates/app/views/login_logout/user_sessions/new.html.erb +3 -0
  44. data/lib/generators/templates/app/views/partials/_form_field.html.erb +33 -25
  45. data/lib/generators/templates/app/views/partials/_index_column.html.erb +2 -0
  46. data/lib/generators/templates/app/views/partials/_login_logout_register.html.erb +7 -0
  47. data/lib/generators/templates/app/views/partials/_show_field.html.erb +2 -0
  48. metadata +23 -15
  49. data/Gemfile.lock +0 -209
  50. data/lib/generators/beautiful_devisecancan_generator.rb +0 -128
  51. data/lib/generators/templates/app/assets/javascripts/bootstrap-colorpicker.js +0 -520
  52. data/lib/generators/templates/app/assets/javascripts/tagit.js +0 -489
  53. data/lib/generators/templates/app/assets/stylesheets/colorpicker.css +0 -127
  54. data/lib/generators/templates/app/assets/stylesheets/tagit-dark-grey.css +0 -135
  55. data/lib/generators/templates/app/views/partials/_register_form.html.erb +0 -44
  56. data/lib/generators/templates/app/views/partials/_sign_in_form.html.erb +0 -18
  57. data/lib/generators/templates/app/views/partials/_sign_in_sign_out.html.erb +0 -19
  58. data/lib/generators/templates/lib/custom_failure.rb +0 -15
@@ -0,0 +1,137 @@
1
+ # encoding : utf-8
2
+ class BeautifulSorceryGenerator < Rails::Generators::Base
3
+ require_relative 'beautiful_scaffold_common_methods'
4
+ include BeautifulScaffoldCommonMethods
5
+
6
+ source_root File.expand_path('../templates', __FILE__)
7
+
8
+ #argument :model, :type => :string, :desc => "Name of model (ex: User)"
9
+
10
+ def install_sorcery
11
+ model = "User"
12
+ view_path = "app/views/"
13
+
14
+ if !File.read('Gemfile').include?("sorcery")
15
+ gem("sorcery", "0.16.0")
16
+ end
17
+
18
+ Bundler.with_unbundled_env do
19
+ run "bundle install"
20
+ end
21
+
22
+ raise "Model must be specified" if model.blank?
23
+
24
+ # Install sorcery
25
+ generate("sorcery:install", "remember_me reset_password user_activation brute_force_protection external --model #{model}")
26
+
27
+ # If exist users migration just add columns
28
+ create_user_migration = Dir.glob("db/migrate/*create_users.rb").first
29
+ if create_user_migration
30
+ already_email = File.read(create_user_migration).include?(":email")
31
+ sorcery_core_file = Dir.glob("db/migrate/*sorcery_core.rb").first
32
+ File.open(sorcery_core_file, "w+") do |f|
33
+ f.write("class SorceryCore < ActiveRecord::Migration[6.1]
34
+ def change
35
+ #{(already_email ? '' : 'add_column :users, :email, :string')}
36
+ add_column :users, :crypted_password, :string
37
+ add_column :users, :salt, :string
38
+
39
+ #{(already_email ? '' : 'add_index :users, :email, unique: true')}
40
+ end
41
+ end")
42
+ end
43
+ end
44
+
45
+ # Generate mailer
46
+ copy_file("app/mailers/user_mailer.rb")
47
+
48
+ # Install controllers
49
+ copy_file("app/controllers/user_sessions_controller.rb")
50
+
51
+ # ===== Controller
52
+ inject_into_file("app/controllers/users_controller.rb",
53
+ "\n
54
+ skip_before_action :require_login, only: [:new, :create, :activate]
55
+ \n", after: "< BeautifulController")
56
+
57
+ inject_into_file("app/controllers/users_controller.rb",
58
+ "def activate
59
+ if @user = User.load_from_activation_token(params[:id])
60
+ @user.activate!
61
+ redirect_to(login_path, :notice => 'User was successfully activated.')
62
+ else
63
+ not_authenticated
64
+ end
65
+ end\n\n ", before: "private")
66
+
67
+ # ====== Model
68
+ # Add password & password_confirmation in model
69
+ inject_into_file("app/models/user.rb",
70
+ "\n
71
+ validates :password, length: { minimum: 3 }, if: -> { new_record? || changes[:crypted_password] }
72
+ validates :password, confirmation: true, if: -> { new_record? || changes[:crypted_password] }
73
+ validates :password_confirmation, presence: true, if: -> { new_record? || changes[:crypted_password] }
74
+
75
+ before_update :setup_activation, if: -> { email_changed? }
76
+ after_update :send_activation_needed_email!, if: -> { previous_changes['email'].present? }\n",
77
+ after: "ApplicationRecord")
78
+
79
+ inject_into_file("app/models/user.rb", ":password,:password_confirmation,", :after => "def self.permitted_attributes\n return ")
80
+
81
+ # ====== Views
82
+ inject_into_file("app/views/users/_form.html.erb",
83
+ ' <div class="form-group">
84
+ <%= f.label :password, t(\'app.models.user.bs_attributes.password\', :default => \'password\').capitalize, :class => "control-label" %><br />
85
+ <%= f.password_field :password, :class => "form-control" %>
86
+ </div>
87
+ <div class="form-group">
88
+ <%= f.label :password_confirmation, t(\'app.models.user.bs_attributes.password_confirmation\', :default => \'password_confirmation\').capitalize, :class => "control-label" %><br />
89
+ <%= f.password_field :password_confirmation, :class => "form-control" %>
90
+ </div>', before: '<!-- Beautiful_scaffold - AddField - Do not remove -->')
91
+
92
+ # Install all views for login/logout
93
+ directory "app/views/login_logout", "app/views"
94
+
95
+ # Domain in action_mailer
96
+ for current_env in ['production', 'development', 'test']
97
+ inject_into_file("config/environments/#{current_env}.rb", " config.action_mailer.default_url_options = { :host => 'localhost:3000' }", :after => "Rails.application.configure do\n" )
98
+ end
99
+
100
+ # In model
101
+ #remove_file("app/models/user.rb") # remove generated by sorcery
102
+ #copy_file("app/models/user.rb") # copy BS version ;)
103
+
104
+ # Limited access
105
+ inject_into_file("app/controllers/beautiful_controller.rb",
106
+ "\n before_action :require_login, except: [:dashboard]\n",
107
+ :after => 'layout "beautiful_layout"' + "\n")
108
+
109
+ inject_into_file("config/initializers/sorcery.rb",
110
+ "\nuser.user_activation_mailer = UserMailer\n",
111
+ :after => "# user.user_activation_mailer =\n")
112
+
113
+ # Routes (session)
114
+ inject_into_file("config/routes.rb",
115
+ '
116
+ resources :user_sessions, only: [:create]
117
+ get "login" => "user_sessions#new", :as => :login
118
+ post "logout" => "user_sessions#destroy", :as => :logout' + "\n\n\n",
119
+ :after => "Rails.application.routes.draw do\n")
120
+
121
+ # Activate
122
+ inject_into_file("config/routes.rb", " do
123
+ member do
124
+ get :activate
125
+ end
126
+ end", after: 'resources :users, concerns: :bs_routes')
127
+
128
+ copy_file("#{view_path}partials/_login_logout_register.html.erb", "#{view_path}layouts/_login_logout_register.html.erb")
129
+
130
+ # Sign in sign out
131
+ inject_into_file("#{view_path}layouts/beautiful_layout.html.erb",
132
+ "\n<%= render :partial => 'layouts/login_logout_register' %>\n",
133
+ :after => "<!-- Beautiful_scaffold - Signin - Do not remove -->")
134
+
135
+ say "Beautiful-Scaffold enable 'user_activation' sorcery module for you, so when you sign up, find in logs the activation link. You can't sign in yourself until you activate the account"
136
+ end
137
+ end
@@ -0,0 +1,61 @@
1
+ # encoding : utf-8
2
+ class BeautifulStorageGenerator < Rails::Generators::Base
3
+ require_relative 'beautiful_scaffold_common_methods'
4
+ include BeautifulScaffoldCommonMethods
5
+
6
+ source_root File.expand_path('../templates', __FILE__)
7
+
8
+ # TODO voir pour engine
9
+
10
+ argument :model, :type => :string, :desc => "Name of model (ex: user)"
11
+ argument :storage_name, :type => :string, :desc => "Storage's name (ex: picture_file)"
12
+
13
+ class_option :mountable_engine, default: nil
14
+
15
+ def install_storage
16
+
17
+ #if !File.read('Gemfile').include?("image_processing")
18
+ gem("image_processing", '~> 1.2')
19
+ #end
20
+
21
+ Bundler.with_unbundled_env do
22
+ run "bundle install"
23
+ end
24
+
25
+ # Install activestorage
26
+ run "bin/rails active_storage:install"
27
+ #run "rake db:migrate"
28
+
29
+ raise "Model must be specified" if model.blank?
30
+ raise "Attachment must be specified" if storage_name.blank?
31
+
32
+ # ===== Model
33
+ inject_into_file("app/models/#{engine_name}#{model}.rb",
34
+ "\n
35
+ has_one_attached :#{storage_name}
36
+ \n", after: "< ApplicationRecord")
37
+ inject_into_file("app/models/#{engine_name}#{model}.rb", ":#{storage_name},", :after => "def self.permitted_attributes\n return ")
38
+
39
+ # ====== Views
40
+ inject_into_file("app/views/#{engine_name}#{model_pluralize}/_form.html.erb",
41
+ " <div class='form-group'>
42
+ <%= f.label :#{storage_name}, t('app.models.#{model}.bs_attributes.#{storage_name}', :default => '#{storage_name}').capitalize, :class => 'control-label' %><br />
43
+ <%= f.file_field :#{storage_name}, direct_upload: true, :class => 'form-control' %>
44
+ </div>\n", before: '<!-- Beautiful_scaffold - AddField - Do not remove -->')
45
+
46
+ inject_into_file("app/views/#{engine_name}#{model_pluralize}/_form.html.erb",
47
+ ", multipart: true", after: "form_for(@#{model}")
48
+
49
+ inject_into_file("app/views/#{engine_name}#{model_pluralize}/show.html.erb",
50
+ "<p><b><%= t('app.models.#{model}.bs_attributes.#{storage_name}', :default => '#{storage_name}') %>:</b><br><%= image_tag @#{model}.#{storage_name}.variant(resize_to_limit: [100, 100]) %></p>",
51
+ before: "<!-- Beautiful_scaffold - AddField - Field - Do not remove -->")
52
+
53
+ # Controller
54
+ #inject_into_file("app/controllers/#{engine_name}#{model_pluralize}_controller.rb",
55
+ # "\n before_action :require_login, except: [:dashboard]\n",
56
+ # :after => 'layout "beautiful_layout"' + "\n")
57
+
58
+ say "You must run 'rake db:migrate' to create activestorage migrations !"
59
+
60
+ end
61
+ end
@@ -4,14 +4,12 @@
4
4
  //= require popper
5
5
  //= require bootstrap-sprockets
6
6
  //= require a-wysihtml5-0.3.0.min
7
- //= require bootstrap-colorpicker
8
7
  //= require moment
9
8
  //= require moment/fr
10
9
  //= require tempusdominus-bootstrap-4.js
11
10
  //= require bootstrap-datetimepicker-for-beautiful-scaffold
12
11
  //= require bootstrap-wysihtml5
13
12
  //= require jstree.min.js
14
- //= require tagit.js
15
13
  //= require jquery-barcode
16
14
  //= require beautiful_scaffold
17
15
  //= require fixed_menu
@@ -18,42 +18,27 @@ function bs_init(){
18
18
  return false;
19
19
  });
20
20
 
21
- // Tagit
21
+ // habtm (select2 - tag)
22
22
  $('.bs-tagit').each(function( index ) {
23
23
  var tagitelt = this;
24
- $(tagitelt).tagit({
25
- tagSource : function( request, response ) {
26
-
27
- var par = $(tagitelt).attr("data-param");
28
- var url = $(tagitelt).attr("data-url");
29
- var result = $(tagitelt).attr("data-result");
30
- var data_to_send = {
31
- "skip_save_search": true
32
- };
33
- data_to_send[par] = request.term;
34
- $.ajax({
35
- url: url,
36
- type: "POST",
37
- data: data_to_send,
38
- dataType: "json",
39
- success: function( data ) {
40
- response( $.map( data, function( item ) {
41
- return { label: item[result], value: item.id };
42
- }));
43
- }
44
- });
45
- },
46
- triggerKeys:['enter', 'comma', 'tab'],
47
- select : true,
48
- allowNewTags : false
24
+ $(tagitelt).select2({
25
+ ajax: {
26
+ processResults: function (data) {
27
+ // Transforms the top-level key of the response object from 'items' to 'results'
28
+ return {
29
+ results: $.map(data, function (obj) {
30
+ obj.id = obj.id;
31
+ obj.text = obj.caption;
32
+ return obj;
33
+ })
34
+ };
35
+ }
36
+ }
49
37
  });
50
- // Bootstrap...
51
- $('.tagit-input').addClass("form-control");
52
38
  });
53
39
 
54
- // Wysiwyg and color field
40
+ // Wysiwyg field
55
41
  $('.wysiwyg-editor').wysihtml5({"html": true});
56
- $('.color').colorpicker({format: 'rgba'});
57
42
 
58
43
  // Processing
59
44
  $(document).on('click', '#checkall', function(){
@@ -1,21 +1,22 @@
1
1
  function datetimepicker_init(){
2
- $('.tpicker').datetimepicker({ format: 'LT' }).on('change.datetimepicker', function(elt){
3
- console.log('===============> time');
4
- console.log(elt);
5
- console.log($(elt.target).attr('data-field'));
2
+ $('.tpicker').datetimepicker({ format: 'LT', widgetPositioning: {
3
+ horizontal: 'auto',
4
+ vertical: 'auto'
5
+ } });
6
+ $('.tpicker').on('change.datetimepicker', function(elt){
6
7
  var eltid = $(elt.target).attr('data-field');
7
- $('#' + eltid + '_4i').val(elt.date.hour());
8
- $('#' + eltid + '_5i').val(elt.date.minute());
8
+ $('#' + eltid + '4i').val(elt.date.hour());
9
+ $('#' + eltid + '5i').val(elt.date.minute());
9
10
  });
10
-
11
- $('.dpicker').datetimepicker({ format: 'L' }).on('change.datetimepicker', function(elt){
12
- console.log('===============> date');
13
- console.log(elt);
14
- console.log($(elt.target).attr('data-field'));
11
+ $('.dpicker').datetimepicker({ format: 'L', widgetPositioning: {
12
+ horizontal: 'auto',
13
+ vertical: 'auto'
14
+ } });
15
+ $('.dpicker').on('change.datetimepicker', function(elt){
15
16
  var eltid = $(elt.target).attr('data-field');
16
- $('#' + eltid + '_3i').val(elt.date.date());
17
- $('#' + eltid + '_2i').val(elt.date.month()+1);
18
- $('#' + eltid + '_1i').val(elt.date.year());
17
+ $('#' + eltid + '3i').val(elt.date.date());
18
+ $('#' + eltid + '2i').val(elt.date.month()+1);
19
+ $('#' + eltid + '1i').val(elt.date.year());
19
20
  });
20
21
  $(document).on('click', '.dpicker', function(e){
21
22
  $(this).datetimepicker('show');
@@ -24,6 +25,6 @@ function datetimepicker_init(){
24
25
  $(this).datetimepicker('show');
25
26
  });
26
27
  $(".datetimepicker-input").each(function(i, elt){
27
- $(elt).removeAttr("name");
28
+ $(elt).removeAttr("name");
28
29
  });
29
30
  }
@@ -11,8 +11,6 @@
11
11
  *= require_self
12
12
  *= require jquery-ui
13
13
  *= require beautiful-scaffold
14
- *= require tagit-dark-grey
15
- *= require colorpicker
16
14
  *= require bootstrap-wysihtml5
17
15
  *= require themes/default/style
18
16
  */
@@ -177,10 +177,12 @@ html, body {
177
177
  margin-bottom: 0px;
178
178
  margin-left: 20px;
179
179
  }
180
+ /*
180
181
  .search-and-filter .form-group label{
181
182
  margin-bottom: 0;
182
183
  margin-top: 5px;
183
184
  }
185
+ */
184
186
 
185
187
  /*
186
188
  div.filler.show-menu{
@@ -199,4 +201,10 @@ div.fixed.hide-menu{
199
201
 
200
202
  .title-index{
201
203
  font-size: 30px;
202
- }
204
+ }
205
+
206
+ .overview-color{
207
+ display:inline-block;
208
+ width: 40px;
209
+ height: 24px;
210
+ }
@@ -0,0 +1,20 @@
1
+ class UserSessionsController < BeautifulController
2
+
3
+ skip_before_action :require_login, only: [:new, :create]
4
+
5
+ def create
6
+ @user = login(params[:email], params[:password])
7
+
8
+ if @user
9
+ redirect_back_or_to(:users, notice: 'Login successful')
10
+ else
11
+ flash.now[:alert] = 'Login failed'
12
+ render action: 'new'
13
+ end
14
+ end
15
+
16
+ def destroy
17
+ logout
18
+ redirect_to(:users, notice: 'Logged out!')
19
+ end
20
+ end
@@ -92,12 +92,15 @@ module BeautifulHelper
92
92
 
93
93
  cap = i18n_translate_path(model_name, attribute_name)
94
94
 
95
+ type_of_column = ar_model.columns_hash[attribute_name].type unless ar_model.columns_hash[attribute_name].nil?
96
+ type_of_column ||= :other
97
+
95
98
  infostr = ''
96
99
  response = '' # See at end
100
+ response += '<div class="form-check form-check-inline">' if type_of_column == :boolean
97
101
  response += f.label name_field, t(cap, :default => default_caption).capitalize, :class => "control-label"
102
+ response += '</div>' if type_of_column == :boolean
98
103
 
99
- type_of_column = ar_model.columns_hash[attribute_name].type unless ar_model.columns_hash[attribute_name].nil?
100
- type_of_column ||= :other
101
104
  case type_of_column
102
105
  when :date, :datetime
103
106
  dt = (type_of_column == :datetime)
@@ -178,9 +181,20 @@ module BeautifulHelper
178
181
  infostr = info_input(model_name, [(name_field + "_dp_lt").to_sym, (name_field + "_tp_lt").to_sym, (name_field + "_dp_gt").to_sym, (name_field + "_tp_gt").to_sym])
179
182
  when :boolean
180
183
  # Specify a default value (false) in rails migration
181
- response += f.label name_field + "_eq_true", raw(f.radio_button((name_field + "_eq").to_sym, true)) + " " + h(t(:yes, :default => "Yes")), :class => "checkbox inline"
182
- response += f.label name_field + "_eq_false", raw(f.radio_button((name_field + "_eq").to_sym, false)) + " " + h(t(:no, :default => "No")), :class => "checkbox inline"
183
- response += f.label name_field + "_eq", raw(f.radio_button((name_field + "_eq").to_sym, nil)) + " " + h(t(:all, :default => "All")), :class => "checkbox inline"
184
+ response += '<div class="form-check form-check-inline">'
185
+ response += f.radio_button((name_field + "_eq").to_sym, true, { class: 'form-check-input'})
186
+ response += f.label name_field + "_eq_true", h(t(:yes, default: "Yes")), class: "form-check-label"
187
+ response += '</div>'
188
+
189
+ response += '<div class="form-check form-check-inline">'
190
+ response += f.radio_button((name_field + "_eq").to_sym, false, { class: 'form-check-input'})
191
+ response += f.label name_field + "_eq_false", h(t(:no, default: "No")), class: "form-check-label"
192
+ response += '</div>'
193
+
194
+ response += '<div class="form-check form-check-inline">'
195
+ response += f.radio_button((name_field + "_eq").to_sym, nil, { class: 'form-check-input'})
196
+ response += f.label name_field + "_eq", h(t(:all, default: "All")), class: "form-check-label"
197
+ response += '</div>'
184
198
 
185
199
  infostr = (begin session['search'][model_name][(name_field + "_eq").to_sym] == "on" ? "" : "info" rescue "" end)
186
200
  when :string
@@ -47,3 +47,11 @@ en:
47
47
  register: "Register"
48
48
  search_and_filter: "Search and filter"
49
49
  more_options: "More options..."
50
+ edit_profile: "edit profile"
51
+ logout: "Logout"
52
+ register: "Register"
53
+ login: "Login"
54
+ logged_out: "Logged out"
55
+ login_failed: "Login failed"
56
+ login_successful: "Login successful"
57
+ crypted_password: "Crypted password"
@@ -46,4 +46,12 @@ fr:
46
46
  send_me_reset_password_instructions: "Me ré-envoyer les instructions de réinitialisation du mot de passe"
47
47
  register: "Inscription"
48
48
  search_and_filter: "Option de filtre"
49
- more_options: "Plus d'options..."
49
+ more_options: "Plus d'options..."
50
+ edit_profile: "Editer mon profil"
51
+ logout: "Déconnexion"
52
+ register: "S'incrire"
53
+ login: "S'identifier"
54
+ logged_out: "déconnecté"
55
+ login_failed: "Erreur d'identification"
56
+ login_successful: "Identification réussie"
57
+ crypted_password: "Crypted password"