kaze 0.6.0 → 0.8.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.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -0
  3. data/lib/kaze/commands/install_command.rb +10 -4
  4. data/lib/kaze/version.rb +1 -1
  5. data/stubs/default/app/forms/auth/login_form.rb +2 -2
  6. data/stubs/default/app/forms/auth/new_password_form.rb +2 -2
  7. data/stubs/default/app/forms/auth/send_password_reset_link_form.rb +2 -4
  8. data/stubs/default/app/models/session_guard.rb +157 -0
  9. data/stubs/default/db/migrate/20240101000000_create_users.rb +1 -0
  10. data/stubs/default/test/test_helper.rb +1 -1
  11. data/stubs/hotwire/app/components/application_logo_component.rb +2 -5
  12. data/stubs/hotwire/app/controllers/auth/authenticated_session_controller.rb +1 -1
  13. data/stubs/hotwire/app/controllers/concerns/set_current_auth.rb +1 -1
  14. data/stubs/hotwire/app/views/layouts/_navigation.html.erb +1 -1
  15. data/stubs/hotwire/app/views/layouts/guest.html.erb +1 -1
  16. data/stubs/inertia-common/app/controllers/auth/authenticated_session_controller.rb +1 -1
  17. data/stubs/inertia-common/app/controllers/concerns/set_current_auth.rb +1 -1
  18. data/stubs/inertia-react-ts/app/javascript/Components/ApplicationLogo.tsx +2 -9
  19. data/stubs/inertia-react-ts/app/javascript/Components/Checkbox.tsx +1 -4
  20. data/stubs/inertia-react-ts/app/javascript/Components/DangerButton.tsx +1 -1
  21. data/stubs/inertia-react-ts/app/javascript/Components/Dropdown.tsx +2 -7
  22. data/stubs/inertia-react-ts/app/javascript/Components/InputError.tsx +1 -1
  23. data/stubs/inertia-react-ts/app/javascript/Components/InputLabel.tsx +1 -4
  24. data/stubs/inertia-react-ts/app/javascript/Components/NavLink.tsx +4 -4
  25. data/stubs/inertia-react-ts/app/javascript/Components/PrimaryButton.tsx +1 -1
  26. data/stubs/inertia-react-ts/app/javascript/Components/SecondaryButton.tsx +1 -1
  27. data/stubs/inertia-react-ts/app/javascript/Components/TextInput.tsx +1 -4
  28. data/stubs/inertia-react-ts/app/javascript/Layouts/AuthenticatedLayout.tsx +1 -1
  29. data/stubs/inertia-react-ts/app/javascript/Layouts/GuestLayout.tsx +1 -1
  30. data/stubs/inertia-vue-ts/app/javascript/Components/ApplicationLogo.vue +2 -9
  31. data/stubs/inertia-vue-ts/app/javascript/Layouts/AuthenticatedLayout.vue +1 -1
  32. data/stubs/inertia-vue-ts/app/javascript/Layouts/GuestLayout.vue +1 -1
  33. metadata +3 -4
  34. data/MIT-LICENSE +0 -20
  35. data/stubs/default/app/models/auth.rb +0 -57
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 57126b1b287c8bf01b88c9baaae1a139d4791fe50e575262ec483ef8ad58e6e1
4
- data.tar.gz: 254ed015dfcab378aae5ef24b69c90819fc88f46b4e3557811f7a3b50c3a5bd8
3
+ metadata.gz: ed80aded8509882926dcf8c40613b78779b50a01bf6a00edd3b130769e9020f5
4
+ data.tar.gz: fedfaa322d578f194d46923d05c33dec0a0638b47653eb77b6a2898c9e1be49b
5
5
  SHA512:
6
- metadata.gz: ee1afd04c5c57655b90e2f43d93730e9abc9cfc2989dba0b5c9e8684c041628ca80c7aeb496c5c8cae3a26e71c1ec21af2de6e7404fe60290f8b5a8eac2639cd
7
- data.tar.gz: c4fdc51d36d33cfa6a346a10ef933f7b2cdffeb08958ca6aac5b42cf3e5ac335245892ef1662a881ddd33ce0dc9b74dfd019b6b07683dc8ec82474b28c8e6174
6
+ metadata.gz: d94bc100f51b08ce70e149c898f7c36422980a0225e37e289146394bb2e216b37bed34be1a4a21c6ebdc091105abfebbe372dfcccf05d23886b348615a151673
7
+ data.tar.gz: b6cbabd31838a806daeaa3cd719fc5e725242ae56783eb57a1028438e388a7b7f009edb04bb70a642383547c567bc46e7496f69053296d9834a661b0fbbd5e0e
data/README.md CHANGED
@@ -1,3 +1,5 @@
1
+ <p align="center"><img src="/art/logo.svg" alt="Logo Kaze"></p>
2
+
1
3
  # Kaze
2
4
 
3
5
  Heavily inspired by [Laravel Breeze](https://github.com/laravel/breeze), this gem offers authentication and application starter kits to give you a head start building your new Rails application. These kits automatically scaffold your application with the routes, controllers, and views you need to register and authenticate your application's users.
@@ -76,12 +76,18 @@ class Kaze::Commands::InstallCommand < Thor
76
76
 
77
77
  def run_command(command)
78
78
  Open3.popen3(command) do |stdin, stdout, stderr, wait_thr|
79
- Thread.new do
80
- stdout.each { |line| say line }
79
+ stdout_thread = Thread.new do
80
+ while (line = stdout.gets) do
81
+ say line
82
+ end
81
83
  end
82
- Thread.new do
83
- stderr.each { |line| say line, :red }
84
+ stderr_thread = Thread.new do
85
+ while (line = stderr.gets) do
86
+ say line, :red
87
+ end
84
88
  end
89
+ stdout_thread.join
90
+ stderr_thread.join
85
91
  wait_thr.value
86
92
  end
87
93
  end
data/lib/kaze/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Kaze
2
- VERSION = '0.6.0'
2
+ VERSION = '0.8.0'
3
3
  end
@@ -1,5 +1,5 @@
1
1
  class Auth::LoginForm < ApplicationForm
2
- attr_accessor :email, :password
2
+ attr_accessor :email, :password, :remember
3
3
 
4
4
  validates :email, presence: true, email: true
5
5
  validates :password, presence: true
@@ -7,6 +7,6 @@ class Auth::LoginForm < ApplicationForm
7
7
  def authenticate
8
8
  return if invalid?
9
9
 
10
- errors.add(:email, message: 'These credentials do not match our records.') unless Current.auth.attempt(email: email, password: password)
10
+ errors.add(:email, message: 'These credentials do not match our records.') unless Current.auth.attempt({ email: @email, password: @password }, @remember)
11
11
  end
12
12
  end
@@ -7,14 +7,14 @@ class Auth::NewPasswordForm < ApplicationForm
7
7
  def reset?
8
8
  return false if invalid?
9
9
 
10
- user = User.find_by_token_for(:password_reset, token)
10
+ user = User.find_by_token_for(:password_reset, @token)
11
11
 
12
12
  if user.nil?
13
13
  errors.add(:password, message: 'This password reset token is invalid.')
14
14
  return false
15
15
  end
16
16
 
17
- user.update(password: password)
17
+ user.update(password: @password)
18
18
 
19
19
  true
20
20
  end
@@ -6,16 +6,14 @@ class Auth::SendPasswordResetLinkForm < ApplicationForm
6
6
  def send_reset_link?
7
7
  return false if invalid?
8
8
 
9
- user = User.find_by(email: email)
9
+ user = User.find_by(email: @email)
10
10
 
11
11
  if user.nil?
12
12
  errors.add(:email, message: "We can't find a user with that email address.")
13
13
  return false
14
14
  end
15
15
 
16
- token = user.generate_token_for(:password_reset)
17
-
18
- user.send_password_reset_notification(token)
16
+ user.send_password_reset_notification(user.generate_token_for(:password_reset))
19
17
 
20
18
  true
21
19
  end
@@ -0,0 +1,157 @@
1
+ class SessionGuard
2
+ attr_reader :name
3
+ attr_reader :last_attempted
4
+ attr_reader :via_remember
5
+ attr_reader :remember_duration
6
+ attr_reader :session
7
+ attr_reader :cookies
8
+ attr_reader :logged_out
9
+ attr_reader :recall_attempted
10
+ attr_reader :user
11
+
12
+ def initialize(name:, session:, cookies: nil)
13
+ @name = name
14
+ @session = session
15
+ @cookies = cookies
16
+ @via_remember = false
17
+ @remember_duration = 576000
18
+ @logged_out = false
19
+ @recall_attempted = false
20
+ end
21
+
22
+ def get_user
23
+ return nil if @logged_out
24
+
25
+ return @user unless @user.nil?
26
+
27
+ id = @session[get_name]
28
+
29
+ @user = User.find_by(id: id) unless id.nil?
30
+
31
+ if @user.nil?
32
+ @user = user_from_recaller
33
+
34
+ update_session(@user.id) if @user
35
+ end
36
+
37
+ @user
38
+ end
39
+
40
+ def attempt(credentials = {}, remember = false)
41
+ @last_attempted = user = User.authenticate_by(credentials)
42
+
43
+ return false if user.nil?
44
+
45
+ login(user, remember)
46
+
47
+ true
48
+ end
49
+
50
+ def login(user, remember = false)
51
+ update_session(user.id)
52
+
53
+ if remember
54
+ ensure_remember_token_is_set(user)
55
+ create_recaller_cookie(user)
56
+ end
57
+
58
+ set_user(user)
59
+ end
60
+
61
+ def logout
62
+ user = get_user
63
+
64
+ clear_user_data_from_storage
65
+
66
+ cycle_remember_token(user) unless @user.nil? || user.remember_token.blank?
67
+
68
+ @user = nil
69
+
70
+ @logged_out = true
71
+ end
72
+
73
+ def set_user(user)
74
+ @user = user
75
+ @logged_out = false
76
+ end
77
+
78
+ def check?
79
+ !get_user.nil?
80
+ end
81
+
82
+ private
83
+
84
+ def user_from_recaller
85
+ _recaller = recaller
86
+
87
+ return nil if _recaller.nil? || !_recaller.valid? || @recall_attempted
88
+
89
+ @recall_attempted = true
90
+
91
+ user = User.find_by(id: _recaller.id, remember_token: _recaller.token)
92
+
93
+ @via_remember = true unless user.nil?
94
+
95
+ user
96
+ end
97
+
98
+ def recaller
99
+ return nil if @cookies.nil?
100
+
101
+ _recaller = @cookies.signed[get_recaller_name]
102
+
103
+ _recaller ? Recaller.new(_recaller) : nil
104
+ end
105
+
106
+ def update_session(id)
107
+ @session[get_name] = id
108
+ end
109
+
110
+ def ensure_remember_token_is_set(user)
111
+ cycle_remember_token(user) if user.remember_token.blank?
112
+ end
113
+
114
+ def create_recaller_cookie(user)
115
+ @cookies.signed[get_recaller_name] = {
116
+ value: "#{user.id}|#{user.remember_token}|#{user.password_digest}",
117
+ expires: @remember_duration.minutes.from_now
118
+ }
119
+ end
120
+
121
+ def clear_user_data_from_storage
122
+ @session.delete(get_name)
123
+ @cookies.delete(get_recaller_name) unless @cookies.nil?
124
+ end
125
+
126
+ def cycle_remember_token(user)
127
+ user.update(remember_token: SecureRandom.alphanumeric(60))
128
+ end
129
+
130
+ def get_name
131
+ "login_#{@name}_#{Digest::SHA1.hexdigest(self.class.name)}".to_sym
132
+ end
133
+
134
+ def get_recaller_name
135
+ "remember_#{@name}_#{Digest::SHA1.hexdigest(self.class.name)}".to_sym
136
+ end
137
+ end
138
+
139
+ class Recaller
140
+ attr_reader :recaller
141
+
142
+ def initialize(recaller)
143
+ @recaller = recaller.split('|')
144
+ end
145
+
146
+ def id
147
+ @recaller[0]
148
+ end
149
+
150
+ def token
151
+ @recaller[1]
152
+ end
153
+
154
+ def valid?
155
+ @recaller.length >= 3 && @recaller[0].present? && @recaller[1].present?
156
+ end
157
+ end
@@ -4,6 +4,7 @@ class CreateUsers < ActiveRecord::Migration
4
4
  table.string :name
5
5
  table.string :email
6
6
  table.string :password_digest
7
+ table.string :remember_token, null: true
7
8
  table.timestamps
8
9
  end
9
10
  end
@@ -18,7 +18,7 @@ module ActiveSupport
18
18
  end
19
19
 
20
20
  def current_auth
21
- Auth.new('web', session)
21
+ SessionGuard.new(name: 'web', session: session)
22
22
  end
23
23
 
24
24
  def assert_authenticated
@@ -1,10 +1,7 @@
1
1
  class ApplicationLogoComponent < ViewComponent::Base
2
2
  erb_template <<~ERB
3
- <svg viewBox="0 -6 32 32" xmlns="http://www.w3.org/2000/svg" <%= sanitize @attributes.join(" ") %>>
4
- <g fill="none" fill-rule="evenodd">
5
- <path d="M0-6h32v32H0z"/>
6
- <path fill="#c00" fill-rule="nonzero" d="M.985 19.636s.422-4.163 3.375-9.087c2.954-4.924 7.99-8.65 12.083-9.017 8.144-.816 15.46 6.485 15.46 6.485s-.24.168-.494.38C23.42 2.49 18.54 5.274 17.005 6.02c-7.033 3.925-4.91 13.616-4.91 13.616H.987zM24.137 2.32c-.45-.182-.9-.35-1.364-.505l.056-.93c.885.254 1.237.423 1.363.493l-.056.943zM22.8 5.304c.45.028.915.084 1.393.183l-.056.872c-.464-.1-.928-.155-1.392-.17l.056-.885zM17.597.913c-.407 0-.815.015-1.223.058l-.268-.83c.465-.056.915-.084 1.35-.084l.282.858h-.14zm.676 5.178c.35-.154.76-.31 1.237-.45l.31.93c-.41.125-.817.294-1.225.49l-.323-.97zm-6.386-3.7c-.366.184-.718.395-1.083.62l-.647-.985c.38-.225.745-.42 1.097-.604l.633.97zm2.883 6.33c.252-.323.548-.646.87-.942l.634.957c-.31.323-.59.647-.83 1L14.77 8.72zm-2.04 4.53c.112-.506.24-1.027.422-1.547l1.012.802c-.14.548-.24 1.097-.295 1.645l-1.14-.9zM6.57 6.57c-.34.35-.662.73-.958 1.11L4.53 6.752c.323-.352.674-.704 1.04-1.055l1 .872zm-4.25 6.286c-.224.52-.52 1.21-.702 1.688L0 13.954c.14-.38.436-1.084.703-1.69l1.618.592zm10.2 3.967l1.518.548c.084.663.21 1.28.337 1.83l-1.688-.605c-.07-.422-.14-1.027-.168-1.772z"/>
7
- </g>
3
+ <svg viewBox="0 0 300 300" xmlns="http://www.w3.org/2000/svg" <%= sanitize @attributes.join(" ") %>>
4
+ <path d="m 237.03985,281.43515 c -1.54085,-2.49315 -1.43016,-32.97159 0.24592,-67.72985 3.02813,-62.79557 2.98467,-63.24086 -6.84044,-70.12264 -5.43834,-3.80913 -16.32202,-6.92574 -24.18594,-6.92574 -22.00734,0 -30.84257,-6.63121 -30.84257,-23.14872 0,-18.460367 5.31742,-22.209117 35.7331,-25.191397 27.97004,-2.74248 30.5663,-4.04226 26.94175,-13.48771 -2.14986,-5.6024 -13.90805,-6.59952 -77.8227,-6.59952 -69.400535,0 -75.177944,-0.58548 -73.8551,-7.48424 1.284851,-6.700534 9.490461,-7.708169 78.36353,-9.622595 42.31063,-1.176095 74.04161,-3.44104 70.51333,-5.033217 -11.28272,-5.091508 -103.7232,-12.917843 -134.65799,-11.40068 l -29.878628,1.465415 -3.171696,17.106837 c -1.744436,9.40876 -4.948521,63.009007 -7.120182,119.111597 -2.277699,58.84196 -5.815243,103.87156 -8.360116,106.41647 -2.4264,2.42639 -7.676475,3.15877 -11.666833,1.62754 -5.877786,-2.25554 -6.747202,-6.22009 -4.579445,-20.88223 1.471667,-9.954 3.74014,-63.32438 5.041047,-118.60085 2.647925,-112.511911 3.2489,-117.857541 13.890324,-123.552663 4.513472,-2.415528 45.033525,-3.067128 100.341569,-1.613517 109.0299,2.86548 110.09891,3.263428 110.09891,40.985371 0,30.923222 -7.28516,39.906492 -35.24013,43.454229 -29.06687,3.68892 -37.46391,6.17185 -37.46391,11.07783 0,2.19365 11.40965,3.98851 25.35478,3.98851 37.65833,0 38.79584,2.06051 38.79584,70.27428 0,31.25825 -1.20855,65.65073 -2.68573,76.42778 -2.59506,18.93304 -11.18137,28.79145 -16.94872,19.45971 z M 102.84208,259.48743 c -5.809371,-2.9396 -13.184926,-10.12819 -16.390123,-15.97462 -8.396565,-15.3158 2.912296,-41.49358 19.494463,-45.12587 20.60401,-4.51326 22.42665,-5.69589 22.42665,-14.55198 0,-6.8018 -2.78507,-8.68766 -12.83013,-8.68766 -16.253558,0 -29.936969,-13.44405 -29.936969,-29.41328 0,-14.42513 5.553783,-19.82093 24.591079,-23.89154 9.82484,-2.1008 13.8993,-5.37975 13.8993,-11.1856 0,-6.50902 -3.05408,-8.21363 -14.71608,-8.21363 -16.019022,0 -24.105594,-7.285117 -14.699611,-13.242787 3.241585,-2.05321 12.812471,-3.76252 21.268621,-3.79858 19.92576,-0.0847 30.60952,11.25947 28.76224,30.540617 -1.22046,12.73879 -3.23695,14.76612 -18.47681,18.57607 -30.922304,7.73057 -36.377959,19.24518 -9.11843,19.24518 22.57064,0 29.1179,7.65172 27.56665,32.21701 l -1.34139,21.24186 -20.81946,5.13821 c -11.45071,2.826 -21.79219,6.1109 -22.981063,7.29978 -4.590664,4.59067 3.475793,15.68791 14.430943,19.85304 16.19851,6.15868 88.0503,3.43548 90.32313,-3.42324 1.28741,-3.88501 -5.33813,-5.34589 -24.24513,-5.34589 -19.38669,0 -26.01664,-1.51819 -26.01664,-5.9575 0,-8.34429 9.63998,-11.14934 38.3165,-11.14934 28.67934,0 35.63045,5.45011 33.61018,26.35253 -0.96086,9.94142 -4.50427,15.66293 -12.05276,19.46151 -14.27136,7.1817 -96.89032,7.20826 -111.06516,0.0342 z m 57.07409,-60.66299 c -4.41463,-11.5043 3.01548,-16.23905 21.50632,-13.70463 20.26375,2.77747 30.64103,-1.74032 26.8271,-11.67922 -1.8078,-4.7111 -8.00515,-6.84671 -19.86838,-6.84671 -19.48707,0 -22.72529,-6.68 -6.27087,-12.93598 25.01034,-9.50892 44.62703,0.19588 44.62703,22.07791 0,17.75258 -8.58709,23.84253 -37.57444,26.6478 -21.20481,2.05209 -27.38199,1.30033 -29.24676,-3.55917 z" />
8
5
  </svg>
9
6
  ERB
10
7
 
@@ -13,7 +13,7 @@ class Auth::AuthenticatedSessionController < ApplicationController
13
13
  end
14
14
 
15
15
  def create
16
- @form = Auth::LoginForm.new params.permit(:email, :password)
16
+ @form = Auth::LoginForm.new params.permit(:email, :password, :remember)
17
17
 
18
18
  @form.authenticate
19
19
 
@@ -3,7 +3,7 @@ module SetCurrentAuth
3
3
 
4
4
  included do
5
5
  before_action do
6
- Current.auth = Auth.new('web', session)
6
+ Current.auth = SessionGuard.new(name: 'web', session: session, cookies: cookies)
7
7
  end
8
8
  end
9
9
  end
@@ -6,7 +6,7 @@
6
6
  <!-- Logo -->
7
7
  <div class="shrink-0 flex items-center">
8
8
  <a href="/">
9
- <%= render(ApplicationLogoComponent.new({ class: "block h-9 w-auto fill-current text-gray-800 dark:text-gray-200" })) %>
9
+ <%= render(ApplicationLogoComponent.new({ class: "block h-9 w-auto fill-current text-red-800 dark:text-red-200" })) %>
10
10
  </a>
11
11
  </div>
12
12
  <!-- Navigation Links -->
@@ -16,7 +16,7 @@
16
16
  <div class="min-h-screen flex flex-col sm:justify-center items-center pt-6 sm:pt-0 bg-gray-100 dark:bg-gray-900">
17
17
  <div>
18
18
  <a href="/">
19
- <%= render(ApplicationLogoComponent.new({ class: "w-20 h-20 fill-current text-gray-500" })) %>
19
+ <%= render(ApplicationLogoComponent.new({ class: "w-20 h-20 fill-current text-red-500" })) %>
20
20
  </a>
21
21
  </div>
22
22
  <div class="w-full sm:max-w-md mt-6 px-6 py-4 bg-white dark:bg-gray-800 shadow-md overflow-hidden sm:rounded-lg">
@@ -12,7 +12,7 @@ class Auth::AuthenticatedSessionController < ApplicationController
12
12
  end
13
13
 
14
14
  def create
15
- form = Auth::LoginForm.new params.permit(:email, :password)
15
+ form = Auth::LoginForm.new params.permit(:email, :password, :remember)
16
16
 
17
17
  form.authenticate
18
18
 
@@ -3,7 +3,7 @@ module SetCurrentAuth
3
3
 
4
4
  included do
5
5
  before_action do
6
- Current.auth = Auth.new('web', session)
6
+ Current.auth = SessionGuard.new(name: 'web', session: session, cookies: cookies)
7
7
  end
8
8
  end
9
9
  end
@@ -2,15 +2,8 @@ import { SVGAttributes } from 'react'
2
2
 
3
3
  export default function ApplicationLogo(props: SVGAttributes<SVGElement>) {
4
4
  return (
5
- <svg {...props} viewBox="0 -6 32 32" xmlns="http://www.w3.org/2000/svg">
6
- <g fill="none" fillRule="evenodd">
7
- <path d="M0-6h32v32H0z" />
8
- <path
9
- fill="#c00"
10
- fillRule="nonzero"
11
- d="M.985 19.636s.422-4.163 3.375-9.087c2.954-4.924 7.99-8.65 12.083-9.017 8.144-.816 15.46 6.485 15.46 6.485s-.24.168-.494.38C23.42 2.49 18.54 5.274 17.005 6.02c-7.033 3.925-4.91 13.616-4.91 13.616H.987zM24.137 2.32c-.45-.182-.9-.35-1.364-.505l.056-.93c.885.254 1.237.423 1.363.493l-.056.943zM22.8 5.304c.45.028.915.084 1.393.183l-.056.872c-.464-.1-.928-.155-1.392-.17l.056-.885zM17.597.913c-.407 0-.815.015-1.223.058l-.268-.83c.465-.056.915-.084 1.35-.084l.282.858h-.14zm.676 5.178c.35-.154.76-.31 1.237-.45l.31.93c-.41.125-.817.294-1.225.49l-.323-.97zm-6.386-3.7c-.366.184-.718.395-1.083.62l-.647-.985c.38-.225.745-.42 1.097-.604l.633.97zm2.883 6.33c.252-.323.548-.646.87-.942l.634.957c-.31.323-.59.647-.83 1L14.77 8.72zm-2.04 4.53c.112-.506.24-1.027.422-1.547l1.012.802c-.14.548-.24 1.097-.295 1.645l-1.14-.9zM6.57 6.57c-.34.35-.662.73-.958 1.11L4.53 6.752c.323-.352.674-.704 1.04-1.055l1 .872zm-4.25 6.286c-.224.52-.52 1.21-.702 1.688L0 13.954c.14-.38.436-1.084.703-1.69l1.618.592zm10.2 3.967l1.518.548c.084.663.21 1.28.337 1.83l-1.688-.605c-.07-.422-.14-1.027-.168-1.772z"
12
- />
13
- </g>
5
+ <svg {...props} viewBox="0 0 300 300" xmlns="http://www.w3.org/2000/svg">
6
+ <path d="m 237.03985,281.43515 c -1.54085,-2.49315 -1.43016,-32.97159 0.24592,-67.72985 3.02813,-62.79557 2.98467,-63.24086 -6.84044,-70.12264 -5.43834,-3.80913 -16.32202,-6.92574 -24.18594,-6.92574 -22.00734,0 -30.84257,-6.63121 -30.84257,-23.14872 0,-18.460367 5.31742,-22.209117 35.7331,-25.191397 27.97004,-2.74248 30.5663,-4.04226 26.94175,-13.48771 -2.14986,-5.6024 -13.90805,-6.59952 -77.8227,-6.59952 -69.400535,0 -75.177944,-0.58548 -73.8551,-7.48424 1.284851,-6.700534 9.490461,-7.708169 78.36353,-9.622595 42.31063,-1.176095 74.04161,-3.44104 70.51333,-5.033217 -11.28272,-5.091508 -103.7232,-12.917843 -134.65799,-11.40068 l -29.878628,1.465415 -3.171696,17.106837 c -1.744436,9.40876 -4.948521,63.009007 -7.120182,119.111597 -2.277699,58.84196 -5.815243,103.87156 -8.360116,106.41647 -2.4264,2.42639 -7.676475,3.15877 -11.666833,1.62754 -5.877786,-2.25554 -6.747202,-6.22009 -4.579445,-20.88223 1.471667,-9.954 3.74014,-63.32438 5.041047,-118.60085 2.647925,-112.511911 3.2489,-117.857541 13.890324,-123.552663 4.513472,-2.415528 45.033525,-3.067128 100.341569,-1.613517 109.0299,2.86548 110.09891,3.263428 110.09891,40.985371 0,30.923222 -7.28516,39.906492 -35.24013,43.454229 -29.06687,3.68892 -37.46391,6.17185 -37.46391,11.07783 0,2.19365 11.40965,3.98851 25.35478,3.98851 37.65833,0 38.79584,2.06051 38.79584,70.27428 0,31.25825 -1.20855,65.65073 -2.68573,76.42778 -2.59506,18.93304 -11.18137,28.79145 -16.94872,19.45971 z M 102.84208,259.48743 c -5.809371,-2.9396 -13.184926,-10.12819 -16.390123,-15.97462 -8.396565,-15.3158 2.912296,-41.49358 19.494463,-45.12587 20.60401,-4.51326 22.42665,-5.69589 22.42665,-14.55198 0,-6.8018 -2.78507,-8.68766 -12.83013,-8.68766 -16.253558,0 -29.936969,-13.44405 -29.936969,-29.41328 0,-14.42513 5.553783,-19.82093 24.591079,-23.89154 9.82484,-2.1008 13.8993,-5.37975 13.8993,-11.1856 0,-6.50902 -3.05408,-8.21363 -14.71608,-8.21363 -16.019022,0 -24.105594,-7.285117 -14.699611,-13.242787 3.241585,-2.05321 12.812471,-3.76252 21.268621,-3.79858 19.92576,-0.0847 30.60952,11.25947 28.76224,30.540617 -1.22046,12.73879 -3.23695,14.76612 -18.47681,18.57607 -30.922304,7.73057 -36.377959,19.24518 -9.11843,19.24518 22.57064,0 29.1179,7.65172 27.56665,32.21701 l -1.34139,21.24186 -20.81946,5.13821 c -11.45071,2.826 -21.79219,6.1109 -22.981063,7.29978 -4.590664,4.59067 3.475793,15.68791 14.430943,19.85304 16.19851,6.15868 88.0503,3.43548 90.32313,-3.42324 1.28741,-3.88501 -5.33813,-5.34589 -24.24513,-5.34589 -19.38669,0 -26.01664,-1.51819 -26.01664,-5.9575 0,-8.34429 9.63998,-11.14934 38.3165,-11.14934 28.67934,0 35.63045,5.45011 33.61018,26.35253 -0.96086,9.94142 -4.50427,15.66293 -12.05276,19.46151 -14.27136,7.1817 -96.89032,7.20826 -111.06516,0.0342 z m 57.07409,-60.66299 c -4.41463,-11.5043 3.01548,-16.23905 21.50632,-13.70463 20.26375,2.77747 30.64103,-1.74032 26.8271,-11.67922 -1.8078,-4.7111 -8.00515,-6.84671 -19.86838,-6.84671 -19.48707,0 -22.72529,-6.68 -6.27087,-12.93598 25.01034,-9.50892 44.62703,0.19588 44.62703,22.07791 0,17.75258 -8.58709,23.84253 -37.57444,26.6478 -21.20481,2.05209 -27.38199,1.30033 -29.24676,-3.55917 z" />
14
7
  </svg>
15
8
  )
16
9
  }
@@ -8,10 +8,7 @@ export default function Checkbox({
8
8
  <input
9
9
  {...props}
10
10
  type="checkbox"
11
- className={
12
- 'rounded dark:bg-gray-900 border-gray-300 dark:border-gray-700 text-indigo-600 shadow-sm focus:ring-indigo-500 dark:focus:ring-indigo-600 dark:focus:ring-offset-gray-800 ' +
13
- className
14
- }
11
+ className={`rounded dark:bg-gray-900 border-gray-300 dark:border-gray-700 text-indigo-600 shadow-sm focus:ring-indigo-500 dark:focus:ring-indigo-600 dark:focus:ring-offset-gray-800 ${className}`}
15
12
  />
16
13
  )
17
14
  }
@@ -12,7 +12,7 @@ export default function DangerButton({
12
12
  className={
13
13
  `inline-flex items-center px-4 py-2 bg-red-600 border border-transparent rounded-md font-semibold text-xs text-white uppercase tracking-widest hover:bg-red-500 active:bg-red-700 focus:outline-none focus:ring-2 focus:ring-red-500 focus:ring-offset-2 dark:focus:ring-offset-gray-800 transition ease-in-out duration-150 ${
14
14
  disabled && 'opacity-25'
15
- } ` + className
15
+ } ${className}`
16
16
  }
17
17
  disabled={disabled}
18
18
  >
@@ -94,9 +94,7 @@ const Content = ({
94
94
  onClick={() => setOpen(false)}
95
95
  >
96
96
  <div
97
- className={
98
- `rounded-md ring-1 ring-black ring-opacity-5 ` + contentClasses
99
- }
97
+ className={`rounded-md ring-1 ring-black ring-opacity-5 ${contentClasses}`}
100
98
  >
101
99
  {children}
102
100
  </div>
@@ -114,10 +112,7 @@ const DropdownLink = ({
114
112
  return (
115
113
  <Link
116
114
  {...props}
117
- className={
118
- 'block w-full px-4 py-2 text-start text-sm leading-5 text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800 focus:outline-none focus:bg-gray-100 dark:focus:bg-gray-800 transition duration-150 ease-in-out ' +
119
- className
120
- }
115
+ className={`block w-full px-4 py-2 text-start text-sm leading-5 text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800 focus:outline-none focus:bg-gray-100 dark:focus:bg-gray-800 transition duration-150 ease-in-out ${className}`}
121
116
  >
122
117
  {children}
123
118
  </Link>
@@ -8,7 +8,7 @@ export default function InputError({
8
8
  return message ? (
9
9
  <p
10
10
  {...props}
11
- className={'text-sm text-red-600 dark:text-red-400 ' + className}
11
+ className={`text-sm text-red-600 dark:text-red-400 ${className}`}
12
12
  >
13
13
  {message}
14
14
  </p>
@@ -9,10 +9,7 @@ export default function InputLabel({
9
9
  return (
10
10
  <label
11
11
  {...props}
12
- className={
13
- `block font-medium text-sm text-gray-700 dark:text-gray-300 ` +
14
- className
15
- }
12
+ className={`block font-medium text-sm text-gray-700 dark:text-gray-300 ${className}`}
16
13
  >
17
14
  {value ? value : children}
18
15
  </label>
@@ -10,11 +10,11 @@ export default function NavLink({
10
10
  <Link
11
11
  {...props}
12
12
  className={
13
- 'inline-flex items-center px-1 pt-1 border-b-2 text-sm font-medium leading-5 transition duration-150 ease-in-out focus:outline-none ' +
14
- (active
13
+ `inline-flex items-center px-1 pt-1 border-b-2 text-sm font-medium leading-5 transition duration-150 ease-in-out focus:outline-none ${
14
+ active
15
15
  ? 'border-indigo-400 dark:border-indigo-600 text-gray-900 dark:text-gray-100 focus:border-indigo-700 '
16
- : 'border-transparent text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-300 hover:border-gray-300 dark:hover:border-gray-700 focus:text-gray-700 dark:focus:text-gray-300 focus:border-gray-300 dark:focus:border-gray-700 ') +
17
- className
16
+ : 'border-transparent text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-300 hover:border-gray-300 dark:hover:border-gray-700 focus:text-gray-700 dark:focus:text-gray-300 focus:border-gray-300 dark:focus:border-gray-700 '
17
+ } ${className}`
18
18
  }
19
19
  >
20
20
  {children}
@@ -12,7 +12,7 @@ export default function PrimaryButton({
12
12
  className={
13
13
  `inline-flex items-center px-4 py-2 bg-gray-800 dark:bg-gray-200 border border-transparent rounded-md font-semibold text-xs text-white dark:text-gray-800 uppercase tracking-widest hover:bg-gray-700 dark:hover:bg-white focus:bg-gray-700 dark:focus:bg-white active:bg-gray-900 dark:active:bg-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 dark:focus:ring-offset-gray-800 transition ease-in-out duration-150 ${
14
14
  disabled && 'opacity-25'
15
- } ` + className
15
+ } ${className}`
16
16
  }
17
17
  disabled={disabled}
18
18
  >
@@ -14,7 +14,7 @@ export default function SecondaryButton({
14
14
  className={
15
15
  `inline-flex items-center px-4 py-2 bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-500 rounded-md font-semibold text-xs text-gray-700 dark:text-gray-300 uppercase tracking-widest shadow-sm hover:bg-gray-50 dark:hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 dark:focus:ring-offset-gray-800 disabled:opacity-25 transition ease-in-out duration-150 ${
16
16
  disabled && 'opacity-25'
17
- } ` + className
17
+ } ${className}`
18
18
  }
19
19
  disabled={disabled}
20
20
  >
@@ -31,10 +31,7 @@ export default forwardRef(function TextInput(
31
31
  <input
32
32
  {...props}
33
33
  type={type}
34
- className={
35
- 'border-gray-300 dark:border-gray-700 dark:bg-gray-900 dark:text-gray-300 focus:border-indigo-500 dark:focus:border-indigo-600 focus:ring-indigo-500 dark:focus:ring-indigo-600 rounded-md shadow-sm ' +
36
- className
37
- }
34
+ className={`border-gray-300 dark:border-gray-700 dark:bg-gray-900 dark:text-gray-300 focus:border-indigo-500 dark:focus:border-indigo-600 focus:ring-indigo-500 dark:focus:ring-indigo-600 rounded-md shadow-sm ${className}`}
38
35
  ref={localRef}
39
36
  />
40
37
  )
@@ -25,7 +25,7 @@ export default function Authenticated({
25
25
  <div className="flex">
26
26
  <div className="shrink-0 flex items-center">
27
27
  <Link href="/">
28
- <ApplicationLogo className="block h-9 w-auto fill-current text-gray-800" />
28
+ <ApplicationLogo className="block h-9 w-auto fill-current text-red-800" />
29
29
  </Link>
30
30
  </div>
31
31
 
@@ -7,7 +7,7 @@ export default function Guest({ children }: PropsWithChildren) {
7
7
  <div className="min-h-screen flex flex-col sm:justify-center items-center pt-6 sm:pt-0 bg-gray-100">
8
8
  <div>
9
9
  <Link href="/">
10
- <ApplicationLogo className="w-20 h-20 fill-current text-gray-500" />
10
+ <ApplicationLogo className="w-20 h-20 fill-current text-red-500" />
11
11
  </Link>
12
12
  </div>
13
13
 
@@ -1,12 +1,5 @@
1
1
  <template>
2
- <svg viewBox="0 -6 32 32" xmlns="http://www.w3.org/2000/svg">
3
- <g fill="none" fill-rule="evenodd">
4
- <path d="M0-6h32v32H0z" />
5
- <path
6
- fill="#c00"
7
- fill-rule="nonzero"
8
- d="M.985 19.636s.422-4.163 3.375-9.087c2.954-4.924 7.99-8.65 12.083-9.017 8.144-.816 15.46 6.485 15.46 6.485s-.24.168-.494.38C23.42 2.49 18.54 5.274 17.005 6.02c-7.033 3.925-4.91 13.616-4.91 13.616H.987zM24.137 2.32c-.45-.182-.9-.35-1.364-.505l.056-.93c.885.254 1.237.423 1.363.493l-.056.943zM22.8 5.304c.45.028.915.084 1.393.183l-.056.872c-.464-.1-.928-.155-1.392-.17l.056-.885zM17.597.913c-.407 0-.815.015-1.223.058l-.268-.83c.465-.056.915-.084 1.35-.084l.282.858h-.14zm.676 5.178c.35-.154.76-.31 1.237-.45l.31.93c-.41.125-.817.294-1.225.49l-.323-.97zm-6.386-3.7c-.366.184-.718.395-1.083.62l-.647-.985c.38-.225.745-.42 1.097-.604l.633.97zm2.883 6.33c.252-.323.548-.646.87-.942l.634.957c-.31.323-.59.647-.83 1L14.77 8.72zm-2.04 4.53c.112-.506.24-1.027.422-1.547l1.012.802c-.14.548-.24 1.097-.295 1.645l-1.14-.9zM6.57 6.57c-.34.35-.662.73-.958 1.11L4.53 6.752c.323-.352.674-.704 1.04-1.055l1 .872zm-4.25 6.286c-.224.52-.52 1.21-.702 1.688L0 13.954c.14-.38.436-1.084.703-1.69l1.618.592zm10.2 3.967l1.518.548c.084.663.21 1.28.337 1.83l-1.688-.605c-.07-.422-.14-1.027-.168-1.772z"
9
- />
10
- </g>
2
+ <svg viewBox="0 0 300 300" xmlns="http://www.w3.org/2000/svg">
3
+ <path d="m 237.03985,281.43515 c -1.54085,-2.49315 -1.43016,-32.97159 0.24592,-67.72985 3.02813,-62.79557 2.98467,-63.24086 -6.84044,-70.12264 -5.43834,-3.80913 -16.32202,-6.92574 -24.18594,-6.92574 -22.00734,0 -30.84257,-6.63121 -30.84257,-23.14872 0,-18.460367 5.31742,-22.209117 35.7331,-25.191397 27.97004,-2.74248 30.5663,-4.04226 26.94175,-13.48771 -2.14986,-5.6024 -13.90805,-6.59952 -77.8227,-6.59952 -69.400535,0 -75.177944,-0.58548 -73.8551,-7.48424 1.284851,-6.700534 9.490461,-7.708169 78.36353,-9.622595 42.31063,-1.176095 74.04161,-3.44104 70.51333,-5.033217 -11.28272,-5.091508 -103.7232,-12.917843 -134.65799,-11.40068 l -29.878628,1.465415 -3.171696,17.106837 c -1.744436,9.40876 -4.948521,63.009007 -7.120182,119.111597 -2.277699,58.84196 -5.815243,103.87156 -8.360116,106.41647 -2.4264,2.42639 -7.676475,3.15877 -11.666833,1.62754 -5.877786,-2.25554 -6.747202,-6.22009 -4.579445,-20.88223 1.471667,-9.954 3.74014,-63.32438 5.041047,-118.60085 2.647925,-112.511911 3.2489,-117.857541 13.890324,-123.552663 4.513472,-2.415528 45.033525,-3.067128 100.341569,-1.613517 109.0299,2.86548 110.09891,3.263428 110.09891,40.985371 0,30.923222 -7.28516,39.906492 -35.24013,43.454229 -29.06687,3.68892 -37.46391,6.17185 -37.46391,11.07783 0,2.19365 11.40965,3.98851 25.35478,3.98851 37.65833,0 38.79584,2.06051 38.79584,70.27428 0,31.25825 -1.20855,65.65073 -2.68573,76.42778 -2.59506,18.93304 -11.18137,28.79145 -16.94872,19.45971 z M 102.84208,259.48743 c -5.809371,-2.9396 -13.184926,-10.12819 -16.390123,-15.97462 -8.396565,-15.3158 2.912296,-41.49358 19.494463,-45.12587 20.60401,-4.51326 22.42665,-5.69589 22.42665,-14.55198 0,-6.8018 -2.78507,-8.68766 -12.83013,-8.68766 -16.253558,0 -29.936969,-13.44405 -29.936969,-29.41328 0,-14.42513 5.553783,-19.82093 24.591079,-23.89154 9.82484,-2.1008 13.8993,-5.37975 13.8993,-11.1856 0,-6.50902 -3.05408,-8.21363 -14.71608,-8.21363 -16.019022,0 -24.105594,-7.285117 -14.699611,-13.242787 3.241585,-2.05321 12.812471,-3.76252 21.268621,-3.79858 19.92576,-0.0847 30.60952,11.25947 28.76224,30.540617 -1.22046,12.73879 -3.23695,14.76612 -18.47681,18.57607 -30.922304,7.73057 -36.377959,19.24518 -9.11843,19.24518 22.57064,0 29.1179,7.65172 27.56665,32.21701 l -1.34139,21.24186 -20.81946,5.13821 c -11.45071,2.826 -21.79219,6.1109 -22.981063,7.29978 -4.590664,4.59067 3.475793,15.68791 14.430943,19.85304 16.19851,6.15868 88.0503,3.43548 90.32313,-3.42324 1.28741,-3.88501 -5.33813,-5.34589 -24.24513,-5.34589 -19.38669,0 -26.01664,-1.51819 -26.01664,-5.9575 0,-8.34429 9.63998,-11.14934 38.3165,-11.14934 28.67934,0 35.63045,5.45011 33.61018,26.35253 -0.96086,9.94142 -4.50427,15.66293 -12.05276,19.46151 -14.27136,7.1817 -96.89032,7.20826 -111.06516,0.0342 z m 57.07409,-60.66299 c -4.41463,-11.5043 3.01548,-16.23905 21.50632,-13.70463 20.26375,2.77747 30.64103,-1.74032 26.8271,-11.67922 -1.8078,-4.7111 -8.00515,-6.84671 -19.86838,-6.84671 -19.48707,0 -22.72529,-6.68 -6.27087,-12.93598 25.01034,-9.50892 44.62703,0.19588 44.62703,22.07791 0,17.75258 -8.58709,23.84253 -37.57444,26.6478 -21.20481,2.05209 -27.38199,1.30033 -29.24676,-3.55917 z" />
11
4
  </svg>
12
5
  </template>
@@ -27,7 +27,7 @@ const { pathname = '' } = typeof window !== 'undefined' ? window.location : {}
27
27
  <div class="shrink-0 flex items-center">
28
28
  <Link href="/">
29
29
  <ApplicationLogo
30
- class="block h-9 w-auto fill-current text-gray-800 dark:text-gray-200"
30
+ class="block h-9 w-auto fill-current text-red-800 dark:text-red-200"
31
31
  />
32
32
  </Link>
33
33
  </div>
@@ -9,7 +9,7 @@ import { Link } from '@inertiajs/vue3'
9
9
  >
10
10
  <div>
11
11
  <Link href="/">
12
- <ApplicationLogo class="w-20 h-20 fill-current text-gray-500" />
12
+ <ApplicationLogo class="w-20 h-20 fill-current text-red-500" />
13
13
  </Link>
14
14
  </div>
15
15
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kaze
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cuong Giang
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-06-14 00:00:00.000000000 Z
11
+ date: 2024-06-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -60,7 +60,6 @@ executables:
60
60
  extensions: []
61
61
  extra_rdoc_files: []
62
62
  files:
63
- - MIT-LICENSE
64
63
  - README.md
65
64
  - bin/kaze
66
65
  - lib/kaze.rb
@@ -84,9 +83,9 @@ files:
84
83
  - stubs/default/app/mailers/application_mailer.rb
85
84
  - stubs/default/app/mailers/user_mailer.rb
86
85
  - stubs/default/app/models/application_record.rb
87
- - stubs/default/app/models/auth.rb
88
86
  - stubs/default/app/models/concerns/can_reset_password.rb
89
87
  - stubs/default/app/models/current.rb
88
+ - stubs/default/app/models/session_guard.rb
90
89
  - stubs/default/app/models/user.rb
91
90
  - stubs/default/app/validators/current_password_validator.rb
92
91
  - stubs/default/app/validators/email_validator.rb
data/MIT-LICENSE DELETED
@@ -1,20 +0,0 @@
1
- Copyright (c) 2024 Cuong Giang
2
-
3
- Permission is hereby granted, free of charge, to any person obtaining
4
- a copy of this software and associated documentation files (the
5
- "Software"), to deal in the Software without restriction, including
6
- without limitation the rights to use, copy, modify, merge, publish,
7
- distribute, sublicense, and/or sell copies of the Software, and to
8
- permit persons to whom the Software is furnished to do so, subject to
9
- the following conditions:
10
-
11
- The above copyright notice and this permission notice shall be
12
- included in all copies or substantial portions of the Software.
13
-
14
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -1,57 +0,0 @@
1
- class Auth
2
- attr_reader :name, :session, :user
3
-
4
- def initialize(name, session)
5
- @name = name
6
- @session = session
7
- end
8
-
9
- def get_user
10
- return @user unless @user.nil?
11
-
12
- id = @session[get_name]
13
-
14
- @user = User.find_by(id: id) unless id.nil?
15
-
16
- @user
17
- end
18
-
19
- def get_name
20
- "login_#{@name}_#{Digest::SHA1.hexdigest(self.class.name)}"
21
- end
22
-
23
- def check?
24
- not get_user.nil?
25
- end
26
-
27
- def attempt(credentials = {})
28
- user = User.authenticate_by(credentials)
29
-
30
- return false if user.nil?
31
-
32
- login user
33
-
34
- true
35
- end
36
-
37
- def login(user)
38
- update_session user.id
39
-
40
- set_user user
41
- end
42
-
43
- def set_user(user)
44
- @user = user
45
- end
46
-
47
- def logout
48
- @session[get_name] = nil
49
- @user = nil
50
- end
51
-
52
- private
53
-
54
- def update_session(id)
55
- @session[get_name] = id
56
- end
57
- end