lato 3.4.0 → 3.5.0
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 +34 -0
- data/app/models/lato/user.rb +61 -0
- data/app/views/lato/account/_form-web3.html.erb +71 -0
- data/app/views/lato/account/index.html.erb +3 -15
- data/config/locales/en.yml +4 -0
- data/config/locales/it.yml +4 -0
- data/config/routes.rb +1 -0
- data/db/migrate/20240222125124_add_web3_to_lato_users.rb +5 -0
- data/db/migrate/20240222171418_add_indexes_on_lato_users_email.rb +5 -0
- data/lib/lato/config.rb +5 -0
- data/lib/lato/version.rb +1 -1
- data/lib/lato.rb +1 -0
- metadata +19 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b47a9599a3d8d0fcac7a1d46e05ac69dee4f8d8beae27641d02c683d6ae63764
|
4
|
+
data.tar.gz: 65d0f084ae8c26c18a8604a87c2320fa7e2ca381e5d2153b42ea7aa2d6267d03
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 115c515734b76597d2a50b449d2a76176e094c6090a807184b02b3cda6ce3ad580d5db150d3eafb18d836023a75d4838c3bca8958639f1e9eb82f78360256e68
|
7
|
+
data.tar.gz: 531c0bffd01d6b67d73bf85250d5a4336293828a302a1c4dfa73a474a1d5aa401928a6f7df3f1f2bf2e236dfec433628506700af67ee387452872dd40197afa1
|
@@ -17,6 +17,40 @@ module Lato
|
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
|
+
def update_web3_action
|
21
|
+
if @session.user.web3_connection_completed?
|
22
|
+
respond_to do |format|
|
23
|
+
if @session.user.remove_web3_connection
|
24
|
+
format.html { redirect_to lato.account_path }
|
25
|
+
format.json { render json: @session.user }
|
26
|
+
else
|
27
|
+
format.html { render :index, status: :unprocessable_entity }
|
28
|
+
format.json { render json: @session.user.errors, status: :unprocessable_entity }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
elsif @session.user.web3_connection_started?
|
32
|
+
respond_to do |format|
|
33
|
+
if @session.user.complete_web3_connection(params.require(:user).permit(:web3_address, :web3_signed_nonce))
|
34
|
+
format.html { redirect_to lato.account_path }
|
35
|
+
format.json { render json: @session.user }
|
36
|
+
else
|
37
|
+
format.html { render :index, status: :unprocessable_entity }
|
38
|
+
format.json { render json: @session.user.errors, status: :unprocessable_entity }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
else
|
42
|
+
respond_to do |format|
|
43
|
+
if @session.user.start_web3_connection
|
44
|
+
format.html { redirect_to lato.account_path }
|
45
|
+
format.json { render json: @session.user }
|
46
|
+
else
|
47
|
+
format.html { render :index, status: :unprocessable_entity }
|
48
|
+
format.json { render json: @session.user.errors, status: :unprocessable_entity }
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
20
54
|
def request_verify_email_action
|
21
55
|
respond_to do |format|
|
22
56
|
if @session.user.request_verify_email
|
data/app/models/lato/user.rb
CHANGED
@@ -38,6 +38,7 @@ module Lato
|
|
38
38
|
self.email_verified_at = nil if email_changed?
|
39
39
|
self.accepted_privacy_policy_version = Lato.config.legal_privacy_policy_version if accepted_privacy_policy_version_changed?
|
40
40
|
self.accepted_terms_and_conditions_version = Lato.config.legal_terms_and_conditions_version if accepted_terms_and_conditions_version_changed?
|
41
|
+
self.web3_address = web3_address&.downcase&.strip if web3_address_changed?
|
41
42
|
end
|
42
43
|
|
43
44
|
# Questions
|
@@ -51,6 +52,14 @@ module Lato
|
|
51
52
|
@valid_accepted_terms_and_conditions_version ||= accepted_terms_and_conditions_version >= Lato.config.legal_terms_and_conditions_version
|
52
53
|
end
|
53
54
|
|
55
|
+
def web3_connection_completed?
|
56
|
+
@web3_connection_completed ||= !web3_address.blank?
|
57
|
+
end
|
58
|
+
|
59
|
+
def web3_connection_started?
|
60
|
+
@web3_connection_started ||= !c_web3_nonce.blank?
|
61
|
+
end
|
62
|
+
|
54
63
|
# Helpers
|
55
64
|
##
|
56
65
|
|
@@ -232,6 +241,42 @@ module Lato
|
|
232
241
|
end
|
233
242
|
end
|
234
243
|
|
244
|
+
def start_web3_connection
|
245
|
+
update(web3_address: nil)
|
246
|
+
c_web3_nonce(SecureRandom.hex(32))
|
247
|
+
|
248
|
+
true
|
249
|
+
end
|
250
|
+
|
251
|
+
def complete_web3_connection(params)
|
252
|
+
nonce = c_web3_nonce
|
253
|
+
c_web3_nonce__clear # Important to rollback to status 0 of web3 connection
|
254
|
+
|
255
|
+
unless nonce
|
256
|
+
errors.add(:base, :web3_nonce_expired)
|
257
|
+
return
|
258
|
+
end
|
259
|
+
|
260
|
+
signature_pubkey = Eth::Signature.personal_recover(nonce, params[:web3_signed_nonce])
|
261
|
+
signature_address = Eth::Util.public_key_to_address signature_pubkey
|
262
|
+
unless signature_address.to_s.downcase == params[:web3_address].downcase
|
263
|
+
errors.add(:base, :web3_address_invalid)
|
264
|
+
return
|
265
|
+
end
|
266
|
+
|
267
|
+
update(web3_address: params[:web3_address])
|
268
|
+
rescue StandardError => e
|
269
|
+
c_web3_nonce__clear # Important to rollback to status 0 of web3 connection
|
270
|
+
errors.add(:base, :web3_connection_error)
|
271
|
+
false
|
272
|
+
end
|
273
|
+
|
274
|
+
def remove_web3_connection
|
275
|
+
update(web3_address: nil)
|
276
|
+
c_web3_nonce__clear
|
277
|
+
true
|
278
|
+
end
|
279
|
+
|
235
280
|
# Cache
|
236
281
|
##
|
237
282
|
|
@@ -258,5 +303,21 @@ module Lato
|
|
258
303
|
Rails.cache.write(cache_key, value, expires_in: 30.minutes)
|
259
304
|
value
|
260
305
|
end
|
306
|
+
|
307
|
+
def c_web3_nonce(value = nil)
|
308
|
+
cache_key = "Lato::User/c_web3_nonce/#{id}"
|
309
|
+
return Rails.cache.read(cache_key) if value.nil?
|
310
|
+
|
311
|
+
Rails.cache.write(cache_key, value, expires_in: 1.minutes)
|
312
|
+
@web3_connection_started = nil # HARD FIX: reset web3 connection status
|
313
|
+
value
|
314
|
+
end
|
315
|
+
|
316
|
+
def c_web3_nonce__clear
|
317
|
+
cache_key = "Lato::User/c_web3_nonce/#{id}"
|
318
|
+
Rails.cache.delete(cache_key)
|
319
|
+
@web3_connection_started = nil # HARD FIX: reset web3 connection status
|
320
|
+
true
|
321
|
+
end
|
261
322
|
end
|
262
323
|
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
<%
|
2
|
+
|
3
|
+
user ||= Lato::User.new
|
4
|
+
|
5
|
+
%>
|
6
|
+
|
7
|
+
<%= turbo_frame_tag 'account_form-web3' do %>
|
8
|
+
<%= form_with model: user, url: lato.account_update_web3_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.web3_connection_completed? %>
|
13
|
+
<div class="row">
|
14
|
+
<div class="col col-12">
|
15
|
+
<%= lato_form_item_label form, :web3_address, 'You are connected to the following address' %>
|
16
|
+
<div class="input-group">
|
17
|
+
<%= lato_form_item_input_text form, :web3_address, required: true, readonly: true %>
|
18
|
+
<%= lato_form_submit form, 'Disconnect', class: %w[btn-danger] %>
|
19
|
+
</div>
|
20
|
+
</div>
|
21
|
+
</div>
|
22
|
+
<% elsif user.web3_connection_started? %>
|
23
|
+
<div class="alert alert-light mb-0">
|
24
|
+
<h4 class="alert-heading">Connecting..</h4>
|
25
|
+
<div class="progress" role="progressbar" aria-valuenow="100" aria-valuemin="0" aria-valuemax="100">
|
26
|
+
<div class="progress-bar progress-bar-striped progress-bar-animated" style="width: 100%"></div>
|
27
|
+
</div>
|
28
|
+
</div>
|
29
|
+
|
30
|
+
<span id="account_form-web3__nonce" style="display: none;"><%= user.c_web3_nonce %></span>
|
31
|
+
<%= form.hidden_field :web3_address, id: 'account_form-web3__input-web3_address' %>
|
32
|
+
<%= form.hidden_field :web3_signed_nonce, id: 'account_form-web3__input-web3_signed_nonce' %>
|
33
|
+
<%= lato_form_submit form, 'Confirm', class: %w[btn-primary d-none], id: 'account_form-web3__submit' %>
|
34
|
+
|
35
|
+
<script>
|
36
|
+
(async () => {
|
37
|
+
const ethers = await import('https://cdnjs.cloudflare.com/ajax/libs/ethers/5.7.2/ethers.esm.min.js')
|
38
|
+
|
39
|
+
const nonce = document.getElementById('account_form-web3__nonce').innerText
|
40
|
+
const inputAddress = document.getElementById('account_form-web3__input-web3_address')
|
41
|
+
const inputSignedNonce = document.getElementById('account_form-web3__input-web3_signed_nonce')
|
42
|
+
const submitButton = document.getElementById('account_form-web3__submit')
|
43
|
+
|
44
|
+
let address = ''
|
45
|
+
let signedNonce = ''
|
46
|
+
|
47
|
+
if (window.ethereum) {
|
48
|
+
const provider = new ethers.ethers.providers.Web3Provider(window.ethereum)
|
49
|
+
const signer = provider.getSigner()
|
50
|
+
address = await signer.getAddress()
|
51
|
+
signedNonce = await signer.signMessage(nonce)
|
52
|
+
}
|
53
|
+
|
54
|
+
inputAddress.value = address
|
55
|
+
inputSignedNonce.value = signedNonce
|
56
|
+
submitButton.click()
|
57
|
+
})()
|
58
|
+
</script>
|
59
|
+
<% else %>
|
60
|
+
<div class="alert alert-light mb-0">
|
61
|
+
<h4 class="alert-heading">Connect your wallet</h4>
|
62
|
+
<p>
|
63
|
+
Connect your web3 wallet by clicking the button below and signing the message.
|
64
|
+
</p>
|
65
|
+
<p class="mb-0">
|
66
|
+
<%= lato_form_submit form, 'Connect wallet', class: %w[btn-primary] %>
|
67
|
+
</p>
|
68
|
+
</div>
|
69
|
+
<% end %>
|
70
|
+
<% end %>
|
71
|
+
<% end %>
|
@@ -12,13 +12,13 @@
|
|
12
12
|
</div>
|
13
13
|
</div>
|
14
14
|
|
15
|
-
<% if
|
15
|
+
<% if Lato.config.web3_connection %>
|
16
16
|
<div class="card mb-4">
|
17
17
|
<div class="card-header">
|
18
|
-
<h2 class="fs-4 mb-0"
|
18
|
+
<h2 class="fs-4 mb-0"><%= I18n.t('lato.account_web3') %></h2>
|
19
19
|
</div>
|
20
20
|
<div class="card-body">
|
21
|
-
|
21
|
+
<%= render 'lato/account/form-web3', user: @session.user %>
|
22
22
|
</div>
|
23
23
|
</div>
|
24
24
|
<% end %>
|
@@ -32,18 +32,6 @@
|
|
32
32
|
</div>
|
33
33
|
</div>
|
34
34
|
|
35
|
-
|
36
|
-
<% if false %>
|
37
|
-
<div class="card mb-4">
|
38
|
-
<div class="card-header">
|
39
|
-
<h2 class="fs-4 mb-0">Chiavi API</h2>
|
40
|
-
</div>
|
41
|
-
<div class="card-body">
|
42
|
-
|
43
|
-
</div>
|
44
|
-
</div>
|
45
|
-
<% end %>
|
46
|
-
|
47
35
|
<div class="card mb-4">
|
48
36
|
<div class="card-header">
|
49
37
|
<h2 class="fs-4 mb-0"><%= I18n.t('lato.account_delete') %></h2>
|
data/config/locales/en.yml
CHANGED
@@ -40,6 +40,7 @@ en:
|
|
40
40
|
privacy_policy_update_title: Privacy policy update
|
41
41
|
terms_and_conditions_update_title: Terms and conditions update
|
42
42
|
accept_invitation: Accept invitation
|
43
|
+
account_web3: Web3 connection
|
43
44
|
|
44
45
|
account_controller:
|
45
46
|
update_user_action_notice: Account information properly updated
|
@@ -71,6 +72,9 @@ en:
|
|
71
72
|
password_update_code_invalid: Verification code is invalid
|
72
73
|
privacy_policy_invalid: To accept the privacy policy you must select the confirmation checkbox
|
73
74
|
terms_and_conditions_invalid: To accept the terms and conditions you must select the confirmation checkbox
|
75
|
+
web3_address_invalid: The address you send is not corretly signed
|
76
|
+
web3_nonce_expired: The nonce used to sign the address is expired
|
77
|
+
web3_connection_error: Impossible to connect the wallet
|
74
78
|
password:
|
75
79
|
not_correct: not correct
|
76
80
|
email:
|
data/config/locales/it.yml
CHANGED
@@ -42,6 +42,7 @@ it:
|
|
42
42
|
privacy_policy_update_title: Aggiornamento privacy policy
|
43
43
|
terms_and_conditions_update_title: Aggiornamento termini e condizioni
|
44
44
|
accept_invitation: Accetta invito
|
45
|
+
account_web3: Connessione Web3
|
45
46
|
|
46
47
|
account_controller:
|
47
48
|
update_user_action_notice: Informazioni account aggiornate correttamente
|
@@ -79,6 +80,9 @@ it:
|
|
79
80
|
privacy_policy_invalid: Per accettare la privacy policy devi selezionare la checkbox di conferma
|
80
81
|
terms_and_conditions_invalid: Per accettare i termini e condizioni devi selezionare la checkbox di conferma
|
81
82
|
invitation_invalid: Invito non valido
|
83
|
+
web3_address_invalid: L'inidirizzo inviato non è correttamente firmato
|
84
|
+
web3_nonce_expired: Il nonce utilizzato per firmare l'indirizzo è scaduto
|
85
|
+
web3_connection_error: Impossibile connettere il wallet
|
82
86
|
password:
|
83
87
|
not_correct: non corretta
|
84
88
|
password_confirmation:
|
data/config/routes.rb
CHANGED
@@ -32,6 +32,7 @@ Lato::Engine.routes.draw do
|
|
32
32
|
scope :account do
|
33
33
|
get '', to: 'account#index', as: :account
|
34
34
|
patch 'update_user_action', to: 'account#update_user_action', as: :account_update_user_action
|
35
|
+
patch 'update_web3_action', to: 'account#update_web3_action', as: :account_update_web3_action
|
35
36
|
patch 'request_verify_email_action', to: 'account#request_verify_email_action', as: :account_request_verify_email_action
|
36
37
|
patch 'update_password_action', to: 'account#update_password_action', as: :account_update_password_action
|
37
38
|
delete 'destroy_action', to: 'account#destroy_action', as: :account_destroy_action
|
data/lib/lato/config.rb
CHANGED
@@ -21,6 +21,9 @@ module Lato
|
|
21
21
|
# Legal settings
|
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
|
+
# Web3 connection
|
25
|
+
attr_accessor :web3_connection
|
26
|
+
|
24
27
|
def initialize
|
25
28
|
@application_title = 'Lato'
|
26
29
|
@application_version = '1.0.0'
|
@@ -42,6 +45,8 @@ module Lato
|
|
42
45
|
@legal_privacy_policy_version = 1
|
43
46
|
@legal_terms_and_conditions_url = '#'
|
44
47
|
@legal_terms_and_conditions_version = 1
|
48
|
+
|
49
|
+
@web3_connection = false
|
45
50
|
end
|
46
51
|
end
|
47
52
|
end
|
data/lib/lato/version.rb
CHANGED
data/lib/lato.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.
|
4
|
+
version: 3.5.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-02-
|
11
|
+
date: 2024-02-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -94,6 +94,20 @@ dependencies:
|
|
94
94
|
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: eth
|
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'
|
97
111
|
description: A Rails engine that includes what you need to build a new project!
|
98
112
|
email:
|
99
113
|
- me@gregoriogalante.com
|
@@ -151,6 +165,7 @@ files:
|
|
151
165
|
- app/views/lato/account/_form-destroy.html.erb
|
152
166
|
- app/views/lato/account/_form-password.html.erb
|
153
167
|
- app/views/lato/account/_form-user.html.erb
|
168
|
+
- app/views/lato/account/_form-web3.html.erb
|
154
169
|
- app/views/lato/account/index.html.erb
|
155
170
|
- app/views/lato/authentication/_fields-registration.html.erb
|
156
171
|
- app/views/lato/authentication/_form-accept-invitation.html.erb
|
@@ -207,6 +222,8 @@ files:
|
|
207
222
|
- db/migrate/20230109061533_create_lato_invitations.rb
|
208
223
|
- db/migrate/20230212211748_add_inviter_lato_user_id_to_invitations.rb
|
209
224
|
- db/migrate/20230823165716_create_lato_log_user_signups.rb
|
225
|
+
- db/migrate/20240222125124_add_web3_to_lato_users.rb
|
226
|
+
- db/migrate/20240222171418_add_indexes_on_lato_users_email.rb
|
210
227
|
- lib/lato.rb
|
211
228
|
- lib/lato/btstrap.rb
|
212
229
|
- lib/lato/config.rb
|