activity_notification 2.7.1 → 2.7.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 +4 -4
- data/app/controllers/activity_notification/notifications_controller.rb +19 -2
- data/app/controllers/activity_notification/subscriptions_controller.rb +1 -1
- data/lib/activity_notification/apis/notification_api.rb +17 -0
- data/lib/activity_notification/common.rb +6 -0
- data/lib/activity_notification/config.rb +10 -0
- data/lib/activity_notification/controllers/common_controller.rb +9 -0
- data/lib/activity_notification/controllers/concerns/swagger/notifications_api.rb +8 -1
- data/lib/activity_notification/helpers/view_helpers.rb +10 -2
- data/lib/activity_notification/version.rb +1 -1
- data/lib/generators/templates/activity_notification.rb +5 -0
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9c4c8885cdeaf0c979ae2474e5ca5459a16e0f14c605fa5d2f0ad37076e7c793
|
|
4
|
+
data.tar.gz: 267223c3dbc745920baabb75d5e936cafef5a3fbe2e301f46aab04ae9d6a34a8
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: bcb53649395b3e43ab8e3b4a043a40947305ee35cd15fe16a9737f16c866ff543749e78b00c5c5659d8a34eaf198a6c30b6933d29a048db00d56ea17b7c4694e
|
|
7
|
+
data.tar.gz: cc390e51688280d2c84bb949814ae6a3ecad9f1c444066b45d91316d47fea5bb71a7dec03fd4a582d503cc5f7aad70e47c9c0f7ddf16b1da1f92ae1485c10595
|
|
@@ -4,6 +4,7 @@ module ActivityNotification
|
|
|
4
4
|
# Include CommonController to select target and define common methods
|
|
5
5
|
include CommonController
|
|
6
6
|
before_action :set_notification, except: [:index, :open_all, :destroy_all]
|
|
7
|
+
before_action :validate_time_params, only: [:index, :open_all, :destroy_all]
|
|
7
8
|
|
|
8
9
|
# Shows notification index of the target.
|
|
9
10
|
#
|
|
@@ -125,6 +126,7 @@ module ActivityNotification
|
|
|
125
126
|
# @overload open(params)
|
|
126
127
|
# @param [Hash] params Request parameters
|
|
127
128
|
# @option params [String] :open ('false') Whether the notification will be opened
|
|
129
|
+
# @option params [String] :open_token (nil) Token to open the notification, which is required with open parameter since GET requests are not protected from CSRF (See Notification#open_token)
|
|
128
130
|
# @option params [String] :filter (nil) Filter option to load notification index by their status (Nothing as auto, 'opened' or 'unopened')
|
|
129
131
|
# @option params [String] :limit (nil) Maximum number of notifications to return
|
|
130
132
|
# @option params [String] :without_grouping ('false') Whether notification index will include group members
|
|
@@ -133,7 +135,7 @@ module ActivityNotification
|
|
|
133
135
|
# @return [Response] JavaScript view for ajax request or redirects to back as default
|
|
134
136
|
def move
|
|
135
137
|
with_members = !(params[:with_group_members].to_s.to_boolean(false) || params[:without_grouping].to_s.to_boolean(false))
|
|
136
|
-
@opened_notifications_count = @notification.open!(with_members: with_members) if params[:open].to_s.to_boolean(false)
|
|
138
|
+
@opened_notifications_count = @notification.open!(with_members: with_members) if params[:open].to_s.to_boolean(false) && @notification.valid_open_token?(params[:open_token])
|
|
137
139
|
redirect_to_notifiable_path
|
|
138
140
|
end
|
|
139
141
|
|
|
@@ -171,7 +173,7 @@ module ActivityNotification
|
|
|
171
173
|
# @api protected
|
|
172
174
|
# @return [Hash] options to load notification index
|
|
173
175
|
def set_index_options
|
|
174
|
-
limit =
|
|
176
|
+
limit = index_limit
|
|
175
177
|
reverse = params[:reverse].present? ?
|
|
176
178
|
params[:reverse].to_s.to_boolean(false) : nil
|
|
177
179
|
with_group_members = params[:with_group_members].present? || params[:without_grouping].present? ? params[:with_group_members].to_s.to_boolean(false) || params[:without_grouping].to_s.to_boolean(false) : nil
|
|
@@ -180,6 +182,21 @@ module ActivityNotification
|
|
|
180
182
|
.merge(limit: limit, reverse: reverse, with_group_members: with_group_members)
|
|
181
183
|
end
|
|
182
184
|
|
|
185
|
+
# Validates ISO 8601 time parameters and returns HTTP 400 when they are invalid.
|
|
186
|
+
# @api protected
|
|
187
|
+
# @return [void]
|
|
188
|
+
def validate_time_params
|
|
189
|
+
[:later_than, :earlier_than].each do |param_name|
|
|
190
|
+
next unless params.key?(param_name)
|
|
191
|
+
begin
|
|
192
|
+
Time.iso8601(params[param_name].to_s)
|
|
193
|
+
rescue ArgumentError
|
|
194
|
+
render_invalid_parameter("Parameter is not ISO 8601 time: #{param_name}")
|
|
195
|
+
return
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
|
|
183
200
|
# Loads notification index with request parameters.
|
|
184
201
|
# @api protected
|
|
185
202
|
# @return [Array] Array of notification index
|
|
@@ -198,7 +198,7 @@ module ActivityNotification
|
|
|
198
198
|
# @api protected
|
|
199
199
|
# @return [Hash] options to load subscription index
|
|
200
200
|
def set_index_options
|
|
201
|
-
limit =
|
|
201
|
+
limit = index_limit
|
|
202
202
|
reverse = params[:reverse].present? ? params[:reverse].to_s.to_boolean(false) : nil
|
|
203
203
|
@index_options = params.permit(:filter, :filtered_by_key, :routing_scope, :devise_default_routes)
|
|
204
204
|
.to_h.symbolize_keys.merge(limit: limit, reverse: reverse)
|
|
@@ -707,6 +707,23 @@ module ActivityNotification
|
|
|
707
707
|
unopened_member_count + 1
|
|
708
708
|
end
|
|
709
709
|
|
|
710
|
+
# Returns a token to open the notification by HTTP GET request to move action.
|
|
711
|
+
# GET requests are not protected from CSRF, so move action opens the notification only with this token.
|
|
712
|
+
# move_notification_path_for and move_notification_url_for helpers add this token when open: true is specified.
|
|
713
|
+
#
|
|
714
|
+
# @return [String] Token to open the notification by move action
|
|
715
|
+
def open_token
|
|
716
|
+
ActivityNotification.open_token_verifier.generate(id.to_s, purpose: :open_notification)
|
|
717
|
+
end
|
|
718
|
+
|
|
719
|
+
# Returns if the token is valid to open the notification by move action.
|
|
720
|
+
#
|
|
721
|
+
# @param [String] token Token to verify
|
|
722
|
+
# @return [Boolean] If the token is valid to open the notification
|
|
723
|
+
def valid_open_token?(token)
|
|
724
|
+
token.is_a?(String) && ActivityNotification.open_token_verifier.verified(token, purpose: :open_notification) == id.to_s
|
|
725
|
+
end
|
|
726
|
+
|
|
710
727
|
# Returns if the notification is unopened.
|
|
711
728
|
#
|
|
712
729
|
# @return [Boolean] If the notification is unopened
|
|
@@ -92,6 +92,12 @@ module ActivityNotification
|
|
|
92
92
|
end
|
|
93
93
|
private_class_method :contains_javascript_query_operator?
|
|
94
94
|
|
|
95
|
+
# Returns message verifier to generate and verify tokens to open notifications by move action.
|
|
96
|
+
# @return [ActiveSupport::MessageVerifier] Message verifier for open tokens
|
|
97
|
+
def self.open_token_verifier
|
|
98
|
+
Rails.application.message_verifier("activity_notification_open_token")
|
|
99
|
+
end
|
|
100
|
+
|
|
95
101
|
# Casts to indifferent hash
|
|
96
102
|
# @param [ActionController::Parameters, Hash] hash
|
|
97
103
|
# @return [HashWithIndifferentAccess] Converted indifferent hash
|
|
@@ -249,6 +249,15 @@ module ActivityNotification
|
|
|
249
249
|
# @return [Boolean] Whether the REST API restricts embedded associated records to their id and printable_* method values.
|
|
250
250
|
attr_accessor :restrict_api_response_fields
|
|
251
251
|
|
|
252
|
+
# @overload max_index_limit
|
|
253
|
+
# Returns maximum number of records that notification and subscription index actions of the controllers return
|
|
254
|
+
# @return [Integer, nil] Maximum number of records that index actions return.
|
|
255
|
+
# @overload max_index_limit=(value)
|
|
256
|
+
# Sets maximum number of records that notification and subscription index actions of the controllers return. The limit request parameter is capped by this value, and this value is used when the limit parameter is not specified. Set nil to remove the cap.
|
|
257
|
+
# @param [Integer, nil] max_index_limit The new max_index_limit
|
|
258
|
+
# @return [Integer, nil] Maximum number of records that index actions return.
|
|
259
|
+
attr_accessor :max_index_limit
|
|
260
|
+
|
|
252
261
|
# Initialize configuration for ActivityNotification.
|
|
253
262
|
# These configuration can be overridden in initializer.
|
|
254
263
|
# @return [Config] A new instance of Config
|
|
@@ -282,6 +291,7 @@ module ActivityNotification
|
|
|
282
291
|
@notification_api_channel_prefix = 'activity_notification_api_channel'
|
|
283
292
|
@rescue_optional_target_errors = true
|
|
284
293
|
@restrict_api_response_fields = false
|
|
294
|
+
@max_index_limit = 1000
|
|
285
295
|
end
|
|
286
296
|
|
|
287
297
|
# Sets ORM name for ActivityNotification (:active_record, :mongoid or :dynamodb)
|
|
@@ -103,6 +103,15 @@ module ActivityNotification
|
|
|
103
103
|
render status: 400, json: error_response(code: 400, message: "Invalid parameter", type: message)
|
|
104
104
|
end
|
|
105
105
|
|
|
106
|
+
# Returns limit for index actions from request parameter, capped by ActivityNotification.config.max_index_limit.
|
|
107
|
+
# @api protected
|
|
108
|
+
# @return [Integer, nil] Limit for index actions
|
|
109
|
+
def index_limit
|
|
110
|
+
limit = params[:limit].to_i > 0 ? params[:limit].to_i : nil
|
|
111
|
+
max_limit = ActivityNotification.config.max_index_limit
|
|
112
|
+
max_limit ? [limit || max_limit, max_limit].min : limit
|
|
113
|
+
end
|
|
114
|
+
|
|
106
115
|
# Validate param and return HTTP 400 unless it presents.
|
|
107
116
|
# @api protected
|
|
108
117
|
# @param [String, Symbol] param_name Parameter name to validate
|
|
@@ -294,11 +294,18 @@ module ActivityNotification
|
|
|
294
294
|
parameter do
|
|
295
295
|
key :name, :open
|
|
296
296
|
key :in, :query
|
|
297
|
-
key :description, "Whether the notification will be opened"
|
|
297
|
+
key :description, "Whether the notification will be opened. The notification is opened only with a valid open_token, since GET requests are not protected from CSRF. Use PUT /{target_type}/{target_id}/notifications/{id}/open with move parameter to open and move without a token."
|
|
298
298
|
key :required, false
|
|
299
299
|
key :type, :boolean
|
|
300
300
|
key :default, false
|
|
301
301
|
end
|
|
302
|
+
parameter do
|
|
303
|
+
key :name, :open_token
|
|
304
|
+
key :in, :query
|
|
305
|
+
key :description, "Token to open the notification with open parameter, which is generated by Notification#open_token and added by move_notification_path_for and move_notification_url_for helpers"
|
|
306
|
+
key :required, false
|
|
307
|
+
key :type, :string
|
|
308
|
+
end
|
|
302
309
|
|
|
303
310
|
response 302 do
|
|
304
311
|
key :description, "Redirection to notifiable path"
|
|
@@ -111,7 +111,7 @@ module ActivityNotification
|
|
|
111
111
|
# @todo Needs any other better implementation
|
|
112
112
|
# @todo Must handle devise namespace
|
|
113
113
|
def move_notification_path_for(notification, params = {})
|
|
114
|
-
options = params
|
|
114
|
+
options = move_notification_options(notification, params)
|
|
115
115
|
options.delete(:devise_default_routes) ?
|
|
116
116
|
send("move_#{routing_scope(options)}notification_path", notification, options) :
|
|
117
117
|
send("move_#{routing_scope(options)}#{notification.target.to_resource_name}_notification_path", notification.target, notification, options)
|
|
@@ -195,7 +195,7 @@ module ActivityNotification
|
|
|
195
195
|
# @todo Needs any other better implementation
|
|
196
196
|
# @todo Must handle devise namespace
|
|
197
197
|
def move_notification_url_for(notification, params = {})
|
|
198
|
-
options = params
|
|
198
|
+
options = move_notification_options(notification, params)
|
|
199
199
|
options.delete(:devise_default_routes) ?
|
|
200
200
|
send("move_#{routing_scope(options)}notification_url", notification, options) :
|
|
201
201
|
send("move_#{routing_scope(options)}#{notification.target.to_resource_name}_notification_url", notification.target, notification, options)
|
|
@@ -553,6 +553,14 @@ module ActivityNotification
|
|
|
553
553
|
[root, path].map(&:to_s).join('/')
|
|
554
554
|
end
|
|
555
555
|
|
|
556
|
+
# Prepare options for move_notification path with token to open the notification
|
|
557
|
+
# @api private
|
|
558
|
+
def move_notification_options(notification, params)
|
|
559
|
+
options = params.dup
|
|
560
|
+
options[:open_token] = notification.open_token if options[:open].to_s.to_boolean(false)
|
|
561
|
+
options
|
|
562
|
+
end
|
|
563
|
+
|
|
556
564
|
# Prepare routing scope from options
|
|
557
565
|
# @api private
|
|
558
566
|
def routing_scope(options = {})
|
|
@@ -129,4 +129,9 @@ ActivityNotification.configure do |config|
|
|
|
129
129
|
# your application (see the :with_devise routing option). Default value is false.
|
|
130
130
|
# config.restrict_api_response_fields = false
|
|
131
131
|
|
|
132
|
+
# Configure maximum number of records that notification and subscription index actions of the controllers return.
|
|
133
|
+
# The limit request parameter is capped by this value, and this value is used when the limit parameter is not specified.
|
|
134
|
+
# Set nil to remove the cap. Default value is 1000.
|
|
135
|
+
# config.max_index_limit = 1000
|
|
136
|
+
|
|
132
137
|
end
|