lato 0.1.26 → 0.1.27

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6efff0dabd7587626cdb6a08a71312793654ddfed11b2a60fea58e58475eb8ac
4
- data.tar.gz: ff65ff6ad27a5b14c02742de7bb692a24e87e9305136d0bcfb0e9c9406377c26
3
+ metadata.gz: d39edbfb4463841b8aae209b67bde25c3c7a49dd98020185c9ac2e75b2571bc6
4
+ data.tar.gz: 594d67d40286bfe453c05b2625f891fa3f8fff78ad44f26b6520a89ad9f1d7b4
5
5
  SHA512:
6
- metadata.gz: 9acbbfba492ee88a0f8acf41265966e7904de8e1cf060331b115e12d06ac41f58782935a4ab7b60c20b18bf1a62aa9e7850e69ea66160530e98c7927c2c6d914
7
- data.tar.gz: 532de791068976f1a0b4b693e14e0a10dd5ce88ebf7043065dd0c409fa2a7b1f3195799a00c74f64b36273260458a91e72394f27ee1b5eb83ebf307fba3e5270
6
+ metadata.gz: 0cdeaedaf49f9e0efb6d53035fbbdcb4eeed8d0256e34ce54fc36073478f92592dd486e63144b8a4dab534f74953124e53698b01af2a1df93fd35ccfa206e1ce
7
+ data.tar.gz: 61e8ed6e0ec07edac2b9b8f115bb579dab182fff4c32ddacb48c24f0bbae78056f4d32fbc997c547850e301755e60688438e029226b05c4fcfd2436858e55527
@@ -1,12 +1,19 @@
1
1
  module Lato
2
2
  class AuthenticationController < ApplicationController
3
- before_action :not_authenticate_session, only: %i[signin signin_action signup signup_action]
3
+ before_action :not_authenticate_session, only: %i[signin signin_action signup signup_action accept_invitation accept_invitation_action]
4
4
  before_action :authenticate_session, only: %i[signout signout_action]
5
+
5
6
  before_action :find_user, only: %i[verify_email verify_email_action update_password update_password_action]
6
- before_action :hide_sidebar
7
+ before_action :find_invitation, only: %i[accept_invitation accept_invitation_action]
8
+
7
9
  before_action :lock_signup_if_disabled, only: %i[signup signup_action]
8
10
  before_action :lock_recover_password_if_disabled, only: %i[recover_password recover_password_action update_password update_password_action]
9
11
 
12
+ before_action :hide_sidebar
13
+
14
+ # Signin
15
+ ##
16
+
10
17
  def signin
11
18
  @user = Lato::User.new
12
19
  end
@@ -15,7 +22,10 @@ module Lato
15
22
  @user = Lato::User.new
16
23
 
17
24
  respond_to do |format|
18
- if @user.signin(params.require(:user).permit(:email, :password))
25
+ if @user.signin(params.require(:user).permit(:email, :password).merge(
26
+ ip_address: request.remote_ip,
27
+ user_agent: request.user_agent
28
+ ))
19
29
  session_create(@user.id)
20
30
 
21
31
  format.html { redirect_to lato.root_path }
@@ -27,12 +37,15 @@ module Lato
27
37
  end
28
38
  end
29
39
 
40
+ # Signup
41
+ ##
42
+
30
43
  def signup
31
44
  @user = Lato::User.new
32
45
  end
33
46
 
34
47
  def signup_action
35
- @user = Lato::User.new(params.require(:user).permit(:first_name, :last_name, :email, :password, :password_confirmation, :accepted_privacy_policy_version, :accepted_terms_and_conditions_version))
48
+ @user = Lato::User.new(registration_params)
36
49
 
37
50
  respond_to do |format|
38
51
  if @user.save
@@ -47,6 +60,9 @@ module Lato
47
60
  end
48
61
  end
49
62
 
63
+ # Signout
64
+ ##
65
+
50
66
  def signout; end
51
67
 
52
68
  def signout_action
@@ -58,6 +74,9 @@ module Lato
58
74
  end
59
75
  end
60
76
 
77
+ # Verify email
78
+ ##
79
+
61
80
  def verify_email
62
81
  @code = params[:code]
63
82
  end
@@ -74,6 +93,9 @@ module Lato
74
93
  end
75
94
  end
76
95
 
96
+ # Recover password
97
+ ##
98
+
77
99
  def recover_password
78
100
  @user = Lato::User.new
79
101
  end
@@ -92,6 +114,9 @@ module Lato
92
114
  end
93
115
  end
94
116
 
117
+ # Update password
118
+ ##
119
+
95
120
  def update_password; end
96
121
 
97
122
  def update_password_action
@@ -106,23 +131,55 @@ module Lato
106
131
  end
107
132
  end
108
133
 
134
+ # Accept invitation
135
+ ##
136
+
137
+ def accept_invitation
138
+ @user = Lato::User.new(email: @invitation.email)
139
+ end
140
+
141
+ def accept_invitation_action
142
+ @user = Lato::User.new(registration_params)
143
+
144
+ respond_to do |format|
145
+ if @user.accept_invitation(params.permit(:id, :accepted_code))
146
+ session_create(@user.id)
147
+
148
+ format.html { redirect_to lato.root_path }
149
+ format.json { render json: @user }
150
+ else
151
+ format.html { render :accept_invitation, status: :unprocessable_entity }
152
+ format.json { render json: @user.errors, status: :unprocessable_entity }
153
+ end
154
+ end
155
+ end
156
+
109
157
  private
110
158
 
159
+ def registration_params
160
+ params.require(:user).permit(:first_name, :last_name, :email, :password, :password_confirmation, :accepted_privacy_policy_version, :accepted_terms_and_conditions_version)
161
+ end
162
+
111
163
  def find_user
112
164
  @user = User.find_by(id: params[:id])
113
165
  respond_to_with_not_found unless @user
114
166
  end
115
167
 
168
+ def find_invitation
169
+ @invitation = Lato::Invitation.find_by(id: params[:id], accepted_code: params[:accepted_code])
170
+ respond_to_with_not_found unless @invitation
171
+ end
172
+
116
173
  def lock_signup_if_disabled
117
174
  return unless Lato.config.auth_disable_signup
118
175
 
119
- respond_to_with_not_found
176
+ respond_to_with_not_found
120
177
  end
121
178
 
122
179
  def lock_recover_password_if_disabled
123
180
  return unless Lato.config.auth_disable_recover_password
124
181
 
125
- respond_to_with_not_found
182
+ respond_to_with_not_found
126
183
  end
127
184
  end
128
185
  end
@@ -50,7 +50,7 @@ module Lato
50
50
  columns = options[:columns] || @_lato_index[key][:columns] || collection.column_names || []
51
51
  sortable_columns = @_lato_index[key][:sortable_columns] || []
52
52
  searchable_columns = @_lato_index[key][:searchable_columns] || []
53
- model_name_underscore = options[:model_name] || collection.model.name.gsub('/', '_').underscore
53
+ model_name_underscore = options[:model_name] || collection.model.name.underscore.gsub('/', '_')
54
54
 
55
55
  render(
56
56
  'lato/components/index',
@@ -56,7 +56,9 @@ module Lato
56
56
  yield
57
57
  @operation&.completed
58
58
  rescue StandardError => e
59
- @operation&.failed(e.message)
59
+ return @operation.failed(e.message) if @operation
60
+
61
+ raise e
60
62
  end
61
63
  end
62
64
  end
@@ -0,0 +1,21 @@
1
+ module Lato
2
+ class InvitationMailer < ApplicationMailer
3
+ def invite_mail(invitation_id)
4
+ @invitation = Lato::Invitation.find(invitation_id)
5
+
6
+ set_invitation_locale
7
+
8
+ mail(
9
+ to: @invitation.email,
10
+ subject: 'Hai ricevuto un invito',
11
+ template_path: 'lato/mailer/invitation'
12
+ )
13
+ end
14
+
15
+ private
16
+
17
+ def set_invitation_locale
18
+ I18n.locale = @invitation.lato_user&.locale || I18n.default_locale
19
+ end
20
+ end
21
+ end
@@ -3,6 +3,9 @@ module Lato
3
3
  def email_verification_mail(user_id, code)
4
4
  @user = Lato::User.find(user_id)
5
5
  @code = code
6
+
7
+ set_user_locale
8
+
6
9
  mail(
7
10
  to: @user.email,
8
11
  subject: 'Conferma il tuo indirizzo email',
@@ -13,11 +16,20 @@ module Lato
13
16
  def password_update_mail(user_id, code)
14
17
  @user = Lato::User.find(user_id)
15
18
  @code = code
19
+
20
+ set_user_locale
21
+
16
22
  mail(
17
23
  to: @user.email,
18
24
  subject: 'Imposta una nuova password',
19
25
  template_path: 'lato/mailer/user'
20
26
  )
21
27
  end
28
+
29
+ private
30
+
31
+ def set_user_locale
32
+ I18n.locale = @user.locale || I18n.default_locale
33
+ end
22
34
  end
23
35
  end
@@ -0,0 +1,82 @@
1
+ module Lato
2
+ class Invitation < ApplicationRecord
3
+ attr_accessor :actions
4
+
5
+ # Kredis
6
+ ##
7
+
8
+ kredis_boolean :email_invite_semaphore, expires_in: 2.minutes
9
+
10
+ # Validations
11
+ ##
12
+
13
+ validates :email, presence: true, uniqueness: true
14
+
15
+ # Relations
16
+ ##
17
+
18
+ belongs_to :lato_user, class_name: 'Lato::User', foreign_key: :lato_user_id, optional: true
19
+
20
+ # Hooks
21
+ ##
22
+
23
+ before_validation do
24
+ self.email = email&.downcase&.strip
25
+ end
26
+
27
+ # be sure that email is not already used by another user
28
+ before_create do
29
+ if Lato::User.find_by(email: email)
30
+ errors.add(:email, 'is already used by another user')
31
+ throw :abort
32
+ end
33
+ end
34
+
35
+ # generate a random code for the invitation
36
+ before_create do
37
+ self.accepted_code = SecureRandom.hex(16)
38
+ end
39
+
40
+ # send an email to the invited user
41
+ after_create do
42
+ send_invite
43
+ end
44
+
45
+ # be sure accepted invitations can not be deleted
46
+ before_destroy do
47
+ throw :abort if accepted?
48
+ end
49
+
50
+ # Helpers
51
+ ##
52
+
53
+ def accepted?
54
+ !!accepted_at
55
+ end
56
+
57
+ # Operations
58
+ ##
59
+
60
+ def send_invite
61
+ if accepted?
62
+ errors.add(:base, :already_accepted)
63
+ return false
64
+ end
65
+
66
+ if email_invite_semaphore.value
67
+ errors.add(:base, :email_sending_limit)
68
+ return false
69
+ end
70
+
71
+ delivery = Lato::InvitationMailer.invite_mail(id).deliver_now
72
+ unless delivery
73
+ errors.add(:base, :email_sending_error)
74
+ return false
75
+ end
76
+
77
+ email_invite_semaphore.value = true
78
+
79
+ true
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,8 @@
1
+ module Lato
2
+ class Log::UserSignin < ApplicationRecord
3
+ # Relations
4
+ ##
5
+
6
+ belongs_to :lato_user, class_name: 'Lato::User', foreign_key: :lato_user_id, optional: true
7
+ end
8
+ end
@@ -0,0 +1,14 @@
1
+ module Lato
2
+ module Log
3
+ # This module is used to add log to the application.
4
+ # Log are used to track user actions without sensitive data.
5
+ # Log should not be destroyed.
6
+ before_destroy do
7
+ throw :abort
8
+ end
9
+
10
+ def self.table_name_prefix
11
+ 'lato_log_'
12
+ end
13
+ end
14
+ end
@@ -10,6 +10,11 @@ module Lato
10
10
  has_one_attached :input_file
11
11
  has_one_attached :output_file
12
12
 
13
+ # Relations
14
+ ##
15
+
16
+ belongs_to :lato_user, class_name: 'Lato::User', foreign_key: :lato_user_id, optional: true
17
+
13
18
  # Hooks
14
19
  ##
15
20
 
@@ -50,6 +55,7 @@ module Lato
50
55
  end
51
56
 
52
57
  # Operations
58
+ ##
53
59
 
54
60
  def start
55
61
  begin
@@ -93,7 +99,7 @@ module Lato
93
99
  }
94
100
  operation_params[:input_file] = file unless file.nil?
95
101
 
96
- Operation.create(operation_params)
102
+ Lato::Operation.create(operation_params)
97
103
  end
98
104
  end
99
105
  end
@@ -24,6 +24,9 @@ module Lato
24
24
  ##
25
25
 
26
26
  has_many :lato_operations, class_name: 'Lato::Operation', foreign_key: :lato_user_id, dependent: :nullify
27
+ has_many :lato_invitations, class_name: 'Lato::Invitation', foreign_key: :lato_user_id, dependent: :nullify
28
+
29
+ has_many :lato_log_user_signins, class_name: 'Lato::Log::UserSignin', foreign_key: :lato_user_id, dependent: :nullify
27
30
 
28
31
  # Hooks
29
32
  ##
@@ -80,6 +83,15 @@ module Lato
80
83
  self.id = user.id
81
84
  reload
82
85
 
86
+ begin
87
+ lato_log_user_signins.create(
88
+ ip_address: params[:ip_address],
89
+ user_agent: params[:user_agent]
90
+ )
91
+ rescue StandardError => e
92
+ Rails.logger.error(e)
93
+ end
94
+
83
95
  true
84
96
  end
85
97
 
@@ -120,15 +132,6 @@ module Lato
120
132
  true
121
133
  end
122
134
 
123
- def destroy_with_confirmation(params)
124
- unless params[:email_confirmation] == email
125
- errors.add(:email, :not_correct)
126
- return
127
- end
128
-
129
- destroy
130
- end
131
-
132
135
  def request_recover_password(params)
133
136
  user = Lato::User.find_by(email: params[:email])
134
137
  unless user
@@ -184,5 +187,31 @@ module Lato
184
187
 
185
188
  update(accepted_terms_and_conditions_version: Lato.config.legal_terms_and_conditions_version)
186
189
  end
190
+
191
+ def destroy_with_confirmation(params)
192
+ unless params[:email_confirmation] == email
193
+ errors.add(:email, :not_correct)
194
+ return
195
+ end
196
+
197
+ destroy
198
+ end
199
+
200
+ def accept_invitation(params)
201
+ invitation = Lato::Invitation.find_by(id: params[:id], accepted_code: params[:accepted_code])
202
+ if !invitation || invitation.accepted? || invitation.email != email
203
+ errors.add(:base, :invitation_invalid)
204
+ return
205
+ end
206
+
207
+ ActiveRecord::Base.transaction do
208
+ raise ActiveRecord::Rollback unless save && invitation.update(
209
+ accepted_at: Time.now,
210
+ lato_user_id: id
211
+ )
212
+
213
+ true
214
+ end
215
+ end
187
216
  end
188
217
  end
@@ -0,0 +1,37 @@
1
+ <%
2
+
3
+ email_readonly ||= false
4
+
5
+ %>
6
+
7
+ <div class="row">
8
+ <div class="col col-12 col-md-6 mb-3">
9
+ <%= lato_form_item_label form, :first_name %>
10
+ <%= lato_form_item_input_text form, :first_name, required: true %>
11
+ </div>
12
+
13
+ <div class="col col-12 col-md-6 mb-3">
14
+ <%= lato_form_item_label form, :last_name %>
15
+ <%= lato_form_item_input_text form, :last_name, required: true %>
16
+ </div>
17
+
18
+ <div class="col col-12 mb-3">
19
+ <%= lato_form_item_label form, :email %>
20
+ <%= lato_form_item_input_email form, :email, required: true, readonly: email_readonly %>
21
+ </div>
22
+
23
+ <div class="col col-12 col-md-6 mb-3">
24
+ <%= lato_form_item_label form, :password %>
25
+ <%= lato_form_item_input_password form, :password, required: true %>
26
+ </div>
27
+
28
+ <div class="col col-12 col-md-6 mb-3">
29
+ <%= lato_form_item_label form, :password_confirmation %>
30
+ <%= lato_form_item_input_password form, :password_confirmation, required: true %>
31
+ </div>
32
+ </div>
33
+
34
+ <div class="mb-3 text-muted" style="font-size: 14px;">
35
+ <%= lato_form_item_input_check form, :accepted_privacy_policy_version, I18n.t('lato.privacy_policy_checkbox', link: link_to(I18n.t('lato.privacy_policy'), Lato.config.legal_privacy_policy_url)), required: true %>
36
+ <%= lato_form_item_input_check form, :accepted_terms_and_conditions_version, I18n.t('lato.terms_and_conditions_checkbox', link: link_to(I18n.t('lato.terms_and_conditions'), Lato.config.legal_terms_and_conditions_url)), required: true %>
37
+ </div>
@@ -0,0 +1,18 @@
1
+ <%
2
+
3
+ user ||= Lato::User.new
4
+ invitation ||= Lato::Invitation.new
5
+
6
+ %>
7
+
8
+ <%= turbo_frame_tag 'authentication_form-signup' do %>
9
+ <%= form_with model: user, url: lato.authentication_accept_invitation_action_path(id: invitation.id, accepted_code: invitation.accepted_code), data: { turbo_frame: '_self', controller: 'lato-form' } do |form| %>
10
+ <%= lato_form_errors user, class: %w[mb-3] %>
11
+
12
+ <%= render 'lato/authentication/fields-registration', form: form, email_readonly: true %>
13
+
14
+ <div class="d-flex justify-content-end">
15
+ <%= lato_form_submit form, I18n.t('lato.confirm') %>
16
+ </div>
17
+ <% end %>
18
+ <% end %>
@@ -8,37 +8,7 @@ user ||= Lato::User.new
8
8
  <%= form_with model: user, url: lato.authentication_signup_action_path, data: { turbo_frame: '_self', controller: 'lato-form' } do |form| %>
9
9
  <%= lato_form_errors user, class: %w[mb-3] %>
10
10
 
11
- <div class="row">
12
- <div class="col col-12 col-md-6 mb-3">
13
- <%= lato_form_item_label form, :first_name %>
14
- <%= lato_form_item_input_text form, :first_name, required: true %>
15
- </div>
16
-
17
- <div class="col col-12 col-md-6 mb-3">
18
- <%= lato_form_item_label form, :last_name %>
19
- <%= lato_form_item_input_text form, :last_name, required: true %>
20
- </div>
21
-
22
- <div class="col col-12 mb-3">
23
- <%= lato_form_item_label form, :email %>
24
- <%= lato_form_item_input_email form, :email, required: true %>
25
- </div>
26
-
27
- <div class="col col-12 col-md-6 mb-3">
28
- <%= lato_form_item_label form, :password %>
29
- <%= lato_form_item_input_password form, :password, required: true %>
30
- </div>
31
-
32
- <div class="col col-12 col-md-6 mb-3">
33
- <%= lato_form_item_label form, :password_confirmation %>
34
- <%= lato_form_item_input_password form, :password_confirmation, required: true %>
35
- </div>
36
- </div>
37
-
38
- <div class="mb-3 text-muted" style="font-size: 14px;">
39
- <%= lato_form_item_input_check form, :accepted_privacy_policy_version, I18n.t('lato.privacy_policy_checkbox', link: link_to(I18n.t('lato.privacy_policy'), Lato.config.legal_privacy_policy_url)), required: true %>
40
- <%= lato_form_item_input_check form, :accepted_terms_and_conditions_version, I18n.t('lato.terms_and_conditions_checkbox', link: link_to(I18n.t('lato.terms_and_conditions'), Lato.config.legal_terms_and_conditions_url)), required: true %>
41
- </div>
11
+ <%= render 'lato/authentication/fields-registration', form: form %>
42
12
 
43
13
  <div class="d-flex justify-content-end">
44
14
  <%= lato_form_submit form, I18n.t('lato.signup') %>
@@ -0,0 +1,10 @@
1
+ <div class="w-100 h-100 d-flex justify-content-center align-items-center" style="min-height: calc(100vh - 54px - 2rem)">
2
+ <div class="card w-100" style="max-width: 550px">
3
+ <div class="card-header">
4
+ <h1 class="fs-3 mb-0 text-center"><%= I18n.t('lato.accept_invitation') %></h1>
5
+ </div>
6
+ <div class="card-body">
7
+ <%= render 'lato/authentication/form-accept-invitation', user: @user, invitation: @invitation %>
8
+ </div>
9
+ </div>
10
+ </div>
@@ -0,0 +1,17 @@
1
+ <% if I18n.locale == 'en' %>
2
+
3
+ You have received an invitation to use <%= Lato.config.application_title %>.
4
+ <br><br>
5
+ Click the following link to accept the invitation and complete the registration:
6
+ <br><br>
7
+ <%= link_to lato.authentication_accept_invitation_url(id: @invitation.id, accepted_code: @invitation.accepted_code), lato.authentication_accept_invitation_url(id: @invitation.id, accepted_code: @invitation.accepted_code) %>
8
+
9
+ <% else %>
10
+
11
+ Hai ricevuto un invito per utilizzare <%= Lato.config.application_title %>.
12
+ <br><br>
13
+ Clicca il seguente link per accettare l'invito e completare la registrazione:
14
+ <br><br>
15
+ <%= link_to lato.authentication_accept_invitation_url(id: @invitation.id, accepted_code: @invitation.accepted_code), lato.authentication_accept_invitation_url(id: @invitation.id, accepted_code: @invitation.accepted_code) %>
16
+
17
+ <% end %>
@@ -1,4 +1,4 @@
1
- <% if @user.locale == 'en' %>
1
+ <% if I18n.locale == 'en' %>
2
2
 
3
3
  To have access to all the features of <%= Lato.config.application_title %> you must confirm your email address.
4
4
  <br><br>
@@ -1,4 +1,4 @@
1
- <% if @user.locale == 'en' %>
1
+ <% if I18n.locale == 'en' %>
2
2
 
3
3
  An update to your <%= Lato.config.application_title %> account password has been requested.
4
4
  <br><br>
@@ -13,4 +13,19 @@
13
13
  </div>
14
14
  </div>
15
15
  <% end %>
16
+
17
+ <% if alert %>
18
+ <div class="position-fixed bottom-0 end-0 p-3" style="z-index: 11">
19
+ <div data-controller="lato-feedback" id="feedbackAlert" class="toast hide" role="alert" aria-live="assertive" aria-atomic="true">
20
+ <div class="toast-header">
21
+ <i class="bi bi-check-circle-fill text-danger me-2"></i>
22
+ <strong class="me-auto"><%= I18n.t('lato.operation_failed') %></strong>
23
+ <button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button>
24
+ </div>
25
+ <div class="toast-body">
26
+ <%= alert %>
27
+ </div>
28
+ </div>
29
+ </div>
30
+ <% end %>
16
31
  </div>
@@ -1,7 +1,7 @@
1
- <% if @user.locale == 'en' %>
2
- Hello <%= @user.first_name %>,
1
+ <% if I18n.locale == 'en' %>
2
+ Hello,
3
3
  <br><br>
4
4
  <% else %>
5
- Salve <%= @user.first_name %>,
5
+ Salve,
6
6
  <br><br>
7
- <%end %>
7
+ <% end %>
@@ -36,8 +36,10 @@ en:
36
36
  signout_confirmation_request: "%{user}, Are you sure to leave?"
37
37
  recover_password_code: Code received by email
38
38
  operation_completed: Operation completed
39
+ operation_failed: Operation failed
39
40
  privacy_policy_update_title: Privacy policy update
40
41
  terms_and_conditions_update_title: Terms and conditions update
42
+ accept_invitation: Accept invitation
41
43
 
42
44
  account_controller:
43
45
  update_user_action_notice: Account information properly updated
@@ -79,3 +81,9 @@ en:
79
81
  inclusion: not accepted
80
82
  accepted_terms_and_conditions_version:
81
83
  inclusion: not accepted
84
+ lato/invitation:
85
+ attributes:
86
+ base:
87
+ already_accepted: Invitation already accepted
88
+ email_sending_error: Unable to send mail
89
+ email_sending_limit: Wait at least 2 minutes to try a new invite attempt
@@ -38,8 +38,10 @@ it:
38
38
  signout_confirmation_request: "%{user}, Sei sicuro di voler uscire dal tuo account?"
39
39
  recover_password_code: Codice ricevuto via email
40
40
  operation_completed: Operazione completata
41
+ operation_failed: Operazione fallita
41
42
  privacy_policy_update_title: Aggiornamento privacy policy
42
43
  terms_and_conditions_update_title: Aggiornamento termini e condizioni
44
+ accept_invitation: Accetta invito
43
45
 
44
46
  account_controller:
45
47
  update_user_action_notice: Informazioni account aggiornate correttamente
@@ -76,6 +78,7 @@ it:
76
78
  password_update_code_invalid: Il codice di verifica non risulta valido
77
79
  privacy_policy_invalid: Per accettare la privacy policy devi selezionare la checkbox di conferma
78
80
  terms_and_conditions_invalid: Per accettare i termini e condizioni devi selezionare la checkbox di conferma
81
+ invitation_invalid: Invito non valido
79
82
  password:
80
83
  not_correct: non corretta
81
84
  password_confirmation:
@@ -88,6 +91,14 @@ it:
88
91
  inclusion: non accettata
89
92
  accepted_terms_and_conditions_version:
90
93
  inclusion: non accettati
94
+ lato/invitation:
95
+ attributes:
96
+ base:
97
+ already_accepted: Invito già accettato dall'utente
98
+ email_sending_error: Impossibile inviare mail
99
+ email_sending_limit: Attendi almeno 2 minuti per provare un nuovo tentativo di invito email
100
+
101
+
91
102
  date:
92
103
  abbr_day_names:
93
104
  - dom
data/config/routes.rb CHANGED
@@ -19,6 +19,8 @@ Lato::Engine.routes.draw do
19
19
  post 'recover_password_action', to: 'authentication#recover_password_action', as: :authentication_recover_password_action
20
20
  get 'update_password', to: 'authentication#update_password', as: :authentication_update_password
21
21
  patch 'update_password_action', to: 'authentication#update_password_action', as: :authentication_update_password_action
22
+ get 'accept_invitation', to: 'authentication#accept_invitation', as: :authentication_accept_invitation
23
+ post 'accept_invitation_action', to: 'authentication#accept_invitation_action', as: :authentication_accept_invitation_action
22
24
  end
23
25
 
24
26
  scope :account do
@@ -0,0 +1,10 @@
1
+ class CreateLatoLogUserSignins < ActiveRecord::Migration[7.0]
2
+ def change
3
+ create_table :lato_log_user_signins do |t|
4
+ t.string :ip_address
5
+ t.string :user_agent
6
+ t.references :lato_user, index: true, foreign_key: true
7
+ t.timestamps
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,11 @@
1
+ class CreateLatoInvitations < ActiveRecord::Migration[7.0]
2
+ def change
3
+ create_table :lato_invitations do |t|
4
+ t.string :email
5
+ t.datetime :accepted_at
6
+ t.string :accepted_code
7
+ t.references :lato_user, index: true, foreign_key: true
8
+ t.timestamps
9
+ end
10
+ end
11
+ end
data/lib/lato/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Lato
2
- VERSION = "0.1.26"
2
+ VERSION = "0.1.27"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lato
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.26
4
+ version: 0.1.27
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gregorio Galante
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-12-30 00:00:00.000000000 Z
11
+ date: 2023-01-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -130,9 +130,13 @@ files:
130
130
  - app/helpers/lato/components_helper.rb
131
131
  - app/jobs/lato/application_job.rb
132
132
  - app/mailers/lato/application_mailer.rb
133
+ - app/mailers/lato/invitation_mailer.rb
133
134
  - app/mailers/lato/user_mailer.rb
134
135
  - app/models/concerns/lato_user_application.rb
135
136
  - app/models/lato/application_record.rb
137
+ - app/models/lato/invitation.rb
138
+ - app/models/lato/log.rb
139
+ - app/models/lato/log/user_signin.rb
136
140
  - app/models/lato/operation.rb
137
141
  - app/models/lato/session.rb
138
142
  - app/models/lato/user.rb
@@ -142,11 +146,14 @@ files:
142
146
  - app/views/lato/account/_form-password.html.erb
143
147
  - app/views/lato/account/_form-user.html.erb
144
148
  - app/views/lato/account/index.html.erb
149
+ - app/views/lato/authentication/_fields-registration.html.erb
150
+ - app/views/lato/authentication/_form-accept-invitation.html.erb
145
151
  - app/views/lato/authentication/_form-recover-password.html.erb
146
152
  - app/views/lato/authentication/_form-signin.html.erb
147
153
  - app/views/lato/authentication/_form-signup.html.erb
148
154
  - app/views/lato/authentication/_form-update-password.html.erb
149
155
  - app/views/lato/authentication/_form-verify-email.html.erb
156
+ - app/views/lato/authentication/accept_invitation.html.erb
150
157
  - app/views/lato/authentication/recover_password.html.erb
151
158
  - app/views/lato/authentication/signin.html.erb
152
159
  - app/views/lato/authentication/signout.html.erb
@@ -159,6 +166,7 @@ files:
159
166
  - app/views/lato/components/_operation.html.erb
160
167
  - app/views/lato/components/_page_head.html.erb
161
168
  - app/views/lato/components/_sidebar_nav_item.html.erb
169
+ - app/views/lato/mailer/invitation/invite_mail.html.erb
162
170
  - app/views/lato/mailer/user/email_verification_mail.html.erb
163
171
  - app/views/lato/mailer/user/password_update_mail.html.erb
164
172
  - app/views/lato/operations/show.html.erb
@@ -183,6 +191,8 @@ files:
183
191
  - db/migrate/20221022205744_create_lato_users.rb
184
192
  - db/migrate/20221118072130_create_lato_operations.rb
185
193
  - db/migrate/20221229233844_add_locale_to_lato_user.rb
194
+ - db/migrate/20230109054412_create_lato_log_user_signins.rb
195
+ - db/migrate/20230109061533_create_lato_invitations.rb
186
196
  - lib/lato.rb
187
197
  - lib/lato/btstrap.rb
188
198
  - lib/lato/config.rb