action_auth 1.4.0 → 1.4.2

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: 1370e1eb71e677f2fc9be43d6cf7cb96940f3b59916615c06bc0af02c6231fff
4
- data.tar.gz: 10332892a9e4379fa282688161fcc9127a4ffb97da386b5858d612f460d50073
3
+ metadata.gz: bd82e71b203279a24d5a44196f1e9df519ef646f611f4b1ff3ad7e6b8bc043a9
4
+ data.tar.gz: d4df3340ffdcaa481b49f5e8518a2720b7bec664d2daf47a3c3d594e8a06215a
5
5
  SHA512:
6
- metadata.gz: f59840cc7ab77c07e19e6a181bdc8705d1fdbd9cc643a78fe270175bee205ce1f35c404577c49a2ffe2e638780caa00ed3c18c6d1016763d772039521d37213f
7
- data.tar.gz: b5f26e0a11f7e241d3697d6933ef8ff6047b433c407f1878705fef608ca85415645ba0ea932dba0eaad8860e7ef041766511750eeebca7e1366fb672981bab38
6
+ metadata.gz: 4c02bbf9ea57e5361291a20c6c36a1ad994dfec332eecb50c562380041388f74923b2bb7f227ed835e03e5317e7668485c4229349cb752d94b7585830341ac1e
7
+ data.tar.gz: a6cce71017754f203e43c231a3e604836c904475d899f8a02347a347dcd77b1f3ee27de50a78b1f5c8f6c19eb8bbc54f62e83fab3beb5c596318dfb88fd9d0b6
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.4.0"
2
+ VERSION = "1.4.2"
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.4.0
4
+ version: 1.4.2
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-14 00:00:00.000000000 Z
11
+ date: 2024-08-16 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