redirectr 1.0.4 → 1.0.6

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: cf3a0eaa6ed55c0c7722b84a88addea998ad0844dec44a9610d020bac71bdda5
4
- data.tar.gz: cbe50d0fa0f7f0ff9cc72b2f2997a066cb5a11a0efd70987e69fd39c0a07b5e6
3
+ metadata.gz: 79b2022bb7a4aff997edf0f04e89276a17377b3a28c2fd33b071ce1314b13a9e
4
+ data.tar.gz: 4d271d1e980abeb41ef64cce2c227a1a31cb9bbd4f0e6e87859dc25c2606f55b
5
5
  SHA512:
6
- metadata.gz: 8f940d86c27e9163aa842b6f3f3f92d9f9d1739cad2adbecf73979261d71bb8f1a10031dfe36fc809f9aeaa8028d58129c3ea6d5bce9ef4b45eeb5c32f2828a1
7
- data.tar.gz: fe4aab1b8b7698820cfd26265c578bce574cbf9f2af0ed7ec926ce42230ac9a8edcbb74d58c1afc1075c74decdc836f9af889e43a16cd70a3bbba9d4f69a6fe6
6
+ metadata.gz: e8bdcf8567203138565fbd36c2a991053b2f1b643a91e459d9df88185fb0719ecc20755001b0005841fbc258c33800eb9b8547776fab3c92d6ba11834786c67f
7
+ data.tar.gz: 7b7533058f982773d7431d337a64a1efb9aa69072fe065aa02b35629765d620d7cec936aa2dd1bf7742d4ebfdff8560b28ae6effd1c3d184b498ca646068948d
data/README.md CHANGED
@@ -1,3 +1,5 @@
1
+ [![Test](https://github.com/wvk/redirectr/actions/workflows/test.yml/badge.svg)](https://github.com/wvk/redirectr/actions/workflows/test.yml)
2
+
1
3
  # Redirectr
2
4
 
3
5
  In many web applications, the user triggers actions that result in simple or complex workflows that should, after that workflow is finished, result in the user being redirected to the page where he initially started it. Another example would be a "back"-Link on any page.
@@ -25,34 +27,38 @@ Please read this section if you are already using an older version of Redirectr
25
27
 
26
28
  Pre-1.0 versions of Redirectr automatically included some view helpers (`hidden_referrer_input_tag`, `link_to_back`). This is no longer the case, so please add the following to your `app/helper/application_helper.rb`:
27
29
 
28
- module ApplicationHelper
29
- include Redirectr::ApplicationHelper
30
- end
30
+ ```ruby
31
+ module ApplicationHelper
32
+ include Redirectr::ApplicationHelper
33
+ end
34
+ ````
31
35
 
32
- Please note that methods like `current_path`, `referrer_path` have been removed. Only `current_url`, `referrer_url` exist. Please do also note that the value returned by these methods is not a String containing an URI value anymore. Instead, a Redirectr::ReferrerToken is returned which maps a token to an URI. To get the URI value, call `#to_s` (e.g. when used in a `redirect_to` call). When used as an URL parameter, Rails calls `#to_param` which returns the token.
36
+ Please note that methods like `current_path`, `referrer_path` have been removed. Only `current_url`, `referrer_url` exist. Please do also note that the value returned by these methods is not a String containing an URI value anymore. Instead, a `Redirectr::ReferrerToken` is returned which maps a token to an URI. To get the URI value, call `#to_s` (e.g. when used in a `redirect_to` call). When used as an URL parameter, Rails calls `#to_param` which returns the token.
33
37
 
34
38
  Summary:
35
39
 
36
- # pre-1.0.0:
37
- referrer_url.inspect # => 'https://example.com/...'
38
- redirect_to referrer_url
39
- redirect_to back_or_default
40
-
41
- # post-1.0.0:
42
- referrer_url.inspect # => '#<Redirectr::ReferrerToken:... @url="..." @token="...">'
43
- redirect_to referrer_url.to_s
44
- redirect_to back_or_default.to_s
45
- # OR, if you mount Redirectr::Engine in your routes
46
- redirect_to referrer_url
47
- redirect_to back_or_default
48
-
49
- # pre-1.0.0:
50
- link_to 'take me back', back_or_default(my_url)
51
-
52
- # post-1.0.0:
53
- link_to 'take me back', back_or_default(my_url).to_s
54
- # OR, if you mount Redirectr::Engine in your routes
55
- link_to 'take me back', back_or_default(my_url)
40
+ ```ruby
41
+ # pre-1.0.0:
42
+ referrer_url.inspect # => 'https://example.com/...'
43
+ redirect_to referrer_url
44
+ redirect_to back_or_default
45
+
46
+ # post-1.0.0:
47
+ referrer_url.inspect # => '#<Redirectr::ReferrerToken:... @url="..." @token="...">'
48
+ redirect_to referrer_url.to_s
49
+ redirect_to back_or_default.to_s
50
+ # OR, if you mount Redirectr::Engine in your routes
51
+ redirect_to referrer_url
52
+ redirect_to back_or_default
53
+
54
+ # pre-1.0.0:
55
+ link_to 'take me back', back_or_default(my_url)
56
+
57
+ # post-1.0.0:
58
+ link_to 'take me back', back_or_default(my_url).to_s
59
+ # OR, if you mount Redirectr::Engine in your routes
60
+ link_to 'take me back', back_or_default(my_url)
61
+ ```
56
62
 
57
63
  ## Examples
58
64
 
@@ -62,44 +68,68 @@ Suppose you have an application with a contact form that can be reached via a fo
62
68
 
63
69
  for the footer link to the contact form:
64
70
 
65
- <%= link_to 'Contact us!', new_contact_path(referrer_param => current_url) %>
71
+ ```erb
72
+ <%= link_to 'Contact us!', new_contact_path(referrer_param => current_url) %>
73
+ ```
66
74
 
67
75
  In the 'new contact' view:
68
76
 
69
- <%= form_for ... do |f| %>
70
- <%= hidden_referrer_input_tag %>
71
- <!-- ... -->
72
- <% end %>
77
+ ```erb
78
+ <%= form_for ... do |f| %>
79
+ <%= hidden_referrer_input_tag %>
80
+ <!-- ... -->
81
+ <% end %>
82
+ ```
73
83
 
74
84
  and finally, in the 'create' action of your ContactsController:
75
85
 
76
- def create
77
- # ...
78
- redirect_to back_or_default.to_s
79
- end
86
+ ```ruby
87
+ def create
88
+ # ...
89
+ redirect_to back_or_default.to_s
90
+ end
91
+ ```
80
92
 
81
93
  ### Custom default_url
82
94
 
83
95
  The above will redirect the user back to the page specified in the referrer param. However, if you want to provide a custom fallback url per controller in case no referrer param is provided, just define the `#default_url` in your controller:
84
96
 
85
- class MyController < ApplicationController
86
- def default_url
87
- if @record
88
- my_record_path(@record)
89
- else
90
- my_record_index_path
91
- end
92
- end
97
+ ```ruby
98
+ class MyController < ApplicationController
99
+ def default_url
100
+ if @record
101
+ my_record_path(@record)
102
+ else
103
+ my_record_index_path
93
104
  end
105
+ end
106
+ end
107
+ ```
94
108
 
95
109
  ### Nesting referrers
96
110
 
97
111
  Referrer params can be nested, which is helpful if your workflow involves branching into subworkflows. Thus, it is always possible to pass the referrer_param to another url:
98
112
 
99
- <%= link_to 'go back directly', referrer_or_current_url %>
100
- <%= link_to 'add new Foobar before going back', new_foobar_url(:foobar => {:name => 'My Foo'}, referrer_param => referrer_or_current_url) %>
113
+ ```erb
114
+ <%= link_to 'go back directly', referrer_or_current_url %>
115
+ <%= link_to 'add new Foobar before going back', new_foobar_url(:foobar => {:name => 'My Foo'}, referrer_param => referrer_or_current_url) %>
116
+ ```
117
+
118
+ NOTE: If your URLs include lots of params, it is very advisable to use Referrer Tokens instead of plain URLs to avoid "URI too long" errors. See next section.
119
+
120
+ ### `current_url(anchor: ...)`
121
+
122
+ You can now pass an `anchor:` keyword to `current_url` to override the URL fragment.
123
+ This is useful when linking back to a specific position in a long list (e.g., after editing an item).
101
124
 
102
- NOTE: If your URLs include lots of params, it is very advisable to use Referrer Tokens instead of plain URLs to avoud "URI too long" errors. See next section.
125
+ **Example:**
126
+
127
+ ```ruby
128
+ current_url(anchor: "item-42")
129
+ # => "/projects/7/tasks?filter=done#item-42"
130
+ ```
131
+
132
+ If no anchor is given, the current fragment is preserved (if any).
103
133
 
104
134
  ## Unvalidated Redirect Mitigation
105
135
 
@@ -115,30 +145,47 @@ Redirectr offers three kinds of mitigation, two of them being optional:
115
145
 
116
146
  By default, Redirectr checks the protocol, hostname and port of the referrer against the corresponding values of the current request. You may add your own:
117
147
 
118
- YourApp::Application.configure do
119
- config.x.redirectr.whitelist = %w( http://localhost:3000 https://my.host.com )
120
- end
148
+ ```ruby
149
+ YourApp::Application.configure do
150
+ config.x.redirectr.whitelist = %w( http://localhost:3000 https://my.host.com )
151
+ end
152
+ ```
121
153
 
122
154
  ### Token instead of URL (URL-shortener)
123
155
 
124
156
  Instead of using a URL in the referrer token, redirectr can act as an URL shortener that maps random tokens to URLs. This requires a storage_implementation to be defined:
125
157
 
158
+ ```ruby
159
+ require 'redirectr/referrer_token/active_record_storage'
126
160
 
127
- require 'redirectr/referrer_token/active_record_storage'
128
-
129
- YourApp::Application.configure do
130
- config.x.redirectr.use_referrer_token = true
131
- config.x.redirectr.reuse_tokens = true # set to false to generate a new token for each and every link
132
- config.x.redirectr.storage_implementation = Redirectr::ReferrerToken::ActiveRecordStorage
133
- end
161
+ YourApp::Application.configure do
162
+ config.x.redirectr.use_referrer_token = true
163
+ config.x.redirectr.reuse_tokens = true # set to false to generate a new token for each and every link
164
+ config.x.redirectr.storage_implementation = Redirectr::ReferrerToken::ActiveRecordStorage
165
+ end
166
+ ```
134
167
 
135
168
  This example requires a table named 'redirectr_referrer_tokens' to be present with two columns: `url` and `token`. To install and apply the required schema migration, run:
136
169
 
137
- bundle exec rails redirectr:install:migrations
138
- bundle exec rails db:migrate
170
+ ```bash
171
+ bundle exec rails redirectr:install:migrations
172
+ bundle exec rails db:migrate
173
+ ```
139
174
 
140
175
  Redirectr::ReferrerToken has two representations: #to_s displays the URL and #to_param its tokenized form. Depending on your config, this can be either a random token, an encrypted URL or the plaintext URL.
141
176
 
177
+ ### Graceful Handling of Invalid Referrer Origins
178
+
179
+ Redirectr normally raises `Redirectr::InvalidReferrerToken` when the referrer’s origin (host/protocol/port) is not allowed. If you prefer to **treat such cases as if no referrer was provided**, enable:
180
+
181
+ ```ruby
182
+ YourApp::Application.configure do
183
+ config.x.redirectr.discard_referrer_on_invalid_origin = true
184
+ end
185
+ ```
186
+
187
+ With this option, `referrer_url` returns `nil` for invalid origins rather than raising an exception, so any code using it naturally falls back to its own default handling.
188
+
142
189
  ## Contributions
143
190
 
144
191
  Contributions like bugfixes and new ideas are more than welcome. Please just fork this project on github (https://github.com/wvk/redirectr) and send me a pull request with your changes.
@@ -12,7 +12,7 @@ module Redirectr
12
12
  # Handy for use in forms that are called with a referrer param which
13
13
  # has to be passed on and respected by the form processing action.
14
14
  def hidden_referrer_input_tag(options = {})
15
- hidden_field_tag :referrer, referrer_or_current_url.to_param, options
15
+ hidden_field_tag :referrer, referrer_url.to_param, options
16
16
  end
17
17
 
18
18
  end
@@ -1,3 +1,3 @@
1
1
  module Redirectr
2
- VERSION = '1.0.4'
2
+ VERSION = '1.0.6'
3
3
  end
data/lib/redirectr.rb CHANGED
@@ -28,6 +28,9 @@ module Redirectr
28
28
  class InvalidReferrerToken < ArgumentError
29
29
  end
30
30
 
31
+ class InvalidUrl < ArgumentError
32
+ end
33
+
31
34
  def self.config
32
35
  Rails.configuration.x.redirectr
33
36
  end
@@ -89,14 +92,23 @@ module Redirectr
89
92
  #
90
93
  # <%= link_to my_messages_url referrer_param => current_url %>
91
94
  #
92
- def current_url
93
- if request.respond_to? :url # for rack >= 2.0.0
94
- ReferrerToken(request.url)
95
- elsif request.respond_to? :original_url # for rails >= 4.0.0
96
- ReferrerToken(request.original_url)
97
- else
98
- ReferrerToken(request.env['REQUEST_URI'])
95
+ def current_url(anchor: nil)
96
+ url = if request.respond_to? :url # for rack >= 2.0.0
97
+ request.url
98
+ elsif request.respond_to? :original_url # for rails >= 4.0.0
99
+ request.original_url
100
+ else
101
+ request.env['REQUEST_URI']
102
+ end
103
+ if anchor
104
+ if anchor.is_a?(ActiveRecord::Base)
105
+ anchor = ActionView::RecordIdentifier.dom_id(anchor)
106
+ end
107
+ url = URI.parse(url.to_s)
108
+ url.fragment = anchor
109
+ url = url.to_s
99
110
  end
111
+ ReferrerToken(url)
100
112
  end
101
113
 
102
114
  # Return the referrer or the current path, it the former is not set.
@@ -143,13 +155,15 @@ module Redirectr
143
155
  if self.referrer_url.present?
144
156
  self.referrer_url
145
157
  else
146
- case default
158
+ url = default || self.default_url
159
+
160
+ case url
147
161
  when nil
148
- ReferrerToken(self.default_url)
162
+ raise Redirectr::InvalidUrl, 'No URL given'
149
163
  when String
150
- ReferrerToken(default)
164
+ ReferrerToken(url)
151
165
  else
152
- ReferrerToken(url_for(default))
166
+ ReferrerToken(url_for(url))
153
167
  end
154
168
  end
155
169
  end
@@ -171,6 +185,8 @@ module Redirectr
171
185
  referrer_token
172
186
  elsif parsed_url.relative?
173
187
  referrer_token
188
+ elsif Redirectr.config.discard_referrer_on_invalid_origin
189
+ nil
174
190
  else
175
191
  raise Redirectr::UrlNotInWhitelist, "#{parsed_url.inspect} - #{redirect_whitelist.inspect}"
176
192
  end
@@ -205,4 +221,3 @@ module Redirectr
205
221
  end # module Redirectr
206
222
 
207
223
  ActionController::Base.send :include, Redirectr::ControllerMethods
208
-
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redirectr
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.4
4
+ version: 1.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Willem van Kerkhof
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2024-06-05 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: rails
@@ -63,7 +62,6 @@ homepage: http://github.com/wvk/redirectr
63
62
  licenses:
64
63
  - MIT
65
64
  metadata: {}
66
- post_install_message:
67
65
  rdoc_options: []
68
66
  require_paths:
69
67
  - lib
@@ -78,8 +76,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
78
76
  - !ruby/object:Gem::Version
79
77
  version: '0'
80
78
  requirements: []
81
- rubygems_version: 3.4.20
82
- signing_key:
79
+ rubygems_version: 3.6.7
83
80
  specification_version: 4
84
81
  summary: Rails referrer-URL handling done right
85
82
  test_files: []