lato 3.26.1 → 3.27.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 +14 -32
- data/app/assets/config/lato_manifest.js +3 -1
- data/app/assets/fonts/lato/bootstrap-icons.woff +0 -0
- data/app/assets/fonts/lato/bootstrap-icons.woff2 +0 -0
- data/app/assets/javascripts/lato/controllers/lato_account_webauthn_controller.js +1 -1
- data/app/assets/javascripts/lato/controllers/lato_auto_submit_controller.js +8 -0
- data/app/assets/javascripts/lato/controllers/lato_input_autocomplete2_controller.js +2 -2
- data/app/assets/javascripts/lato/controllers/lato_input_autocomplete_controller.js +2 -2
- data/app/assets/javascripts/lato/controllers/lato_web3_sign_controller.js +30 -0
- data/app/assets/javascripts/lato/debounce.js +8 -0
- data/app/assets/javascripts/lato/vendor/ethers.esm.min.js +1 -0
- data/app/assets/stylesheets/lato/_bootstrap-icons.scss +2079 -0
- data/app/assets/stylesheets/lato/application.scss +1 -1
- data/app/controllers/concerns/lato/sessionable.rb +1 -0
- data/app/controllers/lato/authentication_controller.rb +1 -0
- data/app/models/lato/invitation.rb +9 -0
- data/app/models/lato/session.rb +30 -1
- data/app/models/lato/user.rb +20 -4
- data/app/views/lato/account/_form-web3.html.erb +6 -35
- data/app/views/lato/authentication/_form-verify-email.html.erb +1 -2
- data/app/views/lato/authentication/_form-web3-signin.html.erb +6 -35
- data/app/views/layouts/lato/application.html.erb +2 -2
- data/config/importmap.rb +4 -3
- data/config/locales/en.yml +1 -0
- data/config/locales/fr.yml +1 -0
- data/config/locales/it.yml +1 -0
- data/config/locales/ro.yml +1 -0
- data/lib/lato/config.rb +19 -0
- data/lib/lato/version.rb +1 -1
- metadata +8 -1
|
@@ -20,7 +20,7 @@ $gray-900: #1f262c !default;
|
|
|
20
20
|
$tooltip-opacity: 1;
|
|
21
21
|
$tooltip-max-width: 300px;
|
|
22
22
|
|
|
23
|
-
@import
|
|
23
|
+
@import "bootstrap-icons";
|
|
24
24
|
@import "bootstrap";
|
|
25
25
|
|
|
26
26
|
/** Turbo loading **/
|
|
@@ -50,6 +50,14 @@ module Lato
|
|
|
50
50
|
!!accepted_at
|
|
51
51
|
end
|
|
52
52
|
|
|
53
|
+
# The lifetime counts from the last time the invitation email was sent (send_invite touches the record).
|
|
54
|
+
def expired?
|
|
55
|
+
lifetime = Lato.config.invitation_lifetime
|
|
56
|
+
return false if lifetime.blank? || accepted?
|
|
57
|
+
|
|
58
|
+
updated_at.present? && updated_at <= lifetime.ago
|
|
59
|
+
end
|
|
60
|
+
|
|
53
61
|
# Operations
|
|
54
62
|
##
|
|
55
63
|
|
|
@@ -71,6 +79,7 @@ module Lato
|
|
|
71
79
|
end
|
|
72
80
|
|
|
73
81
|
c_email_invite_semaphore(true)
|
|
82
|
+
touch
|
|
74
83
|
|
|
75
84
|
true
|
|
76
85
|
end
|
data/app/models/lato/session.rb
CHANGED
|
@@ -69,6 +69,21 @@ module Lato
|
|
|
69
69
|
end
|
|
70
70
|
end
|
|
71
71
|
|
|
72
|
+
# Activity is written at most once per interval to avoid a database write on every request.
|
|
73
|
+
ACTIVITY_TOUCH_INTERVAL = 1.minute
|
|
74
|
+
|
|
75
|
+
# Revokes the session when idle for longer than Lato.config.session_idle_timeout, otherwise records the activity.
|
|
76
|
+
def track_activity
|
|
77
|
+
timeout = Lato.config.session_idle_timeout
|
|
78
|
+
return unless timeout && (current = unexpired_record)
|
|
79
|
+
|
|
80
|
+
if current.updated_at <= timeout.ago
|
|
81
|
+
current.destroy!
|
|
82
|
+
elsif current.updated_at <= [ACTIVITY_TOUCH_INTERVAL, timeout / 2].min.ago
|
|
83
|
+
current.touch
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
72
87
|
def destroy
|
|
73
88
|
record&.destroy!
|
|
74
89
|
@session = nil
|
|
@@ -88,9 +103,23 @@ module Lato
|
|
|
88
103
|
|
|
89
104
|
# Always query revocation state, including when a Session instance was already used.
|
|
90
105
|
def record
|
|
106
|
+
scope = unexpired_record_scope
|
|
107
|
+
return unless scope
|
|
108
|
+
|
|
109
|
+
timeout = Lato.config.session_idle_timeout
|
|
110
|
+
scope = scope.where("updated_at > ?", timeout.ago) if timeout
|
|
111
|
+
scope.first
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# Not expired record, ignoring the idle timeout.
|
|
115
|
+
def unexpired_record
|
|
116
|
+
unexpired_record_scope&.first
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def unexpired_record_scope
|
|
91
120
|
return unless @session&.dig(:token).is_a?(String) && @session[:token].present?
|
|
92
121
|
|
|
93
|
-
Lato::SessionRecord.where(lato_user_id: @session[:user_id], token_digest: Digest::SHA256.hexdigest(@session[:token])).where("expires_at > ?", Time.current)
|
|
122
|
+
Lato::SessionRecord.where(lato_user_id: @session[:user_id], token_digest: Digest::SHA256.hexdigest(@session[:token])).where("expires_at > ?", Time.current)
|
|
94
123
|
end
|
|
95
124
|
|
|
96
125
|
def parse_session(session)
|
data/app/models/lato/user.rb
CHANGED
|
@@ -7,6 +7,9 @@ module Lato
|
|
|
7
7
|
|
|
8
8
|
has_secure_password
|
|
9
9
|
|
|
10
|
+
# Evaluated when the class loads: Lato.config.encrypt_authenticator_secret must be set in an initializer.
|
|
11
|
+
encrypts :authenticator_secret if Lato.config.encrypt_authenticator_secret
|
|
12
|
+
|
|
10
13
|
# Validations
|
|
11
14
|
##
|
|
12
15
|
|
|
@@ -333,6 +336,11 @@ module Lato
|
|
|
333
336
|
return
|
|
334
337
|
end
|
|
335
338
|
|
|
339
|
+
if invitation.expired?
|
|
340
|
+
errors.add(:base, :invitation_expired)
|
|
341
|
+
return
|
|
342
|
+
end
|
|
343
|
+
|
|
336
344
|
ActiveRecord::Base.transaction do
|
|
337
345
|
raise ActiveRecord::Rollback unless save && invitation.update(
|
|
338
346
|
accepted_at: Time.now,
|
|
@@ -376,13 +384,15 @@ module Lato
|
|
|
376
384
|
name: email,
|
|
377
385
|
display_name: full_name
|
|
378
386
|
},
|
|
379
|
-
exclude: webauthn_exclude_credentials.map { |cred| Base64.strict_encode64(cred) }
|
|
387
|
+
exclude: webauthn_exclude_credentials.map { |cred| Base64.strict_encode64(cred) },
|
|
388
|
+
authenticator_selection: { user_verification: Lato.config.webauthn_user_verification }
|
|
380
389
|
)
|
|
381
390
|
end
|
|
382
391
|
|
|
383
392
|
def webauthn_authentication_options
|
|
384
393
|
WebAuthn::Credential.options_for_get(
|
|
385
|
-
allow: webauthn_allow_credentials.map { |cred| Base64.strict_encode64(cred) }
|
|
394
|
+
allow: webauthn_allow_credentials.map { |cred| Base64.strict_encode64(cred) },
|
|
395
|
+
user_verification: Lato.config.webauthn_user_verification
|
|
386
396
|
)
|
|
387
397
|
end
|
|
388
398
|
|
|
@@ -399,7 +409,7 @@ module Lato
|
|
|
399
409
|
|
|
400
410
|
parsed_payload = JSON.parse(credential_payload)
|
|
401
411
|
credential = WebAuthn::Credential.from_create(parsed_payload)
|
|
402
|
-
credential.verify(Base64.strict_decode64(encoded_challenge))
|
|
412
|
+
credential.verify(Base64.strict_decode64(encoded_challenge), user_verification: webauthn_user_verification_required?)
|
|
403
413
|
|
|
404
414
|
update(
|
|
405
415
|
webauthn_id: Base64.strict_encode64(credential.raw_id),
|
|
@@ -440,7 +450,8 @@ module Lato
|
|
|
440
450
|
credential.verify(
|
|
441
451
|
encoded_challenge,
|
|
442
452
|
public_key: webauthn_public_key,
|
|
443
|
-
sign_count: webauthn_sign_count.to_i
|
|
453
|
+
sign_count: webauthn_sign_count.to_i,
|
|
454
|
+
user_verification: webauthn_user_verification_required?
|
|
444
455
|
)
|
|
445
456
|
update_column(:webauthn_sign_count, credential.sign_count.to_i)
|
|
446
457
|
|
|
@@ -563,6 +574,11 @@ module Lato
|
|
|
563
574
|
)
|
|
564
575
|
end
|
|
565
576
|
|
|
577
|
+
# The client honours the requested level only as a hint: "required" must also be checked on the response.
|
|
578
|
+
def webauthn_user_verification_required?
|
|
579
|
+
Lato.config.webauthn_user_verification.to_s == 'required'
|
|
580
|
+
end
|
|
581
|
+
|
|
566
582
|
def webauthn_user_handle
|
|
567
583
|
Digest::SHA256.digest("lato-user-#{id}")
|
|
568
584
|
end
|
|
@@ -36,41 +36,12 @@ user ||= Lato::User.new
|
|
|
36
36
|
</div>
|
|
37
37
|
</div>
|
|
38
38
|
|
|
39
|
-
<
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
(async () => {
|
|
46
|
-
// Pinned exact version: dynamic import() can not carry an SRI hash (see README security checklist).
|
|
47
|
-
const ethers = await import('https://cdnjs.cloudflare.com/ajax/libs/ethers/5.7.2/ethers.esm.min.js')
|
|
48
|
-
|
|
49
|
-
const nonce = document.getElementById('account_form-web3__nonce').textContent
|
|
50
|
-
const inputAddress = document.getElementById('account_form-web3__input-web3_address')
|
|
51
|
-
const inputSignedNonce = document.getElementById('account_form-web3__input-web3_signed_nonce')
|
|
52
|
-
const submitButton = document.getElementById('account_form-web3__submit')
|
|
53
|
-
|
|
54
|
-
let address = ''
|
|
55
|
-
let signedNonce = ''
|
|
56
|
-
|
|
57
|
-
try {
|
|
58
|
-
if (window.ethereum) {
|
|
59
|
-
const provider = new ethers.ethers.providers.Web3Provider(window.ethereum)
|
|
60
|
-
await provider.send('eth_requestAccounts', [])
|
|
61
|
-
const signer = provider.getSigner()
|
|
62
|
-
address = await signer.getAddress()
|
|
63
|
-
signedNonce = await signer.signMessage(nonce)
|
|
64
|
-
}
|
|
65
|
-
} catch (error) {
|
|
66
|
-
console.error(error)
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
inputAddress.value = address
|
|
70
|
-
inputSignedNonce.value = signedNonce
|
|
71
|
-
submitButton.click()
|
|
72
|
-
})()
|
|
73
|
-
</script>
|
|
39
|
+
<div data-controller="lato-web3-sign">
|
|
40
|
+
<span id="account_form-web3__nonce" style="display: none;" data-lato-web3-sign-target="nonce"><%= session[:web3_nonce] %></span>
|
|
41
|
+
<%= form.hidden_field :web3_address, id: 'account_form-web3__input-web3_address', data: { lato_web3_sign_target: 'address' } %>
|
|
42
|
+
<%= form.hidden_field :web3_signed_nonce, id: 'account_form-web3__input-web3_signed_nonce', data: { lato_web3_sign_target: 'signedNonce' } %>
|
|
43
|
+
<%= lato_form_submit form, I18n.t('lato.confirm'), class: %w[btn-primary d-none], id: 'account_form-web3__submit', data: { lato_web3_sign_target: 'submit' } %>
|
|
44
|
+
</div>
|
|
74
45
|
<% else %>
|
|
75
46
|
<div class="alert alert-light mb-0">
|
|
76
47
|
<h3 class="alert-heading h4"><%= I18n.t('lato.account_web3_start_title') %></h3>
|
|
@@ -7,12 +7,11 @@ code ||= nil
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
<%= turbo_frame_tag 'authentication_form_verify_email' do %>
|
|
10
|
-
<%= form_with model: user, url: lato.authentication_verify_email_action_path(id: user.id), class: 'text-center', data: { turbo_frame: '_self' } do |form| %>
|
|
10
|
+
<%= form_with model: user, url: lato.authentication_verify_email_action_path(id: user.id), class: 'text-center', data: { turbo_frame: '_self', controller: code ? 'lato-auto-submit' : nil } do |form| %>
|
|
11
11
|
<% if code %>
|
|
12
12
|
<%= form.hidden_field :code, value: code %>
|
|
13
13
|
<%# Visible fallback when JavaScript is disabled or blocked by CSP. %>
|
|
14
14
|
<button type="submit" class="btn btn-primary"><%= I18n.t('lato.verify_email') %></button>
|
|
15
|
-
<script>document.getElementById('authentication_form_verify_email').querySelector('button[type="submit"]').click()</script>
|
|
16
15
|
<% else %>
|
|
17
16
|
<%= lato_form_notices class: %w[mb-3], fixed: true %>
|
|
18
17
|
<%= lato_form_errors user, class: %w[mb-3], fixed: true %>
|
|
@@ -18,41 +18,12 @@ user ||= Lato::User.new
|
|
|
18
18
|
</div>
|
|
19
19
|
</div>
|
|
20
20
|
|
|
21
|
-
<
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
(async () => {
|
|
28
|
-
// Pinned exact version: dynamic import() can not carry an SRI hash (see README security checklist).
|
|
29
|
-
const ethers = await import('https://cdnjs.cloudflare.com/ajax/libs/ethers/5.7.2/ethers.esm.min.js')
|
|
30
|
-
|
|
31
|
-
const nonce = document.getElementById('account_form-web3__nonce').textContent
|
|
32
|
-
const inputAddress = document.getElementById('account_form-web3__input-web3_address')
|
|
33
|
-
const inputSignedNonce = document.getElementById('account_form-web3__input-web3_signed_nonce')
|
|
34
|
-
const submitButton = document.getElementById('account_form-web3__submit')
|
|
35
|
-
|
|
36
|
-
let address = ''
|
|
37
|
-
let signedNonce = ''
|
|
38
|
-
|
|
39
|
-
try {
|
|
40
|
-
if (window.ethereum) {
|
|
41
|
-
const provider = new ethers.ethers.providers.Web3Provider(window.ethereum)
|
|
42
|
-
await provider.send('eth_requestAccounts', [])
|
|
43
|
-
const signer = provider.getSigner()
|
|
44
|
-
address = await signer.getAddress()
|
|
45
|
-
signedNonce = await signer.signMessage(nonce)
|
|
46
|
-
}
|
|
47
|
-
} catch (error) {
|
|
48
|
-
console.error(error)
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
inputAddress.value = address
|
|
52
|
-
inputSignedNonce.value = signedNonce
|
|
53
|
-
submitButton.click()
|
|
54
|
-
})()
|
|
55
|
-
</script>
|
|
21
|
+
<div data-controller="lato-web3-sign">
|
|
22
|
+
<span id="account_form-web3__nonce" style="display: none;" data-lato-web3-sign-target="nonce"><%= session[:web3_nonce] %></span>
|
|
23
|
+
<%= form.hidden_field :web3_address, id: 'account_form-web3__input-web3_address', data: { lato_web3_sign_target: 'address' } %>
|
|
24
|
+
<%= form.hidden_field :web3_signed_nonce, id: 'account_form-web3__input-web3_signed_nonce', data: { lato_web3_sign_target: 'signedNonce' } %>
|
|
25
|
+
<%= lato_form_submit form, I18n.t('lato.confirm'), class: %w[btn-primary d-none], id: 'account_form-web3__submit', data: { lato_web3_sign_target: 'submit' } %>
|
|
26
|
+
</div>
|
|
56
27
|
|
|
57
28
|
<% else %>
|
|
58
29
|
<div class="text-center">
|
|
@@ -17,8 +17,8 @@
|
|
|
17
17
|
|
|
18
18
|
<%= render 'layouts/lato/head_content' %>
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
<%# Popper UMD build from the popper_js gem (bootstrap dependency): Bootstrap reads it from window.Popper %>
|
|
21
|
+
<%= javascript_include_tag "popper" %>
|
|
22
22
|
|
|
23
23
|
<%= stylesheet_link_tag Lato.config.assets_stylesheet_entry, media: "all" %>
|
|
24
24
|
<%= javascript_importmap_tags Lato.config.assets_importmap_entry %>
|
data/config/importmap.rb
CHANGED
|
@@ -4,6 +4,7 @@ pin_all_from Lato::Engine.root.join("app/assets/javascripts/lato/controllers"),
|
|
|
4
4
|
pin "@rails/activestorage", to: "activestorage.esm.js", preload: true
|
|
5
5
|
|
|
6
6
|
pin "bootstrap", to: "bootstrap.js", preload: true
|
|
7
|
-
|
|
8
|
-
pin "
|
|
9
|
-
|
|
7
|
+
pin "local-time", to: "local-time.es2017-esm.js"
|
|
8
|
+
pin "lato/debounce", to: "lato/debounce.js"
|
|
9
|
+
# Vendored (verified against the cdnjs SRI hash) and loaded on demand by the web3 controller.
|
|
10
|
+
pin "ethers", to: "lato/vendor/ethers.esm.min.js", preload: false
|
data/config/locales/en.yml
CHANGED
|
@@ -169,6 +169,7 @@ en:
|
|
|
169
169
|
privacy_policy_invalid: To accept the privacy policy you must select the confirmation checkbox
|
|
170
170
|
terms_and_conditions_invalid: To accept the terms and conditions you must select the confirmation checkbox
|
|
171
171
|
invitation_invalid: Invalid invitation
|
|
172
|
+
invitation_expired: Invitation expired, ask for a new one
|
|
172
173
|
web3_address_invalid: The address you send is not corretly signed
|
|
173
174
|
web3_connection_error: Impossible to connect the wallet
|
|
174
175
|
authenticator_code_invalid: The code you inserted is not correct
|
data/config/locales/fr.yml
CHANGED
|
@@ -176,6 +176,7 @@ fr:
|
|
|
176
176
|
privacy_policy_invalid: Pour accepter la politique de confidentialité, vous devez cocher la case de confirmation
|
|
177
177
|
terms_and_conditions_invalid: Pour accepter les conditions générales, vous devez cocher la case de confirmation
|
|
178
178
|
invitation_invalid: Invitation non valide
|
|
179
|
+
invitation_expired: Invitation expirée, demandez-en une nouvelle
|
|
179
180
|
web3_address_invalid: L'adresse envoyée n'est pas correctement signée
|
|
180
181
|
web3_connection_error: Impossible de connecter le portefeuille
|
|
181
182
|
authenticator_code_invalid: Le code saisi n'est pas correct
|
data/config/locales/it.yml
CHANGED
|
@@ -176,6 +176,7 @@ it:
|
|
|
176
176
|
privacy_policy_invalid: Per accettare la privacy policy devi selezionare la checkbox di conferma
|
|
177
177
|
terms_and_conditions_invalid: Per accettare i termini e condizioni devi selezionare la checkbox di conferma
|
|
178
178
|
invitation_invalid: Invito non valido
|
|
179
|
+
invitation_expired: Invito scaduto, richiedine uno nuovo
|
|
179
180
|
web3_address_invalid: L'inidirizzo inviato non è correttamente firmato
|
|
180
181
|
web3_connection_error: Impossibile connettere il wallet
|
|
181
182
|
authenticator_code_invalid: Il codice inserito non è corretto
|
data/config/locales/ro.yml
CHANGED
|
@@ -176,6 +176,7 @@ ro:
|
|
|
176
176
|
privacy_policy_invalid: Pentru a accepta politica de confidențialitate trebuie să bifezi căsuța de confirmare
|
|
177
177
|
terms_and_conditions_invalid: Pentru a accepta termenii și condițiile trebuie să bifezi căsuța de confirmare
|
|
178
178
|
invitation_invalid: Invitație nevalidă
|
|
179
|
+
invitation_expired: Invitație expirată, solicită una nouă
|
|
179
180
|
web3_address_invalid: Adresa trimisă nu este semnată corect
|
|
180
181
|
web3_connection_error: Imposibil să se conecteze portofelul
|
|
181
182
|
authenticator_code_invalid: Codul introdus nu este corect
|
data/lib/lato/config.rb
CHANGED
|
@@ -9,6 +9,9 @@ module Lato
|
|
|
9
9
|
# Session configs
|
|
10
10
|
attr_accessor :session_lifetime, :session_root_path
|
|
11
11
|
|
|
12
|
+
# Revoke sessions inactive for longer than this duration (nil disables the check)
|
|
13
|
+
attr_accessor :session_idle_timeout
|
|
14
|
+
|
|
12
15
|
# Authentication configs
|
|
13
16
|
attr_accessor :auth_disable_signup, :auth_disable_recover_password, :auth_disable_web3, :auth_disable_authenticator, :auth_disable_webauthn, :auth_disable_signin_success_mail
|
|
14
17
|
|
|
@@ -18,6 +21,9 @@ module Lato
|
|
|
18
21
|
# Minimum password length, checked whenever a password is set
|
|
19
22
|
attr_accessor :auth_password_min_length
|
|
20
23
|
|
|
24
|
+
# Invitations not accepted within this duration from the last invitation email expire (nil means they never expire)
|
|
25
|
+
attr_accessor :invitation_lifetime
|
|
26
|
+
|
|
21
27
|
# Hcaptcha configs
|
|
22
28
|
attr_accessor :hcaptcha_site_key, :hcaptcha_secret
|
|
23
29
|
|
|
@@ -37,6 +43,13 @@ module Lato
|
|
|
37
43
|
# Webauth connection
|
|
38
44
|
attr_accessor :webauthn_connection, :webauthn_origin, :webauthn_rp_name
|
|
39
45
|
|
|
46
|
+
# WebAuthn user verification: "discouraged", "preferred" or "required" (enforced server-side)
|
|
47
|
+
attr_accessor :webauthn_user_verification
|
|
48
|
+
|
|
49
|
+
# Encrypt Lato::User#authenticator_secret with Active Record encryption.
|
|
50
|
+
# Read when Lato::User is loaded: set it in an initializer.
|
|
51
|
+
attr_accessor :encrypt_authenticator_secret
|
|
52
|
+
|
|
40
53
|
# Web3 connection
|
|
41
54
|
# NOTE: It requires the gem 'eth' to be installed in the application Gemfile
|
|
42
55
|
attr_accessor :web3_connection
|
|
@@ -66,6 +79,9 @@ module Lato
|
|
|
66
79
|
|
|
67
80
|
@session_lifetime = 30.days
|
|
68
81
|
@session_root_path = nil # :tutorial_path
|
|
82
|
+
@session_idle_timeout = nil
|
|
83
|
+
|
|
84
|
+
@invitation_lifetime = 30.days
|
|
69
85
|
|
|
70
86
|
@email_from = 'lato@example.com'
|
|
71
87
|
|
|
@@ -79,6 +95,9 @@ module Lato
|
|
|
79
95
|
@webauthn_connection = false
|
|
80
96
|
@webauthn_origin = 'http://localhost:3000'
|
|
81
97
|
@webauthn_rp_name = 'Lato Application'
|
|
98
|
+
@webauthn_user_verification = 'preferred'
|
|
99
|
+
|
|
100
|
+
@encrypt_authenticator_secret = false
|
|
82
101
|
end
|
|
83
102
|
end
|
|
84
103
|
end
|
data/lib/lato/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: lato
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.
|
|
4
|
+
version: 3.27.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Gregorio Galante
|
|
@@ -186,6 +186,8 @@ files:
|
|
|
186
186
|
- README.md
|
|
187
187
|
- Rakefile
|
|
188
188
|
- app/assets/config/lato_manifest.js
|
|
189
|
+
- app/assets/fonts/lato/bootstrap-icons.woff
|
|
190
|
+
- app/assets/fonts/lato/bootstrap-icons.woff2
|
|
189
191
|
- app/assets/images/lato/user-150x150.jpg
|
|
190
192
|
- app/assets/images/lato/user-300x300.jpg
|
|
191
193
|
- app/assets/images/lato/user-600x600.jpg
|
|
@@ -198,6 +200,7 @@ files:
|
|
|
198
200
|
- app/assets/javascripts/lato/controllers/lato_account_webauthn_controller.js
|
|
199
201
|
- app/assets/javascripts/lato/controllers/lato_action_controller.js
|
|
200
202
|
- app/assets/javascripts/lato/controllers/lato_aside_opener_controller.js
|
|
203
|
+
- app/assets/javascripts/lato/controllers/lato_auto_submit_controller.js
|
|
201
204
|
- app/assets/javascripts/lato/controllers/lato_confirm_controller.js
|
|
202
205
|
- app/assets/javascripts/lato/controllers/lato_copyclip_controller.js
|
|
203
206
|
- app/assets/javascripts/lato/controllers/lato_feedback_controller.js
|
|
@@ -214,7 +217,11 @@ files:
|
|
|
214
217
|
- app/assets/javascripts/lato/controllers/lato_network_controller.js
|
|
215
218
|
- app/assets/javascripts/lato/controllers/lato_operation_controller.js
|
|
216
219
|
- app/assets/javascripts/lato/controllers/lato_tooltip_controller.js
|
|
220
|
+
- app/assets/javascripts/lato/controllers/lato_web3_sign_controller.js
|
|
217
221
|
- app/assets/javascripts/lato/controllers/lato_webauthn_auth_controller.js
|
|
222
|
+
- app/assets/javascripts/lato/debounce.js
|
|
223
|
+
- app/assets/javascripts/lato/vendor/ethers.esm.min.js
|
|
224
|
+
- app/assets/stylesheets/lato/_bootstrap-icons.scss
|
|
218
225
|
- app/assets/stylesheets/lato/application.scss
|
|
219
226
|
- app/controllers/concerns/lato/componentable.rb
|
|
220
227
|
- app/controllers/concerns/lato/layoutable.rb
|