passwordless 1.7.0 → 1.8.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: 7e765c341b12f05bb0156802dae574f7a0db31288181d4f71779a6ca49e48cd6
4
- data.tar.gz: 746f09e1aefaea54d0f926c9bff27548ba1f8a4fdeeea0cfbd87ddc4b22ad65f
3
+ metadata.gz: 971e8f0ab8571c17897b3e299c0733a555135e268537168ede2257162f6e7202
4
+ data.tar.gz: 2dfc64b642041c81aaad24b07237116c0250a3c5bc1686c4b7eff33cd4b109e8
5
5
  SHA512:
6
- metadata.gz: 8792ad81a4efbd5a071bb8a119d3e1ad057f2112e2bebbb888bbfdc9a84b95a77e4e2cb68ffb957fecb98f75cf05efb6c17cbd5c97b67a41f1372257eeb1cae9
7
- data.tar.gz: 763dbbba33a8568976b5a5df2c28f0d157dcf9fc92504bf9ca016e85f8239c59b1e6ae48f4fa4e2e5ab2391aba9239ce956f7706c5437e168c27756a80fc9f33
6
+ metadata.gz: 8873bb31b26549582c9297b5ca95d6f1abb0279c2aede005111025bc45b3dcab5619e7f06cc27d5d63ef9e58d166c9c252d3fadc409e4c42e37fc7818a82d395
7
+ data.tar.gz: acddc79fafb500792d493f1d0ccd1f0ffd4fdda8ee02b279d2132b6a325770fb9ff1ceb36e86eb792c4f19743b9600e3ce515375626aa2daf91dc65e27dd8223
data/README.md CHANGED
@@ -166,10 +166,34 @@ config.action_mailer.default_url_options = {host: "www.example.com"}
166
166
  routes.default_url_options[:host] ||= "www.example.com"
167
167
  ```
168
168
 
169
+ Note as well that `passwordless_for` accepts a custom controller. One possible application of this
170
+ is to add a `before_action` that redirects authenticated users from the sign-in routes, as in this example:
171
+
172
+
173
+ ```ruby
174
+ # config/routes.rb
175
+ passwordless_for :users, controller: "sessions"
176
+ ```
177
+
178
+ ```ruby
179
+ # app/controllers/sessions_controller.rb
180
+
181
+ class SessionsController < Passwordless::SessionsController
182
+ before_action :require_unauth!, only: %i[new show]
183
+
184
+ private
185
+
186
+ def require_unauth!
187
+ return unless current_user
188
+ redirect_to("/", notice: "You are already signed in.")
189
+ end
190
+ end
191
+ ```
192
+
169
193
  ### Route constraints
170
194
 
171
195
  With [constraints](https://guides.rubyonrails.org/routing.html#request-based-constraints) you can restrict access to certain routes.
172
- Passwordless provides `Passwordless::Constraint` and it's negative counterpart `Passwordless::NotConstraint` for this purpose.
196
+ Passwordless provides `Passwordless::Constraint` and it's negative counterpart `Passwordless::ConstraintNot` for this purpose.
173
197
 
174
198
  To limit a route to only authenticated `User`s:
175
199
 
@@ -190,7 +214,7 @@ end
190
214
  The negated version has the same API but with the opposite result, ie. ensuring authenticated user **don't** have access:
191
215
 
192
216
  ```ruby
193
- constraints Passwordless::NotConstraint.new(User) do
217
+ constraints Passwordless::ConstraintNot.new(User) do
194
218
  get("/no-users-allowed", to: "secrets#index")
195
219
  end
196
220
  ```
@@ -219,6 +243,8 @@ Passwordless.configure do |config|
219
243
  config.sign_out_redirect_path = '/' # After a user signs out
220
244
 
221
245
  config.paranoid = false # Display email sent notice even when the resource is not found.
246
+
247
+ config.after_session_confirm = ->(request, session) {} # Called after a session is confirmed.
222
248
  end
223
249
  ```
224
250
 
@@ -240,6 +266,22 @@ Passwordless.configure do |config|
240
266
  end
241
267
  ```
242
268
 
269
+ ## After Session Confirm Hook
270
+
271
+ An `after_session_confirm` hook is called after a successful session confirmation – in other words: after a user signs in successfully.
272
+
273
+ ```ruby
274
+ Passwordless.configure do |config|
275
+ config.after_session_confirm = ->(session, request) {
276
+ user = session.authenticatable
277
+ user.update!(
278
+ email_verified: true,
279
+ last_login_ip: request.remote_ip
280
+ )
281
+ }
282
+ end
283
+ ```
284
+
243
285
  ### Token generation
244
286
 
245
287
  By default Passwordless generates short, 6-digit, alpha numeric tokens. You can change the generator using `Passwordless.config.token_generator` to something else that responds to `call(session)` eg.:
data/Rakefile CHANGED
@@ -18,12 +18,10 @@ load("rails/tasks/statistics.rake")
18
18
 
19
19
  require "bundler/gem_tasks"
20
20
 
21
- require "rake/testtask"
22
-
23
- Rake::TestTask.new(:test) do |t|
24
- t.libs << "test"
25
- t.pattern = "test/**/*_test.rb"
26
- t.verbose = false
21
+ task(:test) do
22
+ puts("Use `bin/rails test`")
23
+ puts("-" * 80)
24
+ system("bin/rails test")
27
25
  end
28
26
 
29
27
  task(default: :test)
@@ -150,6 +150,7 @@ module Passwordless
150
150
  def authenticate_and_sign_in(session, token)
151
151
  if session.authenticate(token)
152
152
  sign_in(session)
153
+ call_after_session_confirm(session, request)
153
154
  redirect_to(
154
155
  passwordless_success_redirect_path(session.authenticatable),
155
156
  status: :see_other,
@@ -188,6 +189,12 @@ module Passwordless
188
189
  end
189
190
  end
190
191
 
192
+ def call_after_session_confirm(session, request)
193
+ return unless Passwordless.config.after_session_confirm.respond_to?(:call)
194
+
195
+ Passwordless.config.after_session_confirm.call(session, request)
196
+ end
197
+
191
198
  def find_authenticatable
192
199
  if authenticatable_class.respond_to?(:fetch_resource_for_passwordless)
193
200
  authenticatable_class.fetch_resource_for_passwordless(normalized_email_param)
@@ -26,7 +26,7 @@ module Passwordless
26
26
 
27
27
  mail(
28
28
  to: session.authenticatable.send(email_field),
29
- subject: I18n.t("passwordless.mailer.sign_in.subject")
29
+ subject: I18n.t("passwordless.mailer.sign_in.subject", token: @token)
30
30
  )
31
31
  end
32
32
  end
@@ -6,6 +6,7 @@ class CreatePasswordlessSessions < ActiveRecord::Migration[6.0]
6
6
  t.belongs_to(
7
7
  :authenticatable,
8
8
  polymorphic: true,
9
+ type: :int, # change to e.g. :uuid if your model doesn't use integer IDs
9
10
  index: {name: "authenticatable"}
10
11
  )
11
12
 
@@ -51,6 +51,12 @@ module Passwordless
51
51
 
52
52
  option :paranoid, default: false
53
53
 
54
+ option(
55
+ :after_session_confirm,
56
+ default: lambda do |_session, _request|
57
+ end
58
+ )
59
+
54
60
  def initialize
55
61
  set_defaults!
56
62
  end
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Passwordless
4
4
  # :nodoc:
5
- VERSION = "1.7.0"
5
+ VERSION = "1.8.1"
6
6
  end
data/lib/passwordless.rb CHANGED
@@ -12,8 +12,17 @@ require "passwordless/token_digest"
12
12
  module Passwordless
13
13
  extend Configurable
14
14
 
15
+ LOCK = Mutex.new
16
+
15
17
  def self.context
16
- @context ||= Context.new
18
+ return @context if @context
19
+
20
+ # Routes are lazy loaded in Rails 8 so we need to load them to populate Context#resources.
21
+ Rails.application.try(:reload_routes_unless_loaded)
22
+
23
+ LOCK.synchronize do
24
+ @context ||= Context.new
25
+ end
17
26
  end
18
27
 
19
28
  def self.add_resource(resource, controller:, **defaults)
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: passwordless
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.7.0
4
+ version: 1.8.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mikkel Malmberg
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2024-05-28 00:00:00.000000000 Z
10
+ date: 2025-03-10 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: rails
@@ -38,7 +37,6 @@ dependencies:
38
37
  - - ">="
39
38
  - !ruby/object:Gem::Version
40
39
  version: 3.1.11
41
- description:
42
40
  email:
43
41
  - mikkel@brnbw.com
44
42
  executables: []
@@ -77,7 +75,6 @@ homepage: https://github.com/mikker/passwordless
77
75
  licenses:
78
76
  - MIT
79
77
  metadata: {}
80
- post_install_message:
81
78
  rdoc_options: []
82
79
  require_paths:
83
80
  - lib
@@ -92,8 +89,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
92
89
  - !ruby/object:Gem::Version
93
90
  version: '0'
94
91
  requirements: []
95
- rubygems_version: 3.5.10
96
- signing_key:
92
+ rubygems_version: 3.6.2
97
93
  specification_version: 4
98
94
  summary: Add authentication to your app without all the ickyness of passwords.
99
95
  test_files: []