lato 3.5.8 → 3.6.0
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.
- checksums.yaml +4 -4
- data/README.md +0 -1
- data/app/controllers/concerns/lato/componentable.rb +1 -1
- data/app/controllers/lato/account_controller.rb +14 -0
- data/app/controllers/lato/authentication_controller.rb +56 -8
- data/app/models/lato/user.rb +33 -1
- data/app/views/lato/account/_form-authenticator.html.erb +41 -0
- data/app/views/lato/account/index.html.erb +11 -0
- data/app/views/lato/authentication/_form-authenticator.html.erb +28 -0
- data/app/views/lato/authentication/authenticator.html.erb +10 -0
- data/config/locales/en.yml +10 -0
- data/config/locales/it.yml +10 -0
- data/config/routes.rb +3 -0
- data/db/migrate/20240318074025_add_authenticator_secret_to_user.rb +5 -0
- data/lib/lato/config.rb +7 -1
- data/lib/lato/dependency_helper.rb +44 -0
- data/lib/lato/version.rb +1 -1
- data/lib/lato.rb +3 -1
- metadata +36 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 124f38d5389e35689d3829980d788e5531af092d45fd378b5fbaabdc039ebe51
|
|
4
|
+
data.tar.gz: e6a938bc4549803deb41efd7df596e85148d84488d442f75ac46b9bb8c0191bd
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: fed883559fd4d1859aacc7ca6ca2dc2d65935c1d91d769c23ba71b940d2067cc8d320b84512a9adbd6b0a1540f7e3b33098664c89298a18277fda7fa548a7dc9
|
|
7
|
+
data.tar.gz: 9b87edd528d4c10bb7c82f4b8fa7769d6625560668657dea98b085661d22696c215d138fc3a5af0947d22cfb20c63b014503f472d99516bf6b0594398809e0ca
|
data/README.md
CHANGED
|
@@ -37,7 +37,7 @@ module Lato
|
|
|
37
37
|
if collection.respond_to?(:lato_index_search)
|
|
38
38
|
collection = collection.lato_index_search(search)
|
|
39
39
|
else
|
|
40
|
-
query = @_lato_index[key][:searchable_columns].map { |k| "lower(#{k}) LIKE :search" }
|
|
40
|
+
query = @_lato_index[key][:searchable_columns].map { |k| "#{k.to_s == 'id' ? k : "lower(#{k})"} LIKE :search" }
|
|
41
41
|
collection = collection.where(query.join(' OR '), search: "%#{search.downcase.strip}%")
|
|
42
42
|
end
|
|
43
43
|
end
|
|
@@ -55,6 +55,20 @@ module Lato
|
|
|
55
55
|
end
|
|
56
56
|
end
|
|
57
57
|
|
|
58
|
+
def update_authenticator_action
|
|
59
|
+
return respond_to_with_not_found unless Lato.config.authenticator_connection
|
|
60
|
+
|
|
61
|
+
respond_to do |format|
|
|
62
|
+
if @session.user.generate_authenticator_secret
|
|
63
|
+
format.html { redirect_to lato.account_path }
|
|
64
|
+
format.json { render json: @session.user }
|
|
65
|
+
else
|
|
66
|
+
format.html { render :index, status: :unprocessable_entity }
|
|
67
|
+
format.json { render json: @session.user.errors, status: :unprocessable_entity }
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
58
72
|
def request_verify_email_action
|
|
59
73
|
respond_to do |format|
|
|
60
74
|
if @session.user.request_verify_email
|
|
@@ -10,6 +10,7 @@ module Lato
|
|
|
10
10
|
before_action :lock_signup_if_disabled, only: %i[signup signup_action]
|
|
11
11
|
before_action :lock_recover_password_if_disabled, only: %i[recover_password recover_password_action update_password update_password_action]
|
|
12
12
|
before_action :lock_web3_if_disabled, only: %i[web3_signin web3_signin_action]
|
|
13
|
+
before_action :lock_authenticator_if_disabled, only: %i[authenticator authenticator_action]
|
|
13
14
|
|
|
14
15
|
before_action :hide_sidebar
|
|
15
16
|
|
|
@@ -28,10 +29,13 @@ module Lato
|
|
|
28
29
|
ip_address: request.remote_ip,
|
|
29
30
|
user_agent: request.user_agent
|
|
30
31
|
))
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
if create_session_or_start_authenticator(@user)
|
|
33
|
+
format.html { redirect_to lato.root_path }
|
|
34
|
+
format.json { render json: @user }
|
|
35
|
+
else
|
|
36
|
+
format.html { redirect_to lato.authentication_authenticator_path }
|
|
37
|
+
format.json { render json: @user }
|
|
38
|
+
end
|
|
35
39
|
else
|
|
36
40
|
format.html { render :signin, status: :unprocessable_entity }
|
|
37
41
|
format.json { render json: @user.errors, status: :unprocessable_entity }
|
|
@@ -54,10 +58,13 @@ module Lato
|
|
|
54
58
|
web3_nonce: session[:web3_nonce]
|
|
55
59
|
))
|
|
56
60
|
session[:web3_nonce] = nil
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
+
if create_session_or_start_authenticator(@user)
|
|
62
|
+
format.html { redirect_to lato.root_path }
|
|
63
|
+
format.json { render json: @user }
|
|
64
|
+
else
|
|
65
|
+
format.html { redirect_to lato.authentication_authenticator_path }
|
|
66
|
+
format.json { render json: @user }
|
|
67
|
+
end
|
|
61
68
|
else
|
|
62
69
|
session[:web3_nonce] = nil
|
|
63
70
|
format.html { render :web3_signin, status: :unprocessable_entity }
|
|
@@ -183,6 +190,31 @@ module Lato
|
|
|
183
190
|
end
|
|
184
191
|
end
|
|
185
192
|
|
|
193
|
+
# Authenticator
|
|
194
|
+
##
|
|
195
|
+
|
|
196
|
+
def authenticator
|
|
197
|
+
@user = Lato::User.find_by_id(session[:authenticator_user_id])
|
|
198
|
+
return respond_to_with_not_found unless @user
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
def authenticator_action
|
|
202
|
+
@user = Lato::User.find_by_id(session[:authenticator_user_id])
|
|
203
|
+
|
|
204
|
+
respond_to do |format|
|
|
205
|
+
if @user.authenticator(params.require(:user).permit(:authenticator_code))
|
|
206
|
+
session[:authenticator_user_id] = nil
|
|
207
|
+
session_create(@user.id)
|
|
208
|
+
|
|
209
|
+
format.html { redirect_to lato.root_path }
|
|
210
|
+
format.json { render json: @user }
|
|
211
|
+
else
|
|
212
|
+
format.html { render :authenticator, status: :unprocessable_entity }
|
|
213
|
+
format.json { render json: @user.errors, status: :unprocessable_entity }
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
end
|
|
217
|
+
|
|
186
218
|
private
|
|
187
219
|
|
|
188
220
|
def registration_params
|
|
@@ -199,6 +231,16 @@ module Lato
|
|
|
199
231
|
respond_to_with_not_found unless @invitation
|
|
200
232
|
end
|
|
201
233
|
|
|
234
|
+
def create_session_or_start_authenticator(user)
|
|
235
|
+
if !Lato.config.authenticator_connection || Lato.config.auth_disable_authenticator || !user.authenticator_enabled?
|
|
236
|
+
session_create(user.id)
|
|
237
|
+
return true
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
session[:authenticator_user_id] = user.id
|
|
241
|
+
false
|
|
242
|
+
end
|
|
243
|
+
|
|
202
244
|
def lock_signup_if_disabled
|
|
203
245
|
return unless Lato.config.auth_disable_signup
|
|
204
246
|
|
|
@@ -215,6 +257,12 @@ module Lato
|
|
|
215
257
|
return if Lato.config.web3_connection && !Lato.config.auth_disable_web3
|
|
216
258
|
|
|
217
259
|
|
|
260
|
+
respond_to_with_not_found
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
def lock_authenticator_if_disabled
|
|
264
|
+
return if Lato.config.authenticator_connection && !Lato.config.auth_disable_authenticator
|
|
265
|
+
|
|
218
266
|
respond_to_with_not_found
|
|
219
267
|
end
|
|
220
268
|
end
|
data/app/models/lato/user.rb
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
module Lato
|
|
2
2
|
class User < ApplicationRecord
|
|
3
|
+
include Lato::DependencyHelper
|
|
3
4
|
include LatoUserApplication
|
|
4
5
|
|
|
5
6
|
has_secure_password
|
|
@@ -53,6 +54,10 @@ module Lato
|
|
|
53
54
|
@valid_accepted_terms_and_conditions_version ||= accepted_terms_and_conditions_version >= Lato.config.legal_terms_and_conditions_version
|
|
54
55
|
end
|
|
55
56
|
|
|
57
|
+
def authenticator_enabled?
|
|
58
|
+
!authenticator_secret.blank?
|
|
59
|
+
end
|
|
60
|
+
|
|
56
61
|
# Helpers
|
|
57
62
|
##
|
|
58
63
|
|
|
@@ -64,6 +69,10 @@ module Lato
|
|
|
64
69
|
@gravatar_image_url ||= "https://www.gravatar.com/avatar/#{Digest::MD5.hexdigest(email)}?s=#{size}"
|
|
65
70
|
end
|
|
66
71
|
|
|
72
|
+
def authenticator_qr_code_base64(size = 200)
|
|
73
|
+
"data:image/png;base64,#{Base64.strict_encode64(RQRCode::QRCode.new(ROTP::TOTP.new(authenticator_secret, :issuer => Lato.config.application_title).provisioning_uri(email).to_s).as_png(size: size, border_modules: 0).to_s)}"
|
|
74
|
+
end
|
|
75
|
+
|
|
67
76
|
# Operations
|
|
68
77
|
##
|
|
69
78
|
|
|
@@ -112,6 +121,8 @@ module Lato
|
|
|
112
121
|
end
|
|
113
122
|
|
|
114
123
|
def web3_signin(params)
|
|
124
|
+
depends_on('eth')
|
|
125
|
+
|
|
115
126
|
self.web3_address = params[:web3_address]
|
|
116
127
|
|
|
117
128
|
user = Lato::User.find_by(web3_address: params[:web3_address].downcase)
|
|
@@ -221,7 +232,9 @@ module Lato
|
|
|
221
232
|
|
|
222
233
|
c_password_update_code('')
|
|
223
234
|
|
|
224
|
-
update(params.permit(:password, :password_confirmation)
|
|
235
|
+
update(params.permit(:password, :password_confirmation).merge(
|
|
236
|
+
authenticator_secret: nil # Reset authenticator secret when password is updated
|
|
237
|
+
))
|
|
225
238
|
end
|
|
226
239
|
|
|
227
240
|
def update_accepted_privacy_policy_version(params)
|
|
@@ -269,6 +282,8 @@ module Lato
|
|
|
269
282
|
end
|
|
270
283
|
|
|
271
284
|
def add_web3_connection(params)
|
|
285
|
+
depends_on('eth')
|
|
286
|
+
|
|
272
287
|
signature_pubkey = Eth::Signature.personal_recover(params[:web3_nonce], params[:web3_signed_nonce])
|
|
273
288
|
signature_address = Eth::Util.public_key_to_address signature_pubkey
|
|
274
289
|
unless signature_address.to_s.downcase == params[:web3_address].downcase
|
|
@@ -287,6 +302,23 @@ module Lato
|
|
|
287
302
|
true
|
|
288
303
|
end
|
|
289
304
|
|
|
305
|
+
def generate_authenticator_secret
|
|
306
|
+
update(authenticator_secret: ROTP::Base32.random)
|
|
307
|
+
end
|
|
308
|
+
|
|
309
|
+
def authenticator(params)
|
|
310
|
+
return false unless authenticator_enabled?
|
|
311
|
+
|
|
312
|
+
totp = ROTP::TOTP.new(authenticator_secret)
|
|
313
|
+
result = totp.verify(params[:authenticator_code])
|
|
314
|
+
unless result
|
|
315
|
+
errors.add(:base, :authenticator_code_invalid)
|
|
316
|
+
return
|
|
317
|
+
end
|
|
318
|
+
|
|
319
|
+
true
|
|
320
|
+
end
|
|
321
|
+
|
|
290
322
|
# Cache
|
|
291
323
|
##
|
|
292
324
|
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
<%
|
|
2
|
+
|
|
3
|
+
user ||= Lato::User.new
|
|
4
|
+
|
|
5
|
+
%>
|
|
6
|
+
|
|
7
|
+
<%= turbo_frame_tag 'account_form-authenticator' do %>
|
|
8
|
+
<%= form_with model: user, url: lato.account_update_authenticator_action_path, data: { turbo_frame: '_self', controller: 'lato-form' } do |form| %>
|
|
9
|
+
<%= lato_form_notices class: %w[mb-3] %>
|
|
10
|
+
<%= lato_form_errors user, class: %w[mb-3] %>
|
|
11
|
+
|
|
12
|
+
<% if user.authenticator_secret %>
|
|
13
|
+
<div class="d-block d-md-flex align-items-stretch">
|
|
14
|
+
<div class="text-center mb-3 mb-md-0 me-md-3">
|
|
15
|
+
<img src="<%= user.authenticator_qr_code_base64 %>" />
|
|
16
|
+
</div>
|
|
17
|
+
<div class="d-flex flex-column justify-content-between">
|
|
18
|
+
<div class="alert alert-light">
|
|
19
|
+
<p>
|
|
20
|
+
<%= raw I18n.t('lato.account_authenticator_ready_qr') %>
|
|
21
|
+
</p>
|
|
22
|
+
</div>
|
|
23
|
+
|
|
24
|
+
<div class="d-flex justify-content-end">
|
|
25
|
+
<%= lato_form_submit form, I18n.t('lato.reset_qr_code'), class: %w[btn-danger] %>
|
|
26
|
+
</div>
|
|
27
|
+
</div>
|
|
28
|
+
</div>
|
|
29
|
+
<% else %>
|
|
30
|
+
<div class="alert alert-light mb-0">
|
|
31
|
+
<h4 class="alert-heading"><%= I18n.t('lato.account_authenticator_start_title') %></h4>
|
|
32
|
+
<p>
|
|
33
|
+
<%= raw I18n.t('lato.account_authenticator_start_description') %>
|
|
34
|
+
</p>
|
|
35
|
+
<p class="mb-0">
|
|
36
|
+
<%= lato_form_submit form, I18n.t('lato.generate_qr_code'), class: %w[btn-primary] %>
|
|
37
|
+
</p>
|
|
38
|
+
</div>
|
|
39
|
+
<% end %>
|
|
40
|
+
<% end %>
|
|
41
|
+
<% end %>
|
|
@@ -32,6 +32,17 @@
|
|
|
32
32
|
</div>
|
|
33
33
|
<% end %>
|
|
34
34
|
|
|
35
|
+
<% if Lato.config.authenticator_connection %>
|
|
36
|
+
<div class="card mb-4">
|
|
37
|
+
<div class="card-header">
|
|
38
|
+
<h2 class="fs-4 mb-0"><%= I18n.t('lato.account_authenticator') %></h2>
|
|
39
|
+
</div>
|
|
40
|
+
<div class="card-body">
|
|
41
|
+
<%= render 'lato/account/form-authenticator', user: @session.user %>
|
|
42
|
+
</div>
|
|
43
|
+
</div>
|
|
44
|
+
<% end %>
|
|
45
|
+
|
|
35
46
|
<div class="card mb-4">
|
|
36
47
|
<div class="card-header">
|
|
37
48
|
<h2 class="fs-4 mb-0"><%= I18n.t('lato.account_delete') %></h2>
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
<%
|
|
2
|
+
|
|
3
|
+
user ||= Lato::User.new
|
|
4
|
+
|
|
5
|
+
%>
|
|
6
|
+
|
|
7
|
+
<%= turbo_frame_tag 'authentication_form-authenticator' do %>
|
|
8
|
+
<%= form_with model: user, url: lato.authentication_authenticator_action_path, method: :post, data: { turbo_frame: '_self', controller: 'lato-form' } do |form| %>
|
|
9
|
+
<%= lato_form_notices class: %w[mb-3] %>
|
|
10
|
+
<%= lato_form_errors user, class: %w[mb-3] %>
|
|
11
|
+
|
|
12
|
+
<div class="mb-3 text-center">
|
|
13
|
+
<p><%= raw I18n.t('lato.authenticator_code_help', email: user.email) %></p>
|
|
14
|
+
</div>
|
|
15
|
+
|
|
16
|
+
<div class="mb-3">
|
|
17
|
+
<%= lato_form_item_input_text form, :authenticator_code, required: true %>
|
|
18
|
+
</div>
|
|
19
|
+
|
|
20
|
+
<div>
|
|
21
|
+
<%= lato_form_submit form, I18n.t('lato.confirm'), class: %w[d-block w-100] %>
|
|
22
|
+
</div>
|
|
23
|
+
|
|
24
|
+
<div class="text-center mt-3 mb-3">
|
|
25
|
+
<%= I18n.t('lato.or').downcase %> <%= link_to I18n.t('lato.reset_password').downcase, lato.authentication_recover_password_path %>
|
|
26
|
+
</div>
|
|
27
|
+
<% end %>
|
|
28
|
+
<% end %>
|
|
@@ -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: 400px">
|
|
3
|
+
<div class="card-header">
|
|
4
|
+
<h1 class="fs-3 mb-0 text-center"><%= I18n.t('lato.authenticator') %></h1>
|
|
5
|
+
</div>
|
|
6
|
+
<div class="card-body">
|
|
7
|
+
<%= render 'lato/authentication/form-authenticator', user: @user %>
|
|
8
|
+
</div>
|
|
9
|
+
</div>
|
|
10
|
+
</div>
|
data/config/locales/en.yml
CHANGED
|
@@ -49,6 +49,15 @@ en:
|
|
|
49
49
|
web3_signin: Web3 Login
|
|
50
50
|
retry: Retry
|
|
51
51
|
back: Go back
|
|
52
|
+
account_authenticator: Google Authenticator
|
|
53
|
+
account_authenticator_start_title: Enable Google Authenticator
|
|
54
|
+
account_authenticator_start_description: Generate a QR code by clicking the button below and scan it with the Google Authenticator app on your phone.<br>This will allow you to use the protect your account with a second factor authentication.
|
|
55
|
+
account_authenticator_ready_qr: Scan the QR code with the Google Authenticator app to use the account protection with a second factor authentication.
|
|
56
|
+
generate_qr_code: Generate QR code
|
|
57
|
+
reset_qr_code: Reset QR code
|
|
58
|
+
authenticator: Two-factor authentication
|
|
59
|
+
authenticator_code_help: Insert the code generated by the Google Authenticator app for the account <b>%{email}</b>
|
|
60
|
+
reset_password: Reset your password
|
|
52
61
|
|
|
53
62
|
account_controller:
|
|
54
63
|
update_user_action_notice: Account information properly updated
|
|
@@ -82,6 +91,7 @@ en:
|
|
|
82
91
|
terms_and_conditions_invalid: To accept the terms and conditions you must select the confirmation checkbox
|
|
83
92
|
web3_address_invalid: The address you send is not corretly signed
|
|
84
93
|
web3_connection_error: Impossible to connect the wallet
|
|
94
|
+
authenticator_code_invalid: The code you inserted is not correct
|
|
85
95
|
password:
|
|
86
96
|
not_correct: not correct
|
|
87
97
|
email:
|
data/config/locales/it.yml
CHANGED
|
@@ -51,6 +51,15 @@ it:
|
|
|
51
51
|
web3_signin: Accedi con Web3
|
|
52
52
|
retry: Riprova
|
|
53
53
|
back: Torna indietro
|
|
54
|
+
account_authenticator: Google Authenticator
|
|
55
|
+
account_authenticator_start_title: Abilita Google Authenticator
|
|
56
|
+
account_authenticator_start_description: Genera un codice QR cliccando il pulsante sottostante e scansionalo con l'app Google Authenticator sul tuo telefono.<br>Questo ti permetterà di proteggere il tuo account con un'autenticazione a due fattori.
|
|
57
|
+
account_authenticator_ready_qr: Scansiona il codice QR con l'app Google Authenticator per utilizzare la protezione dell'account con un'autenticazione a due fattori.
|
|
58
|
+
generate_qr_code: Genera codice QR
|
|
59
|
+
reset_qr_code: Resetta codice QR
|
|
60
|
+
authenticator: Autenticazione a due fattori
|
|
61
|
+
authenticator_code_help: Inserisci il codice generato dall'app Google Authenticator per l'account <b>%{email}</b>
|
|
62
|
+
reset_password: Reimposta la tua password
|
|
54
63
|
|
|
55
64
|
account_controller:
|
|
56
65
|
update_user_action_notice: Informazioni account aggiornate correttamente
|
|
@@ -90,6 +99,7 @@ it:
|
|
|
90
99
|
invitation_invalid: Invito non valido
|
|
91
100
|
web3_address_invalid: L'inidirizzo inviato non è correttamente firmato
|
|
92
101
|
web3_connection_error: Impossibile connettere il wallet
|
|
102
|
+
authenticator_code_invalid: Il codice inserito non è corretto
|
|
93
103
|
password:
|
|
94
104
|
not_correct: non corretta
|
|
95
105
|
password_confirmation:
|
data/config/routes.rb
CHANGED
|
@@ -26,6 +26,8 @@ Lato::Engine.routes.draw do
|
|
|
26
26
|
patch 'update_password_action', to: 'authentication#update_password_action', as: :authentication_update_password_action
|
|
27
27
|
get 'accept_invitation', to: 'authentication#accept_invitation', as: :authentication_accept_invitation
|
|
28
28
|
post 'accept_invitation_action', to: 'authentication#accept_invitation_action', as: :authentication_accept_invitation_action
|
|
29
|
+
get 'authenticator', to: 'authentication#authenticator', as: :authentication_authenticator
|
|
30
|
+
post 'authenticator_action', to: 'authentication#authenticator_action', as: :authentication_authenticator_action
|
|
29
31
|
end
|
|
30
32
|
|
|
31
33
|
# Account
|
|
@@ -35,6 +37,7 @@ Lato::Engine.routes.draw do
|
|
|
35
37
|
get '', to: 'account#index', as: :account
|
|
36
38
|
patch 'update_user_action', to: 'account#update_user_action', as: :account_update_user_action
|
|
37
39
|
patch 'update_web3_action', to: 'account#update_web3_action', as: :account_update_web3_action
|
|
40
|
+
patch 'update_authenticator_action', to: 'account#update_authenticator_action', as: :account_update_authenticator_action
|
|
38
41
|
patch 'request_verify_email_action', to: 'account#request_verify_email_action', as: :account_request_verify_email_action
|
|
39
42
|
patch 'update_password_action', to: 'account#update_password_action', as: :account_update_password_action
|
|
40
43
|
delete 'destroy_action', to: 'account#destroy_action', as: :account_destroy_action
|
data/lib/lato/config.rb
CHANGED
|
@@ -10,7 +10,7 @@ module Lato
|
|
|
10
10
|
attr_accessor :session_lifetime, :session_root_path
|
|
11
11
|
|
|
12
12
|
# Authentication configs
|
|
13
|
-
attr_accessor :auth_disable_signup, :auth_disable_recover_password, :auth_disable_web3
|
|
13
|
+
attr_accessor :auth_disable_signup, :auth_disable_recover_password, :auth_disable_web3, :auth_disable_authenticator
|
|
14
14
|
|
|
15
15
|
# Assets configs
|
|
16
16
|
attr_accessor :assets_stylesheet_entry
|
|
@@ -22,8 +22,12 @@ module Lato
|
|
|
22
22
|
attr_accessor :legal_privacy_policy_url, :legal_privacy_policy_version, :legal_terms_and_conditions_url, :legal_terms_and_conditions_version
|
|
23
23
|
|
|
24
24
|
# Web3 connection
|
|
25
|
+
# NOTE: It requires the gem 'eth' to be installed in the application Gemfile
|
|
25
26
|
attr_accessor :web3_connection
|
|
26
27
|
|
|
28
|
+
# Authenticator connection
|
|
29
|
+
attr_accessor :authenticator_connection
|
|
30
|
+
|
|
27
31
|
def initialize
|
|
28
32
|
@application_title = 'Lato'
|
|
29
33
|
@application_version = '1.0.0'
|
|
@@ -34,6 +38,7 @@ module Lato
|
|
|
34
38
|
@auth_disable_signup = false
|
|
35
39
|
@auth_disable_recover_password = false
|
|
36
40
|
@auth_disable_web3 = false
|
|
41
|
+
@auth_disable_authenticator = false
|
|
37
42
|
|
|
38
43
|
@assets_stylesheet_entry = 'application'
|
|
39
44
|
|
|
@@ -48,6 +53,7 @@ module Lato
|
|
|
48
53
|
@legal_terms_and_conditions_version = 1
|
|
49
54
|
|
|
50
55
|
@web3_connection = false
|
|
56
|
+
@authenticator_connection = false
|
|
51
57
|
end
|
|
52
58
|
end
|
|
53
59
|
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# NOTE: Taken from https://github.com/andreibondarev/langchainrb/blob/main/lib/langchain/dependency_helper.rb
|
|
4
|
+
# Thanks to Andrei Bondarev for the inspiration!!
|
|
5
|
+
|
|
6
|
+
module Lato
|
|
7
|
+
module DependencyHelper
|
|
8
|
+
class LoadError < ::LoadError; end
|
|
9
|
+
|
|
10
|
+
class VersionError < ScriptError; end
|
|
11
|
+
|
|
12
|
+
# This method requires and loads the given gem, and then checks to see if the version of the gem meets the requirements listed in `lato.gemspec`
|
|
13
|
+
# This solution was built to avoid auto-loading every single gem in the Gemfile when the developer will mostly likely be only using a few of them.
|
|
14
|
+
#
|
|
15
|
+
# @param gem_name [String] The name of the gem to load
|
|
16
|
+
# @return [Boolean] Whether or not the gem was loaded successfully
|
|
17
|
+
# @raise [LoadError] If the gem is not installed
|
|
18
|
+
# @raise [VersionError] If the gem is installed, but the version does not meet the requirements
|
|
19
|
+
#
|
|
20
|
+
def depends_on(gem_name, req: true)
|
|
21
|
+
gem(gem_name) # require the gem
|
|
22
|
+
|
|
23
|
+
return(true) unless defined?(Bundler) # If we're in a non-bundler environment, we're no longer able to determine if we'll meet requirements
|
|
24
|
+
|
|
25
|
+
gem_version = Gem.loaded_specs[gem_name].version
|
|
26
|
+
gem_requirement = Bundler.load.dependencies.find { |g| g.name == gem_name }&.requirement
|
|
27
|
+
|
|
28
|
+
raise LoadError unless gem_requirement
|
|
29
|
+
|
|
30
|
+
unless gem_requirement.satisfied_by?(gem_version)
|
|
31
|
+
raise VersionError, "The #{gem_name} gem is installed, but version #{gem_requirement} is required. You have #{gem_version}."
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
lib_name = gem_name if req == true
|
|
35
|
+
lib_name = req if req.is_a?(String)
|
|
36
|
+
|
|
37
|
+
require(lib_name) if lib_name
|
|
38
|
+
|
|
39
|
+
true
|
|
40
|
+
rescue ::LoadError
|
|
41
|
+
raise LoadError, "Could not load #{gem_name}. Please ensure that the #{gem_name} gem is installed."
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
data/lib/lato/version.rb
CHANGED
data/lib/lato.rb
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
require "kaminari"
|
|
2
2
|
require "bootstrap"
|
|
3
3
|
require "browser"
|
|
4
|
-
require "
|
|
4
|
+
require "rotp"
|
|
5
|
+
require "rqrcode"
|
|
5
6
|
|
|
6
7
|
require "lato/version"
|
|
7
8
|
require "lato/engine"
|
|
8
9
|
require "lato/config"
|
|
9
10
|
require "lato/btstrap"
|
|
11
|
+
require "lato/dependency_helper"
|
|
10
12
|
|
|
11
13
|
module Lato
|
|
12
14
|
class << self
|
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: 3.
|
|
4
|
+
version: 3.6.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Gregorio Galante
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2024-03-
|
|
11
|
+
date: 2024-03-27 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rails
|
|
@@ -95,7 +95,21 @@ dependencies:
|
|
|
95
95
|
- !ruby/object:Gem::Version
|
|
96
96
|
version: '0'
|
|
97
97
|
- !ruby/object:Gem::Dependency
|
|
98
|
-
name:
|
|
98
|
+
name: rqrcode
|
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
|
100
|
+
requirements:
|
|
101
|
+
- - ">="
|
|
102
|
+
- !ruby/object:Gem::Version
|
|
103
|
+
version: '0'
|
|
104
|
+
type: :runtime
|
|
105
|
+
prerelease: false
|
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
107
|
+
requirements:
|
|
108
|
+
- - ">="
|
|
109
|
+
- !ruby/object:Gem::Version
|
|
110
|
+
version: '0'
|
|
111
|
+
- !ruby/object:Gem::Dependency
|
|
112
|
+
name: rotp
|
|
99
113
|
requirement: !ruby/object:Gem::Requirement
|
|
100
114
|
requirements:
|
|
101
115
|
- - ">="
|
|
@@ -108,6 +122,20 @@ dependencies:
|
|
|
108
122
|
- - ">="
|
|
109
123
|
- !ruby/object:Gem::Version
|
|
110
124
|
version: '0'
|
|
125
|
+
- !ruby/object:Gem::Dependency
|
|
126
|
+
name: eth
|
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
|
128
|
+
requirements:
|
|
129
|
+
- - ">="
|
|
130
|
+
- !ruby/object:Gem::Version
|
|
131
|
+
version: '0'
|
|
132
|
+
type: :development
|
|
133
|
+
prerelease: false
|
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
135
|
+
requirements:
|
|
136
|
+
- - ">="
|
|
137
|
+
- !ruby/object:Gem::Version
|
|
138
|
+
version: '0'
|
|
111
139
|
description: A Rails engine that includes what you need to build a new project!
|
|
112
140
|
email:
|
|
113
141
|
- me@gregoriogalante.com
|
|
@@ -162,6 +190,7 @@ files:
|
|
|
162
190
|
- app/models/lato/user.rb
|
|
163
191
|
- app/views/lato/account/_alert-accepted-privacy-policy-version.html.erb
|
|
164
192
|
- app/views/lato/account/_alert-accepted-terms-and-conditions-version.html.erb
|
|
193
|
+
- app/views/lato/account/_form-authenticator.html.erb
|
|
165
194
|
- app/views/lato/account/_form-destroy.html.erb
|
|
166
195
|
- app/views/lato/account/_form-password.html.erb
|
|
167
196
|
- app/views/lato/account/_form-user.html.erb
|
|
@@ -169,6 +198,7 @@ files:
|
|
|
169
198
|
- app/views/lato/account/index.html.erb
|
|
170
199
|
- app/views/lato/authentication/_fields-registration.html.erb
|
|
171
200
|
- app/views/lato/authentication/_form-accept-invitation.html.erb
|
|
201
|
+
- app/views/lato/authentication/_form-authenticator.html.erb
|
|
172
202
|
- app/views/lato/authentication/_form-recover-password.html.erb
|
|
173
203
|
- app/views/lato/authentication/_form-signin.html.erb
|
|
174
204
|
- app/views/lato/authentication/_form-signup.html.erb
|
|
@@ -176,6 +206,7 @@ files:
|
|
|
176
206
|
- app/views/lato/authentication/_form-verify-email.html.erb
|
|
177
207
|
- app/views/lato/authentication/_form-web3-signin.html.erb
|
|
178
208
|
- app/views/lato/authentication/accept_invitation.html.erb
|
|
209
|
+
- app/views/lato/authentication/authenticator.html.erb
|
|
179
210
|
- app/views/lato/authentication/recover_password.html.erb
|
|
180
211
|
- app/views/lato/authentication/signin.html.erb
|
|
181
212
|
- app/views/lato/authentication/signout.html.erb
|
|
@@ -226,9 +257,11 @@ files:
|
|
|
226
257
|
- db/migrate/20230823165716_create_lato_log_user_signups.rb
|
|
227
258
|
- db/migrate/20240222125124_add_web3_to_lato_users.rb
|
|
228
259
|
- db/migrate/20240222171418_add_indexes_on_lato_users_email.rb
|
|
260
|
+
- db/migrate/20240318074025_add_authenticator_secret_to_user.rb
|
|
229
261
|
- lib/lato.rb
|
|
230
262
|
- lib/lato/btstrap.rb
|
|
231
263
|
- lib/lato/config.rb
|
|
264
|
+
- lib/lato/dependency_helper.rb
|
|
232
265
|
- lib/lato/engine.rb
|
|
233
266
|
- lib/lato/version.rb
|
|
234
267
|
- lib/tasks/lato_tasks.rake
|