lato 0.2.0 → 0.3.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/README.md +13 -7
- data/app/assets/javascripts/lato/application.js +14 -4
- data/app/models/lato/invitation.rb +14 -7
- data/app/models/lato/user.rb +42 -18
- data/app/views/layouts/lato/_head_content.html.erb +12 -0
- data/lib/lato/config.rb +2 -1
- data/lib/lato/version.rb +1 -1
- data/lib/tasks/lato_tasks.rake +140 -0
- 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: a06ea7d40cf529ec24e928cb3ad0ae2b897e4db4af3287526f8f3889e122e79f
|
4
|
+
data.tar.gz: 9fb8d0fd297e86acd19e70f9e26a41b1a4d032fec68895920d972e968147cc08
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5ff61a9b5da01fc2f86e083a524ec9fa2f8d823632efd9a2d965a332130be08167940dbb8897661515d0416c2c9ed15a2392028d6ca6126e5dd978a3dc173f78
|
7
|
+
data.tar.gz: 6bc388648360531a63712342f708e25506b67313ef15a52b96b18405f9c7d076c552a305a6b8816a16fb93842343e0593a6b26efafb0bf8a1c1be8a21d8b5e2d
|
data/README.md
CHANGED
@@ -9,15 +9,11 @@ Add required dependencies to your application's Gemfile:
|
|
9
9
|
gem "importmap-rails" # NOTE: Probably already installed in default rails 7 project
|
10
10
|
|
11
11
|
# Hotwire's SPA-like page accelerator [https://turbo.hotwired.dev]
|
12
|
-
gem "turbo-rails"
|
12
|
+
gem "turbo-rails" # NOTE: Probably already installed in default rails 7 project
|
13
13
|
|
14
14
|
# Hotwire's modest JavaScript framework [https://stimulus.hotwired.dev]
|
15
15
|
gem "stimulus-rails" # NOTE: Probably already installed in default rails 7 project
|
16
16
|
|
17
|
-
# Use Kredis as Redis interface [https://github.com/rails/kredis]
|
18
|
-
# NOTE: Installation -> https://github.com/rails/kredis#installation
|
19
|
-
gem "kredis"
|
20
|
-
|
21
17
|
# Use Sass to process CSS
|
22
18
|
gem "sassc-rails"
|
23
19
|
|
@@ -73,9 +69,19 @@ end
|
|
73
69
|
|
74
70
|
```
|
75
71
|
|
76
|
-
|
72
|
+
### Extra tasks
|
73
|
+
Lato integrates by default a basic PWAs manifest and service worker. To re-generate them with all required assets follow these steps:
|
77
74
|
|
78
|
-
|
75
|
+
1. Complete the configuration of lato on a custom initializer (see [configuration](https://github.com/lato-gam/lato/blob/main/lib/lato/config.rb) options for more details)
|
76
|
+
2. Add an icon.png file on **public/icon.png** with minimum size of 512x512px
|
77
|
+
3. Run the following commands:
|
78
|
+
|
79
|
+
```bash
|
80
|
+
$ rails lato:generate:favicon
|
81
|
+
$ rails lato:generate:pwa
|
82
|
+
```
|
83
|
+
|
84
|
+
## Development
|
79
85
|
|
80
86
|
Clone repository, install dependencies, run migrations and start:
|
81
87
|
|
@@ -5,6 +5,20 @@ import "bootstrap"
|
|
5
5
|
// Import controllers (stimulus rails)
|
6
6
|
import "controllers"
|
7
7
|
|
8
|
+
/**
|
9
|
+
* Include service worker
|
10
|
+
*/
|
11
|
+
|
12
|
+
if (navigator.serviceWorker) {
|
13
|
+
navigator.serviceWorker.register("/service-worker.js", { scope: "/" })
|
14
|
+
.then(() => navigator.serviceWorker.ready)
|
15
|
+
.then((registration) => {
|
16
|
+
const event = new CustomEvent("service-worker:ready", { detail: registration })
|
17
|
+
document.dispatchEvent(event)
|
18
|
+
})
|
19
|
+
.then(() => console.log("[App]", "Service worker registered! -> listen to 'service-worker:ready' document event to get the registration object"))
|
20
|
+
}
|
21
|
+
|
8
22
|
/**
|
9
23
|
* Fix form inside turbo-frame tag with redirect
|
10
24
|
* https://github.com/hotwired/turbo-rails/issues/440
|
@@ -22,15 +36,11 @@ document.addEventListener("turbo:frame-missing", event => {
|
|
22
36
|
const PAGE_TRANSITION_TIME = 50
|
23
37
|
|
24
38
|
document.addEventListener('DOMContentLoaded', () => {
|
25
|
-
console.log('DOMContentLoaded')
|
26
|
-
|
27
39
|
// add is-loaded class
|
28
40
|
document.body.classList.add('is-loaded')
|
29
41
|
})
|
30
42
|
|
31
43
|
document.addEventListener('turbo:load', () => {
|
32
|
-
console.log('turbo:load')
|
33
|
-
|
34
44
|
setTimeout(() => {
|
35
45
|
// add is-loaded class
|
36
46
|
document.body.classList.add('is-loaded')
|
@@ -2,11 +2,6 @@ module Lato
|
|
2
2
|
class Invitation < ApplicationRecord
|
3
3
|
attr_accessor :actions
|
4
4
|
|
5
|
-
# Kredis
|
6
|
-
##
|
7
|
-
|
8
|
-
kredis_boolean :email_invite_semaphore, expires_in: 2.minutes
|
9
|
-
|
10
5
|
# Validations
|
11
6
|
##
|
12
7
|
|
@@ -64,7 +59,7 @@ module Lato
|
|
64
59
|
return false
|
65
60
|
end
|
66
61
|
|
67
|
-
if
|
62
|
+
if c_email_invite_semaphore
|
68
63
|
errors.add(:base, :email_sending_limit)
|
69
64
|
return false
|
70
65
|
end
|
@@ -75,9 +70,21 @@ module Lato
|
|
75
70
|
return false
|
76
71
|
end
|
77
72
|
|
78
|
-
|
73
|
+
c_email_invite_semaphore(true)
|
79
74
|
|
80
75
|
true
|
81
76
|
end
|
77
|
+
|
78
|
+
|
79
|
+
# Cache
|
80
|
+
##
|
81
|
+
|
82
|
+
def c_email_invite_semaphore(value = nil)
|
83
|
+
cache_key = "Lato::Invitation/c_email_invite_semaphore/#{id}"
|
84
|
+
return Rails.cache.read(cache_key) if value.nil?
|
85
|
+
|
86
|
+
Rails.cache.write(cache_key, value, expires_in: 2.minutes)
|
87
|
+
value
|
88
|
+
end
|
82
89
|
end
|
83
90
|
end
|
data/app/models/lato/user.rb
CHANGED
@@ -4,13 +4,6 @@ module Lato
|
|
4
4
|
|
5
5
|
has_secure_password
|
6
6
|
|
7
|
-
# Kredis
|
8
|
-
##
|
9
|
-
|
10
|
-
kredis_boolean :email_verification_semaphore, expires_in: 2.minutes
|
11
|
-
kredis_string :email_verification_code, expires_in: 30.minutes
|
12
|
-
kredis_string :password_update_code, expires_in: 30.minutes
|
13
|
-
|
14
7
|
# Validations
|
15
8
|
##
|
16
9
|
|
@@ -113,7 +106,7 @@ module Lato
|
|
113
106
|
end
|
114
107
|
|
115
108
|
def request_verify_email
|
116
|
-
if
|
109
|
+
if c_email_verification_semaphore
|
117
110
|
errors.add(:base, :email_verification_limit)
|
118
111
|
return
|
119
112
|
end
|
@@ -125,25 +118,27 @@ module Lato
|
|
125
118
|
return
|
126
119
|
end
|
127
120
|
|
128
|
-
|
129
|
-
|
121
|
+
c_email_verification_code(code)
|
122
|
+
c_email_verification_semaphore(true)
|
130
123
|
|
131
124
|
true
|
132
125
|
end
|
133
126
|
|
134
127
|
def verify_email(params)
|
135
|
-
|
128
|
+
email_verification_code = c_email_verification_code
|
129
|
+
|
130
|
+
if email_verification_code.blank?
|
136
131
|
errors.add(:base, :email_verification_code_expired)
|
137
132
|
return
|
138
133
|
end
|
139
134
|
|
140
|
-
unless email_verification_code
|
135
|
+
unless email_verification_code == params[:code]
|
141
136
|
errors.add(:base, :email_verification_code_invalid)
|
142
137
|
return
|
143
138
|
end
|
144
139
|
|
145
|
-
|
146
|
-
|
140
|
+
c_email_verification_code('')
|
141
|
+
c_email_verification_semaphore(false)
|
147
142
|
|
148
143
|
update_column(:email_verified_at, Time.now)
|
149
144
|
true
|
@@ -166,23 +161,25 @@ module Lato
|
|
166
161
|
self.id = user.id
|
167
162
|
reload
|
168
163
|
|
169
|
-
|
164
|
+
c_password_update_code(code)
|
170
165
|
|
171
166
|
true
|
172
167
|
end
|
173
168
|
|
174
169
|
def update_password(params)
|
175
|
-
|
170
|
+
password_update_code = c_password_update_code
|
171
|
+
|
172
|
+
if password_update_code.blank?
|
176
173
|
errors.add(:base, :password_update_code_expired)
|
177
174
|
return
|
178
175
|
end
|
179
176
|
|
180
|
-
unless password_update_code
|
177
|
+
unless password_update_code == params[:code]
|
181
178
|
errors.add(:base, :password_update_code_invalid)
|
182
179
|
return
|
183
180
|
end
|
184
181
|
|
185
|
-
|
182
|
+
c_password_update_code('')
|
186
183
|
|
187
184
|
update(params.permit(:password, :password_confirmation))
|
188
185
|
end
|
@@ -230,5 +227,32 @@ module Lato
|
|
230
227
|
true
|
231
228
|
end
|
232
229
|
end
|
230
|
+
|
231
|
+
# Cache
|
232
|
+
##
|
233
|
+
|
234
|
+
def c_email_verification_semaphore(value = nil)
|
235
|
+
cache_key = "Lato::User/c_email_verification_semaphore/#{id}"
|
236
|
+
return Rails.cache.read(cache_key) if value.nil?
|
237
|
+
|
238
|
+
Rails.cache.write(cache_key, value, expires_in: 2.minutes)
|
239
|
+
value
|
240
|
+
end
|
241
|
+
|
242
|
+
def c_email_verification_code(value = nil)
|
243
|
+
cache_key = "Lato::User/c_email_verification_code/#{id}"
|
244
|
+
return Rails.cache.read(cache_key) if value.nil?
|
245
|
+
|
246
|
+
Rails.cache.write(cache_key, value, expires_in: 30.minutes)
|
247
|
+
value
|
248
|
+
end
|
249
|
+
|
250
|
+
def c_password_update_code(value = nil)
|
251
|
+
cache_key = "Lato::User/c_password_update_code/#{id}"
|
252
|
+
return Rails.cache.read(cache_key) if value.nil?
|
253
|
+
|
254
|
+
Rails.cache.write(cache_key, value, expires_in: 30.minutes)
|
255
|
+
value
|
256
|
+
end
|
233
257
|
end
|
234
258
|
end
|
@@ -1 +1,13 @@
|
|
1
|
+
<meta name="application-name" content="<%= Lato.config.application_title %>">
|
2
|
+
<meta name="theme-color" content="<%= Lato.config.application_brand_color %>">
|
3
|
+
<meta name="full-screen" content="yes">
|
4
|
+
<meta name="browsermode" content="application">
|
5
|
+
<meta name="screen-orientation" content="portrait">
|
6
|
+
<meta name="apple-mobile-web-app-capable" content="yes">
|
7
|
+
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
8
|
+
<meta name="apple-mobile-web-app-title" content="<%= Lato.config.application_title %>">
|
9
|
+
|
10
|
+
<link rel="icon" href="/favicon.ico">
|
11
|
+
<link rel="manifest" href="/manifest.json">
|
12
|
+
|
1
13
|
<!-- Free for head tags -->
|
data/lib/lato/config.rb
CHANGED
@@ -4,7 +4,7 @@ module Lato
|
|
4
4
|
##
|
5
5
|
class Config
|
6
6
|
# Applicaction configs
|
7
|
-
attr_accessor :application_title, :application_version, :application_company_name, :application_company_url
|
7
|
+
attr_accessor :application_title, :application_version, :application_company_name, :application_company_url, :application_brand_color
|
8
8
|
|
9
9
|
# Session configs
|
10
10
|
attr_accessor :session_lifetime, :session_root_path
|
@@ -26,6 +26,7 @@ module Lato
|
|
26
26
|
@application_version = '1.0.0'
|
27
27
|
@application_company_name = 'Lato Team'
|
28
28
|
@application_company_url = 'https://github.com/Lato-GAM'
|
29
|
+
@application_brand_color = '#03256c'
|
29
30
|
|
30
31
|
@auth_disable_signup = false
|
31
32
|
@auth_disable_recover_password = false
|
data/lib/lato/version.rb
CHANGED
data/lib/tasks/lato_tasks.rake
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'fileutils'
|
2
|
+
require 'json'
|
2
3
|
|
3
4
|
namespace :lato do
|
4
5
|
namespace :install do
|
@@ -33,6 +34,145 @@ namespace :lato do
|
|
33
34
|
gem_concern_path = Lato::Engine.root.join('app', 'models', 'concerns', 'lato_user_application.rb').to_s
|
34
35
|
app_concern_path = Rails.root.join('app', 'models', 'concerns', 'lato_user_application.rb').to_s
|
35
36
|
FileUtils.copy(gem_concern_path, app_concern_path) unless File.exist? app_concern_path
|
37
|
+
|
38
|
+
# Generate sample manifest.json file in public folder
|
39
|
+
##
|
40
|
+
|
41
|
+
manifest_path = Rails.root.join('public', 'manifest.json')
|
42
|
+
unless File.exist? manifest_path
|
43
|
+
manifest = {
|
44
|
+
name: "Application",
|
45
|
+
short_name: "Application",
|
46
|
+
start_url: "/",
|
47
|
+
scope: "/",
|
48
|
+
display: "standalone",
|
49
|
+
orientation: "portrait",
|
50
|
+
theme_color: "#000000",
|
51
|
+
background_color: "#000000",
|
52
|
+
icons: []
|
53
|
+
}
|
54
|
+
File.open(manifest_path, 'w') { |f| f.write(JSON.pretty_generate(manifest)) }
|
55
|
+
end
|
56
|
+
|
57
|
+
# Generate sample service-worker.js file in public folder
|
58
|
+
##
|
59
|
+
|
60
|
+
service_worker_path = Rails.root.join('public', 'service-worker.js')
|
61
|
+
unless File.exist? service_worker_path
|
62
|
+
service_worker = <<-JS
|
63
|
+
function onInstall(event) {
|
64
|
+
console.log('[Serviceworker]', "Installing!", event);
|
65
|
+
}
|
66
|
+
function onActivate(event) {
|
67
|
+
console.log('[Serviceworker]', "Activating!", event);
|
68
|
+
}
|
69
|
+
function onFetch(event) {
|
70
|
+
console.log('[Serviceworker]', "Fetching!", event);
|
71
|
+
}
|
72
|
+
self.addEventListener('install', onInstall);
|
73
|
+
self.addEventListener('activate', onActivate);
|
74
|
+
self.addEventListener('fetch', onFetch);
|
75
|
+
JS
|
76
|
+
File.open(service_worker_path, 'w') { |f| f.write(service_worker) }
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
namespace :generate do
|
82
|
+
desc "Generate PWA icons from a single icon.png file (512x512) that should be placed inside 'public' folder"
|
83
|
+
# Usage: rails lato:generate:pwa
|
84
|
+
task :pwa do
|
85
|
+
# check if icon.png exists
|
86
|
+
icon_path = Rails.root.join('public', 'icon.png')
|
87
|
+
unless File.exist? icon_path
|
88
|
+
puts 'ERROR: icon.png file not found inside public folder'
|
89
|
+
return
|
90
|
+
end
|
91
|
+
|
92
|
+
# check MiniMagick is installed
|
93
|
+
begin
|
94
|
+
require 'mini_magick'
|
95
|
+
rescue LoadError
|
96
|
+
puts 'ERROR: mini_magick gem not found, please add it to your Gemfile'
|
97
|
+
return
|
98
|
+
end
|
99
|
+
|
100
|
+
# be sure icon.png is min 512x512
|
101
|
+
image = MiniMagick::Image.open(icon_path)
|
102
|
+
if image.width < 512 || image.height < 512 || image.width != image.height
|
103
|
+
puts 'ERROR: icon.png image size is not valid, it should be square and min 512x512'
|
104
|
+
return
|
105
|
+
end
|
106
|
+
|
107
|
+
# create icons folder if not exists
|
108
|
+
icons_path = Rails.root.join('public', 'icons')
|
109
|
+
FileUtils.mkdir_p(icons_path) unless File.exist? icons_path
|
110
|
+
|
111
|
+
# create icons
|
112
|
+
sizes = [16, 32, 48, 72, 96, 144, 152, 192, 384, 512]
|
113
|
+
sizes.each do |size|
|
114
|
+
file_path = "#{icons_path}/icon_#{size}x#{size}.png"
|
115
|
+
file_image = MiniMagick::Image.open(icon_path)
|
116
|
+
FileUtils.rm(file_path) if File.exist? file_path
|
117
|
+
file_image.resize "#{size}x#{size}"
|
118
|
+
file_image.write file_path
|
119
|
+
end
|
120
|
+
|
121
|
+
# create manifest.json
|
122
|
+
manifest_path = Rails.root.join('public', 'manifest.json')
|
123
|
+
manifest = {
|
124
|
+
name: Lato.config.application_title,
|
125
|
+
short_name: Lato.config.application_title,
|
126
|
+
start_url: '/',
|
127
|
+
scope: '/',
|
128
|
+
display: 'standalone',
|
129
|
+
orientation: 'portrait',
|
130
|
+
theme_color: Lato.config.application_brand_color,
|
131
|
+
background_color: Lato.config.application_brand_color,
|
132
|
+
icons: []
|
133
|
+
}
|
134
|
+
sizes.each do |size|
|
135
|
+
manifest[:icons] << {
|
136
|
+
src: "/icons/icon_#{size}x#{size}.png",
|
137
|
+
sizes: "#{size}x#{size}",
|
138
|
+
type: 'image/png'
|
139
|
+
}
|
140
|
+
end
|
141
|
+
FileUtils.rm(manifest_path) if File.exist? manifest_path
|
142
|
+
File.open(manifest_path, 'w') { |f| f.write(JSON.pretty_generate(manifest)) }
|
143
|
+
end
|
144
|
+
|
145
|
+
desc "Generate favicon.ico from a single icon.png file (512x512) that should be placed inside 'public' folder"
|
146
|
+
# Usage: rails lato:generate:favicon
|
147
|
+
task :favicon do
|
148
|
+
# check if icon.png exists
|
149
|
+
icon_path = Rails.root.join('public', 'icon.png')
|
150
|
+
unless File.exist? icon_path
|
151
|
+
puts 'ERROR: icon.png file not found inside public folder'
|
152
|
+
return
|
153
|
+
end
|
154
|
+
|
155
|
+
# check MiniMagick is installed
|
156
|
+
begin
|
157
|
+
require 'mini_magick'
|
158
|
+
rescue LoadError
|
159
|
+
puts 'ERROR: mini_magick gem not found, please add it to your Gemfile'
|
160
|
+
return
|
161
|
+
end
|
162
|
+
|
163
|
+
# be sure icon.png is min 512x512
|
164
|
+
image = MiniMagick::Image.open(icon_path)
|
165
|
+
if image.width < 512 || image.height < 512 || image.width != image.height
|
166
|
+
puts 'ERROR: icon.png image size is not valid, it should be square and min 512x512'
|
167
|
+
return
|
168
|
+
end
|
169
|
+
|
170
|
+
# create favicon.ico
|
171
|
+
file_path = Rails.root.join('public', 'favicon.ico')
|
172
|
+
file_image = MiniMagick::Image.open(icon_path)
|
173
|
+
FileUtils.rm(file_path) if File.exist? file_path
|
174
|
+
file_image.resize '48x48'
|
175
|
+
file_image.write file_path
|
36
176
|
end
|
37
177
|
end
|
38
178
|
end
|
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: 0.
|
4
|
+
version: 0.3.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: 2023-10-
|
11
|
+
date: 2023-10-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|