action_auth 1.0.0 → 1.2.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: 24c21d0f3f0275043c101a941be6587f6ab14dcd56be5951e410a15c66d2ce59
4
- data.tar.gz: 0406533a71d0411f164c20dc805e1f9e43988ffd7d979dc9ece4f8a20050bf30
3
+ metadata.gz: 2199e638d124811034db20d5d3cd6f0b23d56acf260d42e18f9559bf54405295
4
+ data.tar.gz: ab312a35ead67087ab41cfb30f54a42696521924fb1e695870e87632742497d6
5
5
  SHA512:
6
- metadata.gz: 415a5088415bdc54b813b8a199486e733442b6346ec9ba30b2995bf9428983478aa86e8406adb2cf18bf7271669dad2f0de50f9658dbe0627d4b61b6423ee66f
7
- data.tar.gz: 795b6cc968062e90034ddfb08ad4f251a69b7bd5a50b580d706f98fa99c71276da291ef0bce15964153593a05aef4e5f3b171d2e5e980928754d6800b2324dea
6
+ metadata.gz: 53f6e3b604bc0037a751269cd16975e243e84ebd1018419764c88a2b60a8309455736b2b7a2ec1e6b29cb2970e4e0020348756fed9658400f32d2d3a2f3b179a
7
+ data.tar.gz: 0ccad04b7a3e4ccbb50e80149b40d452364089600a2a5462ea2392ece13151f8903f65c491d8bd3dc5507ae6fac3ac6430ae18b0b0ac247acb434f898a3c3055
data/README.md CHANGED
@@ -98,11 +98,13 @@ settings.
98
98
 
99
99
  ```ruby
100
100
  ActionAuth.configure do |config|
101
+ config.allow_user_deletion = true
102
+ config.default_from_email = "from@example.com"
103
+ config.magic_link_enabled = true
104
+ config.verify_email_on_sign_in = true
101
105
  config.webauthn_enabled = true
102
106
  config.webauthn_origin = "http://localhost:3000" # or "https://example.com"
103
107
  config.webauthn_rp_name = Rails.application.class.to_s.deconstantize
104
- config.verify_email_on_sign_in = true
105
- config.default_from_email = "from@example.com"
106
108
  end
107
109
  ```
108
110
 
@@ -124,11 +126,11 @@ These are the planned features for ActionAuth. The ones that are checked off are
124
126
 
125
127
  ✅ - Passkeys/Hardware Security Keys
126
128
 
127
- - Magic Links
129
+ - Magic Links
128
130
 
129
131
  ⏳ - OAuth with Google, Facebook, Github, Twitter, etc.
130
132
 
131
- - Account Deletion
133
+ - Account Deletion
132
134
 
133
135
  ⏳ - Account Lockout
134
136
 
@@ -212,6 +214,29 @@ they can add a Passkey to their account. The Passkey could be an iCloud Keychain
212
214
  key like a Yubikey, or a mobile device. If enabled and configured, the user will be prompted to use
213
215
  their Passkey after they log in.
214
216
 
217
+ ## Magic Links
218
+
219
+ Magic Links are a way to authenticate a user without requiring a password. This is done by sending
220
+ an email to the user with a link that will log them in. This is a great way to allow users to log in
221
+ without having to remember a password. This is especially useful for users who may not have a password
222
+ manager or have a hard time remembering passwords.
223
+
224
+ ## Account Deletion
225
+
226
+ Account deletion is a feature that is enabled by default. When a user deletes their account, the account
227
+ is marked as deleted and the user is logged out. The user will no longer be able to log in with their
228
+ email and password. The user will need to create a new account if they wish to continue using the application.
229
+
230
+ Here's an example of how you may want to add a delete account button to your application. Obviously, you
231
+ will want to style this to fit your application and have some kind of confirmation dialog.
232
+
233
+ ```
234
+ <p>
235
+ Unhappy with the service?
236
+ <%= button_to "Delete Account", action_auth.users_path, method: :delete %>
237
+ </p>
238
+ ```
239
+
215
240
  #### Configuration
216
241
 
217
242
  The migrations are already copied over to your application when you run
@@ -272,7 +297,7 @@ We can set the user to become a User record instead of an ActionAuth::User recor
272
297
  class Current < ActiveSupport::CurrentAttributes
273
298
  def user
274
299
  return unless ActionAuth::Current.user
275
- ActionAuth::Current.user.becomes(User)
300
+ ActionAuth::Current.user&.becomes(User)
276
301
  end
277
302
  end
278
303
  ```
@@ -0,0 +1,20 @@
1
+ module ActionAuth
2
+ class Magics::RequestsController < ApplicationController
3
+ def new
4
+ end
5
+
6
+ def create
7
+ user = User.find_or_initialize_by(email: params[:email])
8
+ if user.new_record?
9
+ password = SecureRandom.hex(32)
10
+ user.password = password
11
+ user.password_confirmation = password
12
+ user.save!
13
+ end
14
+
15
+ UserMailer.with(user: user).magic_link.deliver_later
16
+
17
+ redirect_to sign_in_path, notice: "Check your email for a magic link."
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,15 @@
1
+ module ActionAuth
2
+ class Magics::SignInsController < ApplicationController
3
+ def show
4
+ user = ActionAuth::User.find_by_token_for(:magic_token, params[:token])
5
+ if user
6
+ @session = user.sessions.create
7
+ cookies.signed.permanent[:session_token] = { value: @session.id, httponly: true }
8
+ user.update(verified: true)
9
+ redirect_to main_app.root_path, notice: "Signed In"
10
+ else
11
+ redirect_to sign_in_path, alert: "Authentication failed, please try again."
12
+ end
13
+ end
14
+ end
15
+ 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
@@ -13,5 +13,12 @@ module ActionAuth
13
13
 
14
14
  mail to: @user.email, subject: "Verify your email"
15
15
  end
16
+
17
+ def magic_link
18
+ @user = params[:user]
19
+ @signed_id = @user.generate_token_for(:magic_token)
20
+
21
+ mail to: @user.email, subject: "Sign in to your account"
22
+ end
16
23
  end
17
24
  end
@@ -20,6 +20,10 @@ module ActionAuth
20
20
  password_salt.last(10)
21
21
  end
22
22
 
23
+ generates_token_for :magic_token, expires_in: 20.minutes do
24
+ password_salt.last(10)
25
+ end
26
+
23
27
  validates :email, presence: true, uniqueness: true, format: { with: URI::MailTo::EMAIL_REGEXP }
24
28
  validates :password, allow_nil: true, length: { minimum: 12 }
25
29
 
@@ -0,0 +1,21 @@
1
+ <h1>Sign up</h1>
2
+
3
+ <%= form_with(url: magics_requests_path) do |form| %>
4
+ <div class="mb-3">
5
+ <%= form.label :email, style: "display: block" %>
6
+ <%= form.email_field :email, required: true, autofocus: true, autocomplete: "email" %>
7
+ </div>
8
+
9
+ <div class="mb-3">
10
+ <%= form.submit "Request Magic Link", class: "btn btn-primary" %>
11
+ </div>
12
+ <% end %>
13
+
14
+ <div class="mb-3">
15
+ <%= link_to "Sign In", sign_in_path %> |
16
+ <%= link_to "Sign Up", sign_up_path %> |
17
+ <%= link_to "Reset Password", new_identity_password_reset_path %>
18
+ <% if ActionAuth.configuration.verify_email_on_sign_in %>
19
+ | <%= link_to "Verify Email", identity_email_verification_path %>
20
+ <% end %>
21
+ </div>
@@ -36,6 +36,9 @@
36
36
 
37
37
  <div class="mb-3">
38
38
  <%= link_to "Sign In", sign_in_path %> |
39
+ <% if ActionAuth.configuration.magic_link_enabled? %>
40
+ <%= link_to "Magic Link", new_magics_requests_path %> |
41
+ <% end %>
39
42
  <%= link_to "Reset Password", new_identity_password_reset_path %>
40
43
  <% if ActionAuth.configuration.verify_email_on_sign_in %>
41
44
  | <%= link_to "Verify Email", identity_email_verification_path %>
@@ -21,6 +21,9 @@
21
21
 
22
22
  <div class="mb-3">
23
23
  <%= link_to "Sign Up", sign_up_path %> |
24
+ <% if ActionAuth.configuration.magic_link_enabled? %>
25
+ <%= link_to "Magic Link", new_magics_requests_path %> |
26
+ <% end %>
24
27
  <%= link_to "Reset Password", new_identity_password_reset_path %>
25
28
  <% if ActionAuth.configuration.verify_email_on_sign_in %>
26
29
  | <%= link_to "Verify Email", identity_email_verification_path %>
@@ -0,0 +1,3 @@
1
+ <p>
2
+ Use this <%= link_to "link", magics_sign_ins_url(token: @signed_id) %> to sign in.
3
+ </p>
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
@@ -18,4 +23,11 @@ ActionAuth::Engine.routes.draw do
18
23
 
19
24
  resource :webauthn_credential_authentications, only: [:new, :create]
20
25
  end
26
+
27
+ if ActionAuth.configuration.magic_link_enabled?
28
+ namespace :magics do
29
+ resource :sign_ins, only: [:show]
30
+ resource :requests, only: [:new, :create]
31
+ end
32
+ end
21
33
  end
@@ -1,18 +1,31 @@
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 :default_from_email
11
+
9
12
 
10
13
  def initialize
14
+ @allow_user_deletion = true
15
+ @default_from_email = "from@example.com"
16
+ @magic_link_enabled = true
17
+ @verify_email_on_sign_in = true
11
18
  @webauthn_enabled = defined?(WebAuthn)
12
19
  @webauthn_origin = "http://localhost:3000"
13
20
  @webauthn_rp_name = Rails.application.class.to_s.deconstantize
14
- @verify_email_on_sign_in = true
15
- @default_from_email = "from@example.com"
21
+ end
22
+
23
+ def allow_user_deletion?
24
+ @allow_user_deletion.respond_to?(:call) ? @allow_user_deletion.call : @allow_user_deletion
25
+ end
26
+
27
+ def magic_link_enabled?
28
+ @magic_link_enabled.respond_to?(:call) ? @magic_link_enabled.call : @magic_link_enabled
16
29
  end
17
30
 
18
31
  def webauthn_enabled?
@@ -1,3 +1,3 @@
1
1
  module ActionAuth
2
- VERSION = "1.0.0"
2
+ VERSION = "1.2.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.0.0
4
+ version: 1.2.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-06 00:00:00.000000000 Z
11
+ date: 2024-08-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -56,9 +56,12 @@ files:
56
56
  - app/controllers/action_auth/identity/email_verifications_controller.rb
57
57
  - app/controllers/action_auth/identity/emails_controller.rb
58
58
  - app/controllers/action_auth/identity/password_resets_controller.rb
59
+ - app/controllers/action_auth/magics/requests_controller.rb
60
+ - app/controllers/action_auth/magics/sign_ins_controller.rb
59
61
  - app/controllers/action_auth/passwords_controller.rb
60
62
  - app/controllers/action_auth/registrations_controller.rb
61
63
  - app/controllers/action_auth/sessions_controller.rb
64
+ - app/controllers/action_auth/users_controller.rb
62
65
  - app/controllers/action_auth/webauthn_credential_authentications_controller.rb
63
66
  - app/controllers/action_auth/webauthn_credentials_controller.rb
64
67
  - app/helpers/action_auth/application_helper.rb
@@ -73,12 +76,14 @@ files:
73
76
  - app/views/action_auth/identity/emails/edit.html.erb
74
77
  - app/views/action_auth/identity/password_resets/edit.html.erb
75
78
  - app/views/action_auth/identity/password_resets/new.html.erb
79
+ - app/views/action_auth/magics/requests/new.html.erb
76
80
  - app/views/action_auth/passwords/edit.html.erb
77
81
  - app/views/action_auth/registrations/new.html.erb
78
82
  - app/views/action_auth/sessions/index.html.erb
79
83
  - app/views/action_auth/sessions/new.html.erb
80
84
  - app/views/action_auth/user_mailer/email_verification.html.erb
81
85
  - app/views/action_auth/user_mailer/email_verification.text.erb
86
+ - app/views/action_auth/user_mailer/magic_link.html.erb
82
87
  - app/views/action_auth/user_mailer/password_reset.html.erb
83
88
  - app/views/action_auth/user_mailer/password_reset.text.erb
84
89
  - app/views/action_auth/webauthn_credential_authentications/new.html.erb