simple_calendar 3.1.2 → 3.1.3

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: a1789f19b1f7e2ff7dfe9734bd1ef5a4ff45a76204c52f63155854fca76cc033
4
- data.tar.gz: 7128d7d5d2f8a65d9377aafdd828edd8e30d8e7a2f56ca0f7ca7c95a81bb5928
3
+ metadata.gz: ff7274d9f8305cdc76ae38121b4722d5279eb9e548e0fcf15496952bf1bf96cd
4
+ data.tar.gz: 5fd6aa597857b392849405a1bb21ef1ef810857b58dfc1e53c096087c2f09374
5
5
  SHA512:
6
- metadata.gz: acf827741610c4a259770cdf52da653156816c7bb75c31a1228b543ebcf5761b66c72b3594da14dd680c542947fd2b018629d0ccd089d7c685ef21704c30413a
7
- data.tar.gz: 22f93c93d076483140e00c79ed33a8e194d3d1ad3624513fa7e9959be6107e5d1a7c5b9909464b98a1fbecfd3ec0a918293d51d12969aa9ff06f810992b6c051
6
+ metadata.gz: 2dfd685ac91b3df7126c3705d7e9bf40141dc8e094b416cb01ee68ddb3d50528493844601fabebe2b2996edacc1a12b04af1816dbbf87e624eb2c469dd1f76aa
7
+ data.tar.gz: a44fd4ac691982e753d79b51ae60ebc1a72a202cb62c89d950939bbe42dd499f48772d3e9ee22ace84ebed9c8cf90bb0165a1dbe62414f83c461f200e85f406f
@@ -2,14 +2,15 @@ require "rails"
2
2
 
3
3
  module SimpleCalendar
4
4
  class Calendar
5
- # Besides form noise, this drops keys url_for treats as URL options instead of query
6
- # params. Passing them through from the request would let a crafted link change the
7
- # host, protocol, route, etc. of the Previous / Today / Next links (open redirect,
8
- # javascript: XSS, 500s).
9
- PARAM_KEY_BLACKLIST = :authenticity_token, :commit, :utf8, :_method, :script_name,
10
- :host, :protocol, :port, :subdomain, :domain, :tld_length, :trailing_slash, :anchor,
11
- :params, :only_path, :original_script_name, :relative_url_root, :user, :password,
12
- :use_route, :_recall
5
+ PARAM_KEY_BLACKLIST = :authenticity_token, :commit, :utf8, :_method, :script_name
6
+
7
+ # Keys url_for treats as URL options instead of query params. The built-in links don't
8
+ # need these dropped (see url_for_date), but custom calendars that copied the old
9
+ # `url_for(@params.merge(...))` override pass @params straight to url_for, so they're
10
+ # left out of @params to keep those links from being pointed at another host, etc.
11
+ URL_OPTION_KEYS = :host, :protocol, :port, :subdomain, :domain, :tld_length,
12
+ :trailing_slash, :anchor, :params, :only_path, :original_script_name,
13
+ :relative_url_root, :user, :password, :use_route, :_recall
13
14
 
14
15
  attr_accessor :view_context, :options
15
16
 
@@ -20,12 +21,15 @@ module SimpleCalendar
20
21
  @block = block
21
22
 
22
23
  # Next and previous view links should use the same params as the current view
23
- @params = @view_context.respond_to?(:params) ? @view_context.params : {}
24
- @params = @params.to_unsafe_h if @params.respond_to?(:to_unsafe_h)
25
- @params = @params.with_indifferent_access.except(*PARAM_KEY_BLACKLIST)
24
+ @request_params = @view_context.respond_to?(:params) ? @view_context.params : {}
25
+ @request_params = @request_params.to_unsafe_h if @request_params.respond_to?(:to_unsafe_h)
26
+ @request_params = @request_params.with_indifferent_access.except(*PARAM_KEY_BLACKLIST)
27
+
28
+ # Params passed in by the developer are trusted, so they're allowed to be url_for options
29
+ @calendar_params = @options.fetch(:params, {}).to_h.symbolize_keys
26
30
 
27
- # Add in any additional params the user passed in
28
- @params.merge!(@options.fetch(:params, {}))
31
+ # Nothing in here uses @params anymore, but custom calendars still build their own links from it
32
+ @params = @request_params.except(*URL_OPTION_KEYS).merge(@calendar_params)
29
33
  end
30
34
 
31
35
  def render_in(view_context, &block)
@@ -72,15 +76,25 @@ module SimpleCalendar
72
76
  end
73
77
 
74
78
  def url_for_next_view
75
- view_context.url_for(@params.merge(start_date_param => (date_range.last + 1.day).iso8601))
79
+ url_for_date(date_range.last + 1.day)
76
80
  end
77
81
 
78
82
  def url_for_previous_view
79
- view_context.url_for(@params.merge(start_date_param => (date_range.first - date_range.count.days).iso8601))
83
+ url_for_date(date_range.first - date_range.count.days)
80
84
  end
81
85
 
82
86
  def url_for_today_view
83
- view_context.url_for(@params.merge(start_date_param => Time.current.to_date.iso8601))
87
+ url_for_date(Time.current.to_date)
88
+ end
89
+
90
+ # Only routing params and params passed in by the developer are given to url_for as
91
+ # options. Everything else from the request goes under `params:`, which url_for always
92
+ # treats as query params, so no request param can be read as a URL option. Route
93
+ # segments named like a URL option (say `servers/:host`) are left to url_for, which
94
+ # fills them in from the current request as path segments.
95
+ def url_for_date(date)
96
+ url_options = path_parameters.except(*URL_OPTION_KEYS).merge(@calendar_params).merge(start_date_param => date.iso8601)
97
+ view_context.url_for(url_options.merge(params: @request_params.except(*path_parameters.keys, *url_options.keys)))
84
98
  end
85
99
 
86
100
  def date_range
@@ -146,6 +160,10 @@ module SimpleCalendar
146
160
 
147
161
  private
148
162
 
163
+ def path_parameters
164
+ view_context.try(:request)&.path_parameters || {}
165
+ end
166
+
149
167
  def start_date_from_params
150
168
  view_context.params[start_date_param].try(:to_date)
151
169
  rescue ArgumentError # Date::Error inherits from ArgumentError
@@ -5,7 +5,7 @@ module SimpleCalendar
5
5
  end
6
6
 
7
7
  def url_for_previous_view
8
- view_context.url_for(@params.merge(start_date_param => (date_range.first - 1.day).iso8601))
8
+ url_for_date(date_range.first - 1.day)
9
9
  end
10
10
  end
11
11
  end
@@ -1,3 +1,3 @@
1
1
  module SimpleCalendar
2
- VERSION = "3.1.2"
2
+ VERSION = "3.1.3"
3
3
  end
@@ -21,7 +21,7 @@ module SimpleCalendar
21
21
  end
22
22
 
23
23
  def url_for_previous_view
24
- view_context.url_for(@params.merge(start_date_param => (date_range.first - 1.day).iso8601))
24
+ url_for_date(date_range.first - 1.day)
25
25
  end
26
26
 
27
27
  private
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: simple_calendar
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.2
4
+ version: 3.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Oliver
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-10-12 00:00:00.000000000 Z
11
+ date: 2026-10-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails