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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8ca2373e2e8293f273e4c0ed7995b3657b420112041a5969626bb77c50f48c84
4
- data.tar.gz: df0f81bd41462215dff6e7c7e3e241dbd1f16ee758c2a7e7bf08ef66072719f2
3
+ metadata.gz: b47a9599a3d8d0fcac7a1d46e05ac69dee4f8d8beae27641d02c683d6ae63764
4
+ data.tar.gz: 65d0f084ae8c26c18a8604a87c2320fa7e2ca381e5d2153b42ea7aa2d6267d03
5
5
  SHA512:
6
- metadata.gz: d9b0e2cefe23edd91bad291c340147e5da9b9f9262746682f9671ac8d0e88f25ab6c040f3c80afe843e4144bf301dbb1af877228740e695bd8a4108e42201c51
7
- data.tar.gz: 6bd100032415c248a66c6e7a2f4e17094778b784e3d4bbf1e3bc1351a2f2e91632b81fbde9792837fed1b7d4e34dd02f850cba3d5e98c94ac2527beff231cbf9
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
@@ -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 false %>
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">Dati di fatturazione</h2>
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>
@@ -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:
@@ -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
@@ -0,0 +1,5 @@
1
+ class AddWeb3ToLatoUsers < ActiveRecord::Migration[7.1]
2
+ def change
3
+ add_column :lato_users, :web3_address, :string
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class AddIndexesOnLatoUsersEmail < ActiveRecord::Migration[7.1]
2
+ def change
3
+ add_index :lato_users, :email, unique: true
4
+ end
5
+ end
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
@@ -1,3 +1,3 @@
1
1
  module Lato
2
- VERSION = "3.4.0"
2
+ VERSION = "3.5.0"
3
3
  end
data/lib/lato.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  require "kaminari"
2
2
  require "bootstrap"
3
3
  require "browser"
4
+ require "eth"
4
5
 
5
6
  require "lato/version"
6
7
  require "lato/engine"
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.0
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-09 00:00:00.000000000 Z
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