lato 3.4.0 → 3.5.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/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
|