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 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