lato 3.5.4 → 3.5.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/controllers/lato/account_controller.rb +6 -4
- data/app/controllers/lato/authentication_controller.rb +5 -6
- data/app/models/lato/user.rb +7 -56
- data/app/views/lato/account/_form-web3.html.erb +13 -9
- data/app/views/lato/authentication/_form-web3-signin.html.erb +52 -36
- data/app/views/lato/components/_index.html.erb +1 -1
- data/config/locales/en.yml +2 -1
- data/config/locales/it.yml +2 -1
- data/lib/lato/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 483e3307bae77fd1b1958ac3a135d079c88c26956946e32f05d5579cb8ff4f18
|
4
|
+
data.tar.gz: a0fbdb88be7672b6d1ee63dd84e460455214ec5c6ee3c37e7cf97bfc3f515eec
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0171b96580ff965fd37ae3bf3cae1f08a072896b3916903017dd701cb9d5f13d835bdae907f9b0d903f2fe13733726aacf52584db23dd95dc7cf381a3c85437c
|
7
|
+
data.tar.gz: a85c0609a7ea4ac253b16fc3e65b47e453d83237869534255fb448b07abfd1cfdb3087f512c705a57d4ef951ebb8f6d9ba2455cd5e8302e3c0f3053669fa8637
|
@@ -20,7 +20,7 @@ module Lato
|
|
20
20
|
def update_web3_action
|
21
21
|
return respond_to_with_not_found unless Lato.config.web3_connection
|
22
22
|
|
23
|
-
if @session.user.
|
23
|
+
if @session.user.web3_address
|
24
24
|
respond_to do |format|
|
25
25
|
if @session.user.remove_web3_connection
|
26
26
|
format.html { redirect_to lato.account_path }
|
@@ -30,19 +30,21 @@ module Lato
|
|
30
30
|
format.json { render json: @session.user.errors, status: :unprocessable_entity }
|
31
31
|
end
|
32
32
|
end
|
33
|
-
elsif
|
33
|
+
elsif session[:web3_nonce]
|
34
34
|
respond_to do |format|
|
35
|
-
if @session.user.
|
35
|
+
if @session.user.add_web3_connection(params.require(:user).permit(:web3_address, :web3_signed_nonce).merge(web3_nonce: session[:web3_nonce]))
|
36
|
+
session[:web3_nonce] = nil
|
36
37
|
format.html { redirect_to lato.account_path }
|
37
38
|
format.json { render json: @session.user }
|
38
39
|
else
|
40
|
+
session[:web3_nonce] = nil
|
39
41
|
format.html { render :index, status: :unprocessable_entity }
|
40
42
|
format.json { render json: @session.user.errors, status: :unprocessable_entity }
|
41
43
|
end
|
42
44
|
end
|
43
45
|
else
|
44
46
|
respond_to do |format|
|
45
|
-
if
|
47
|
+
if session[:web3_nonce] = SecureRandom.hex(32)
|
46
48
|
format.html { redirect_to lato.account_path }
|
47
49
|
format.json { render json: @session.user }
|
48
50
|
else
|
@@ -40,27 +40,26 @@ module Lato
|
|
40
40
|
end
|
41
41
|
|
42
42
|
def web3_signin
|
43
|
-
session[:web3_signin_id] = SecureRandom.hex
|
44
|
-
|
45
43
|
@user = Lato::User.new
|
46
|
-
|
47
|
-
@user.start_web3_signin
|
44
|
+
session[:web3_nonce] = SecureRandom.hex(32)
|
48
45
|
end
|
49
46
|
|
50
47
|
def web3_signin_action
|
51
48
|
@user = Lato::User.new
|
52
|
-
@user.id = session[:web3_signin_id] # This is a temporary id to identify the user
|
53
49
|
|
54
50
|
respond_to do |format|
|
55
51
|
if @user.web3_signin(params.require(:user).permit(:web3_address, :web3_signed_nonce).merge(
|
56
52
|
ip_address: request.remote_ip,
|
57
|
-
user_agent: request.user_agent
|
53
|
+
user_agent: request.user_agent,
|
54
|
+
web3_nonce: session[:web3_nonce]
|
58
55
|
))
|
56
|
+
session[:web3_nonce] = nil
|
59
57
|
session_create(@user.id)
|
60
58
|
|
61
59
|
format.html { redirect_to lato.root_path }
|
62
60
|
format.json { render json: @user }
|
63
61
|
else
|
62
|
+
session[:web3_nonce] = nil
|
64
63
|
format.html { render :web3_signin, status: :unprocessable_entity }
|
65
64
|
format.json { render json: @user.errors, status: :unprocessable_entity }
|
66
65
|
end
|
data/app/models/lato/user.rb
CHANGED
@@ -53,14 +53,6 @@ module Lato
|
|
53
53
|
@valid_accepted_terms_and_conditions_version ||= accepted_terms_and_conditions_version >= Lato.config.legal_terms_and_conditions_version
|
54
54
|
end
|
55
55
|
|
56
|
-
def web3_connection_completed?
|
57
|
-
@web3_connection_completed ||= !web3_address.blank?
|
58
|
-
end
|
59
|
-
|
60
|
-
def web3_connection_started?
|
61
|
-
@web3_connection_started ||= !c_web3_nonce.blank?
|
62
|
-
end
|
63
|
-
|
64
56
|
# Helpers
|
65
57
|
##
|
66
58
|
|
@@ -119,10 +111,6 @@ module Lato
|
|
119
111
|
true
|
120
112
|
end
|
121
113
|
|
122
|
-
def start_web3_signin
|
123
|
-
c_web3_nonce(SecureRandom.hex(32))
|
124
|
-
end
|
125
|
-
|
126
114
|
def web3_signin(params)
|
127
115
|
self.web3_address = params[:web3_address]
|
128
116
|
|
@@ -132,7 +120,7 @@ module Lato
|
|
132
120
|
return
|
133
121
|
end
|
134
122
|
|
135
|
-
signature_pubkey = Eth::Signature.personal_recover(
|
123
|
+
signature_pubkey = Eth::Signature.personal_recover(params[:web3_nonce], params[:web3_signed_nonce])
|
136
124
|
signature_address = Eth::Util.public_key_to_address signature_pubkey
|
137
125
|
unless signature_address.to_s.downcase == params[:web3_address].downcase
|
138
126
|
errors.add(:web3_signed_nonce, :not_correct)
|
@@ -151,8 +139,10 @@ module Lato
|
|
151
139
|
Rails.logger.error(e)
|
152
140
|
end
|
153
141
|
|
154
|
-
c_web3_nonce__clear
|
155
142
|
true
|
143
|
+
rescue StandardError => e
|
144
|
+
errors.add(:base, :web3_connection_error)
|
145
|
+
false
|
156
146
|
end
|
157
147
|
|
158
148
|
def request_verify_email
|
@@ -278,45 +268,22 @@ module Lato
|
|
278
268
|
end
|
279
269
|
end
|
280
270
|
|
281
|
-
def
|
282
|
-
|
283
|
-
c_web3_nonce(SecureRandom.hex(32))
|
284
|
-
|
285
|
-
true
|
286
|
-
end
|
287
|
-
|
288
|
-
def complete_web3_connection(params)
|
289
|
-
nonce = c_web3_nonce
|
290
|
-
c_web3_nonce__clear # Important to rollback to status 0 of web3 connection
|
291
|
-
|
292
|
-
unless nonce
|
293
|
-
errors.add(:base, :web3_nonce_expired)
|
294
|
-
return
|
295
|
-
end
|
296
|
-
|
297
|
-
signature_pubkey = Eth::Signature.personal_recover(nonce, params[:web3_signed_nonce])
|
271
|
+
def add_web3_connection(params)
|
272
|
+
signature_pubkey = Eth::Signature.personal_recover(params[:web3_nonce], params[:web3_signed_nonce])
|
298
273
|
signature_address = Eth::Util.public_key_to_address signature_pubkey
|
299
274
|
unless signature_address.to_s.downcase == params[:web3_address].downcase
|
300
275
|
errors.add(:base, :web3_address_invalid)
|
301
276
|
return
|
302
277
|
end
|
303
278
|
|
304
|
-
|
305
|
-
return true if result
|
306
|
-
|
307
|
-
web3_address = nil # Important to rollback to status 0 of web3 connection
|
308
|
-
reload
|
309
|
-
|
310
|
-
false
|
279
|
+
update(web3_address: params[:web3_address])
|
311
280
|
rescue StandardError => e
|
312
|
-
c_web3_nonce__clear # Important to rollback to status 0 of web3 connection
|
313
281
|
errors.add(:base, :web3_connection_error)
|
314
282
|
false
|
315
283
|
end
|
316
284
|
|
317
285
|
def remove_web3_connection
|
318
286
|
update(web3_address: nil)
|
319
|
-
c_web3_nonce__clear
|
320
287
|
true
|
321
288
|
end
|
322
289
|
|
@@ -346,21 +313,5 @@ module Lato
|
|
346
313
|
Rails.cache.write(cache_key, value, expires_in: 30.minutes)
|
347
314
|
value
|
348
315
|
end
|
349
|
-
|
350
|
-
def c_web3_nonce(value = nil)
|
351
|
-
cache_key = "Lato::User/c_web3_nonce/#{id}"
|
352
|
-
return Rails.cache.read(cache_key) if value.nil?
|
353
|
-
|
354
|
-
Rails.cache.write(cache_key, value, expires_in: 1.minutes)
|
355
|
-
@web3_connection_started = nil # HARD FIX: reset web3 connection status
|
356
|
-
value
|
357
|
-
end
|
358
|
-
|
359
|
-
def c_web3_nonce__clear
|
360
|
-
cache_key = "Lato::User/c_web3_nonce/#{id}"
|
361
|
-
Rails.cache.delete(cache_key)
|
362
|
-
@web3_connection_started = nil # HARD FIX: reset web3 connection status
|
363
|
-
true
|
364
|
-
end
|
365
316
|
end
|
366
317
|
end
|
@@ -9,7 +9,7 @@ user ||= Lato::User.new
|
|
9
9
|
<%= lato_form_notices class: %w[mb-3] %>
|
10
10
|
<%= lato_form_errors user, class: %w[mb-3] %>
|
11
11
|
|
12
|
-
<% if user.
|
12
|
+
<% if user.web3_address %>
|
13
13
|
<div class="row">
|
14
14
|
<div class="col col-12 mb-3">
|
15
15
|
<%= lato_form_item_label form, :web3_address %>
|
@@ -23,7 +23,7 @@ user ||= Lato::User.new
|
|
23
23
|
<div class="d-flex justify-content-end">
|
24
24
|
<%= lato_form_submit form, I18n.t('lato.disconnect_wallet'), class: %w[btn-danger] %>
|
25
25
|
</div>
|
26
|
-
<% elsif
|
26
|
+
<% elsif session[:web3_nonce] %>
|
27
27
|
<div class="alert alert-light mb-0">
|
28
28
|
<h4 class="alert-heading">Connecting..</h4>
|
29
29
|
<div class="progress" role="progressbar" aria-valuenow="100" aria-valuemin="0" aria-valuemax="100">
|
@@ -31,7 +31,7 @@ user ||= Lato::User.new
|
|
31
31
|
</div>
|
32
32
|
</div>
|
33
33
|
|
34
|
-
<span id="account_form-web3__nonce" style="display: none;"><%=
|
34
|
+
<span id="account_form-web3__nonce" style="display: none;"><%= session[:web3_nonce] %></span>
|
35
35
|
<%= form.hidden_field :web3_address, id: 'account_form-web3__input-web3_address' %>
|
36
36
|
<%= form.hidden_field :web3_signed_nonce, id: 'account_form-web3__input-web3_signed_nonce' %>
|
37
37
|
<%= lato_form_submit form, 'Confirm', class: %w[btn-primary d-none], id: 'account_form-web3__submit' %>
|
@@ -48,12 +48,16 @@ user ||= Lato::User.new
|
|
48
48
|
let address = ''
|
49
49
|
let signedNonce = ''
|
50
50
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
51
|
+
try {
|
52
|
+
if (window.ethereum) {
|
53
|
+
const provider = new ethers.ethers.providers.Web3Provider(window.ethereum)
|
54
|
+
await provider.send('eth_requestAccounts', [])
|
55
|
+
const signer = provider.getSigner()
|
56
|
+
address = await signer.getAddress()
|
57
|
+
signedNonce = await signer.signMessage(nonce)
|
58
|
+
}
|
59
|
+
} catch (error) {
|
60
|
+
console.error(error)
|
57
61
|
}
|
58
62
|
|
59
63
|
inputAddress.value = address
|
@@ -8,43 +8,59 @@ user ||= Lato::User.new
|
|
8
8
|
<%= form_with model: user, url: lato.authentication_web3_signin_action_path, data: { turbo_frame: '_self', controller: 'lato-form' } do |form| %>
|
9
9
|
<%= lato_form_notices class: %w[mb-3] %>
|
10
10
|
<%= lato_form_errors user, class: %w[mb-3] %>
|
11
|
+
|
12
|
+
<% if session[:web3_nonce] %>
|
11
13
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
14
|
+
<div class="alert alert-light mb-0 text-center">
|
15
|
+
<h4 class="alert-heading">Connecting..</h4>
|
16
|
+
<div class="progress" role="progressbar" aria-valuenow="100" aria-valuemin="0" aria-valuemax="100">
|
17
|
+
<div class="progress-bar progress-bar-striped progress-bar-animated" style="width: 100%"></div>
|
18
|
+
</div>
|
16
19
|
</div>
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
20
|
+
|
21
|
+
<span id="account_form-web3__nonce" style="display: none;"><%= session[:web3_nonce] %></span>
|
22
|
+
<%= form.hidden_field :web3_address, id: 'account_form-web3__input-web3_address' %>
|
23
|
+
<%= form.hidden_field :web3_signed_nonce, id: 'account_form-web3__input-web3_signed_nonce' %>
|
24
|
+
<%= lato_form_submit form, 'Confirm', class: %w[btn-primary d-none], id: 'account_form-web3__submit' %>
|
25
|
+
|
26
|
+
<script>
|
27
|
+
(async () => {
|
28
|
+
const ethers = await import('https://cdnjs.cloudflare.com/ajax/libs/ethers/5.7.2/ethers.esm.min.js')
|
29
|
+
|
30
|
+
const nonce = document.getElementById('account_form-web3__nonce').innerText
|
31
|
+
const inputAddress = document.getElementById('account_form-web3__input-web3_address')
|
32
|
+
const inputSignedNonce = document.getElementById('account_form-web3__input-web3_signed_nonce')
|
33
|
+
const submitButton = document.getElementById('account_form-web3__submit')
|
34
|
+
|
35
|
+
let address = ''
|
36
|
+
let signedNonce = ''
|
37
|
+
|
38
|
+
try {
|
39
|
+
if (window.ethereum) {
|
40
|
+
const provider = new ethers.ethers.providers.Web3Provider(window.ethereum)
|
41
|
+
await provider.send('eth_requestAccounts', [])
|
42
|
+
const signer = provider.getSigner()
|
43
|
+
address = await signer.getAddress()
|
44
|
+
signedNonce = await signer.signMessage(nonce)
|
45
|
+
}
|
46
|
+
} catch (error) {
|
47
|
+
console.error(error)
|
48
|
+
}
|
49
|
+
|
50
|
+
inputAddress.value = address
|
51
|
+
inputSignedNonce.value = signedNonce
|
52
|
+
submitButton.click()
|
53
|
+
})()
|
54
|
+
</script>
|
55
|
+
|
56
|
+
<% else %>
|
57
|
+
<div class="text-center">
|
58
|
+
<%= link_to I18n.t('lato.retry'), lato.authentication_web3_signin_path, class: %w[btn btn-primary], data: { turbo_frame: '_self' } %>
|
59
|
+
|
60
|
+
<div class="mt-3">
|
61
|
+
<%= I18n.t('lato.or').downcase %> <%= link_to I18n.t('lato.back').downcase, lato.authentication_signin_path %>
|
62
|
+
</div>
|
63
|
+
</div>
|
64
|
+
<% end %>
|
49
65
|
<% end %>
|
50
66
|
<% end %>
|
@@ -82,7 +82,7 @@ collection_total = collection.respond_to?(:total_count) ? collection.total_count
|
|
82
82
|
<tr class="align-middle">
|
83
83
|
<% columns.each do |column| %>
|
84
84
|
<th scope="col" class="lato-index-desk-col-label lato-index-desk-col-label-<%= column %>">
|
85
|
-
<div class="d-flex align-items-center">
|
85
|
+
<div class="d-flex align-items-center justify-content-between">
|
86
86
|
<span><%= collection_test_istance.respond_to?(column) ? collection.model.human_attribute_name(column) : lato_index_dynamic_label({
|
87
87
|
key: key,
|
88
88
|
model_name: model_name,
|
data/config/locales/en.yml
CHANGED
@@ -47,6 +47,8 @@ en:
|
|
47
47
|
disconnect_wallet: Disconnect
|
48
48
|
connected_wallet: Connected
|
49
49
|
web3_signin: Web3 Login
|
50
|
+
retry: Retry
|
51
|
+
back: Go back
|
50
52
|
|
51
53
|
account_controller:
|
52
54
|
update_user_action_notice: Account information properly updated
|
@@ -79,7 +81,6 @@ en:
|
|
79
81
|
privacy_policy_invalid: To accept the privacy policy you must select the confirmation checkbox
|
80
82
|
terms_and_conditions_invalid: To accept the terms and conditions you must select the confirmation checkbox
|
81
83
|
web3_address_invalid: The address you send is not corretly signed
|
82
|
-
web3_nonce_expired: The nonce used to sign the address is expired
|
83
84
|
web3_connection_error: Impossible to connect the wallet
|
84
85
|
password:
|
85
86
|
not_correct: not correct
|
data/config/locales/it.yml
CHANGED
@@ -49,6 +49,8 @@ it:
|
|
49
49
|
disconnect_wallet: Disconnetti
|
50
50
|
connected_wallet: Connesso
|
51
51
|
web3_signin: Accedi con Web3
|
52
|
+
retry: Riprova
|
53
|
+
back: Torna indietro
|
52
54
|
|
53
55
|
account_controller:
|
54
56
|
update_user_action_notice: Informazioni account aggiornate correttamente
|
@@ -87,7 +89,6 @@ it:
|
|
87
89
|
terms_and_conditions_invalid: Per accettare i termini e condizioni devi selezionare la checkbox di conferma
|
88
90
|
invitation_invalid: Invito non valido
|
89
91
|
web3_address_invalid: L'inidirizzo inviato non è correttamente firmato
|
90
|
-
web3_nonce_expired: Il nonce utilizzato per firmare l'indirizzo è scaduto
|
91
92
|
web3_connection_error: Impossibile connettere il wallet
|
92
93
|
password:
|
93
94
|
not_correct: non corretta
|
data/lib/lato/version.rb
CHANGED
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.5.
|
4
|
+
version: 3.5.6
|
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-
|
11
|
+
date: 2024-03-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|