activity_notification 1.4.4 → 2.2.4

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.
Files changed (271) hide show
  1. checksums.yaml +5 -5
  2. data/.github/ISSUE_TEMPLATE/bug_report.md +22 -0
  3. data/.github/ISSUE_TEMPLATE/feature_request.md +17 -0
  4. data/.github/pull_request_template.md +13 -0
  5. data/.github/workflows/build.yml +116 -0
  6. data/.gitignore +15 -3
  7. data/CHANGELOG.md +200 -1
  8. data/Gemfile +17 -2
  9. data/Procfile +2 -0
  10. data/README.md +168 -1033
  11. data/Rakefile +19 -10
  12. data/activity_notification.gemspec +14 -9
  13. data/app/channels/activity_notification/notification_api_channel.rb +12 -0
  14. data/app/channels/activity_notification/notification_api_with_devise_channel.rb +46 -0
  15. data/app/channels/activity_notification/notification_channel.rb +37 -0
  16. data/app/channels/activity_notification/notification_with_devise_channel.rb +51 -0
  17. data/app/controllers/activity_notification/apidocs_controller.rb +75 -0
  18. data/app/controllers/activity_notification/notifications_api_controller.rb +143 -0
  19. data/app/controllers/activity_notification/notifications_api_with_devise_controller.rb +7 -0
  20. data/app/controllers/activity_notification/notifications_controller.rb +60 -54
  21. data/app/controllers/activity_notification/subscriptions_api_controller.rb +197 -0
  22. data/app/controllers/activity_notification/subscriptions_api_with_devise_controller.rb +7 -0
  23. data/app/controllers/activity_notification/subscriptions_controller.rb +83 -73
  24. data/app/jobs/activity_notification/notify_all_job.rb +25 -0
  25. data/app/jobs/activity_notification/notify_job.rb +26 -0
  26. data/app/jobs/activity_notification/notify_to_job.rb +25 -0
  27. data/app/views/activity_notification/notifications/default/_default.html.erb +23 -23
  28. data/app/views/activity_notification/notifications/default/_default_without_grouping.html.erb +19 -19
  29. data/app/views/activity_notification/notifications/default/_index.html.erb +3 -3
  30. data/app/views/activity_notification/notifications/default/index.html.erb +60 -7
  31. data/app/views/activity_notification/notifications/default/open.js.erb +2 -2
  32. data/app/views/activity_notification/notifications/default/open_all.js.erb +2 -2
  33. data/app/views/activity_notification/notifications/default/show.html.erb +2 -2
  34. data/app/views/activity_notification/optional_targets/default/action_cable_channel/_default.html.erb +176 -0
  35. data/app/views/activity_notification/optional_targets/default/base/_default.text.erb +1 -1
  36. data/app/views/activity_notification/optional_targets/default/slack/_default.text.erb +1 -1
  37. data/app/views/activity_notification/subscriptions/default/_form.html.erb +2 -2
  38. data/app/views/activity_notification/subscriptions/default/_notification_keys.html.erb +5 -33
  39. data/app/views/activity_notification/subscriptions/default/_subscription.html.erb +8 -8
  40. data/app/views/activity_notification/subscriptions/default/index.html.erb +13 -9
  41. data/app/views/activity_notification/subscriptions/default/show.html.erb +3 -3
  42. data/app/views/activity_notification/subscriptions/default/subscribe.js.erb +1 -1
  43. data/app/views/activity_notification/subscriptions/default/subscribe_to_email.js.erb +1 -1
  44. data/app/views/activity_notification/subscriptions/default/subscribe_to_optional_target.js.erb +1 -1
  45. data/app/views/activity_notification/subscriptions/default/unsubscribe.js.erb +1 -1
  46. data/app/views/activity_notification/subscriptions/default/unsubscribe_to_email.js.erb +1 -1
  47. data/app/views/activity_notification/subscriptions/default/unsubscribe_to_optional_target.js.erb +1 -1
  48. data/bin/_dynamodblocal +4 -0
  49. data/bin/bundle_update.sh +7 -0
  50. data/bin/deploy_on_heroku.sh +16 -0
  51. data/bin/install_dynamodblocal.sh +5 -0
  52. data/bin/start_dynamodblocal.sh +47 -0
  53. data/bin/stop_dynamodblocal.sh +34 -0
  54. data/docs/CODE_OF_CONDUCT.md +76 -0
  55. data/docs/CONTRIBUTING.md +36 -0
  56. data/docs/Functions.md +1146 -0
  57. data/docs/Setup.md +817 -0
  58. data/docs/Testing.md +148 -0
  59. data/gemfiles/Gemfile.rails-5.0 +8 -1
  60. data/gemfiles/Gemfile.rails-5.1 +7 -1
  61. data/gemfiles/Gemfile.rails-5.2 +24 -0
  62. data/gemfiles/Gemfile.rails-6.0 +23 -0
  63. data/gemfiles/Gemfile.rails-6.1 +22 -0
  64. data/gemfiles/Gemfile.rails-7.0 +25 -0
  65. data/lib/activity_notification/apis/notification_api.rb +356 -159
  66. data/lib/activity_notification/apis/subscription_api.rb +98 -59
  67. data/lib/activity_notification/apis/swagger.rb +6 -0
  68. data/lib/activity_notification/common.rb +18 -7
  69. data/lib/activity_notification/config.rb +176 -30
  70. data/lib/activity_notification/controllers/common_api_controller.rb +30 -0
  71. data/lib/activity_notification/controllers/common_controller.rb +47 -27
  72. data/lib/activity_notification/controllers/concerns/swagger/error_responses.rb +55 -0
  73. data/lib/activity_notification/controllers/concerns/swagger/notifications_api.rb +273 -0
  74. data/lib/activity_notification/controllers/concerns/swagger/notifications_parameters.rb +92 -0
  75. data/lib/activity_notification/controllers/concerns/swagger/subscriptions_api.rb +405 -0
  76. data/lib/activity_notification/controllers/concerns/swagger/subscriptions_parameters.rb +50 -0
  77. data/lib/activity_notification/controllers/devise_authentication_controller.rb +22 -5
  78. data/lib/activity_notification/gem_version.rb +14 -0
  79. data/lib/activity_notification/helpers/errors.rb +6 -0
  80. data/lib/activity_notification/helpers/view_helpers.rb +118 -28
  81. data/lib/activity_notification/mailers/helpers.rb +19 -12
  82. data/lib/activity_notification/models/concerns/notifiable.rb +142 -55
  83. data/lib/activity_notification/models/concerns/subscriber.rb +28 -13
  84. data/lib/activity_notification/models/concerns/swagger/error_schema.rb +36 -0
  85. data/lib/activity_notification/models/concerns/swagger/notification_schema.rb +209 -0
  86. data/lib/activity_notification/models/concerns/swagger/subscription_schema.rb +162 -0
  87. data/lib/activity_notification/models/concerns/target.rb +131 -32
  88. data/lib/activity_notification/models/notification.rb +1 -0
  89. data/lib/activity_notification/models/subscription.rb +1 -0
  90. data/lib/activity_notification/models.rb +23 -1
  91. data/lib/activity_notification/optional_targets/action_cable_api_channel.rb +69 -0
  92. data/lib/activity_notification/optional_targets/action_cable_channel.rb +68 -0
  93. data/lib/activity_notification/optional_targets/base.rb +9 -15
  94. data/lib/activity_notification/orm/active_record/notification.rb +23 -34
  95. data/lib/activity_notification/orm/active_record/subscription.rb +1 -1
  96. data/lib/activity_notification/orm/active_record.rb +1 -1
  97. data/lib/activity_notification/orm/dynamoid/extension.rb +262 -0
  98. data/lib/activity_notification/orm/dynamoid/notification.rb +224 -0
  99. data/lib/activity_notification/orm/dynamoid/subscription.rb +82 -0
  100. data/lib/activity_notification/orm/dynamoid.rb +530 -0
  101. data/lib/activity_notification/orm/mongoid/notification.rb +29 -28
  102. data/lib/activity_notification/orm/mongoid/subscription.rb +3 -3
  103. data/lib/activity_notification/orm/mongoid.rb +33 -1
  104. data/lib/activity_notification/rails/routes.rb +273 -60
  105. data/lib/activity_notification/renderable.rb +22 -7
  106. data/lib/activity_notification/roles/acts_as_notifiable.rb +64 -1
  107. data/lib/activity_notification/roles/acts_as_target.rb +99 -9
  108. data/lib/activity_notification/version.rb +1 -1
  109. data/lib/activity_notification.rb +14 -0
  110. data/lib/generators/activity_notification/controllers_generator.rb +2 -1
  111. data/lib/generators/templates/activity_notification.rb +61 -7
  112. data/lib/generators/templates/controllers/README +2 -2
  113. data/lib/generators/templates/controllers/notifications_api_controller.rb +31 -0
  114. data/lib/generators/templates/controllers/notifications_api_with_devise_controller.rb +31 -0
  115. data/lib/generators/templates/controllers/notifications_controller.rb +1 -37
  116. data/lib/generators/templates/controllers/notifications_with_devise_controller.rb +1 -45
  117. data/lib/generators/templates/controllers/subscriptions_api_controller.rb +61 -0
  118. data/lib/generators/templates/controllers/subscriptions_api_with_devise_controller.rb +61 -0
  119. data/lib/generators/templates/controllers/subscriptions_controller.rb +14 -37
  120. data/lib/generators/templates/controllers/subscriptions_with_devise_controller.rb +14 -45
  121. data/lib/generators/templates/migrations/migration.rb +5 -5
  122. data/lib/generators/templates/models/README +8 -4
  123. data/lib/generators/templates/models/notification.rb +1 -1
  124. data/lib/generators/templates/models/subscription.rb +1 -1
  125. data/lib/tasks/activity_notification_tasks.rake +14 -4
  126. data/package.json +8 -0
  127. data/spec/channels/notification_api_channel_shared_examples.rb +59 -0
  128. data/spec/channels/notification_api_channel_spec.rb +49 -0
  129. data/spec/channels/notification_api_with_devise_channel_spec.rb +76 -0
  130. data/spec/channels/notification_channel_shared_examples.rb +59 -0
  131. data/spec/channels/notification_channel_spec.rb +48 -0
  132. data/spec/channels/notification_with_devise_channel_spec.rb +97 -0
  133. data/spec/concerns/apis/notification_api_spec.rb +177 -12
  134. data/spec/concerns/apis/subscription_api_spec.rb +146 -4
  135. data/spec/concerns/common_spec.rb +25 -3
  136. data/spec/concerns/models/notifiable_spec.rb +161 -11
  137. data/spec/concerns/models/subscriber_spec.rb +253 -79
  138. data/spec/concerns/models/target_spec.rb +180 -47
  139. data/spec/concerns/renderable_spec.rb +35 -16
  140. data/spec/config_spec.rb +52 -1
  141. data/spec/controllers/controller_spec_utility.rb +100 -0
  142. data/spec/controllers/notifications_api_controller_shared_examples.rb +506 -0
  143. data/spec/controllers/notifications_api_controller_spec.rb +19 -0
  144. data/spec/controllers/notifications_api_with_devise_controller_spec.rb +60 -0
  145. data/spec/controllers/notifications_controller_shared_examples.rb +55 -76
  146. data/spec/controllers/notifications_controller_spec.rb +1 -2
  147. data/spec/controllers/notifications_with_devise_controller_spec.rb +14 -8
  148. data/spec/controllers/subscriptions_api_controller_shared_examples.rb +750 -0
  149. data/spec/controllers/subscriptions_api_controller_spec.rb +19 -0
  150. data/spec/controllers/subscriptions_api_with_devise_controller_spec.rb +60 -0
  151. data/spec/controllers/subscriptions_controller_shared_examples.rb +99 -121
  152. data/spec/controllers/subscriptions_controller_spec.rb +1 -2
  153. data/spec/controllers/subscriptions_with_devise_controller_spec.rb +14 -8
  154. data/spec/factories/notifications.rb +1 -1
  155. data/spec/factories/subscriptions.rb +3 -3
  156. data/spec/factories/users.rb +3 -3
  157. data/spec/generators/migration/migration_generator_spec.rb +29 -4
  158. data/spec/helpers/view_helpers_spec.rb +31 -21
  159. data/spec/jobs/notify_all_job_spec.rb +23 -0
  160. data/spec/jobs/notify_job_spec.rb +23 -0
  161. data/spec/jobs/notify_to_job_spec.rb +23 -0
  162. data/spec/mailers/mailer_spec.rb +42 -1
  163. data/spec/models/dummy/dummy_group_spec.rb +4 -0
  164. data/spec/models/dummy/dummy_notifiable_spec.rb +4 -0
  165. data/spec/models/dummy/dummy_notifier_spec.rb +4 -0
  166. data/spec/models/dummy/dummy_subscriber_spec.rb +3 -0
  167. data/spec/models/dummy/dummy_target_spec.rb +4 -0
  168. data/spec/models/notification_spec.rb +181 -45
  169. data/spec/models/subscription_spec.rb +77 -27
  170. data/spec/optional_targets/action_cable_api_channel_spec.rb +34 -0
  171. data/spec/optional_targets/action_cable_channel_spec.rb +41 -0
  172. data/spec/optional_targets/amazon_sns_spec.rb +0 -2
  173. data/spec/optional_targets/slack_spec.rb +0 -2
  174. data/spec/orm/dynamoid_spec.rb +115 -0
  175. data/spec/rails_app/Rakefile +9 -0
  176. data/spec/rails_app/app/assets/config/manifest.js +3 -0
  177. data/spec/rails_app/app/assets/javascripts/application.js +2 -1
  178. data/spec/rails_app/app/assets/javascripts/cable.js +12 -0
  179. data/spec/rails_app/app/controllers/admins_controller.rb +21 -0
  180. data/spec/rails_app/app/controllers/application_controller.rb +1 -1
  181. data/spec/rails_app/app/controllers/articles_controller.rb +6 -1
  182. data/spec/rails_app/app/controllers/comments_controller.rb +3 -1
  183. data/spec/rails_app/app/controllers/spa_controller.rb +7 -0
  184. data/spec/rails_app/app/controllers/users/notifications_controller.rb +0 -65
  185. data/spec/rails_app/app/controllers/users/notifications_with_devise_controller.rb +0 -73
  186. data/spec/rails_app/app/controllers/users/subscriptions_controller.rb +0 -77
  187. data/spec/rails_app/app/controllers/users/subscriptions_with_devise_controller.rb +0 -85
  188. data/spec/rails_app/app/controllers/users_controller.rb +26 -0
  189. data/spec/rails_app/app/javascript/App.vue +40 -0
  190. data/spec/rails_app/app/javascript/components/DeviseTokenAuth.vue +82 -0
  191. data/spec/rails_app/app/javascript/components/Top.vue +98 -0
  192. data/spec/rails_app/app/javascript/components/notifications/Index.vue +200 -0
  193. data/spec/rails_app/app/javascript/components/notifications/Notification.vue +133 -0
  194. data/spec/rails_app/app/javascript/components/notifications/NotificationContent.vue +122 -0
  195. data/spec/rails_app/app/javascript/components/subscriptions/Index.vue +279 -0
  196. data/spec/rails_app/app/javascript/components/subscriptions/NewSubscription.vue +112 -0
  197. data/spec/rails_app/app/javascript/components/subscriptions/NotificationKey.vue +141 -0
  198. data/spec/rails_app/app/javascript/components/subscriptions/Subscription.vue +226 -0
  199. data/spec/rails_app/app/javascript/config/development.js +5 -0
  200. data/spec/rails_app/app/javascript/config/environment.js +7 -0
  201. data/spec/rails_app/app/javascript/config/production.js +5 -0
  202. data/spec/rails_app/app/javascript/config/test.js +5 -0
  203. data/spec/rails_app/app/javascript/packs/application.js +18 -0
  204. data/spec/rails_app/app/javascript/packs/spa.js +14 -0
  205. data/spec/rails_app/app/javascript/router/index.js +73 -0
  206. data/spec/rails_app/app/javascript/store/index.js +37 -0
  207. data/spec/rails_app/app/models/admin.rb +15 -10
  208. data/spec/rails_app/app/models/article.rb +25 -20
  209. data/spec/rails_app/app/models/comment.rb +27 -62
  210. data/spec/rails_app/app/models/dummy/dummy_base.rb +1 -0
  211. data/spec/rails_app/app/models/dummy/dummy_group.rb +9 -0
  212. data/spec/rails_app/app/models/dummy/dummy_notifiable.rb +1 -0
  213. data/spec/rails_app/app/models/dummy/dummy_notifiable_target.rb +27 -0
  214. data/spec/rails_app/app/models/dummy/dummy_notifier.rb +1 -0
  215. data/spec/rails_app/app/models/dummy/dummy_subscriber.rb +1 -0
  216. data/spec/rails_app/app/models/dummy/dummy_target.rb +1 -0
  217. data/spec/rails_app/app/models/user.rb +44 -18
  218. data/spec/rails_app/app/views/activity_notification/notifications/default/article/_update.html.erb +146 -0
  219. data/spec/rails_app/app/views/activity_notification/notifications/users/overridden/custom/_test.html.erb +1 -0
  220. data/spec/rails_app/app/views/activity_notification/optional_targets/admins/amazon_sns/comment/_default.text.erb +1 -1
  221. data/spec/rails_app/app/views/articles/index.html.erb +68 -20
  222. data/spec/rails_app/app/views/articles/show.html.erb +1 -1
  223. data/spec/rails_app/app/views/layouts/_header.html.erb +9 -3
  224. data/spec/rails_app/app/views/spa/index.html.erb +2 -0
  225. data/spec/rails_app/babel.config.js +72 -0
  226. data/spec/rails_app/bin/webpack +18 -0
  227. data/spec/rails_app/bin/webpack-dev-server +18 -0
  228. data/spec/rails_app/config/application.rb +26 -6
  229. data/spec/rails_app/config/cable.yml +8 -0
  230. data/spec/rails_app/config/database.yml +1 -1
  231. data/spec/rails_app/config/dynamoid.rb +13 -0
  232. data/spec/rails_app/config/environment.rb +5 -1
  233. data/spec/rails_app/config/environments/development.rb +5 -0
  234. data/spec/rails_app/config/environments/production.rb +7 -1
  235. data/spec/rails_app/config/environments/test.rb +7 -11
  236. data/spec/rails_app/config/initializers/activity_notification.rb +63 -9
  237. data/spec/rails_app/config/initializers/copy_it.aws.rb.template +6 -0
  238. data/spec/rails_app/config/initializers/devise_token_auth.rb +55 -0
  239. data/spec/rails_app/config/initializers/mysql.rb +9 -0
  240. data/spec/rails_app/config/locales/activity_notification.en.yml +10 -4
  241. data/spec/rails_app/config/routes.rb +42 -1
  242. data/spec/rails_app/config/webpack/development.js +5 -0
  243. data/spec/rails_app/config/webpack/environment.js +7 -0
  244. data/spec/rails_app/config/webpack/loaders/vue.js +6 -0
  245. data/spec/rails_app/config/webpack/production.js +5 -0
  246. data/spec/rails_app/config/webpack/test.js +5 -0
  247. data/spec/rails_app/config/webpacker.yml +97 -0
  248. data/spec/rails_app/db/migrate/{20160715050433_create_test_tables.rb → 20160716000000_create_test_tables.rb} +1 -1
  249. data/spec/rails_app/db/migrate/{20160715050420_create_activity_notification_tables.rb → 20181209000000_create_activity_notification_tables.rb} +3 -3
  250. data/spec/rails_app/db/migrate/20191201000000_add_tokens_to_users.rb +10 -0
  251. data/spec/rails_app/db/schema.rb +46 -43
  252. data/spec/rails_app/db/seeds.rb +28 -4
  253. data/spec/rails_app/lib/custom_optional_targets/raise_error.rb +14 -0
  254. data/spec/rails_app/lib/mailer_previews/mailer_preview.rb +14 -4
  255. data/spec/rails_app/package.json +23 -0
  256. data/spec/rails_app/postcss.config.js +12 -0
  257. data/spec/roles/acts_as_group_spec.rb +0 -2
  258. data/spec/roles/acts_as_notifiable_spec.rb +80 -20
  259. data/spec/roles/acts_as_notifier_spec.rb +0 -2
  260. data/spec/roles/acts_as_target_spec.rb +1 -5
  261. data/spec/spec_helper.rb +13 -11
  262. data/spec/version_spec.rb +31 -0
  263. metadata +306 -53
  264. data/.travis.yml +0 -85
  265. data/Gemfile.lock +0 -234
  266. data/gemfiles/Gemfile.rails-4.2 +0 -17
  267. data/gemfiles/Gemfile.rails-4.2.lock +0 -225
  268. data/gemfiles/Gemfile.rails-5.0.lock +0 -234
  269. data/gemfiles/Gemfile.rails-5.1.lock +0 -234
  270. data/spec/rails_app/app/views/activity_notification/notifications/users/overriden/custom/_test.html.erb +0 -1
  271. /data/spec/rails_app/app/{models → assets/images}/.keep +0 -0
@@ -19,7 +19,10 @@ module ActivityNotification
19
19
  :_notification_email_allowed,
20
20
  :_batch_notification_email_allowed,
21
21
  :_notification_subscription_allowed,
22
+ :_notification_action_cable_allowed,
23
+ :_notification_action_cable_with_devise,
22
24
  :_notification_devise_resource,
25
+ :_notification_current_devise_target,
23
26
  :_printable_notification_target_name
24
27
  set_target_class_defaults
25
28
  end
@@ -34,12 +37,15 @@ module ActivityNotification
34
37
  # Sets default values to target class fields.
35
38
  # @return [NilClass] nil
36
39
  def set_target_class_defaults
37
- self._notification_email = nil
38
- self._notification_email_allowed = ActivityNotification.config.email_enabled
39
- self._batch_notification_email_allowed = ActivityNotification.config.email_enabled
40
- self._notification_subscription_allowed = ActivityNotification.config.subscription_enabled
41
- self._notification_devise_resource = ->(model) { model }
42
- self._printable_notification_target_name = :printable_name
40
+ self._notification_email = nil
41
+ self._notification_email_allowed = ActivityNotification.config.email_enabled
42
+ self._batch_notification_email_allowed = ActivityNotification.config.email_enabled
43
+ self._notification_subscription_allowed = ActivityNotification.config.subscription_enabled
44
+ self._notification_action_cable_allowed = ActivityNotification.config.action_cable_enabled || ActivityNotification.config.action_cable_api_enabled
45
+ self._notification_action_cable_with_devise = ActivityNotification.config.action_cable_with_devise
46
+ self._notification_devise_resource = ->(model) { model }
47
+ self._notification_current_devise_target = ->(current_resource) { current_resource }
48
+ self._printable_notification_target_name = :printable_name
43
49
  nil
44
50
  end
45
51
 
@@ -55,6 +61,8 @@ module ActivityNotification
55
61
  # @option options [String] :filtered_by_group_type (nil) Group type for filter, valid with :filtered_by_group_id
56
62
  # @option options [String] :filtered_by_group_id (nil) Group instance id for filter, valid with :filtered_by_group_type
57
63
  # @option options [String] :filtered_by_key (nil) Key of the notification for filter
64
+ # @option options [String] :later_than (nil) ISO 8601 format time to filter notifications later than specified time
65
+ # @option options [String] :earlier_than (nil) ISO 8601 format time to filter notifications earlier than specified time
58
66
  # @option options [Array|Hash] :custom_filter (nil) Custom notification filter (e.g. ["created_at >= ?", time.hour.ago])
59
67
  # @return [Array<Notificaion>] All notifications for this target type
60
68
  def all_notifications(options = {})
@@ -73,8 +81,8 @@ module ActivityNotification
73
81
  end
74
82
  target_notifications = target_notifications.limit(options[:limit]) if options[:limit].present?
75
83
  as_latest_group_member ?
76
- target_notifications.map{ |n| n.latest_group_member } :
77
- target_notifications.to_a
84
+ target_notifications.latest_order!(reverse).map{ |n| n.latest_group_member } :
85
+ target_notifications.latest_order!(reverse).to_a
78
86
  end
79
87
 
80
88
  # Gets all notifications for this target type grouped by targets.
@@ -95,6 +103,8 @@ module ActivityNotification
95
103
  # @option options [String] :filtered_by_group_type (nil) Group type for filter, valid with :filtered_by_group_id
96
104
  # @option options [String] :filtered_by_group_id (nil) Group instance id for filter, valid with :filtered_by_group_type
97
105
  # @option options [String] :filtered_by_key (nil) Key of the notification for filter
106
+ # @option options [String] :later_than (nil) ISO 8601 format time to filter notifications later than specified time
107
+ # @option options [String] :earlier_than (nil) ISO 8601 format time to filter notifications earlier than specified time
98
108
  # @option options [Array|Hash] :custom_filter (nil) Custom notification filter (e.g. ["created_at >= ?", time.hour.ago])
99
109
  # @return [Hash<Target, Notificaion>] All notifications for this target type grouped by targets
100
110
  def notification_index_map(options = {})
@@ -117,6 +127,8 @@ module ActivityNotification
117
127
  # @option options [String] :filtered_by_group_type (nil) Group type for filter, valid with :filtered_by_group_id
118
128
  # @option options [String] :filtered_by_group_id (nil) Group instance id for filter, valid with :filtered_by_group_type
119
129
  # @option options [String] :filtered_by_key (nil) Key of the notification for filter
130
+ # @option options [String] :later_than (nil) ISO 8601 format time to filter notifications later than specified time
131
+ # @option options [String] :earlier_than (nil) ISO 8601 format time to filter notifications earlier than specified time
120
132
  # @option options [Array|Hash] :custom_filter (nil) Custom notification filter (e.g. ["created_at >= ?", time.hour.ago])
121
133
  # @option options [Boolean] :send_later (false) If it sends notification email asynchronously
122
134
  # @option options [String, Symbol] :fallback (:batch_default) Fallback template to use when MissingTemplate is raised
@@ -130,6 +142,15 @@ module ActivityNotification
130
142
  }.to_h
131
143
  end
132
144
 
145
+ # Resolves current authenticated target by devise authentication from current resource signed in with Devise.
146
+ # This method is able to be overridden.
147
+ #
148
+ # @param [Object] current_resource Current resource signed in with Devise
149
+ # @return [Object] Current authenticated target by devise authentication
150
+ def resolve_current_devise_target(current_resource)
151
+ _notification_current_devise_target.call(current_resource)
152
+ end
153
+
133
154
  # Returns if subscription management is allowed for this target type.
134
155
  # @return [Boolean] If subscription management is allowed for this target type
135
156
  def subscription_enabled?
@@ -139,15 +160,15 @@ module ActivityNotification
139
160
  end
140
161
 
141
162
  # Returns target email address for email notification.
142
- # This method is able to be overriden.
163
+ # This method is able to be overridden.
143
164
  #
144
165
  # @return [String] Target email address
145
166
  def mailer_to
146
167
  resolve_value(_notification_email)
147
168
  end
148
169
 
149
- # Returns if sending notification email is allowed for the target from configured field or overriden method.
150
- # This method is able to be overriden.
170
+ # Returns if sending notification email is allowed for the target from configured field or overridden method.
171
+ # This method is able to be overridden.
151
172
  #
152
173
  # @param [Object] notifiable Notifiable instance of the notification
153
174
  # @param [String] key Key of the notification
@@ -156,8 +177,8 @@ module ActivityNotification
156
177
  resolve_value(_notification_email_allowed, notifiable, key)
157
178
  end
158
179
 
159
- # Returns if sending batch notification email is allowed for the target from configured field or overriden method.
160
- # This method is able to be overriden.
180
+ # Returns if sending batch notification email is allowed for the target from configured field or overridden method.
181
+ # This method is able to be overridden.
161
182
  #
162
183
  # @param [String] key Key of the notifications
163
184
  # @return [Boolean] If sending batch notification email is allowed for the target
@@ -165,8 +186,8 @@ module ActivityNotification
165
186
  resolve_value(_batch_notification_email_allowed, key)
166
187
  end
167
188
 
168
- # Returns if subscription management is allowed for the target from configured field or overriden method.
169
- # This method is able to be overriden.
189
+ # Returns if subscription management is allowed for the target from configured field or overridden method.
190
+ # This method is able to be overridden.
170
191
  #
171
192
  # @param [String] key Key of the notifications
172
193
  # @return [Boolean] If subscription management is allowed for the target
@@ -175,13 +196,44 @@ module ActivityNotification
175
196
  end
176
197
  alias_method :notification_subscription_allowed?, :subscription_allowed?
177
198
 
199
+ # Returns if publishing WebSocket using ActionCable is allowed for the target from configured field or overridden method.
200
+ # This method is able to be overridden.
201
+ #
202
+ # @param [Object] notifiable Notifiable instance of the notification
203
+ # @param [String] key Key of the notification
204
+ # @return [Boolean] If publishing WebSocket using ActionCable is allowed for the target
205
+ def notification_action_cable_allowed?(notifiable = nil, key = nil)
206
+ resolve_value(_notification_action_cable_allowed, notifiable, key)
207
+ end
208
+
209
+ # Returns if publishing WebSocket using ActionCable is allowed only for the authenticated target with Devise from configured field or overridden method.
210
+ #
211
+ # @return [Boolean] If publishing WebSocket using ActionCable is allowed for the target
212
+ def notification_action_cable_with_devise?
213
+ resolve_value(_notification_action_cable_with_devise)
214
+ end
215
+
216
+ # Returns notification ActionCable channel class name from action_cable_with_devise? configuration.
217
+ #
218
+ # @return [String] Notification ActionCable channel class name from action_cable_with_devise? configuration
219
+ def notification_action_cable_channel_class_name
220
+ notification_action_cable_with_devise? ? "ActivityNotification::NotificationWithDeviseChannel" : "ActivityNotification::NotificationChannel"
221
+ end
222
+
223
+ # Returns Devise resource model associated with this target.
224
+ #
225
+ # @return [Object] Devise resource model associated with this target
226
+ def notification_devise_resource
227
+ resolve_value(_notification_devise_resource)
228
+ end
229
+
178
230
  # Returns if current resource signed in with Devise is authenticated for the notification.
179
- # This method is able to be overriden.
231
+ # This method is able to be overridden.
180
232
  #
181
233
  # @param [Object] current_resource Current resource signed in with Devise
182
234
  # @return [Boolean] If current resource signed in with Devise is authenticated for the notification
183
235
  def authenticated_with_devise?(current_resource)
184
- devise_resource = resolve_value(_notification_devise_resource)
236
+ devise_resource = notification_devise_resource
185
237
  unless current_resource.blank? or current_resource.is_a? devise_resource.class
186
238
  raise TypeError,
187
239
  "Different type of current resource #{current_resource.class} "\
@@ -207,6 +259,8 @@ module ActivityNotification
207
259
  # @option options [String] :filtered_by_group_type (nil) Group type for filter, valid with :filtered_by_group_id
208
260
  # @option options [String] :filtered_by_group_id (nil) Group instance id for filter, valid with :filtered_by_group_type
209
261
  # @option options [String] :filtered_by_key (nil) Key of the notification for filter
262
+ # @option options [String] :later_than (nil) ISO 8601 format time to filter notifications later than specified time
263
+ # @option options [String] :earlier_than (nil) ISO 8601 format time to filter notifications earlier than specified time
210
264
  # @option options [Array|Hash] :custom_filter (nil) Custom notification filter (e.g. ["created_at >= ?", time.hour.ago])
211
265
  # @return [Integer] Count of unopened notifications of the target
212
266
  def unopened_notification_count(options = {})
@@ -223,10 +277,12 @@ module ActivityNotification
223
277
  # @option options [String] :filtered_by_group_type (nil) Group type for filter, valid with :filtered_by_group_id
224
278
  # @option options [String] :filtered_by_group_id (nil) Group instance id for filter, valid with :filtered_by_group_type
225
279
  # @option options [String] :filtered_by_key (nil) Key of the notification for filter
280
+ # @option options [String] :later_than (nil) ISO 8601 format time to filter notifications later than specified time
281
+ # @option options [String] :earlier_than (nil) ISO 8601 format time to filter notifications earlier than specified time
226
282
  # @option options [Array|Hash] :custom_filter (nil) Custom notification filter (e.g. ["created_at >= ?", time.hour.ago])
227
283
  # @return [Boolean] If the target has unopened notifications
228
284
  def has_unopened_notifications?(options = {})
229
- _unopened_notification_index(options).present?
285
+ _unopened_notification_index(options).exists?
230
286
  end
231
287
 
232
288
  # Returns automatically arranged notification index of the target.
@@ -248,6 +304,8 @@ module ActivityNotification
248
304
  # @option options [String] :filtered_by_group_type (nil) Group type for filter, valid with :filtered_by_group_id
249
305
  # @option options [String] :filtered_by_group_id (nil) Group instance id for filter, valid with :filtered_by_group_type
250
306
  # @option options [String] :filtered_by_key (nil) Key of the notification for filter
307
+ # @option options [String] :later_than (nil) ISO 8601 format time to filter notifications later than specified time
308
+ # @option options [String] :earlier_than (nil) ISO 8601 format time to filter notifications earlier than specified time
251
309
  # @option options [Array|Hash] :custom_filter (nil) Custom notification filter (e.g. ["created_at >= ?", time.hour.ago])
252
310
  # @return [Array<Notificaion>] Notification index of the target
253
311
  def notification_index(options = {})
@@ -271,6 +329,8 @@ module ActivityNotification
271
329
  # @option options [String] :filtered_by_group_type (nil) Group type for filter, valid with :filtered_by_group_id
272
330
  # @option options [String] :filtered_by_group_id (nil) Group instance id for filter, valid with :filtered_by_group_type
273
331
  # @option options [String] :filtered_by_key (nil) Key of the notification for filter
332
+ # @option options [String] :later_than (nil) ISO 8601 format time to filter notifications later than specified time
333
+ # @option options [String] :earlier_than (nil) ISO 8601 format time to filter notifications earlier than specified time
274
334
  # @option options [Array|Hash] :custom_filter (nil) Custom notification filter (e.g. ["created_at >= ?", time.hour.ago])
275
335
  # @return [Array<Notificaion>] Unopened notification index of the target
276
336
  def unopened_notification_index(options = {})
@@ -292,6 +352,8 @@ module ActivityNotification
292
352
  # @option options [String] :filtered_by_group_type (nil) Group type for filter, valid with :filtered_by_group_id
293
353
  # @option options [String] :filtered_by_group_id (nil) Group instance id for filter, valid with :filtered_by_group_type
294
354
  # @option options [String] :filtered_by_key (nil) Key of the notification for filter
355
+ # @option options [String] :later_than (nil) ISO 8601 format time to filter notifications later than specified time
356
+ # @option options [String] :earlier_than (nil) ISO 8601 format time to filter notifications earlier than specified time
295
357
  # @option options [Array|Hash] :custom_filter (nil) Custom notification filter (e.g. ["created_at >= ?", time.hour.ago])
296
358
  # @return [Array<Notificaion>] Opened notification index of the target
297
359
  def opened_notification_index(options = {})
@@ -314,10 +376,31 @@ module ActivityNotification
314
376
  # @option options [Boolean] :publish_optional_targets (true) Whether it publishes notification to optional targets
315
377
  # @option options [Hash<String, Hash>] :optional_targets ({}) Options for optional targets, keys are optional target name (:amazon_sns or :slack etc) and values are options
316
378
  # @return [Notification] Generated notification instance
317
- def notify_to(notifiable, options = {})
379
+ def receive_notification_of(notifiable, options = {})
318
380
  Notification.notify_to(self, notifiable, options)
319
381
  end
320
-
382
+ alias_method :receive_notification_now_of, :receive_notification_of
383
+
384
+ # Generates notifications to this target later by ActiveJob queue.
385
+ # This method calls NotificationApi#notify_later_to internally with self target instance.
386
+ # @see NotificationApi#notify_later_to
387
+ #
388
+ # @param [Object] notifiable Notifiable instance to notify
389
+ # @param [Hash] options Options for notifications
390
+ # @option options [String] :key (notifiable.default_notification_key) Key of the notification
391
+ # @option options [Object] :group (nil) Group unit of the notifications
392
+ # @option options [ActiveSupport::Duration] :group_expiry_delay (nil) Expiry period of a notification group
393
+ # @option options [Object] :notifier (nil) Notifier of the notifications
394
+ # @option options [Hash] :parameters ({}) Additional parameters of the notifications
395
+ # @option options [Boolean] :send_email (true) Whether it sends notification email
396
+ # @option options [Boolean] :send_later (true) Whether it sends notification email asynchronously
397
+ # @option options [Boolean] :publish_optional_targets (true) Whether it publishes notification to optional targets
398
+ # @option options [Hash<String, Hash>] :optional_targets ({}) Options for optional targets, keys are optional target name (:amazon_sns or :slack etc) and values are options
399
+ # @return [Notification] Generated notification instance
400
+ def receive_notification_later_of(notifiable, options = {})
401
+ Notification.notify_later_to(self, notifiable, options)
402
+ end
403
+
321
404
  # Opens all notifications of this target.
322
405
  # This method calls NotificationApi#open_all_of internally with self target instance.
323
406
  # @see NotificationApi#open_all_of
@@ -329,7 +412,9 @@ module ActivityNotification
329
412
  # @option options [String] :filtered_by_group_type (nil) Group type for filter, valid with :filtered_by_group_id
330
413
  # @option options [String] :filtered_by_group_id (nil) Group instance id for filter, valid with :filtered_by_group_type
331
414
  # @option options [String] :filtered_by_key (nil) Key of the notification for filter
332
- # @return [Integer] Number of opened notification records
415
+ # @option options [String] :later_than (nil) ISO 8601 format time to filter notifications later than specified time
416
+ # @option options [String] :earlier_than (nil) ISO 8601 format time to filter notifications earlier than specified time
417
+ # @return [Array<Notification>] Opened notification records
333
418
  def open_all_notifications(options = {})
334
419
  Notification.open_all_of(self, options)
335
420
  end
@@ -357,6 +442,8 @@ module ActivityNotification
357
442
  # @option options [String] :filtered_by_group_type (nil) Group type for filter, valid with :filtered_by_group_id
358
443
  # @option options [String] :filtered_by_group_id (nil) Group instance id for filter, valid with :filtered_by_group_type
359
444
  # @option options [String] :filtered_by_key (nil) Key of the notification for filter
445
+ # @option options [String] :later_than (nil) ISO 8601 format time to filter notifications later than specified time
446
+ # @option options [String] :earlier_than (nil) ISO 8601 format time to filter notifications earlier than specified time
360
447
  # @option options [Array|Hash] :custom_filter (nil) Custom notification filter (e.g. ["created_at >= ?", time.hour.ago])
361
448
  # @return [Array<Notificaion>] Notification index of the target with attributes
362
449
  def notification_index_with_attributes(options = {})
@@ -380,10 +467,12 @@ module ActivityNotification
380
467
  # @option options [String] :filtered_by_group_type (nil) Group type for filter, valid with :filtered_by_group_id
381
468
  # @option options [String] :filtered_by_group_id (nil) Group instance id for filter, valid with :filtered_by_group_type
382
469
  # @option options [String] :filtered_by_key (nil) Key of the notification for filter
470
+ # @option options [String] :later_than (nil) ISO 8601 format time to filter notifications later than specified time
471
+ # @option options [String] :earlier_than (nil) ISO 8601 format time to filter notifications earlier than specified time
383
472
  # @option options [Array|Hash] :custom_filter (nil) Custom notification filter (e.g. ["created_at >= ?", time.hour.ago])
384
473
  # @return [Array<Notificaion>] Unopened notification index of the target with attributes
385
474
  def unopened_notification_index_with_attributes(options = {})
386
- include_attributes _unopened_notification_index(options)
475
+ include_attributes(_unopened_notification_index(options)).to_a
387
476
  end
388
477
 
389
478
  # Gets opened notification index of the target with including attributes like target, notifiable, group and notifier.
@@ -401,10 +490,12 @@ module ActivityNotification
401
490
  # @option options [String] :filtered_by_group_type (nil) Group type for filter, valid with :filtered_by_group_id
402
491
  # @option options [String] :filtered_by_group_id (nil) Group instance id for filter, valid with :filtered_by_group_type
403
492
  # @option options [String] :filtered_by_key (nil) Key of the notification for filter
493
+ # @option options [String] :later_than (nil) ISO 8601 format time to filter notifications later than specified time
494
+ # @option options [String] :earlier_than (nil) ISO 8601 format time to filter notifications earlier than specified time
404
495
  # @option options [Array|Hash] :custom_filter (nil) Custom notification filter (e.g. ["created_at >= ?", time.hour.ago])
405
496
  # @return [Array<Notificaion>] Opened notification index of the target with attributes
406
497
  def opened_notification_index_with_attributes(options = {})
407
- include_attributes _opened_notification_index(options)
498
+ include_attributes(_opened_notification_index(options)).to_a
408
499
  end
409
500
 
410
501
  # Sends notification email to the target.
@@ -450,7 +541,7 @@ module ActivityNotification
450
541
  # @param [String] key Key of the notification
451
542
  # @param [Boolean] subscribe_as_default Default subscription value to use when the subscription record does not configured
452
543
  # @return [Boolean] If the target subscribes the notification email or the subscription management is not allowed for the target
453
- def subscribes_to_notification_email?(key, subscribe_as_default = ActivityNotification.config.subscribe_as_default)
544
+ def subscribes_to_notification_email?(key, subscribe_as_default = ActivityNotification.config.subscribe_to_email_as_default)
454
545
  !subscription_allowed?(key) || _subscribes_to_notification_email?(key, subscribe_as_default)
455
546
  end
456
547
  alias_method :subscribes_to_email?, :subscribes_to_notification_email?
@@ -462,7 +553,7 @@ module ActivityNotification
462
553
  # @param [String, Symbol] optional_target_name Class name of the optional target implementation (e.g. :amazon_sns, :slack)
463
554
  # @param [Boolean] subscribe_as_default Default subscription value to use when the subscription record does not configured
464
555
  # @return [Boolean] If the target subscribes the notification email or the subscription management is not allowed for the target
465
- def subscribes_to_optional_target?(key, optional_target_name, subscribe_as_default = ActivityNotification.config.subscribe_as_default)
556
+ def subscribes_to_optional_target?(key, optional_target_name, subscribe_as_default = ActivityNotification.config.subscribe_to_optional_targets_as_default)
466
557
  !subscription_allowed?(key) || _subscribes_to_optional_target?(key, optional_target_name, subscribe_as_default)
467
558
  end
468
559
 
@@ -480,8 +571,10 @@ module ActivityNotification
480
571
  # @option options [String] :filtered_by_group_type (nil) Group type for filter, valid with :filtered_by_group_id
481
572
  # @option options [String] :filtered_by_group_id (nil) Group instance id for filter, valid with :filtered_by_group_type
482
573
  # @option options [String] :filtered_by_key (nil) Key of the notification for filter
574
+ # @option options [String] :later_than (nil) ISO 8601 format time to filter notifications later than specified time
575
+ # @option options [String] :earlier_than (nil) ISO 8601 format time to filter notifications earlier than specified time
483
576
  # @option options [Array|Hash] :custom_filter (nil) Custom notification filter (e.g. ["created_at >= ?", time.hour.ago])
484
- # @return [ActiveRecord_AssociationRelation<Notificaion>] Unopened notification index of the target
577
+ # @return [ActiveRecord_AssociationRelation<Notificaion>|Mongoid::Criteria<Notificaion>|Dynamoid::Criteria::Chain] Unopened notification index of the target
485
578
  def _unopened_notification_index(options = {})
486
579
  reverse = options[:reverse] || false
487
580
  with_group_members = options[:with_group_members] || false
@@ -500,8 +593,10 @@ module ActivityNotification
500
593
  # @option options [String] :filtered_by_group_type (nil) Group type for filter, valid with :filtered_by_group_id
501
594
  # @option options [String] :filtered_by_group_id (nil) Group instance id for filter, valid with :filtered_by_group_type
502
595
  # @option options [String] :filtered_by_key (nil) Key of the notification for filter
596
+ # @option options [String] :later_than (nil) ISO 8601 format time to filter notifications later than specified time
597
+ # @option options [String] :earlier_than (nil) ISO 8601 format time to filter notifications earlier than specified time
503
598
  # @option options [Array|Hash] :custom_filter (nil) Custom notification filter (e.g. ["created_at >= ?", time.hour.ago])
504
- # @return [Array<Notificaion>] Opened notification index of the target
599
+ # @return [ActiveRecord_AssociationRelation<Notificaion>|Mongoid::Criteria<Notificaion>|Dynamoid::Criteria::Chain] Opened notification index of the target
505
600
  def _opened_notification_index(options = {})
506
601
  limit = options[:limit] || ActivityNotification.config.opened_index_limit
507
602
  reverse = options[:reverse] || false
@@ -514,11 +609,11 @@ module ActivityNotification
514
609
  # Otherwise, target, notifiable and or notifier will be include without group.
515
610
  # @api private
516
611
  #
517
- # @param [ActiveRecord_AssociationRelation<Notificaion>] target_index Notification index
518
- # @return [ActiveRecord_AssociationRelation<Notificaion>] Notification index with attributes
612
+ # @param [ActiveRecord_AssociationRelation<Notificaion>|Mongoid::Criteria<Notificaion>|Dynamoid::Criteria::Chain] target_index Notification index
613
+ # @return [ActiveRecord_AssociationRelation<Notificaion>|Mongoid::Criteria<Notificaion>|Dynamoid::Criteria::Chain] Notification index with attributes
519
614
  def include_attributes(target_index)
520
615
  if target_index.present?
521
- Notification.group_member_exists?(target_index) ?
616
+ Notification.group_member_exists?(target_index.to_a) ?
522
617
  target_index.with_target.with_notifiable.with_group.with_notifier :
523
618
  target_index.with_target.with_notifiable.with_notifier
524
619
  else
@@ -540,6 +635,8 @@ module ActivityNotification
540
635
  # @option options [String] :filtered_by_group_type (nil) Group type for filter, valid with :filtered_by_group_id
541
636
  # @option options [String] :filtered_by_group_id (nil) Group instance id for filter, valid with :filtered_by_group_type
542
637
  # @option options [String] :filtered_by_key (nil) Key of the notification for filter
638
+ # @option options [String] :later_than (nil) ISO 8601 format time to filter notifications later than specified time
639
+ # @option options [String] :earlier_than (nil) ISO 8601 format time to filter notifications earlier than specified time
543
640
  # @option options [Array|Hash] :custom_filter (nil) Custom notification filter (e.g. ["created_at >= ?", time.hour.ago])
544
641
  # @return [Array<Notificaion>] Notification index of the target
545
642
  def arrange_single_notification_index(loading_index_method, options = {})
@@ -567,6 +664,8 @@ module ActivityNotification
567
664
  # @option options [String] :filtered_by_group_type (nil) Group type for filter, valid with :filtered_by_group_id
568
665
  # @option options [String] :filtered_by_group_id (nil) Group instance id for filter, valid with :filtered_by_group_type
569
666
  # @option options [String] :filtered_by_key (nil) Key of the notification for filter
667
+ # @option options [String] :later_than (nil) ISO 8601 format time to filter notifications later than specified time
668
+ # @option options [String] :earlier_than (nil) ISO 8601 format time to filter notifications earlier than specified time
570
669
  # @option options [Array|Hash] :custom_filter (nil) Custom notification filter (e.g. ["created_at >= ?", time.hour.ago])
571
670
  # @return [Array<Notificaion>] Notification index of the target
572
671
  def arrange_notification_index(loading_unopened_index_method, loading_opened_index_method, options = {})
@@ -574,7 +673,7 @@ module ActivityNotification
574
673
  if has_unopened_notifications?(options)
575
674
  # Return unopened notifications first
576
675
  target_unopened_index = arrange_single_notification_index(loading_unopened_index_method, options)
577
- # Total limit if notification index
676
+ # Total limit of notification index
578
677
  total_limit = options[:limit] || ActivityNotification.config.opened_index_limit
579
678
  # Additionaly, return opened notifications unless unopened index size overs the limit
580
679
  if (opened_limit = total_limit - target_unopened_index.size) > 0
@@ -590,4 +689,4 @@ module ActivityNotification
590
689
  end
591
690
 
592
691
  end
593
- end
692
+ end
@@ -1,5 +1,6 @@
1
1
  module ActivityNotification
2
2
  # Notification model implementation with ORM.
3
3
  class Notification < inherit_orm("Notification")
4
+ include Swagger::NotificationSchema
4
5
  end
5
6
  end
@@ -1,6 +1,7 @@
1
1
  module ActivityNotification
2
2
  # Subscription model implementation with ORM.
3
3
  class Subscription < inherit_orm("Subscription")
4
+ include Swagger::SubscriptionSchema
4
5
  end
5
6
  end
6
7
 
@@ -17,4 +17,26 @@ module ActivityNotification
17
17
  end
18
18
  end
19
19
 
20
- ActiveRecord::Base.class_eval { include ActivityNotification::Models } if defined?(ActiveRecord::Base)
20
+ if defined?(ActiveRecord::Base)
21
+ ActiveRecord::Base.class_eval { include ActivityNotification::Models }
22
+
23
+ # https://github.com/simukappu/activity_notification/issues/166
24
+ # https://discuss.rubyonrails.org/t/cve-2022-32224-possible-rce-escalation-bug-with-serialized-columns-in-active-record/81017
25
+ if (Gem::Version.new("5.2.8.1") <= Rails.gem_version && Rails.gem_version < Gem::Version.new("6.0")) ||
26
+ (Gem::Version.new("6.0.5.1") <= Rails.gem_version && Rails.gem_version < Gem::Version.new("6.1")) ||
27
+ (Gem::Version.new("6.1.6.1") <= Rails.gem_version && Rails.gem_version < Gem::Version.new("7.0"))
28
+ ActiveRecord::Base.yaml_column_permitted_classes ||= []
29
+ ActiveRecord::Base.yaml_column_permitted_classes << ActiveSupport::HashWithIndifferentAccess
30
+ ActiveRecord::Base.yaml_column_permitted_classes << ActiveSupport::TimeWithZone
31
+ ActiveRecord::Base.yaml_column_permitted_classes << ActiveSupport::TimeZone
32
+ ActiveRecord::Base.yaml_column_permitted_classes << Symbol
33
+ ActiveRecord::Base.yaml_column_permitted_classes << Time
34
+ elsif Gem::Version.new("7.0.3.1") <= Rails.gem_version
35
+ ActiveRecord.yaml_column_permitted_classes ||= []
36
+ ActiveRecord.yaml_column_permitted_classes << ActiveSupport::HashWithIndifferentAccess
37
+ ActiveRecord.yaml_column_permitted_classes << ActiveSupport::TimeWithZone
38
+ ActiveRecord.yaml_column_permitted_classes << ActiveSupport::TimeZone
39
+ ActiveRecord.yaml_column_permitted_classes << Symbol
40
+ ActiveRecord.yaml_column_permitted_classes << Time
41
+ end
42
+ end
@@ -0,0 +1,69 @@
1
+ module ActivityNotification
2
+ module OptionalTarget
3
+ # Optional target implementation to broadcast to Action Cable API channel
4
+ class ActionCableApiChannel < ActivityNotification::OptionalTarget::Base
5
+ # Initialize method to prepare Action Cable API channel
6
+ # @param [Hash] options Options for initializing
7
+ # @option options [String] :channel_prefix (ActivityNotification.config.notification_api_channel_prefix) Channel name prefix to broadcast notifications
8
+ # @option options [String] :composite_key_delimiter (ActivityNotification.config.composite_key_delimiter) Composite key delimiter for channel name
9
+ def initialize_target(options = {})
10
+ @channel_prefix = options.delete(:channel_prefix) || ActivityNotification.config.notification_api_channel_prefix
11
+ @composite_key_delimiter = options.delete(:composite_key_delimiter) || ActivityNotification.config.composite_key_delimiter
12
+ end
13
+
14
+ # Broadcast to ActionCable API subscribers
15
+ # @param [Notification] notification Notification instance
16
+ # @param [Hash] options Options for publishing
17
+ def notify(notification, options = {})
18
+ if notification_action_cable_api_allowed?(notification)
19
+ target_channel_name = "#{@channel_prefix}_#{notification.target_type}#{@composite_key_delimiter}#{notification.target_id}"
20
+ ActionCable.server.broadcast(target_channel_name, format_message(notification, options))
21
+ end
22
+ end
23
+
24
+ # Check if Action Cable notification API is allowed
25
+ # @param [Notification] notification Notification instance
26
+ # @return [Boolean] Whether Action Cable notification API is allowed
27
+ def notification_action_cable_api_allowed?(notification)
28
+ notification.target.notification_action_cable_allowed?(notification.notifiable, notification.key) &&
29
+ notification.notifiable.notifiable_action_cable_api_allowed?(notification.target, notification.key)
30
+ end
31
+
32
+ # Format message to broadcast
33
+ # @param [Notification] notification Notification instance
34
+ # @param [Hash] options Options for publishing
35
+ # @return [Hash] Formatted message to broadcast
36
+ def format_message(notification, options = {})
37
+ {
38
+ notification: notification.as_json(notification_json_options.merge(options)),
39
+ group_owner: notification.group_owner? ? nil : notification.group_owner.as_json(notification_json_options.merge(options))
40
+ }
41
+ end
42
+
43
+ protected
44
+
45
+ # Returns options for notification JSON
46
+ # @api protected
47
+ def notification_json_options
48
+ {
49
+ include: {
50
+ target: { methods: [:printable_type, :printable_target_name] },
51
+ notifiable: { methods: [:printable_type] },
52
+ group: { methods: [:printable_type, :printable_group_name] },
53
+ notifier: { methods: [:printable_type, :printable_notifier_name] },
54
+ group_members: {}
55
+ },
56
+ methods: [:notifiable_path, :printable_notifiable_name, :group_member_notifier_count, :group_notification_count, :text]
57
+ }
58
+ end
59
+
60
+ # Overriden rendering notification message using format_message
61
+ # @param [Notification] notification Notification instance
62
+ # @param [Hash] options Options for rendering
63
+ # @return [String] Rendered json formatted message to broadcast
64
+ def render_notification_message(notification, options = {})
65
+ format_message(notification, options)
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,68 @@
1
+ module ActivityNotification
2
+ module OptionalTarget
3
+ # Optional target implementation to broadcast to Action Cable channel
4
+ class ActionCableChannel < ActivityNotification::OptionalTarget::Base
5
+ # Initialize method to prepare Action Cable channel
6
+ # @param [Hash] options Options for initializing
7
+ # @option options [String] :channel_prefix (ActivityNotification.config.notification_channel_prefix) Channel name prefix to broadcast notifications
8
+ # @option options [String] :composite_key_delimiter (ActivityNotification.config.composite_key_delimiter) Composite key delimiter for channel name
9
+ def initialize_target(options = {})
10
+ @channel_prefix = options.delete(:channel_prefix) || ActivityNotification.config.notification_channel_prefix
11
+ @composite_key_delimiter = options.delete(:composite_key_delimiter) || ActivityNotification.config.composite_key_delimiter
12
+ end
13
+
14
+ # Broadcast to ActionCable subscribers
15
+ # @param [Notification] notification Notification instance
16
+ # @param [Hash] options Options for publishing
17
+ # @option options [String, Symbol] :target (nil) Target type name to find template or i18n text
18
+ # @option options [String] :partial_root ("activity_notification/notifications/#{target}", controller.target_view_path, 'activity_notification/notifications/default') Partial template name
19
+ # @option options [String] :partial (self.key.tr('.', '/')) Root path of partial template
20
+ # @option options [String] :layout (nil) Layout template name
21
+ # @option options [String] :layout_root ('layouts') Root path of layout template
22
+ # @option options [String, Symbol] :fallback (:default) Fallback template to use when MissingTemplate is raised. Set :text to use i18n text as fallback.
23
+ # @option options [String] :filter (nil) Filter option to load notification index (Nothing as auto, 'opened' or 'unopened')
24
+ # @option options [String] :limit (nil) Limit to query for notifications
25
+ # @option options [String] :without_grouping ('false') If notification index will include group members
26
+ # @option options [String] :with_group_members ('false') If notification index will include group members
27
+ # @option options [String] :filtered_by_type (nil) Notifiable type for filter
28
+ # @option options [String] :filtered_by_group_type (nil) Group type for filter, valid with :filtered_by_group_id
29
+ # @option options [String] :filtered_by_group_id (nil) Group instance id for filter, valid with :filtered_by_group_type
30
+ # @option options [String] :filtered_by_key (nil) Key of the notification for filter
31
+ # @option options [String] :later_than (nil) ISO 8601 format time to filter notification index later than specified time
32
+ # @option options [String] :earlier_than (nil) ISO 8601 format time to filter notification index earlier than specified time
33
+ # @option options [Hash] others Parameters to be set as locals
34
+ def notify(notification, options = {})
35
+ if notification_action_cable_allowed?(notification)
36
+ target_channel_name = "#{@channel_prefix}_#{notification.target_type}#{@composite_key_delimiter}#{notification.target_id}"
37
+ index_options = options.slice(:filter, :limit, :without_grouping, :with_group_members, :filtered_by_type, :filtered_by_group_type, :filtered_by_group_id, :filtered_by_key, :later_than, :earlier_than)
38
+ ActionCable.server.broadcast(target_channel_name, format_message(notification, options))
39
+ end
40
+ end
41
+
42
+ # Check if Action Cable notification is allowed
43
+ # @param [Notification] notification Notification instance
44
+ # @return [Boolean] Whether Action Cable notification is allowed
45
+ def notification_action_cable_allowed?(notification)
46
+ notification.target.notification_action_cable_allowed?(notification.notifiable, notification.key) &&
47
+ notification.notifiable.notifiable_action_cable_allowed?(notification.target, notification.key)
48
+ end
49
+
50
+ # Format message to broadcast
51
+ # @param [Notification] notification Notification instance
52
+ # @param [Hash] options Options for publishing
53
+ # @return [Hash] Formatted message to broadcast
54
+ def format_message(notification, options = {})
55
+ index_options = options.slice(:filter, :limit, :without_grouping, :with_group_members, :filtered_by_type, :filtered_by_group_type, :filtered_by_group_id, :filtered_by_key, :later_than, :earlier_than)
56
+ {
57
+ id: notification.id,
58
+ view: render_notification_message(notification, options),
59
+ text: notification.text(options),
60
+ notifiable_path: notification.notifiable_path,
61
+ group_owner_id: notification.group_owner_id,
62
+ group_owner_view: notification.group_owner? ? nil : render_notification_message(notification.group_owner, options),
63
+ unopened_notification_count: notification.target.unopened_notification_count(index_options)
64
+ }
65
+ end
66
+ end
67
+ end
68
+ end
@@ -3,22 +3,11 @@ module ActivityNotification
3
3
  module OptionalTarget
4
4
  # Abstract optional target class to develop optional notification target class.
5
5
  class Base
6
- # View context to render notification message
7
- # @return View context to render notification message
8
- attr_accessor :view_context
9
-
10
6
  # Initialize method to create view context in this OptionalTarget instance
11
7
  # @param [Hash] options Options for initializing target
12
8
  # @option options [Boolean] :skip_initializing_target (false) Whether skip calling initialize_target method
13
9
  # @option options [Hash] others Options for initializing target
14
10
  def initialize(options = {})
15
- @view_context = ActionView::Base.new(ActionController::Base.view_paths, {})
16
- @view_context.class_eval do
17
- include Rails.application.routes.url_helpers
18
- def default_url_options
19
- ActionMailer::Base.default_url_options
20
- end
21
- end
22
11
  initialize_target(options) unless options.delete(:skip_initializing_target)
23
12
  end
24
13
 
@@ -28,13 +17,13 @@ module ActivityNotification
28
17
  self.class.name.demodulize.underscore.to_sym
29
18
  end
30
19
 
31
- # Initialize method to be overriden in user implementation class
20
+ # Initialize method to be overridden in user implementation class
32
21
  # @param [Hash] _options Options for initializing
33
22
  def initialize_target(_options = {})
34
23
  raise NotImplementedError, "You have to implement #{self.class}##{__method__}"
35
24
  end
36
25
 
37
- # Publishing notification method to be overriden in user implementation class
26
+ # Publishing notification method to be overridden in user implementation class
38
27
  # @param [Notification] _notification Notification instance
39
28
  # @param [Hash] _options Options for publishing
40
29
  def notify(_notification, _options = {})
@@ -64,12 +53,17 @@ module ActivityNotification
64
53
  "activity_notification/optional_targets/default/base"
65
54
  ]
66
55
  options[:fallback] ||= :default
67
- @view_context.assign((options[:assignment] || {}).merge(notification: notification, target: notification.target))
68
56
 
69
57
  message, missing_template = nil, nil
70
58
  partial_root_list.each do |partial_root|
71
59
  begin
72
- message = notification.render(@view_context, options.merge(partial_root: partial_root)).to_str
60
+ message = notification.render(
61
+ ActivityNotification::NotificationsController.renderer,
62
+ options.merge(
63
+ partial_root: partial_root,
64
+ assigns: (options[:assignment] || {}).merge(notification: notification, target: notification.target)
65
+ )
66
+ ).to_s
73
67
  break
74
68
  rescue ActionView::MissingTemplate => e
75
69
  missing_template = e