activity_notification 2.6.1 → 2.7.1
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 +3 -5
- data/app/channels/activity_notification/notification_api_channel.rb +2 -0
- data/app/channels/activity_notification/notification_channel.rb +2 -0
- data/app/controllers/activity_notification/notifications_api_controller.rb +19 -8
- data/app/controllers/activity_notification/notifications_controller.rb +17 -2
- data/app/controllers/activity_notification/subscriptions_api_controller.rb +5 -2
- data/app/views/activity_notification/notifications/default/index.html.erb +1 -1
- data/docs/Functions.md +20 -2
- data/lib/activity_notification/apis/notification_api.rb +1 -1
- data/lib/activity_notification/apis/subscription_api.rb +1 -1
- data/lib/activity_notification/common.rb +45 -0
- data/lib/activity_notification/config.rb +10 -0
- data/lib/activity_notification/helpers/view_helpers.rb +1 -1
- data/lib/activity_notification/orm/dynamoid.rb +1 -1
- data/lib/activity_notification/version.rb +1 -1
- data/lib/generators/templates/activity_notification.rb +8 -0
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 56122565c61de552c48285f449429a7d64616f5c13f04f0e023a68b33273db6f
|
|
4
|
+
data.tar.gz: 6462762a8f2d8b7b68b82be0632c1dd3d89379aa7fe904c6f4492053be2633fb
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: fd7b507f00663ebcf26694a0c8c98a0051f51f7bf35e67687a77e668fb61f500f1cf84e2fa433ecbc39bf59357449fcd0cfd0303b107b7e16ea9838d39e3848f
|
|
7
|
+
data.tar.gz: 12cd4b4e589aa66e4ccb6108beb5624d5b13f3d327234491520551c5d9134afabe718367ee3d5193a92e9a1fd2491c9bf5d59250e8e2bb8588c3bcdfaf8565b7
|
data/README.md
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
# ActivityNotification
|
|
2
2
|
|
|
3
|
-
[](https://github.com/simukappu/activity_notification/actions/workflows/build.yml)
|
|
4
|
-
[](https://coveralls.io/github/simukappu/activity_notification?branch=master)
|
|
5
|
-
[](https://depfu.com/repos/simukappu/activity_notification)
|
|
6
|
-
[](http://inch-ci.org/github/simukappu/activity_notification)
|
|
7
3
|
[](https://rubygems.org/gems/activity_notification)
|
|
8
4
|
[](https://rubygems.org/gems/activity_notification)
|
|
9
|
-
[](https://github.com/simukappu/activity_notification/actions/workflows/build.yml)
|
|
6
|
+
[](https://coveralls.io/github/simukappu/activity_notification?branch=master)
|
|
7
|
+
[](MIT-LICENSE)
|
|
10
8
|
|
|
11
9
|
*activity_notification* provides integrated user activity notifications for [Ruby on Rails](https://rubyonrails.org). You can easily use it to configure multiple notification targets and make activity notifications with notifiable models, like adding comments, responding etc.
|
|
12
10
|
|
|
@@ -4,6 +4,8 @@ class ActivityNotification::NotificationApiChannel < ActivityNotification::Notif
|
|
|
4
4
|
# ActionCable::Channel::Base#subscribed
|
|
5
5
|
# @see https://api.rubyonrails.org/classes/ActionCable/Channel/Base.html#method-i-subscribed
|
|
6
6
|
def subscribed
|
|
7
|
+
# before_subscribe callbacks do not halt the chain on reject
|
|
8
|
+
return if subscription_rejected?
|
|
7
9
|
stream_from "#{ActivityNotification.config.notification_api_channel_prefix}_#{@target.to_class_name}#{ActivityNotification.config.composite_key_delimiter}#{@target.id}"
|
|
8
10
|
rescue
|
|
9
11
|
reject
|
|
@@ -7,6 +7,8 @@ if defined?(ActionCable)
|
|
|
7
7
|
# ActionCable::Channel::Base#subscribed
|
|
8
8
|
# @see https://api.rubyonrails.org/classes/ActionCable/Channel/Base.html#method-i-subscribed
|
|
9
9
|
def subscribed
|
|
10
|
+
# before_subscribe callbacks do not halt the chain on reject
|
|
11
|
+
return if subscription_rejected?
|
|
10
12
|
stream_from "#{ActivityNotification.config.notification_channel_prefix}_#{@target.to_class_name}#{ActivityNotification.config.composite_key_delimiter}#{@target.id}"
|
|
11
13
|
rescue
|
|
12
14
|
reject
|
|
@@ -5,7 +5,6 @@ module ActivityNotification
|
|
|
5
5
|
include Swagger::NotificationsApi
|
|
6
6
|
# Include CommonApiController to select target and define common methods
|
|
7
7
|
include CommonApiController
|
|
8
|
-
protect_from_forgery except: [:open_all]
|
|
9
8
|
rescue_from ActivityNotification::NotifiableNotFoundError, with: :render_notifiable_not_found
|
|
10
9
|
|
|
11
10
|
# Returns notification index of the target.
|
|
@@ -135,14 +134,26 @@ module ActivityNotification
|
|
|
135
134
|
# Returns options for notification JSON
|
|
136
135
|
# @api protected
|
|
137
136
|
def notification_json_options
|
|
137
|
+
include_options =
|
|
138
|
+
if ActivityNotification.config.restrict_api_response_fields
|
|
139
|
+
{
|
|
140
|
+
target: { only: [:id], methods: [:printable_type, :printable_target_name] },
|
|
141
|
+
notifiable: { only: [:id], methods: [:printable_type] },
|
|
142
|
+
group: { only: [:id], methods: [:printable_type, :printable_group_name] },
|
|
143
|
+
notifier: { only: [:id], methods: [:printable_type, :printable_notifier_name] },
|
|
144
|
+
group_members: { only: [:id] }
|
|
145
|
+
}
|
|
146
|
+
else
|
|
147
|
+
{
|
|
148
|
+
target: { methods: [:printable_type, :printable_target_name] },
|
|
149
|
+
notifiable: { methods: [:printable_type] },
|
|
150
|
+
group: { methods: [:printable_type, :printable_group_name] },
|
|
151
|
+
notifier: { methods: [:printable_type, :printable_notifier_name] },
|
|
152
|
+
group_members: {}
|
|
153
|
+
}
|
|
154
|
+
end
|
|
138
155
|
{
|
|
139
|
-
include:
|
|
140
|
-
target: { methods: [:printable_type, :printable_target_name] },
|
|
141
|
-
notifiable: { methods: [:printable_type] },
|
|
142
|
-
group: { methods: [:printable_type, :printable_group_name] },
|
|
143
|
-
notifier: { methods: [:printable_type, :printable_notifier_name] },
|
|
144
|
-
group_members: {}
|
|
145
|
-
},
|
|
156
|
+
include: include_options,
|
|
146
157
|
methods: [:notifiable_path, :printable_notifiable_name, :group_member_notifier_count, :group_notification_count]
|
|
147
158
|
}
|
|
148
159
|
end
|
|
@@ -47,7 +47,7 @@ module ActivityNotification
|
|
|
47
47
|
# @option params [String] :reload ('true') Whether notification index will be reloaded
|
|
48
48
|
# @return [Response] JavaScript view for ajax request or redirects to back as default
|
|
49
49
|
def open_all
|
|
50
|
-
@opened_notifications = @target.open_all_notifications(
|
|
50
|
+
@opened_notifications = @target.open_all_notifications(bulk_action_options)
|
|
51
51
|
return_back_or_ajax
|
|
52
52
|
end
|
|
53
53
|
|
|
@@ -70,7 +70,7 @@ module ActivityNotification
|
|
|
70
70
|
# @option params [String] :reload ('true') Whether notification index will be reloaded
|
|
71
71
|
# @return [Response] JavaScript view for ajax request or redirects to back as default
|
|
72
72
|
def destroy_all
|
|
73
|
-
@destroyed_notifications = @target.destroy_all_notifications(
|
|
73
|
+
@destroyed_notifications = @target.destroy_all_notifications(bulk_action_options)
|
|
74
74
|
set_index_options
|
|
75
75
|
load_index if params[:reload].to_s.to_boolean(true)
|
|
76
76
|
return_back_or_ajax
|
|
@@ -152,6 +152,21 @@ module ActivityNotification
|
|
|
152
152
|
validate_target(@notification = Notification.with_target.find(params[:id]))
|
|
153
153
|
end
|
|
154
154
|
|
|
155
|
+
# Builds a permitted options hash for bulk actions (open_all / destroy_all)
|
|
156
|
+
# from request parameters.
|
|
157
|
+
# Only known-safe filter keys are permitted here. Request parameters must
|
|
158
|
+
# never be forwarded to the model layer as-is, because :custom_filter is
|
|
159
|
+
# passed straight to ActiveRecord's where as a raw SQL fragment and would
|
|
160
|
+
# allow SQL injection from untrusted input.
|
|
161
|
+
# @api protected
|
|
162
|
+
# @return [Hash] permitted options for bulk actions
|
|
163
|
+
def bulk_action_options
|
|
164
|
+
params.permit(:filter, :limit, :reverse, :without_grouping, :with_group_members,
|
|
165
|
+
:filtered_by_type, :filtered_by_group_type, :filtered_by_group_id, :filtered_by_key,
|
|
166
|
+
:later_than, :earlier_than, :routing_scope, :devise_default_routes, ids: [])
|
|
167
|
+
.to_h.symbolize_keys
|
|
168
|
+
end
|
|
169
|
+
|
|
155
170
|
# Sets options to load notification index from request parameters.
|
|
156
171
|
# @api protected
|
|
157
172
|
# @return [Hash] options to load notification index
|
|
@@ -5,7 +5,6 @@ module ActivityNotification
|
|
|
5
5
|
include Swagger::SubscriptionsApi
|
|
6
6
|
# Include CommonApiController to select target and define common methods
|
|
7
7
|
include CommonApiController
|
|
8
|
-
protect_from_forgery except: [:create]
|
|
9
8
|
before_action :set_subscription, except: [:index, :create, :find, :optional_target_names]
|
|
10
9
|
before_action ->{ validate_param(:key) }, only: [:find, :optional_target_names]
|
|
11
10
|
|
|
@@ -171,7 +170,11 @@ module ActivityNotification
|
|
|
171
170
|
# Returns include option for subscription JSON
|
|
172
171
|
# @api protected
|
|
173
172
|
def subscription_json_include_option
|
|
174
|
-
|
|
173
|
+
if ActivityNotification.config.restrict_api_response_fields
|
|
174
|
+
{ target: { only: [:id], methods: [:printable_type, :printable_target_name] } }.freeze
|
|
175
|
+
else
|
|
176
|
+
[:target].freeze
|
|
177
|
+
end
|
|
175
178
|
end
|
|
176
179
|
|
|
177
180
|
# Returns methods option for subscription JSON
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
</style>
|
|
41
41
|
|
|
42
42
|
<% if @target.notification_action_cable_allowed? %>
|
|
43
|
-
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/push.js/1.0.9/push.min.js"></script>
|
|
43
|
+
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/push.js/1.0.9/push.min.js" integrity="sha512-eiqtDDb4GUVCSqOSOTz/s/eiU4B31GrdSb17aPAA4Lv/Cjc8o+hnDvuNkgXhSI5yHuDvYkuojMaQmrB5JB31XQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
|
44
44
|
<script>
|
|
45
45
|
App.activity_notification = App.cable.subscriptions.create(
|
|
46
46
|
{
|
data/docs/Functions.md
CHANGED
|
@@ -336,6 +336,8 @@ You can also add conditions to filter notifications, like this:
|
|
|
336
336
|
User.send_batch_unopened_notification_email(batch_key: 'batch.comment.post', filtered_by_key: 'comment.post', custom_filter: ["created_at >= ?", time.hour.ago])
|
|
337
337
|
```
|
|
338
338
|
|
|
339
|
+
*custom_filter* accepts an array of a SQL fragment with bind parameters or a hash of conditions. Write it in your application code and never build it from request parameters, since it is passed to the ORM query layer as is. A raw SQL string, an array without bind parameters and MongoDB JavaScript operators (`$where`, `$function` and `$accumulator`) are rejected with `ArgumentError`.
|
|
340
|
+
|
|
339
341
|
#### Batch sender configuration
|
|
340
342
|
|
|
341
343
|
*activity_notification* uses same sender configuration of real-time email notification as batch email sender.
|
|
@@ -709,6 +711,22 @@ When you want to use REST API backend integrated with Devise authentication, see
|
|
|
709
711
|
|
|
710
712
|
You can see [sample single page application](/spec/rails_app/app/javascript/) using [Vue.js](https://vuejs.org) as a part of example Rails application. This sample application works with *activity_notification* REST API backend.
|
|
711
713
|
|
|
714
|
+
#### Securing the REST API
|
|
715
|
+
|
|
716
|
+
The REST API endpoints do not authenticate requests on their own. Authenticating requests and authorizing access to a target's notifications and subscriptions is the responsibility of your application. The recommended way is to use the *:with_devise* option so that only the authenticated resource can access its own records. See [REST API backend with Devise Token Auth](#rest-api-backend-with-devise-token-auth) for the setup. The controllers shipped for *:with_devise* return HTTP 403 for a target that does not belong to the authenticated resource.
|
|
717
|
+
|
|
718
|
+
By default, notification and subscription responses embed the associated records (target, notifiable, notifier, group, group members and subscription target) with all of their database columns. When those associated records are your user model, the response can include columns you may not want to expose to the frontend, such as authentication identifiers. Two options are available to reduce this exposure.
|
|
719
|
+
|
|
720
|
+
The simplest option is to enable *config.restrict_api_response_fields*, which restricts every embedded associated record to its *id* and *printable_\** method values instead of all columns. It is disabled by default to preserve the existing response shape:
|
|
721
|
+
|
|
722
|
+
```ruby
|
|
723
|
+
ActivityNotification.configure do |config|
|
|
724
|
+
config.restrict_api_response_fields = true
|
|
725
|
+
end
|
|
726
|
+
```
|
|
727
|
+
|
|
728
|
+
If you need finer control over the response shape, override the serialization options in your own API controllers instead. *ActivityNotification::NotificationsApiController#notification_json_options* and *ActivityNotification::SubscriptionsApiController#subscription_json_include_option* are protected methods that you can override to return only the fields your frontend consumes.
|
|
729
|
+
|
|
712
730
|
#### API reference as OpenAPI Specification
|
|
713
731
|
|
|
714
732
|
*activity_notification* provides API reference as [OpenAPI Specification](https://github.com/OAI/OpenAPI-Specification).
|
|
@@ -991,7 +1009,7 @@ Then, *activity_notification* will broadcast configured notifications to target
|
|
|
991
1009
|
You can simply create subscriptions for the specified target in your view like this:
|
|
992
1010
|
|
|
993
1011
|
```js
|
|
994
|
-
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/push.js/1.0.9/push.min.js"></script>
|
|
1012
|
+
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/push.js/1.0.9/push.min.js" integrity="sha512-eiqtDDb4GUVCSqOSOTz/s/eiU4B31GrdSb17aPAA4Lv/Cjc8o+hnDvuNkgXhSI5yHuDvYkuojMaQmrB5JB31XQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
|
995
1013
|
<script>
|
|
996
1014
|
App.activity_notification = App.cable.subscriptions.create(
|
|
997
1015
|
{
|
|
@@ -1029,7 +1047,7 @@ You can simply create subscriptions for the specified target in your view like t
|
|
|
1029
1047
|
or create subscriptions in your single page application with API channels like this:
|
|
1030
1048
|
|
|
1031
1049
|
```js
|
|
1032
|
-
// Vue.js implementation with
|
|
1050
|
+
// Vue.js implementation with a small Action Cable plugin (see spec/rails_app/app/javascript/plugins/action-cable.js)
|
|
1033
1051
|
export default {
|
|
1034
1052
|
// ...
|
|
1035
1053
|
mounted () {
|
|
@@ -135,7 +135,7 @@ module ActivityNotification
|
|
|
135
135
|
filtered_notifications = filtered_notifications.earlier_than(Time.iso8601(options[:earlier_than]))
|
|
136
136
|
end
|
|
137
137
|
if options.has_key?(:custom_filter)
|
|
138
|
-
filtered_notifications = filtered_notifications.where(options[:custom_filter])
|
|
138
|
+
filtered_notifications = filtered_notifications.where(ActivityNotification.validate_custom_filter(options[:custom_filter]))
|
|
139
139
|
end
|
|
140
140
|
filtered_notifications
|
|
141
141
|
}
|
|
@@ -31,7 +31,7 @@ module ActivityNotification
|
|
|
31
31
|
filtered_subscriptions = filtered_subscriptions.filtered_by_key(options[:filtered_by_key])
|
|
32
32
|
end
|
|
33
33
|
if options.has_key?(:custom_filter)
|
|
34
|
-
filtered_subscriptions = filtered_subscriptions.where(options[:custom_filter])
|
|
34
|
+
filtered_subscriptions = filtered_subscriptions.where(ActivityNotification.validate_custom_filter(options[:custom_filter]))
|
|
35
35
|
end
|
|
36
36
|
filtered_subscriptions
|
|
37
37
|
}
|
|
@@ -47,6 +47,51 @@ module ActivityNotification
|
|
|
47
47
|
end
|
|
48
48
|
end
|
|
49
49
|
|
|
50
|
+
# MongoDB query operators which execute JavaScript on the database server.
|
|
51
|
+
JAVASCRIPT_QUERY_OPERATORS = %w[$where $function $accumulator].freeze
|
|
52
|
+
|
|
53
|
+
# Validates a :custom_filter value before it is passed to the ORM query layer.
|
|
54
|
+
# custom_filter is a trusted input written by the application developer and
|
|
55
|
+
# must not be built from request parameters. This validation rejects the forms
|
|
56
|
+
# that run raw SQL or server-side JavaScript:
|
|
57
|
+
# - A String, since ActiveRecord's where treats it as a raw SQL fragment
|
|
58
|
+
# - An Array without bind parameters (e.g. ["1=1"]), which is also a raw SQL fragment
|
|
59
|
+
# - A Hash containing MongoDB JavaScript operators ($where, $function and $accumulator)
|
|
60
|
+
# The supported forms are an Array of a SQL fragment with bind parameters
|
|
61
|
+
# (e.g. ["created_at >= ?", time]) or a Hash of conditions.
|
|
62
|
+
# @param [Array, Hash] custom_filter Custom filter value
|
|
63
|
+
# @return [Array, Hash] The same value when it is safe to use
|
|
64
|
+
# @raise [ArgumentError] When custom_filter is not in the supported forms
|
|
65
|
+
def self.validate_custom_filter(custom_filter)
|
|
66
|
+
valid =
|
|
67
|
+
case custom_filter
|
|
68
|
+
when Array then custom_filter.size >= 2 && custom_filter.first.is_a?(String)
|
|
69
|
+
when Hash then !contains_javascript_query_operator?(custom_filter)
|
|
70
|
+
else false
|
|
71
|
+
end
|
|
72
|
+
unless valid
|
|
73
|
+
raise ArgumentError,
|
|
74
|
+
":custom_filter must be an array of a SQL fragment and bind parameters " \
|
|
75
|
+
"(e.g. [\"created_at >= ?\", time]) or a hash of conditions without JavaScript operators"
|
|
76
|
+
end
|
|
77
|
+
custom_filter
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# Returns whether the value contains MongoDB query operators which execute JavaScript.
|
|
81
|
+
# @param [Object] value Value to check
|
|
82
|
+
# @return [Boolean] Whether the value contains JavaScript query operators
|
|
83
|
+
def self.contains_javascript_query_operator?(value)
|
|
84
|
+
case value
|
|
85
|
+
when Hash
|
|
86
|
+
value.any? { |k, v| JAVASCRIPT_QUERY_OPERATORS.include?(k.to_s) || contains_javascript_query_operator?(v) }
|
|
87
|
+
when Array
|
|
88
|
+
value.any? { |v| contains_javascript_query_operator?(v) }
|
|
89
|
+
else
|
|
90
|
+
false
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
private_class_method :contains_javascript_query_operator?
|
|
94
|
+
|
|
50
95
|
# Casts to indifferent hash
|
|
51
96
|
# @param [ActionController::Parameters, Hash] hash
|
|
52
97
|
# @return [HashWithIndifferentAccess] Converted indifferent hash
|
|
@@ -240,6 +240,15 @@ module ActivityNotification
|
|
|
240
240
|
# @return [Boolean] Whether activity_notification internally rescues optional target errors.
|
|
241
241
|
attr_accessor :rescue_optional_target_errors
|
|
242
242
|
|
|
243
|
+
# @overload restrict_api_response_fields
|
|
244
|
+
# Returns whether the REST API restricts embedded associated records to their id and printable_* method values
|
|
245
|
+
# @return [Boolean] Whether the REST API restricts embedded associated records to their id and printable_* method values.
|
|
246
|
+
# @overload restrict_api_response_fields=(value)
|
|
247
|
+
# Sets whether the REST API restricts embedded associated records (target, notifiable, notifier, group, group members and subscription target) in JSON responses to their id and printable_* method values instead of all database columns. This is an opt-in hardening option to avoid exposing columns the frontend does not need (e.g. authentication identifiers on an associated user record). It is disabled by default to preserve the existing response shape.
|
|
248
|
+
# @param [Boolean] restrict_api_response_fields The new restrict_api_response_fields
|
|
249
|
+
# @return [Boolean] Whether the REST API restricts embedded associated records to their id and printable_* method values.
|
|
250
|
+
attr_accessor :restrict_api_response_fields
|
|
251
|
+
|
|
243
252
|
# Initialize configuration for ActivityNotification.
|
|
244
253
|
# These configuration can be overridden in initializer.
|
|
245
254
|
# @return [Config] A new instance of Config
|
|
@@ -272,6 +281,7 @@ module ActivityNotification
|
|
|
272
281
|
@notification_channel_prefix = 'activity_notification_channel'
|
|
273
282
|
@notification_api_channel_prefix = 'activity_notification_api_channel'
|
|
274
283
|
@rescue_optional_target_errors = true
|
|
284
|
+
@restrict_api_response_fields = false
|
|
275
285
|
end
|
|
276
286
|
|
|
277
287
|
# Sets ORM name for ActivityNotification (:active_record, :mongoid or :dynamodb)
|
|
@@ -21,7 +21,7 @@ module ActivityNotification
|
|
|
21
21
|
notifications.render self, options
|
|
22
22
|
elsif notifications.respond_to?(:map)
|
|
23
23
|
return nil if (notifications.respond_to?(:empty?) ? notifications.empty? : notifications.to_a.empty?)
|
|
24
|
-
notifications.map {|notification| notification.render self, options.dup }
|
|
24
|
+
safe_join(notifications.map {|notification| notification.render self, options.dup })
|
|
25
25
|
end
|
|
26
26
|
end
|
|
27
27
|
alias_method :render_notifications, :render_notification
|
|
@@ -332,7 +332,7 @@ module Dynamoid # :nodoc: all
|
|
|
332
332
|
filtered_notifications = filtered_notifications.earlier_than(Time.iso8601(options[:earlier_than]))
|
|
333
333
|
end
|
|
334
334
|
if options.has_key?(:custom_filter)
|
|
335
|
-
filtered_notifications = filtered_notifications.where(options[:custom_filter])
|
|
335
|
+
filtered_notifications = filtered_notifications.where(ActivityNotification.validate_custom_filter(options[:custom_filter]))
|
|
336
336
|
end
|
|
337
337
|
filtered_notifications
|
|
338
338
|
end
|
|
@@ -121,4 +121,12 @@ ActivityNotification.configure do |config|
|
|
|
121
121
|
# See https://github.com/simukappu/activity_notification/issues/155 for more details.
|
|
122
122
|
config.rescue_optional_target_errors = true
|
|
123
123
|
|
|
124
|
+
# Configure if the REST API restricts embedded associated records in JSON responses.
|
|
125
|
+
# When set true, associated records (target, notifiable, notifier, group, group members
|
|
126
|
+
# and subscription target) are serialized with only their id and printable_* method values
|
|
127
|
+
# instead of all database columns, to avoid exposing columns the frontend does not need.
|
|
128
|
+
# Note that authentication and authorization of the REST API is still the responsibility of
|
|
129
|
+
# your application (see the :with_devise routing option). Default value is false.
|
|
130
|
+
# config.restrict_api_response_fields = false
|
|
131
|
+
|
|
124
132
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: activity_notification
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.
|
|
4
|
+
version: 2.7.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Shota Yamazaki
|
|
@@ -311,7 +311,7 @@ description: Integrated user activity notifications for Ruby on Rails. Provides
|
|
|
311
311
|
to configure multiple notification targets and make activity notifications with
|
|
312
312
|
notifiable models, like adding comments, responding etc.
|
|
313
313
|
email:
|
|
314
|
-
- shota.yamazaki.
|
|
314
|
+
- shota.yamazaki.work@gmail.com
|
|
315
315
|
executables: []
|
|
316
316
|
extensions: []
|
|
317
317
|
extra_rdoc_files: []
|