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 +4 -4
- data/README.md +103 -56
- data/app/helpers/redirectr/application_helper.rb +1 -1
- data/lib/redirectr/version.rb +1 -1
- data/lib/redirectr.rb +27 -12
- metadata +3 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 79b2022bb7a4aff997edf0f04e89276a17377b3a28c2fd33b071ce1314b13a9e
|
|
4
|
+
data.tar.gz: 4d271d1e980abeb41ef64cce2c227a1a31cb9bbd4f0e6e87859dc25c2606f55b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e8bdcf8567203138565fbd36c2a991053b2f1b643a91e459d9df88185fb0719ecc20755001b0005841fbc258c33800eb9b8547776fab3c92d6ba11834786c67f
|
|
7
|
+
data.tar.gz: 7b7533058f982773d7431d337a64a1efb9aa69072fe065aa02b35629765d620d7cec936aa2dd1bf7742d4ebfdff8560b28ae6effd1c3d184b498ca646068948d
|
data/README.md
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
[](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
|
-
|
|
29
|
-
|
|
30
|
-
|
|
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
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
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
|
-
|
|
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
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
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
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
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
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
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
|
-
|
|
100
|
-
|
|
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
|
-
|
|
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
|
-
|
|
119
|
-
|
|
120
|
-
|
|
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
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
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
|
-
|
|
138
|
-
|
|
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,
|
|
15
|
+
hidden_field_tag :referrer, referrer_url.to_param, options
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
end
|
data/lib/redirectr/version.rb
CHANGED
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
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
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
|
-
|
|
158
|
+
url = default || self.default_url
|
|
159
|
+
|
|
160
|
+
case url
|
|
147
161
|
when nil
|
|
148
|
-
|
|
162
|
+
raise Redirectr::InvalidUrl, 'No URL given'
|
|
149
163
|
when String
|
|
150
|
-
ReferrerToken(
|
|
164
|
+
ReferrerToken(url)
|
|
151
165
|
else
|
|
152
|
-
ReferrerToken(url_for(
|
|
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
|
+
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:
|
|
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.
|
|
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: []
|