action_auth 1.3.0 → 1.4.1

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: c9adce01d4651e8af6f14f8738bb4f762512485d75640d9fd1993ef68fa6c37a
4
- data.tar.gz: 9b0c5e31a61b57efef137cb9429de5015390da6a01ce6ce1bad200a3b881ccbb
3
+ metadata.gz: f2082f44369afe3132a783d6bd8477b7df97188bf29c55791a131ed4b5cc8034
4
+ data.tar.gz: ca85a89d45d638a85bef5a9f18c5e881deea0d716feddc5ac33d49c687e0f0d7
5
5
  SHA512:
6
- metadata.gz: 132b6dad72a8a2d4531febde70f32cb3e793ab98a23d48567a9ec7c2e62655737e9c5c608f302e011c10018e787422c2d4205a1739feea3aeb7849e82ea19c82
7
- data.tar.gz: a4fed6bd6daf8ae5c2de6cdf3e4b46090a349a4426155d368d9ec94713e0b2e00288c4c199724253a9f96ac2722c0647e3382a2c1b0b23bdb196756a4d7b00c0
6
+ metadata.gz: 6409ba5c720feb68d07b4e9dc4a8fa1d234e990fdcfe3fe710410f3671ae4d044ff58784c0015a67dc07083a0b4b840fcbcdc2494191bcfb852208ede5c0fadf
7
+ data.tar.gz: b156d5b0c0e6edc056b5935c3f18ec5677ea925e3dcfe8979e13048e2db0526ebcfed8f91b33f6d1109daf87cef8f510b7367bf488740a5de9d5593a81f9adaf
data/README.md CHANGED
@@ -102,6 +102,7 @@ ActionAuth.configure do |config|
102
102
  config.allow_user_deletion = true
103
103
  config.default_from_email = "from@example.com"
104
104
  config.magic_link_enabled = true
105
+ config.passkey_only = true # Allows sign in with only a passkey
105
106
  config.verify_email_on_sign_in = true
106
107
  config.webauthn_enabled = true
107
108
  config.webauthn_origin = "http://localhost:3000" # or "https://example.com"
@@ -127,6 +128,8 @@ These are the planned features for ActionAuth. The ones that are checked off are
127
128
 
128
129
  ✅ - Passkeys/Hardware Security Keys
129
130
 
131
+ ✅ - Passkeys sign in without email/password
132
+
130
133
  ✅ - Magic Links
131
134
 
132
135
  ⏳ - OAuth with Google, Facebook, Github, Twitter, etc.
@@ -141,8 +144,6 @@ These are the planned features for ActionAuth. The ones that are checked off are
141
144
 
142
145
  ⏳ - Account Impersonation
143
146
 
144
-
145
-
146
147
  ## Usage
147
148
 
148
149
  ### Routes
@@ -43,7 +43,9 @@ const Credential = {
43
43
 
44
44
  get: function (credentialOptions) {
45
45
  const self = this;
46
- const webauthnUrl = document.querySelector('meta[name="webauthn_auth_url"]').getAttribute("content");
46
+ const webauthnUrlTag = document.querySelector('meta[name="passkey_auth_url"]') ||
47
+ document.querySelector('meta[name="webauthn_auth_url"]');
48
+ const webauthnUrl = webauthnUrlTag.getAttribute("content");
47
49
  WebAuthnJSON.get({ "publicKey": credentialOptions }).then(function (credential) {
48
50
  self.callback(webauthnUrl, credential, "/");
49
51
  });
@@ -36,6 +36,7 @@ body {
36
36
  margin-right: 5px;
37
37
  }
38
38
  }
39
+
39
40
  .container-fluid {
40
41
  -webkit-text-size-adjust: 100%;
41
42
  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
@@ -78,6 +79,11 @@ input[type="password"] {
78
79
  margin-bottom: 1rem !important;
79
80
  }
80
81
 
82
+ .mx-3 {
83
+ margin-left: 1rem !important;
84
+ margin-right: 1rem !important;
85
+ }
86
+
81
87
  .btn {
82
88
  padding: 0.375rem 0.75rem;
83
89
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
@@ -0,0 +1,24 @@
1
+ module ActionAuth
2
+ module Sessions
3
+ class PasskeysController < ApplicationController
4
+ def new
5
+ get_options = WebAuthn::Credential.options_for_get
6
+ session[:current_challenge] = get_options.challenge
7
+ @options = get_options
8
+ end
9
+
10
+ def create
11
+ webauthn_credential = WebAuthn::Credential.from_get(params)
12
+ credential = WebauthnCredential.find_by(external_id: webauthn_credential.id)
13
+ user = User.find_by(id: credential&.user_id)
14
+ if credential && user
15
+ session = user.sessions.create
16
+ cookies.signed.permanent[:session_token] = { value: session.id, httponly: true }
17
+ redirect_to main_app.root_path(format: :html), notice: "Signed in successfully"
18
+ else
19
+ redirect_to sign_in_path(format: :html), alert: "That passkey is incorrect" and return
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -1,4 +1,4 @@
1
- <h1>Sign up</h1>
1
+ <h1>Request Magic Link</h1>
2
2
 
3
3
  <%= form_with(url: magics_requests_path) do |form| %>
4
4
  <div class="mb-3">
@@ -8,11 +8,16 @@
8
8
 
9
9
  <div class="mb-3">
10
10
  <%= form.submit "Request Magic Link", class: "btn btn-primary" %>
11
+ <span class="mx-3">or</span>
12
+ <%= link_to "Sign In", sign_in_path %>
13
+ <% if ActionAuth.configuration.passkey_only? %>
14
+ <span class="mx-3">or</span>
15
+ <%= link_to "Passkey", new_sessions_passkey_path %>
16
+ <% end %>
11
17
  </div>
12
18
  <% end %>
13
19
 
14
20
  <div class="mb-3">
15
- <%= link_to "Sign In", sign_in_path %> |
16
21
  <%= link_to "Sign Up", sign_up_path %> |
17
22
  <%= link_to "Reset Password", new_identity_password_reset_path %>
18
23
  <% if ActionAuth.configuration.verify_email_on_sign_in %>
@@ -39,6 +39,9 @@
39
39
  <% if ActionAuth.configuration.magic_link_enabled? %>
40
40
  <%= link_to "Magic Link", new_magics_requests_path %> |
41
41
  <% end %>
42
+ <% if ActionAuth.configuration.passkey_only? %>
43
+ <%= link_to "Passkey", new_sessions_passkey_path %> |
44
+ <% end %>
42
45
  <%= link_to "Reset Password", new_identity_password_reset_path %>
43
46
  <% if ActionAuth.configuration.verify_email_on_sign_in %>
44
47
  | <%= link_to "Verify Email", identity_email_verification_path %>
@@ -16,14 +16,19 @@
16
16
 
17
17
  <div class="mb-3">
18
18
  <%= form.submit "Sign in", class: "btn btn-primary" %>
19
+ <% if ActionAuth.configuration.magic_link_enabled? %>
20
+ <span class="mx-3">or</span>
21
+ <%= link_to "Magic Link", new_magics_requests_path %>
22
+ <% end %>
23
+ <% if ActionAuth.configuration.passkey_only? %>
24
+ <span class="mx-3">or</span>
25
+ <%= link_to "Passkey", new_sessions_passkey_path %>
26
+ <% end %>
19
27
  </div>
20
28
  <% end %>
21
29
 
22
30
  <div class="mb-3">
23
31
  <%= 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 %>
27
32
  <%= link_to "Reset Password", new_identity_password_reset_path %>
28
33
  <% if ActionAuth.configuration.verify_email_on_sign_in %>
29
34
  | <%= link_to "Verify Email", identity_email_verification_path %>
@@ -0,0 +1,20 @@
1
+ <h2 class="action-auth--text-center">Use a passkey to sign in</h2>
2
+ <%= tag :meta, name: :passkey_auth_url, content: action_auth.sessions_passkeys_url %>
3
+
4
+ <%= content_tag :div,
5
+ id: "webauthn_credential_form",
6
+ data: {
7
+ controller: "credential-authenticator",
8
+ "credential-authenticator-options-value": @options
9
+ },
10
+ class: "action-auth--text-center" do %>
11
+
12
+ <div class="mb-3 action-auth--text-center">
13
+ Insert a USB key, if necessary, and tap it.
14
+ An account with a matching passkey is required.
15
+ </div>
16
+ <% end %>
17
+
18
+ <%= content_for :cancel_path do %>
19
+ <%= link_to "Cancel", action_auth.sign_in_path %>
20
+ <% end %>
data/config/routes.rb CHANGED
@@ -10,6 +10,11 @@ ActionAuth::Engine.routes.draw do
10
10
  resource :password_reset, only: [:new, :edit, :create, :update]
11
11
  end
12
12
  resource :password, only: [:edit, :update]
13
+ namespace :sessions do
14
+ if ActionAuth.configuration.webauthn_enabled? && ActionAuth.configuration.passkey_only?
15
+ resources :passkeys, only: [:new, :create]
16
+ end
17
+ end
13
18
  resources :sessions, only: [:index, :show, :destroy]
14
19
 
15
20
  if ActionAuth.configuration.allow_user_deletion?
@@ -14,6 +14,7 @@ module ActionAuth
14
14
  @allow_user_deletion = true
15
15
  @default_from_email = "from@example.com"
16
16
  @magic_link_enabled = true
17
+ @passkey_only = true
17
18
  @pwned_enabled = defined?(Pwned)
18
19
  @verify_email_on_sign_in = true
19
20
  @webauthn_enabled = defined?(WebAuthn)
@@ -29,6 +30,10 @@ module ActionAuth
29
30
  @magic_link_enabled == true
30
31
  end
31
32
 
33
+ def passkey_only?
34
+ webauthn_enabled? && @passkey_only == true
35
+ end
36
+
32
37
  def webauthn_enabled?
33
38
  @webauthn_enabled.respond_to?(:call) ? @webauthn_enabled.call : @webauthn_enabled
34
39
  end
@@ -1,3 +1,3 @@
1
1
  module ActionAuth
2
- VERSION = "1.3.0"
2
+ VERSION = "1.4.1"
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.3.0
4
+ version: 1.4.1
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-13 00:00:00.000000000 Z
11
+ date: 2024-08-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -60,6 +60,7 @@ files:
60
60
  - app/controllers/action_auth/magics/sign_ins_controller.rb
61
61
  - app/controllers/action_auth/passwords_controller.rb
62
62
  - app/controllers/action_auth/registrations_controller.rb
63
+ - app/controllers/action_auth/sessions/passkeys_controller.rb
63
64
  - app/controllers/action_auth/sessions_controller.rb
64
65
  - app/controllers/action_auth/users_controller.rb
65
66
  - app/controllers/action_auth/webauthn_credential_authentications_controller.rb
@@ -81,6 +82,7 @@ files:
81
82
  - app/views/action_auth/registrations/new.html.erb
82
83
  - app/views/action_auth/sessions/index.html.erb
83
84
  - app/views/action_auth/sessions/new.html.erb
85
+ - app/views/action_auth/sessions/passkeys/new.html.erb
84
86
  - app/views/action_auth/user_mailer/email_verification.html.erb
85
87
  - app/views/action_auth/user_mailer/email_verification.text.erb
86
88
  - app/views/action_auth/user_mailer/magic_link.html.erb
@@ -125,7 +127,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
125
127
  - !ruby/object:Gem::Version
126
128
  version: '0'
127
129
  requirements: []
128
- rubygems_version: 3.5.17
130
+ rubygems_version: 3.5.11
129
131
  signing_key:
130
132
  specification_version: 4
131
133
  summary: A simple Rails engine for authorization.