two_step 1.0.1 → 1.0.2

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: 5eab54d43eb0a7ab7a916218a79582d48dd138715d09d6ac4e161819cdc31e6e
4
- data.tar.gz: 1602d5a1307fc85b8e2777844c5afbbb1f82046392f8e3665a40043056da1d6b
3
+ metadata.gz: 61361b42ca13fa684c90f1f66adba40bb47392bef1121ed9f8340ee0900fd82a
4
+ data.tar.gz: 9b4389eafe47979a1d2182fc85f13ae223e8d43149cf6b38ff16dd68181d09d5
5
5
  SHA512:
6
- metadata.gz: b9df3fad7cd3b59172395a3ceb65fbeb9315294cf4eb6e33d45000a80f184bfe7446928d9361e41c8216ab79060a4a3f3f44f7cf6c8ba6499ca5f803fb63bdb7
7
- data.tar.gz: 3f2e88dd39177fc3373566b3469c974e9aa8417d1ab8348dd5f07ef28afb17663dc036bac4ebeb4ee2e85e40e30a124335ca77d822916fe43f62d9f67b160945
6
+ metadata.gz: 564a48da2a552ea7b3dd4ac7c774be6c99ec1bd3dc2767f5b32a587f60e5f98f1d367101b48784026572165d47581c1d4205cd93461e2b39e5e472078eefd9f3
7
+ data.tar.gz: 68d6546f3299edef59c2d1eba6100b6e1b3db865afbf4e0e870aee42f48cf9e9247c6e01cb119b9043948516a122d035e843f45e3c486a8d1f3e3bde730f750e
data/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.0.2] - 2026-06-07
4
+
5
+ ### Added
6
+
7
+ - Added a `challenge_skip_allowed` configuration hook for conditionally skipping TwoStep challenges
8
+
3
9
  ## [1.0.1] - 2026-05-24
4
10
 
5
11
  ### Changed
data/README.md CHANGED
@@ -125,6 +125,7 @@ TwoStep.configure do |config|
125
125
 
126
126
  config.login_path = "/login"
127
127
  config.after_two_step_login_path = "/"
128
+ config.challenge_skip_allowed = ->(_resource, _controller) { false }
128
129
 
129
130
  config.on_authentication_success = ->(resource, session, _controller) {
130
131
  session.delete(:two_step_pending_user_id)
@@ -144,6 +145,7 @@ Notes:
144
145
  - `resource_finder` and `current_resource_finder` may accept either `session` alone or `session, controller`.
145
146
  - `login_path` can be a string or a callable that receives `controller`.
146
147
  - `after_two_step_login_path` can be a string or a callable that receives `resource, controller`.
148
+ - `challenge_skip_allowed` can be a boolean-like value or a callable that receives `resource, controller`; it defaults to `false`.
147
149
  - `on_authentication_success` can accept `resource, session` or `resource, session, controller`.
148
150
  - `layout_title`, `layout_stylesheets`, `layout_html_attributes`, `layout_body_attributes`, and `layout_brand` can be plain values or callables that receive `controller`.
149
151
 
@@ -153,6 +155,7 @@ Example using controller-aware hooks:
153
155
  TwoStep.configure do |config|
154
156
  config.login_path = ->(controller) { controller.main_app.login_path }
155
157
  config.after_two_step_login_path = ->(_resource, controller) { controller.main_app.dashboard_path }
158
+ config.challenge_skip_allowed = ->(resource, _controller) { resource.two_step_skip_granted? }
156
159
 
157
160
  config.on_authentication_success = lambda do |resource, _session, controller|
158
161
  controller.reset_session
@@ -3,6 +3,7 @@
3
3
  module TwoStep
4
4
  class TwoStepChallengesController < ApplicationController
5
5
  before_action :require_pending_resource
6
+ helper_method :challenge_skip_allowed?
6
7
 
7
8
  def new
8
9
  end
@@ -16,6 +17,17 @@ module TwoStep
16
17
  end
17
18
  end
18
19
 
20
+ def skip
21
+ resource = pending_resource
22
+
23
+ if challenge_skip_allowed?
24
+ complete_two_step(resource)
25
+ else
26
+ flash.now[:alert] = I18n.t("two_step.challenges.skip_unavailable")
27
+ render :new, status: :forbidden
28
+ end
29
+ end
30
+
19
31
  private
20
32
 
21
33
  def verify_backup(resource)
@@ -44,6 +56,10 @@ module TwoStep
44
56
  redirect_to TwoStep.configuration.resolve_login_path(controller: self) unless pending_resource
45
57
  end
46
58
 
59
+ def challenge_skip_allowed?
60
+ TwoStep.configuration.challenge_skip_allowed_for?(pending_resource, controller: self)
61
+ end
62
+
47
63
  def complete_two_step(resource)
48
64
  TwoStep.configuration.run_authentication_success(resource, session, controller: self)
49
65
  redirect_to TwoStep.configuration.resolve_after_two_step_login_path(resource, controller: self)
@@ -25,3 +25,12 @@
25
25
  <%= form.submit t("two_step.views.challenge.submit_backup", default: "Verify backup code") %>
26
26
  <% end %>
27
27
  </details>
28
+
29
+ <% if challenge_skip_allowed? %>
30
+ <div class="two_step-actions two_step-actions--skip">
31
+ <%= button_to t("two_step.views.challenge.skip", default: "Skip"),
32
+ skip_two_step_challenge_path,
33
+ method: :post,
34
+ class: "two_step-skip-button" %>
35
+ </div>
36
+ <% end %>
@@ -3,6 +3,7 @@ en:
3
3
  challenges:
4
4
  invalid_otp: "Invalid two-factor code."
5
5
  invalid_backup: "Invalid backup code."
6
+ skip_unavailable: "Skip not allowed."
6
7
  setups:
7
8
  invalid_otp: "Invalid code. Please try again."
8
9
  disabled: "TwoStep disabled."
@@ -18,6 +19,7 @@ en:
18
19
  backup_label: "Backup code"
19
20
  backup_help: "Backup codes are one-time use. Enter one exactly as saved."
20
21
  submit_backup: "Verify backup code"
22
+ skip: "Skip"
21
23
  setup:
22
24
  kicker: "Security setup"
23
25
  title: "Set Up Two-Factor Authentication"
@@ -3,6 +3,7 @@ ja:
3
3
  challenges:
4
4
  invalid_otp: "2段階認証コードが正しくありません。"
5
5
  invalid_backup: "バックアップコードが正しくありません。"
6
+ skip_unavailable: "スキップ不可。"
6
7
  setups:
7
8
  invalid_otp: "コードが正しくありません。もう一度お試しください。"
8
9
  disabled: "2段階認証を無効にしました。"
@@ -18,6 +19,7 @@ ja:
18
19
  backup_label: "バックアップコード"
19
20
  backup_help: "バックアップコードは1回限り有効です。保存した形式で入力してください。"
20
21
  submit_backup: "バックアップコードを確認"
22
+ skip: "スキップ"
21
23
  setup:
22
24
  kicker: "セキュリティ設定"
23
25
  title: "2段階認証を設定"
data/config/routes.rb CHANGED
@@ -1,7 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  TwoStep::Engine.routes.draw do
4
- resource :two_step_challenge, only: %i[new create], path: "challenge"
4
+ resource :two_step_challenge, only: %i[new create], path: "challenge" do
5
+ post :skip, on: :member
6
+ end
5
7
  resource :two_step_setup, only: %i[new create], path: "setup" do
6
8
  post :disable, on: :member
7
9
  end
@@ -13,6 +13,7 @@ module TwoStep
13
13
  :current_resource_finder,
14
14
  :login_path,
15
15
  :after_two_step_login_path,
16
+ :challenge_skip_allowed,
16
17
  :on_authentication_success,
17
18
  :backup_code_digest_method,
18
19
  :backup_code_verify_method,
@@ -32,6 +33,7 @@ module TwoStep
32
33
  @current_resource_finder = ->(*) {}
33
34
  @login_path = "/"
34
35
  @after_two_step_login_path = "/"
36
+ @challenge_skip_allowed = ->(*) { false }
35
37
  @on_authentication_success = ->(*) {}
36
38
  @layout_title = -> { "#{issuer} Security" }
37
39
  @layout_stylesheets = ["two_step/application"]
@@ -66,6 +68,10 @@ module TwoStep
66
68
  resolve_callable(after_two_step_login_path, resource, controller)
67
69
  end
68
70
 
71
+ def challenge_skip_allowed_for?(resource = nil, controller: nil)
72
+ !!resolve_callable(challenge_skip_allowed, resource, controller)
73
+ end
74
+
69
75
  def run_authentication_success(resource, session, controller: nil)
70
76
  resolve_callable(on_authentication_success, resource, session, controller)
71
77
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module TwoStep
4
- VERSION = "1.0.1"
4
+ VERSION = "1.0.2"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: two_step
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Fernand Arioja