action_auth 1.1.0 → 1.3.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: 6c85ae94ede51ba040295cfca1ec2f6a46f412642bc3e3a3ada8fd102bec41ab
4
- data.tar.gz: bf218c5419f6cf1a7f8eb5b70f0cbb58f9af1710be3222ee0a333075af32e5c5
3
+ metadata.gz: c9adce01d4651e8af6f14f8738bb4f762512485d75640d9fd1993ef68fa6c37a
4
+ data.tar.gz: 9b0c5e31a61b57efef137cb9429de5015390da6a01ce6ce1bad200a3b881ccbb
5
5
  SHA512:
6
- metadata.gz: e09cef2c34868ff6e6bd0e4d81f6e5fa577d91c0b38d957f09b36aa48a2cf4a183b2ff0bc400c321eb03829aef23c3976188d108b3e9a2f6f887e2e3a86f7043
7
- data.tar.gz: c3cce12a87a5bfdc1b785ed01cb2cbed07325f9e65150e4fe5e5a7b86c6f6a52f5357aad6d51510a9e87a92f389441b268462917f0ea619980d6d130bd681ad6
6
+ metadata.gz: 132b6dad72a8a2d4531febde70f32cb3e793ab98a23d48567a9ec7c2e62655737e9c5c608f302e011c10018e787422c2d4205a1739feea3aeb7849e82ea19c82
7
+ data.tar.gz: a4fed6bd6daf8ae5c2de6cdf3e4b46090a349a4426155d368d9ec94713e0b2e00288c4c199724253a9f96ac2722c0647e3382a2c1b0b23bdb196756a4d7b00c0
data/README.md CHANGED
@@ -15,12 +15,13 @@ user experience akin to that offered by the well-regarded Devise gem.
15
15
  - [Routes](#routes)
16
16
  - [Helper Methods](#helper-methods)
17
17
  - [Restricting and Changing Routes](#restricting-and-changing-routes)
18
- 5. [WebAuthn](#webauthn)
19
- 6. [Within Your Application](#within-your-application)
20
- 7. Customizing
18
+ 5. [Have I Been Pwned](#have-i-been-pwned)
19
+ 6. [WebAuthn](#webauthn)
20
+ 7. [Within Your Application](#within-your-application)
21
+ 8. Customizing
21
22
  - [Sign In Page](https://github.com/kobaltz/action_auth/wiki/Overriding-Sign-In-page-view)
22
- 7. [License](#license)
23
- 8. [Credits](#credits)
23
+ 9. [License](#license)
24
+ 10. [Credits](#credits)
24
25
 
25
26
  ## Breaking Changes
26
27
 
@@ -98,12 +99,13 @@ settings.
98
99
 
99
100
  ```ruby
100
101
  ActionAuth.configure do |config|
102
+ config.allow_user_deletion = true
103
+ config.default_from_email = "from@example.com"
104
+ config.magic_link_enabled = true
105
+ config.verify_email_on_sign_in = true
101
106
  config.webauthn_enabled = true
102
107
  config.webauthn_origin = "http://localhost:3000" # or "https://example.com"
103
108
  config.webauthn_rp_name = Rails.application.class.to_s.deconstantize
104
- config.verify_email_on_sign_in = true
105
- config.magic_link_enabled = true
106
- config.default_from_email = "from@example.com"
107
109
  end
108
110
  ```
109
111
 
@@ -129,7 +131,9 @@ These are the planned features for ActionAuth. The ones that are checked off are
129
131
 
130
132
  ⏳ - OAuth with Google, Facebook, Github, Twitter, etc.
131
133
 
132
- - Account Deletion
134
+ - Have I Been Pwned Integration
135
+
136
+ ✅ - Account Deletion
133
137
 
134
138
  ⏳ - Account Lockout
135
139
 
@@ -205,6 +209,38 @@ versus a user that is not logged in.
205
209
  end
206
210
  root to: 'welcome#index'
207
211
 
212
+ ## Have I Been Pwned
213
+
214
+ [Have I Been Pwned](https://haveibeenpwned.com/) is a way that youre able to check if a password has been compromised in a data breach. This is a great way to ensure that your users are using secure passwords.
215
+
216
+ Add the `pwned` gem to your Gemfile. That's all you'll have to do to enable this functionality.
217
+
218
+ ```ruby
219
+ bundle add pwned
220
+ ```
221
+
222
+ ## Magic Links
223
+
224
+ Magic Links are a way to authenticate a user without requiring a password. This is done by sending
225
+ an email to the user with a link that will log them in. This is a great way to allow users to log in
226
+ without having to remember a password. This is especially useful for users who may not have a password
227
+ manager or have a hard time remembering passwords.
228
+
229
+ ## Account Deletion
230
+
231
+ Account deletion is a feature that is enabled by default. When a user deletes their account, the account
232
+ is marked as deleted and the user is logged out. The user will no longer be able to log in with their
233
+ email and password. The user will need to create a new account if they wish to continue using the application.
234
+
235
+ Here's an example of how you may want to add a delete account button to your application. Obviously, you
236
+ will want to style this to fit your application and have some kind of confirmation dialog.
237
+
238
+ ```
239
+ <p>
240
+ Unhappy with the service?
241
+ <%= button_to "Delete Account", action_auth.users_path, method: :delete %>
242
+ </p>
243
+ ```
208
244
  ## WebAuthn
209
245
 
210
246
  ActionAuth's approach for WebAuthn is simplicity. It is used as a multifactor authentication step,
@@ -2,6 +2,7 @@ module ActionAuth
2
2
  module Identity
3
3
  class PasswordResetsController < ApplicationController
4
4
  before_action :set_user, only: %i[ edit update ]
5
+ before_action :validate_pwned_password, only: :update
5
6
 
6
7
  def new
7
8
  end
@@ -41,6 +42,16 @@ module ActionAuth
41
42
  def send_password_reset_email
42
43
  UserMailer.with(user: @user).password_reset.deliver_later
43
44
  end
45
+
46
+ def validate_pwned_password
47
+ return unless ActionAuth.configuration.pwned_enabled?
48
+
49
+ pwned = Pwned::Password.new(params[:password])
50
+ if pwned.pwned?
51
+ @user.errors.add(:password, "has been pwned #{pwned.pwned_count} times. Please choose a different password.")
52
+ render :edit, status: :unprocessable_entity
53
+ end
54
+ end
44
55
  end
45
56
  end
46
57
  end
@@ -1,6 +1,7 @@
1
1
  module ActionAuth
2
2
  class PasswordsController < ApplicationController
3
3
  before_action :set_user
4
+ before_action :validate_pwned_password, only: :update
4
5
 
5
6
  def edit
6
7
  end
@@ -22,5 +23,15 @@ module ActionAuth
22
23
  def user_params
23
24
  params.permit(:password, :password_confirmation, :password_challenge).with_defaults(password_challenge: "")
24
25
  end
26
+
27
+ def validate_pwned_password
28
+ return unless ActionAuth.configuration.pwned_enabled?
29
+
30
+ pwned = Pwned::Password.new(params[:password])
31
+ if pwned.pwned?
32
+ @user.errors.add(:password, "has been pwned #{pwned.pwned_count} times. Please choose a different password.")
33
+ render :new, status: :unprocessable_entity
34
+ end
35
+ end
25
36
  end
26
37
  end
@@ -1,5 +1,7 @@
1
1
  module ActionAuth
2
2
  class RegistrationsController < ApplicationController
3
+ before_action :validate_pwned_password, only: :create
4
+
3
5
  def new
4
6
  @user = User.new
5
7
  end
@@ -23,12 +25,25 @@ module ActionAuth
23
25
  end
24
26
 
25
27
  private
26
- def user_params
27
- params.permit(:email, :password, :password_confirmation)
28
- end
29
28
 
30
- def send_email_verification
31
- UserMailer.with(user: @user).email_verification.deliver_later
29
+ def user_params
30
+ params.permit(:email, :password, :password_confirmation)
31
+ end
32
+
33
+ def send_email_verification
34
+ UserMailer.with(user: @user).email_verification.deliver_later
35
+ end
36
+
37
+ def validate_pwned_password
38
+ return unless ActionAuth.configuration.pwned_enabled?
39
+
40
+ pwned = Pwned::Password.new(params[:password])
41
+
42
+ if pwned.pwned?
43
+ @user = User.new(email: params[:email])
44
+ @user.errors.add(:password, "has been pwned #{pwned.pwned_count} times. Please choose a different password.")
45
+ render :new, status: :unprocessable_entity
32
46
  end
47
+ end
33
48
  end
34
49
  end
@@ -0,0 +1,10 @@
1
+ module ActionAuth
2
+ class UsersController < ApplicationController
3
+ before_action :authenticate_user!
4
+
5
+ def destroy
6
+ Current.user.destroy
7
+ redirect_to main_app.root_url, notice: "Your account has been deleted."
8
+ end
9
+ end
10
+ end
@@ -15,18 +15,18 @@
15
15
 
16
16
  <%= form.hidden_field :sid, value: params[:sid] %>
17
17
 
18
- <div>
18
+ <div class="mb-3">
19
19
  <%= form.label :password, "New password", style: "display: block" %>
20
20
  <%= form.password_field :password, required: true, autofocus: true, autocomplete: "new-password" %>
21
21
  <div>12 characters minimum.</div>
22
22
  </div>
23
23
 
24
- <div>
24
+ <div class="mb-3">
25
25
  <%= form.label :password_confirmation, "Confirm new password", style: "display: block" %>
26
26
  <%= form.password_field :password_confirmation, required: true, autocomplete: "new-password" %>
27
27
  </div>
28
28
 
29
29
  <div>
30
- <%= form.submit "Save changes" %>
30
+ <%= form.submit "Save changes", class: "btn btn-primary" %>
31
31
  </div>
32
32
  <% end %>
data/config/routes.rb CHANGED
@@ -3,13 +3,18 @@ ActionAuth::Engine.routes.draw do
3
3
  post "sign_in", to: "sessions#create"
4
4
  get "sign_up", to: "registrations#new"
5
5
  post "sign_up", to: "registrations#create"
6
- resources :sessions, only: [:index, :show, :destroy]
7
- resource :password, only: [:edit, :update]
6
+
8
7
  namespace :identity do
9
8
  resource :email, only: [:edit, :update]
10
9
  resource :email_verification, only: [:show, :create]
11
10
  resource :password_reset, only: [:new, :edit, :create, :update]
12
11
  end
12
+ resource :password, only: [:edit, :update]
13
+ resources :sessions, only: [:index, :show, :destroy]
14
+
15
+ if ActionAuth.configuration.allow_user_deletion?
16
+ resource :users, only: [:destroy]
17
+ end
13
18
 
14
19
  if ActionAuth.configuration.webauthn_enabled?
15
20
  resources :webauthn_credentials, only: [:new, :create, :destroy] do
@@ -1,28 +1,40 @@
1
1
  module ActionAuth
2
2
  class Configuration
3
3
 
4
+ attr_accessor :allow_user_deletion
5
+ attr_accessor :default_from_email
6
+ attr_accessor :magic_link_enabled
7
+ attr_accessor :verify_email_on_sign_in
4
8
  attr_accessor :webauthn_enabled
5
9
  attr_accessor :webauthn_origin
6
10
  attr_accessor :webauthn_rp_name
7
- attr_accessor :verify_email_on_sign_in
8
- attr_accessor :magic_link_enabled
9
- attr_accessor :default_from_email
11
+
10
12
 
11
13
  def initialize
14
+ @allow_user_deletion = true
15
+ @default_from_email = "from@example.com"
16
+ @magic_link_enabled = true
17
+ @pwned_enabled = defined?(Pwned)
18
+ @verify_email_on_sign_in = true
12
19
  @webauthn_enabled = defined?(WebAuthn)
13
20
  @webauthn_origin = "http://localhost:3000"
14
21
  @webauthn_rp_name = Rails.application.class.to_s.deconstantize
15
- @verify_email_on_sign_in = true
16
- @magic_link_enabled = true
17
- @default_from_email = "from@example.com"
22
+ end
23
+
24
+ def allow_user_deletion?
25
+ @allow_user_deletion == true
26
+ end
27
+
28
+ def magic_link_enabled?
29
+ @magic_link_enabled == true
18
30
  end
19
31
 
20
32
  def webauthn_enabled?
21
33
  @webauthn_enabled.respond_to?(:call) ? @webauthn_enabled.call : @webauthn_enabled
22
34
  end
23
35
 
24
- def magic_link_enabled?
25
- @magic_link_enabled.respond_to?(:call) ? @magic_link_enabled.call : @magic_link_enabled
36
+ def pwned_enabled?
37
+ @pwned_enabled.respond_to?(:call) ? @pwned_enabled.call : @pwned_enabled
26
38
  end
27
39
 
28
40
  end
@@ -1,3 +1,3 @@
1
1
  module ActionAuth
2
- VERSION = "1.1.0"
2
+ VERSION = "1.3.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: action_auth
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dave Kimura
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-08-09 00:00:00.000000000 Z
11
+ date: 2024-08-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -61,6 +61,7 @@ files:
61
61
  - app/controllers/action_auth/passwords_controller.rb
62
62
  - app/controllers/action_auth/registrations_controller.rb
63
63
  - app/controllers/action_auth/sessions_controller.rb
64
+ - app/controllers/action_auth/users_controller.rb
64
65
  - app/controllers/action_auth/webauthn_credential_authentications_controller.rb
65
66
  - app/controllers/action_auth/webauthn_credentials_controller.rb
66
67
  - app/helpers/action_auth/application_helper.rb
@@ -124,7 +125,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
124
125
  - !ruby/object:Gem::Version
125
126
  version: '0'
126
127
  requirements: []
127
- rubygems_version: 3.5.16
128
+ rubygems_version: 3.5.17
128
129
  signing_key:
129
130
  specification_version: 4
130
131
  summary: A simple Rails engine for authorization.