activity_notification 1.4.4 → 2.2.4

Sign up to get free protection for your applications and to get access to all the features.
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