rpush 5.2.0 → 6.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +59 -0
- data/README.md +53 -8
- data/lib/generators/templates/add_adm.rb +1 -1
- data/lib/generators/templates/add_alert_is_json_to_rapns_notifications.rb +2 -2
- data/lib/generators/templates/add_app_to_rapns.rb +2 -2
- data/lib/generators/templates/add_fail_after_to_rpush_notifications.rb +1 -1
- data/lib/generators/templates/add_gcm.rb +11 -25
- data/lib/generators/templates/add_rpush.rb +33 -83
- data/lib/generators/templates/add_wpns.rb +1 -1
- data/lib/generators/templates/create_rapns_apps.rb +1 -1
- data/lib/generators/templates/create_rapns_feedback.rb +3 -9
- data/lib/generators/templates/create_rapns_notifications.rb +3 -9
- data/lib/generators/templates/rename_rapns_to_rpush.rb +9 -33
- data/lib/generators/templates/rpush.rb +1 -4
- data/lib/generators/templates/rpush_2_0_0_updates.rb +5 -17
- data/lib/generators/templates/rpush_2_1_0_updates.rb +1 -1
- data/lib/generators/templates/rpush_2_6_0_updates.rb +1 -1
- data/lib/generators/templates/rpush_2_7_0_updates.rb +1 -1
- data/lib/generators/templates/rpush_3_0_0_updates.rb +1 -1
- data/lib/generators/templates/rpush_3_0_1_updates.rb +1 -1
- data/lib/generators/templates/rpush_3_1_0_add_pushy.rb +1 -1
- data/lib/generators/templates/rpush_3_1_1_updates.rb +1 -1
- data/lib/generators/templates/rpush_3_2_0_add_apns_p8.rb +1 -1
- data/lib/generators/templates/rpush_3_2_4_updates.rb +1 -1
- data/lib/generators/templates/rpush_3_3_0_updates.rb +1 -1
- data/lib/generators/templates/rpush_3_3_1_updates.rb +3 -3
- data/lib/generators/templates/rpush_4_1_0_updates.rb +1 -1
- data/lib/generators/templates/rpush_4_1_1_updates.rb +1 -1
- data/lib/generators/templates/rpush_4_2_0_updates.rb +1 -1
- data/lib/rpush/client/active_model/adm/data_validator.rb +1 -1
- data/lib/rpush/client/active_model/apns/app.rb +1 -17
- data/lib/rpush/client/active_model/apns/device_token_format_validator.rb +2 -2
- data/lib/rpush/client/active_model/apns/notification.rb +4 -0
- data/lib/rpush/client/active_model/apns/notification_payload_size_validator.rb +1 -1
- data/lib/rpush/client/active_model/apns2/app.rb +7 -1
- data/lib/rpush/client/active_model/certificate_private_key_validator.rb +19 -0
- data/lib/rpush/client/active_model/gcm/expiry_collapse_key_mutual_inclusion_validator.rb +1 -1
- data/lib/rpush/client/active_model/payload_data_size_validator.rb +1 -1
- data/lib/rpush/client/active_model/registration_ids_count_validator.rb +1 -1
- data/lib/rpush/client/active_model/webpush/app.rb +41 -0
- data/lib/rpush/client/active_model/webpush/notification.rb +66 -0
- data/lib/rpush/client/active_model.rb +4 -0
- data/lib/rpush/client/active_record/apnsp8/notification.rb +1 -0
- data/lib/rpush/client/active_record/webpush/app.rb +11 -0
- data/lib/rpush/client/active_record/webpush/notification.rb +12 -0
- data/lib/rpush/client/active_record.rb +3 -0
- data/lib/rpush/client/redis/apnsp8/notification.rb +2 -0
- data/lib/rpush/client/redis/webpush/app.rb +15 -0
- data/lib/rpush/client/redis/webpush/notification.rb +15 -0
- data/lib/rpush/client/redis.rb +3 -0
- data/lib/rpush/configuration.rb +1 -1
- data/lib/rpush/daemon/apns2/delivery.rb +8 -1
- data/lib/rpush/daemon/apnsp8/delivery.rb +7 -1
- data/lib/rpush/daemon/string_helpers.rb +1 -1
- data/lib/rpush/daemon/webpush/delivery.rb +114 -0
- data/lib/rpush/daemon/webpush.rb +10 -0
- data/lib/rpush/daemon.rb +3 -0
- data/lib/rpush/version.rb +3 -3
- data/spec/functional/apns2_spec.rb +14 -2
- data/spec/functional/retry_spec.rb +1 -1
- data/spec/functional/webpush_spec.rb +31 -0
- data/spec/spec_helper.rb +3 -1
- data/spec/support/active_record_setup.rb +4 -3
- data/spec/support/config/database.yml +4 -4
- data/spec/support/simplecov_helper.rb +1 -1
- data/spec/unit/client/active_record/apns/notification_spec.rb +1 -1
- data/spec/unit/client/active_record/apns2/app_spec.rb +1 -0
- data/spec/unit/client/active_record/apns2/notification_spec.rb +1 -1
- data/spec/unit/client/active_record/apnsp8/notification_spec.rb +28 -0
- data/spec/unit/client/active_record/webpush/app_spec.rb +6 -0
- data/spec/unit/client/active_record/webpush/notification_spec.rb +6 -0
- data/spec/unit/client/redis/apns/notification_spec.rb +1 -1
- data/spec/unit/client/redis/apns2/notification_spec.rb +1 -1
- data/spec/unit/client/redis/apnsp8/notification_spec.rb +29 -0
- data/spec/unit/client/redis/webpush/app_spec.rb +5 -0
- data/spec/unit/client/redis/webpush/notification_spec.rb +5 -0
- data/spec/unit/client/shared/apns/notification.rb +15 -0
- data/spec/unit/client/shared/webpush/app.rb +33 -0
- data/spec/unit/client/shared/webpush/notification.rb +83 -0
- data/spec/unit/daemon/apnsp8/delivery_spec.rb +53 -0
- data/spec/unit/daemon/pushy/delivery_spec.rb +5 -3
- data/spec/unit/daemon/webpush/delivery_spec.rb +144 -0
- metadata +50 -5
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
class RenameRapnsToRpush < ActiveRecord::
|
|
1
|
+
class RenameRapnsToRpush < ActiveRecord::Migration[5.0]
|
|
2
2
|
module Rpush
|
|
3
3
|
class App < ActiveRecord::Base
|
|
4
4
|
self.table_name = 'rpush_apps'
|
|
@@ -18,24 +18,12 @@ class RenameRapnsToRpush < ActiveRecord::VERSION::MAJOR >= 5 ? ActiveRecord::Mig
|
|
|
18
18
|
rename_table :rapns_apps, :rpush_apps
|
|
19
19
|
rename_table :rapns_feedback, :rpush_feedback
|
|
20
20
|
|
|
21
|
-
if
|
|
22
|
-
|
|
23
|
-
rename_index :rpush_notifications, :index_rapns_notifications_multi, :index_rpush_notifications_multi
|
|
24
|
-
end
|
|
25
|
-
else
|
|
26
|
-
if index_name_exists?(:rpush_notifications, :index_rapns_notifications_multi, true)
|
|
27
|
-
rename_index :rpush_notifications, :index_rapns_notifications_multi, :index_rpush_notifications_multi
|
|
28
|
-
end
|
|
21
|
+
if index_name_exists?(:rpush_notifications, :index_rapns_notifications_multi)
|
|
22
|
+
rename_index :rpush_notifications, :index_rapns_notifications_multi, :index_rpush_notifications_multi
|
|
29
23
|
end
|
|
30
24
|
|
|
31
|
-
if
|
|
32
|
-
|
|
33
|
-
rename_index :rpush_feedback, :index_rapns_feedback_on_device_token, :index_rpush_feedback_on_device_token
|
|
34
|
-
end
|
|
35
|
-
else
|
|
36
|
-
if index_name_exists?(:rpush_feedback, :index_rapns_feedback_on_device_token, true)
|
|
37
|
-
rename_index :rpush_feedback, :index_rapns_feedback_on_device_token, :index_rpush_feedback_on_device_token
|
|
38
|
-
end
|
|
25
|
+
if index_name_exists?(:rpush_feedback, :index_rapns_feedback_on_device_token)
|
|
26
|
+
rename_index :rpush_feedback, :index_rapns_feedback_on_device_token, :index_rpush_feedback_on_device_token
|
|
39
27
|
end
|
|
40
28
|
|
|
41
29
|
update_type(RenameRapnsToRpush::Rpush::Notification, 'Rapns::Apns::Notification', 'Rpush::Apns::Notification')
|
|
@@ -60,24 +48,12 @@ class RenameRapnsToRpush < ActiveRecord::VERSION::MAJOR >= 5 ? ActiveRecord::Mig
|
|
|
60
48
|
update_type(RenameRapnsToRpush::Rpush::App, 'Rpush::Adm::App', 'Rapns::Adm::App')
|
|
61
49
|
update_type(RenameRapnsToRpush::Rpush::App, 'Rpush::Wpns::App', 'Rapns::Wpns::App')
|
|
62
50
|
|
|
63
|
-
if
|
|
64
|
-
|
|
65
|
-
rename_index :rpush_notifications, :index_rpush_notifications_multi, :index_rapns_notifications_multi
|
|
66
|
-
end
|
|
67
|
-
else
|
|
68
|
-
if index_name_exists?(:rpush_notifications, :index_rpush_notifications_multi, true)
|
|
69
|
-
rename_index :rpush_notifications, :index_rpush_notifications_multi, :index_rapns_notifications_multi
|
|
70
|
-
end
|
|
51
|
+
if index_name_exists?(:rpush_notifications, :index_rpush_notifications_multi)
|
|
52
|
+
rename_index :rpush_notifications, :index_rpush_notifications_multi, :index_rapns_notifications_multi
|
|
71
53
|
end
|
|
72
54
|
|
|
73
|
-
if
|
|
74
|
-
|
|
75
|
-
rename_index :rpush_feedback, :index_rpush_feedback_on_device_token, :index_rapns_feedback_on_device_token
|
|
76
|
-
end
|
|
77
|
-
else
|
|
78
|
-
if index_name_exists?(:rpush_feedback, :index_rpush_feedback_on_device_token, true)
|
|
79
|
-
rename_index :rpush_feedback, :index_rpush_feedback_on_device_token, :index_rapns_feedback_on_device_token
|
|
80
|
-
end
|
|
55
|
+
if index_name_exists?(:rpush_feedback, :index_rpush_feedback_on_device_token)
|
|
56
|
+
rename_index :rpush_feedback, :index_rpush_feedback_on_device_token, :index_rapns_feedback_on_device_token
|
|
81
57
|
end
|
|
82
58
|
|
|
83
59
|
rename_table :rpush_notifications, :rapns_notifications
|
|
@@ -46,10 +46,7 @@ Rpush.reflect do |on|
|
|
|
46
46
|
# Called when a notification is queued internally for delivery.
|
|
47
47
|
# The internal queue for each app runner can be inspected:
|
|
48
48
|
#
|
|
49
|
-
# Rpush::Daemon::AppRunner.
|
|
50
|
-
# runner.app
|
|
51
|
-
# runner.queue_size
|
|
52
|
-
# end
|
|
49
|
+
# Rpush::Daemon::AppRunner.status
|
|
53
50
|
#
|
|
54
51
|
# on.notification_enqueued do |notification|
|
|
55
52
|
# end
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
class Rpush200Updates < ActiveRecord::
|
|
1
|
+
class Rpush200Updates < ActiveRecord::Migration[5.0]
|
|
2
2
|
module Rpush
|
|
3
3
|
class App < ActiveRecord::Base
|
|
4
4
|
self.table_name = 'rpush_apps'
|
|
@@ -17,14 +17,8 @@ class Rpush200Updates < ActiveRecord::VERSION::MAJOR >= 5 ? ActiveRecord::Migrat
|
|
|
17
17
|
add_column :rpush_notifications, :processing, :boolean, null: false, default: false
|
|
18
18
|
add_column :rpush_notifications, :priority, :integer, null: true
|
|
19
19
|
|
|
20
|
-
if
|
|
21
|
-
|
|
22
|
-
remove_index :rpush_notifications, name: :index_rpush_notifications_multi
|
|
23
|
-
end
|
|
24
|
-
else
|
|
25
|
-
if index_name_exists?(:rpush_notifications, :index_rpush_notifications_multi, true)
|
|
26
|
-
remove_index :rpush_notifications, name: :index_rpush_notifications_multi
|
|
27
|
-
end
|
|
20
|
+
if index_name_exists?(:rpush_notifications, :index_rpush_notifications_multi)
|
|
21
|
+
remove_index :rpush_notifications, name: :index_rpush_notifications_multi
|
|
28
22
|
end
|
|
29
23
|
|
|
30
24
|
add_index :rpush_notifications, [:delivered, :failed], name: 'index_rpush_notifications_multi', where: 'NOT delivered AND NOT failed'
|
|
@@ -52,14 +46,8 @@ class Rpush200Updates < ActiveRecord::VERSION::MAJOR >= 5 ? ActiveRecord::Migrat
|
|
|
52
46
|
change_column :rpush_feedback, :app_id, :string
|
|
53
47
|
rename_column :rpush_feedback, :app_id, :app
|
|
54
48
|
|
|
55
|
-
if
|
|
56
|
-
|
|
57
|
-
remove_index :rpush_notifications, name: :index_rpush_notifications_multi
|
|
58
|
-
end
|
|
59
|
-
else
|
|
60
|
-
if index_name_exists?(:rpush_notifications, :index_rpush_notifications_multi, true)
|
|
61
|
-
remove_index :rpush_notifications, name: :index_rpush_notifications_multi
|
|
62
|
-
end
|
|
49
|
+
if index_name_exists?(:rpush_notifications, :index_rpush_notifications_multi)
|
|
50
|
+
remove_index :rpush_notifications, name: :index_rpush_notifications_multi
|
|
63
51
|
end
|
|
64
52
|
|
|
65
53
|
add_index :rpush_notifications, [:app_id, :delivered, :failed, :deliver_after], name: 'index_rpush_notifications_multi'
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
class Rpush210Updates < ActiveRecord::
|
|
1
|
+
class Rpush210Updates < ActiveRecord::Migration[5.0]
|
|
2
2
|
def self.up
|
|
3
3
|
add_column :rpush_notifications, :url_args, :text, null: true
|
|
4
4
|
add_column :rpush_notifications, :category, :string, null: true
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
class Rpush270Updates < ActiveRecord::
|
|
1
|
+
class Rpush270Updates < ActiveRecord::Migration[5.0]
|
|
2
2
|
def self.up
|
|
3
3
|
change_column :rpush_notifications, :alert, :text
|
|
4
4
|
add_column :rpush_notifications, :notification, :text
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
class Rpush300Updates < ActiveRecord::
|
|
1
|
+
class Rpush300Updates < ActiveRecord::Migration[5.0]
|
|
2
2
|
def self.up
|
|
3
3
|
add_column :rpush_notifications, :mutable_content, :boolean, default: false
|
|
4
4
|
change_column :rpush_notifications, :sound, :string, default: nil
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
class Rpush301Updates < ActiveRecord::
|
|
1
|
+
class Rpush301Updates < ActiveRecord::Migration[5.0]
|
|
2
2
|
def self.up
|
|
3
3
|
change_column_null :rpush_notifications, :mutable_content, false
|
|
4
4
|
change_column_null :rpush_notifications, :content_available, false
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
class Rpush311Updates < ActiveRecord::
|
|
1
|
+
class Rpush311Updates < ActiveRecord::Migration[5.0]
|
|
2
2
|
def self.up
|
|
3
3
|
change_table :rpush_notifications do |t|
|
|
4
4
|
t.remove_index name: 'index_rpush_notifications_multi'
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
class Rpush320AddApnsP8 < ActiveRecord::
|
|
1
|
+
class Rpush320AddApnsP8 < ActiveRecord::Migration[5.0]
|
|
2
2
|
def self.up
|
|
3
3
|
add_column :rpush_apps, :apn_key, :string, null: true
|
|
4
4
|
add_column :rpush_apps, :apn_key_id, :string, null: true
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
class Rpush331Updates < ActiveRecord::
|
|
1
|
+
class Rpush331Updates < ActiveRecord::Migration[5.0]
|
|
2
2
|
def self.up
|
|
3
3
|
change_column :rpush_notifications, :device_token, :string, null: true
|
|
4
4
|
change_column :rpush_feedback, :device_token, :string, null: true
|
|
5
5
|
end
|
|
6
6
|
|
|
7
7
|
def self.down
|
|
8
|
-
change_column :rpush_notifications, :device_token, :string,
|
|
9
|
-
change_column :rpush_feedback, :device_token, :string,
|
|
8
|
+
change_column :rpush_notifications, :device_token, :string, null: true, limit: 64
|
|
9
|
+
change_column :rpush_feedback, :device_token, :string, null: true, limit: 64
|
|
10
10
|
end
|
|
11
11
|
end
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
class Rpush410Updates < ActiveRecord::
|
|
1
|
+
class Rpush410Updates < ActiveRecord::Migration["#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}"]
|
|
2
2
|
def self.up
|
|
3
3
|
add_column :rpush_notifications, :dry_run, :boolean, null: false, default: false
|
|
4
4
|
end
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
class Rpush411Updates < ActiveRecord::
|
|
1
|
+
class Rpush411Updates < ActiveRecord::Migration["#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}"]
|
|
2
2
|
def self.up
|
|
3
3
|
add_column :rpush_apps, :feedback_enabled, :boolean, default: true
|
|
4
4
|
end
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
class Rpush420Updates < ActiveRecord::
|
|
1
|
+
class Rpush420Updates < ActiveRecord::Migration["#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}"]
|
|
2
2
|
def self.up
|
|
3
3
|
add_column :rpush_notifications, :sound_is_json, :boolean, null: true, default: false
|
|
4
4
|
end
|
|
@@ -5,7 +5,7 @@ module Rpush
|
|
|
5
5
|
class DataValidator < ::ActiveModel::Validator
|
|
6
6
|
def validate(record)
|
|
7
7
|
return unless record.collapse_key.nil? && record.data.nil?
|
|
8
|
-
record.errors
|
|
8
|
+
record.errors.add :data, 'must be set unless collapse_key is specified'
|
|
9
9
|
end
|
|
10
10
|
end
|
|
11
11
|
end
|
|
@@ -7,29 +7,13 @@ module Rpush
|
|
|
7
7
|
base.instance_eval do
|
|
8
8
|
validates :environment, presence: true, inclusion: { in: %w(development production sandbox) }
|
|
9
9
|
validates :certificate, presence: true
|
|
10
|
-
|
|
10
|
+
validates_with Rpush::Client::ActiveModel::CertificatePrivateKeyValidator
|
|
11
11
|
end
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
def service_name
|
|
15
15
|
'apns'
|
|
16
16
|
end
|
|
17
|
-
|
|
18
|
-
private
|
|
19
|
-
|
|
20
|
-
def certificate_has_matching_private_key
|
|
21
|
-
result = false
|
|
22
|
-
if certificate.present?
|
|
23
|
-
begin
|
|
24
|
-
x509 = OpenSSL::X509::Certificate.new(certificate)
|
|
25
|
-
pkey = OpenSSL::PKey::RSA.new(certificate, password)
|
|
26
|
-
result = x509 && pkey
|
|
27
|
-
rescue OpenSSL::OpenSSLError
|
|
28
|
-
errors.add :certificate, 'value must contain a certificate and a private key.'
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
result
|
|
32
|
-
end
|
|
33
17
|
end
|
|
34
18
|
end
|
|
35
19
|
end
|
|
@@ -4,8 +4,8 @@ module Rpush
|
|
|
4
4
|
module Apns
|
|
5
5
|
class DeviceTokenFormatValidator < ::ActiveModel::Validator
|
|
6
6
|
def validate(record)
|
|
7
|
-
return if record.device_token =~
|
|
8
|
-
record.errors
|
|
7
|
+
return if record.device_token =~ /\A[a-z0-9]\w+\z/i
|
|
8
|
+
record.errors.add :device_token, "is invalid"
|
|
9
9
|
end
|
|
10
10
|
end
|
|
11
11
|
end
|
|
@@ -52,6 +52,10 @@ module Rpush
|
|
|
52
52
|
self.data = (data || {}).merge(CONTENT_AVAILABLE_KEY => true)
|
|
53
53
|
end
|
|
54
54
|
|
|
55
|
+
def content_available?
|
|
56
|
+
(self.data || {})[CONTENT_AVAILABLE_KEY]
|
|
57
|
+
end
|
|
58
|
+
|
|
55
59
|
def as_json(options = nil) # rubocop:disable Metrics/AbcSize, Metrics/PerceivedComplexity
|
|
56
60
|
json = ActiveSupport::OrderedHash.new
|
|
57
61
|
|
|
@@ -6,7 +6,7 @@ module Rpush
|
|
|
6
6
|
def validate(record)
|
|
7
7
|
limit = record.class.max_payload_bytesize
|
|
8
8
|
return unless record.payload.bytesize > limit
|
|
9
|
-
record.errors
|
|
9
|
+
record.errors.add :base, "APN notification cannot be larger than #{limit} bytes. Try condensing your alert and device attributes."
|
|
10
10
|
end
|
|
11
11
|
end
|
|
12
12
|
end
|
|
@@ -3,7 +3,13 @@ module Rpush
|
|
|
3
3
|
module ActiveModel
|
|
4
4
|
module Apns2
|
|
5
5
|
module App
|
|
6
|
-
|
|
6
|
+
def self.included(base)
|
|
7
|
+
base.instance_eval do
|
|
8
|
+
validates :environment, presence: true, inclusion: { in: %w(development production sandbox) }
|
|
9
|
+
validates :certificate, presence: true
|
|
10
|
+
validates_with Rpush::Client::ActiveModel::CertificatePrivateKeyValidator
|
|
11
|
+
end
|
|
12
|
+
end
|
|
7
13
|
|
|
8
14
|
def service_name
|
|
9
15
|
'apns2'
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module Rpush
|
|
2
|
+
module Client
|
|
3
|
+
module ActiveModel
|
|
4
|
+
class CertificatePrivateKeyValidator < ::ActiveModel::Validator
|
|
5
|
+
def validate(record)
|
|
6
|
+
if record.certificate.present?
|
|
7
|
+
begin
|
|
8
|
+
x509 = OpenSSL::X509::Certificate.new(record.certificate)
|
|
9
|
+
pkey = OpenSSL::PKey::RSA.new(record.certificate, record.password)
|
|
10
|
+
x509 && pkey
|
|
11
|
+
rescue OpenSSL::OpenSSLError
|
|
12
|
+
record.errors.add :certificate, 'value must contain a certificate and a private key.'
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -5,7 +5,7 @@ module Rpush
|
|
|
5
5
|
class ExpiryCollapseKeyMutualInclusionValidator < ::ActiveModel::Validator
|
|
6
6
|
def validate(record)
|
|
7
7
|
return unless record.collapse_key && !record.expiry
|
|
8
|
-
record.errors
|
|
8
|
+
record.errors.add :expiry, 'must be set when using a collapse_key'
|
|
9
9
|
end
|
|
10
10
|
end
|
|
11
11
|
end
|
|
@@ -5,7 +5,7 @@ module Rpush
|
|
|
5
5
|
def validate(record)
|
|
6
6
|
limit = options[:limit] || 1024
|
|
7
7
|
return unless record.data && record.payload_data_size > limit
|
|
8
|
-
record.errors
|
|
8
|
+
record.errors.add :base, "Notification payload data cannot be larger than #{limit} bytes."
|
|
9
9
|
end
|
|
10
10
|
end
|
|
11
11
|
end
|
|
@@ -5,7 +5,7 @@ module Rpush
|
|
|
5
5
|
def validate(record)
|
|
6
6
|
limit = options[:limit] || 100
|
|
7
7
|
return unless record.registration_ids && record.registration_ids.size > limit
|
|
8
|
-
record.errors
|
|
8
|
+
record.errors.add :base, "Number of registration_ids cannot be larger than #{limit}."
|
|
9
9
|
end
|
|
10
10
|
end
|
|
11
11
|
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
module Rpush
|
|
2
|
+
module Client
|
|
3
|
+
module ActiveModel
|
|
4
|
+
module Webpush
|
|
5
|
+
module App
|
|
6
|
+
|
|
7
|
+
class VapidKeypairValidator < ::ActiveModel::Validator
|
|
8
|
+
def validate(record)
|
|
9
|
+
return if record.vapid_keypair.blank?
|
|
10
|
+
keypair = record.vapid
|
|
11
|
+
%i[ subject public_key private_key ].each do |key|
|
|
12
|
+
unless keypair.key?(key)
|
|
13
|
+
record.errors.add(:vapid_keypair, "must have a #{key} entry")
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
rescue
|
|
17
|
+
record.errors.add(:vapid_keypair, 'must be valid JSON')
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def self.included(base)
|
|
22
|
+
base.class_eval do
|
|
23
|
+
alias_attribute :vapid_keypair, :certificate
|
|
24
|
+
validates :vapid_keypair, presence: true
|
|
25
|
+
validates_with VapidKeypairValidator
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def service_name
|
|
30
|
+
'webpush'
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def vapid
|
|
34
|
+
@vapid ||= JSON.parse(vapid_keypair).symbolize_keys
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
module Rpush
|
|
2
|
+
module Client
|
|
3
|
+
module ActiveModel
|
|
4
|
+
module Webpush
|
|
5
|
+
module Notification
|
|
6
|
+
|
|
7
|
+
class RegistrationValidator < ::ActiveModel::Validator
|
|
8
|
+
KEYS = %i[ endpoint keys ].freeze
|
|
9
|
+
def validate(record)
|
|
10
|
+
return if record.registration_ids.blank?
|
|
11
|
+
return if record.registration_ids.size > 1
|
|
12
|
+
reg = record.registration_ids.first
|
|
13
|
+
unless reg.is_a?(Hash) &&
|
|
14
|
+
(KEYS-reg.keys).empty? &&
|
|
15
|
+
reg[:endpoint].is_a?(String) &&
|
|
16
|
+
reg[:keys].is_a?(Hash)
|
|
17
|
+
record.errors.add(:base, 'Registration must have :endpoint (String) and :keys (Hash) keys')
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def self.included(base)
|
|
23
|
+
base.instance_eval do
|
|
24
|
+
alias_attribute :time_to_live, :expiry
|
|
25
|
+
|
|
26
|
+
validates :registration_ids, presence: true
|
|
27
|
+
validates :data, presence: true
|
|
28
|
+
validates :time_to_live, numericality: { only_integer: true, greater_than: 0 }, allow_nil: true
|
|
29
|
+
|
|
30
|
+
validates_with Rpush::Client::ActiveModel::PayloadDataSizeValidator, limit: 4096
|
|
31
|
+
validates_with Rpush::Client::ActiveModel::RegistrationIdsCountValidator, limit: 1
|
|
32
|
+
validates_with RegistrationValidator
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def data=(value)
|
|
37
|
+
value = value.stringify_keys if value.respond_to?(:stringify_keys)
|
|
38
|
+
super value
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def subscription
|
|
42
|
+
@subscription ||= registration_ids.first.deep_symbolize_keys
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def message
|
|
46
|
+
data['message'].presence if data
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# https://webpush-wg.github.io/webpush-protocol/#urgency
|
|
50
|
+
def urgency
|
|
51
|
+
data['urgency'].presence if data
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def as_json(_options = nil)
|
|
55
|
+
{
|
|
56
|
+
'data' => data,
|
|
57
|
+
'time_to_live' => time_to_live,
|
|
58
|
+
'registration_ids' => registration_ids
|
|
59
|
+
}
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
@@ -3,6 +3,7 @@ require 'active_model'
|
|
|
3
3
|
require 'rpush/client/active_model/notification'
|
|
4
4
|
require 'rpush/client/active_model/payload_data_size_validator'
|
|
5
5
|
require 'rpush/client/active_model/registration_ids_count_validator'
|
|
6
|
+
require 'rpush/client/active_model/certificate_private_key_validator'
|
|
6
7
|
|
|
7
8
|
require 'rpush/client/active_model/apns/device_token_format_validator'
|
|
8
9
|
require 'rpush/client/active_model/apns/app'
|
|
@@ -32,3 +33,6 @@ require 'rpush/client/active_model/wns/notification'
|
|
|
32
33
|
require 'rpush/client/active_model/pushy/app'
|
|
33
34
|
require 'rpush/client/active_model/pushy/notification'
|
|
34
35
|
require 'rpush/client/active_model/pushy/time_to_live_validator'
|
|
36
|
+
|
|
37
|
+
require 'rpush/client/active_model/webpush/app'
|
|
38
|
+
require 'rpush/client/active_model/webpush/notification'
|
|
@@ -32,3 +32,6 @@ require 'rpush/client/active_record/adm/app'
|
|
|
32
32
|
|
|
33
33
|
require 'rpush/client/active_record/pushy/notification'
|
|
34
34
|
require 'rpush/client/active_record/pushy/app'
|
|
35
|
+
|
|
36
|
+
require 'rpush/client/active_record/webpush/notification'
|
|
37
|
+
require 'rpush/client/active_record/webpush/app'
|
|
@@ -3,6 +3,8 @@ module Rpush
|
|
|
3
3
|
module Redis
|
|
4
4
|
module Apnsp8
|
|
5
5
|
class Notification < Rpush::Client::Redis::Notification
|
|
6
|
+
include Rpush::Client::ActiveModel::Apns::Notification
|
|
7
|
+
include Rpush::Client::ActiveModel::Apns2::Notification
|
|
6
8
|
include Rpush::Client::ActiveModel::Apnsp8::Notification
|
|
7
9
|
end
|
|
8
10
|
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
module Rpush
|
|
2
|
+
module Client
|
|
3
|
+
module Redis
|
|
4
|
+
module Webpush
|
|
5
|
+
class Notification < Rpush::Client::Redis::Notification
|
|
6
|
+
include Rpush::Client::ActiveModel::Webpush::Notification
|
|
7
|
+
|
|
8
|
+
def time_to_live=(value)
|
|
9
|
+
self.expiry = value
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
data/lib/rpush/client/redis.rb
CHANGED
|
@@ -44,6 +44,9 @@ require 'rpush/client/redis/wns/badge_notification'
|
|
|
44
44
|
require 'rpush/client/redis/pushy/app'
|
|
45
45
|
require 'rpush/client/redis/pushy/notification'
|
|
46
46
|
|
|
47
|
+
require 'rpush/client/redis/webpush/app'
|
|
48
|
+
require 'rpush/client/redis/webpush/notification'
|
|
49
|
+
|
|
47
50
|
Modis.configure do |config|
|
|
48
51
|
config.namespace = :rpush
|
|
49
52
|
end
|
data/lib/rpush/configuration.rb
CHANGED
|
@@ -106,7 +106,7 @@ module Rpush
|
|
|
106
106
|
client_module = Rpush::Client.const_get(client.to_s.camelize)
|
|
107
107
|
Rpush.send(:include, client_module) unless Rpush.ancestors.include?(client_module)
|
|
108
108
|
|
|
109
|
-
[:Apns, :Gcm, :Wpns, :Wns, :Adm, :Pushy].each do |service|
|
|
109
|
+
[:Apns, :Gcm, :Wpns, :Wns, :Adm, :Pushy, :Webpush].each do |service|
|
|
110
110
|
Rpush.const_set(service, client_module.const_get(service)) unless Rpush.const_defined?(service)
|
|
111
111
|
end
|
|
112
112
|
|
|
@@ -107,7 +107,14 @@ module Rpush
|
|
|
107
107
|
end
|
|
108
108
|
|
|
109
109
|
def prepare_headers(notification)
|
|
110
|
-
|
|
110
|
+
headers = {}
|
|
111
|
+
|
|
112
|
+
headers['apns-expiration'] = '0'
|
|
113
|
+
headers['apns-priority'] = '10'
|
|
114
|
+
headers['apns-topic'] = @app.bundle_id
|
|
115
|
+
headers['apns-push-type'] = 'background' if notification.content_available?
|
|
116
|
+
|
|
117
|
+
headers.merge notification_data(notification)[HTTP2_HEADERS_KEY] || {}
|
|
111
118
|
end
|
|
112
119
|
|
|
113
120
|
def notification_data(notification)
|