sendgrid-ruby 5.3.0 → 6.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (143) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/pr-lint.yml +15 -0
  3. data/.github/workflows/test-and-deploy.yml +120 -0
  4. data/.gitignore +2 -0
  5. data/.rubocop.yml +8 -0
  6. data/.rubocop_todo.yml +127 -0
  7. data/CHANGELOG.md +261 -8
  8. data/CODE_OF_CONDUCT.md +57 -25
  9. data/CONTRIBUTING.md +24 -71
  10. data/Dockerfile +14 -0
  11. data/FIRST_TIMERS.md +53 -0
  12. data/Gemfile +0 -1
  13. data/LICENSE +21 -0
  14. data/Makefile +14 -0
  15. data/PULL_REQUEST_TEMPLATE.md +31 -0
  16. data/README.md +39 -43
  17. data/Rakefile +3 -4
  18. data/TROUBLESHOOTING.md +41 -21
  19. data/UPGRADE.md +5 -0
  20. data/USAGE.md +1231 -1122
  21. data/examples/accesssettings/accesssettings.rb +9 -12
  22. data/examples/alerts/alerts.rb +8 -11
  23. data/examples/apikeys/apikeys.rb +12 -15
  24. data/examples/asm/asm.rb +27 -30
  25. data/examples/browsers/browsers.rb +0 -3
  26. data/examples/campaigns/campaigns.rb +29 -32
  27. data/examples/categories/categories.rb +0 -3
  28. data/examples/clients/clients.rb +1 -4
  29. data/examples/contactdb/contactdb.rb +63 -66
  30. data/examples/dataresidency/setregion.rb +48 -0
  31. data/examples/devices/devices.rb +0 -3
  32. data/examples/emailactivity/emailactivity.rb +52 -0
  33. data/examples/geo/geo.rb +0 -3
  34. data/examples/helpers/eventwebhook/example.rb +16 -0
  35. data/examples/helpers/mail/example.rb +30 -19
  36. data/examples/helpers/settings/example.rb +1 -1
  37. data/examples/helpers/stats/example.rb +4 -4
  38. data/examples/ips/ips.rb +31 -21
  39. data/examples/mail/mail.rb +73 -76
  40. data/examples/mailboxproviders/mailboxproviders.rb +0 -3
  41. data/examples/mailsettings/mailsettings.rb +21 -24
  42. data/examples/partnersettings/partnersettings.rb +3 -6
  43. data/examples/scopes/scopes.rb +49 -5
  44. data/examples/{whitelabel/whitelabel.rb → senderauthentication/senderauthentication.rb} +68 -71
  45. data/examples/senders/senders.rb +28 -31
  46. data/examples/stats/stats.rb +0 -3
  47. data/examples/subusers/subusers.rb +17 -20
  48. data/examples/suppression/suppression.rb +23 -26
  49. data/examples/templates/templates.rb +29 -31
  50. data/examples/trackingsettings/trackingsettings.rb +14 -17
  51. data/examples/user/user.rb +41 -44
  52. data/lib/rack/sendgrid_webhook_verification.rb +55 -0
  53. data/lib/sendgrid/base_interface.rb +57 -0
  54. data/lib/sendgrid/helpers/eventwebhook/eventwebhook.rb +50 -0
  55. data/lib/sendgrid/helpers/inbound/README.md +26 -9
  56. data/lib/sendgrid/helpers/inbound/app.rb +15 -3
  57. data/lib/sendgrid/helpers/inbound/public/index.html +2 -2
  58. data/lib/sendgrid/helpers/inbound/sample_data/default_data.txt +2 -2
  59. data/lib/sendgrid/helpers/inbound/sample_data/raw_data.txt +2 -2
  60. data/lib/sendgrid/helpers/inbound/sample_data/raw_data_with_attachments.txt +2 -2
  61. data/lib/sendgrid/helpers/inbound/send.rb +5 -5
  62. data/lib/sendgrid/helpers/ip_management/ip_management.rb +17 -0
  63. data/lib/sendgrid/helpers/mail/README.md +4 -4
  64. data/lib/sendgrid/helpers/mail/asm.rb +4 -18
  65. data/lib/sendgrid/helpers/mail/attachment.rb +30 -38
  66. data/lib/sendgrid/helpers/mail/bcc_settings.rb +4 -18
  67. data/lib/sendgrid/helpers/mail/bypass_list_management.rb +6 -18
  68. data/lib/sendgrid/helpers/mail/category.rb +2 -12
  69. data/lib/sendgrid/helpers/mail/click_tracking.rb +4 -18
  70. data/lib/sendgrid/helpers/mail/content.rb +4 -18
  71. data/lib/sendgrid/helpers/mail/custom_arg.rb +4 -10
  72. data/lib/sendgrid/helpers/mail/email.rb +10 -20
  73. data/lib/sendgrid/helpers/mail/footer.rb +5 -27
  74. data/lib/sendgrid/helpers/mail/ganalytics.rb +9 -55
  75. data/lib/sendgrid/helpers/mail/header.rb +4 -10
  76. data/lib/sendgrid/helpers/mail/mail.rb +37 -87
  77. data/lib/sendgrid/helpers/mail/mail_settings.rb +7 -25
  78. data/lib/sendgrid/helpers/mail/open_tracking.rb +4 -18
  79. data/lib/sendgrid/helpers/mail/personalization.rb +38 -27
  80. data/lib/sendgrid/helpers/mail/section.rb +4 -10
  81. data/lib/sendgrid/helpers/mail/spam_check.rb +5 -27
  82. data/lib/sendgrid/helpers/mail/subscription_tracking.rb +6 -36
  83. data/lib/sendgrid/helpers/mail/substitution.rb +4 -10
  84. data/lib/sendgrid/helpers/mail/tracking_settings.rb +6 -20
  85. data/lib/sendgrid/helpers/permissions/scope.rb +28 -0
  86. data/lib/sendgrid/helpers/permissions/scopes.yml +309 -0
  87. data/lib/sendgrid/helpers/settings/README.md +3 -3
  88. data/lib/sendgrid/helpers/settings/settings.rb +1 -1
  89. data/lib/sendgrid/helpers/settings/tracking_settings_dto.rb +3 -5
  90. data/lib/sendgrid/helpers/stats/metrics.rb +5 -7
  91. data/lib/sendgrid/helpers/stats/stats_response.rb +1 -3
  92. data/lib/sendgrid/sendgrid.rb +21 -0
  93. data/lib/sendgrid/twilio_email.rb +21 -0
  94. data/lib/sendgrid/version.rb +1 -1
  95. data/lib/sendgrid-ruby.rb +7 -1
  96. data/mail_helper_v3.md +21 -21
  97. data/sendgrid-ruby.gemspec +12 -12
  98. data/spec/fixtures/event_webhook.rb +22 -0
  99. data/spec/rack/sendgrid_webhook_verification_spec.rb +142 -0
  100. data/spec/sendgrid/helpers/eventwebhook/eventwebhook_spec.rb +105 -0
  101. data/spec/sendgrid/helpers/ip_management/ip_management_spec.rb +12 -0
  102. data/spec/sendgrid/helpers/settings/mail_settings_dto_spec.rb +3 -3
  103. data/spec/sendgrid/helpers/settings/partner_settings_dto_spec.rb +3 -3
  104. data/spec/sendgrid/helpers/settings/settings_spec.rb +2 -2
  105. data/spec/sendgrid/helpers/settings/tracking_settings_dto_spec.rb +3 -3
  106. data/spec/sendgrid/helpers/settings/user_settings_dto_spec.rb +3 -3
  107. data/spec/sendgrid/helpers/stats/email_stats_spec.rb +22 -23
  108. data/spec/sendgrid/helpers/stats/metrics_spec.rb +19 -20
  109. data/spec/sendgrid/helpers/stats/stats_response_spec.rb +22 -23
  110. data/spec/sendgrid/sendgrid_spec.rb +11 -0
  111. data/spec/sendgrid/twilio_email_spec.rb +11 -0
  112. data/spec/spec_helper.rb +3 -1
  113. data/static/img/github-fork.png +0 -0
  114. data/static/img/github-sign-up.png +0 -0
  115. data/test/sendgrid/helpers/mail/test_attachment.rb +33 -0
  116. data/test/sendgrid/helpers/mail/test_category.rb +0 -2
  117. data/test/sendgrid/helpers/mail/test_data_residency.rb +44 -0
  118. data/test/sendgrid/helpers/mail/test_email.rb +17 -10
  119. data/test/sendgrid/helpers/mail/test_mail.rb +126 -119
  120. data/test/sendgrid/helpers/mail/test_personalizations.rb +145 -92
  121. data/test/sendgrid/permissions/test_scopes.rb +36 -0
  122. data/test/sendgrid/test_sendgrid-ruby.rb +1961 -1979
  123. data/twilio_sendgrid_logo.png +0 -0
  124. data/use-cases/README.md +17 -0
  125. data/use-cases/domain-authentication.md +5 -0
  126. data/use-cases/email-statistics.md +52 -0
  127. data/use-cases/legacy-templates.md +98 -0
  128. data/use-cases/personalizations.md +34 -0
  129. data/use-cases/sms.md +39 -0
  130. data/use-cases/transactional-templates.md +111 -0
  131. data/use-cases/twilio-email.md +13 -0
  132. data/use-cases/twilio-setup.md +54 -0
  133. metadata +99 -45
  134. data/.codeclimate.yml +0 -21
  135. data/.github/ISSUE_TEMPLATE +0 -17
  136. data/.github/PULL_REQUEST_TEMPLATE +0 -24
  137. data/.travis.yml +0 -29
  138. data/LICENSE.txt +0 -22
  139. data/USE_CASES.md +0 -147
  140. data/docker/Dockerfile +0 -12
  141. data/docker/README.md +0 -30
  142. data/lib/sendgrid/client.rb +0 -35
  143. data/test/prism.sh +0 -42
data/mail_helper_v3.md CHANGED
@@ -2,18 +2,18 @@ Hello!
2
2
 
3
3
  It is now time to implement the final piece of our v2 to v3 migration. Before we dig into writing the code, we would love to get feedback on the following proposed interfaces.
4
4
 
5
- We are starting with the use cases below for the first iteration. (we have completed this work on [our C# library](https://github.com/sendgrid/sendgrid-csharp/blob/master/USE_CASES.md), you can check that out for a sneak peek of where we are heading).
5
+ We are starting with the use cases below for the first iteration. (we have completed this work on [our C# library](https://github.com/sendgrid/sendgrid-csharp/blob/HEAD/USE_CASES.md), you can check that out for a sneak peek of where we are heading).
6
6
 
7
7
  # Send a Single Email to a Single Recipient
8
8
 
9
- The following code assumes you are storing the API key in an [environment variable (recommended)](https://github.com/sendgrid/sendgrid-ruby/blob/master/TROUBLESHOOTING.md#environment-variables-and-your-sendgrid-api-key). If you don't have your key stored in an environment variable, you can assign it directly to `api_key` for testing purposes.
9
+ The following code assumes you are storing the API key in an [environment variable (recommended)](TROUBLESHOOTING.md#environment-variables-and-your-sendgrid-api-key). If you don't have your key stored in an environment variable, you can assign it directly to `api_key` for testing purposes.
10
10
 
11
11
  ```ruby
12
12
  require 'sendgrid-ruby'
13
13
 
14
14
  from = SendGrid::Email.new('test@example.com', 'Example User')
15
15
  to = SendGrid::Email.new('test@example.com', 'Example User')
16
- subject = 'Sending with SendGrid is Fun'
16
+ subject = 'Sending with Twilio SendGrid is Fun'
17
17
  plain_text_content = 'and easy to do anywhere, even with Ruby'
18
18
  html_content = '<strong>and easy to do anywhere, even with Ruby</strong>'
19
19
  msg = SendGrid::Mail.create(from: from,
@@ -37,7 +37,7 @@ puts response.headers
37
37
 
38
38
  # Send a Single Email to Multiple Recipients
39
39
 
40
- The following code assumes you are storing the API key in an [environment variable (recommended)](https://github.com/sendgrid/sendgrid-ruby/blob/master/TROUBLESHOOTING.md#environment-variables-and-your-sendgrid-api-key). If you don't have your key stored in an environment variable, you can assign it directly to `api_key` for testing purposes.
40
+ The following code assumes you are storing the API key in an [environment variable (recommended)](TROUBLESHOOTING.md#environment-variables-and-your-sendgrid-api-key). If you don't have your key stored in an environment variable, you can assign it directly to `api_key` for testing purposes.
41
41
 
42
42
  ```ruby
43
43
  require 'sendgrid-ruby'
@@ -48,7 +48,7 @@ tos = [
48
48
  SendGrid::Email.new('test2@example.com', 'Example User2'),
49
49
  SendGrid::Email.new('test3@example.com', 'Example User3')
50
50
  ];
51
- subject = 'Sending with SendGrid is Fun'
51
+ subject = 'Sending with Twilio SendGrid is Fun'
52
52
  plain_text_content = 'and easy to do anywhere, even with Ruby'
53
53
  html_content = '<strong>and easy to do anywhere, even with Ruby</strong>'
54
54
  msg = SendGrid::Mail.create(from: from,
@@ -72,7 +72,7 @@ puts response.headers
72
72
 
73
73
  # Send Multiple Emails to Multiple Recipients
74
74
 
75
- The following code assumes you are storing the API key in an [environment variable (recommended)](https://github.com/sendgrid/sendgrid-ruby/blob/master/TROUBLESHOOTING.md#environment-variables-and-your-sendgrid-api-key). If you don't have your key stored in an environment variable, you can assign it directly to `api_key` for testing purposes.
75
+ The following code assumes you are storing the API key in an [environment variable (recommended)](TROUBLESHOOTING.md#environment-variables-and-your-sendgrid-api-key). If you don't have your key stored in an environment variable, you can assign it directly to `api_key` for testing purposes.
76
76
 
77
77
  ```ruby
78
78
  require 'sendgrid-ruby'
@@ -84,9 +84,9 @@ tos = [
84
84
  SendGrid::Email.new('test3@example.com', 'Example User3')
85
85
  ];
86
86
  subjects = [
87
- 'Sending with SendGrid is Fun',
88
- 'Sending with SendGrid is Super Fun',
89
- 'Sending with SendGrid is Super Duper Fun'
87
+ 'Sending with Twilio SendGrid is Fun',
88
+ 'Sending with Twilio SendGrid is Super Fun',
89
+ 'Sending with Twilio SendGrid is Super Duper Fun'
90
90
  ];
91
91
  plain_text_content = 'and easy to do anywhere, even with Ruby'
92
92
  html_content = '<strong>and easy to do anywhere, even with Ruby</strong>'
@@ -119,14 +119,14 @@ puts response.headers
119
119
 
120
120
  # Kitchen Sink - an example with all settings used
121
121
 
122
- The following code assumes you are storing the API key in an [environment variable (recommended)](https://github.com/sendgrid/sendgrid-ruby/blob/master/TROUBLESHOOTING.md#environment-variables-and-your-sendgrid-api-key). If you don't have your key stored in an environment variable, you can assign it directly to `api_key` for testing purposes.
122
+ The following code assumes you are storing the API key in an [environment variable (recommended)](TROUBLESHOOTING.md#environment-variables-and-your-sendgrid-api-key). If you don't have your key stored in an environment variable, you can assign it directly to `api_key` for testing purposes.
123
123
 
124
124
  ```ruby
125
125
  client = SendGrid::Client.new(api_key: ENV['SENDGRID_API_KEY'])
126
126
 
127
127
  from = SendGrid::Email.new('test@example.com', 'Example User')
128
128
  to = SendGrid::Email.new('test@example.com', 'Example User')
129
- subject = 'Sending with SendGrid is Fun'
129
+ subject = 'Sending with Twilio SendGrid is Fun'
130
130
  plain_text_content = 'and easy to do anywhere, even with Ruby'
131
131
  html_content = '<strong>and easy to do anywhere, even with Ruby</strong>'
132
132
  msg = SendGrid::Message.new(from, to, subject, plain_text_content, html_content)
@@ -233,11 +233,11 @@ msg.set_send_at(1461775052, 1)
233
233
 
234
234
  msg.set_subject('this subject overrides the Global Subject on the second Personalization', 1)
235
235
 
236
- # The values below this comment are global to entire message
236
+ # The values below this comment are global to the entire message
237
237
 
238
238
  msg.set_from(SendGrid::Email.new('test0@example.com', 'Example User0'))
239
239
 
240
- msg.set_global_subject('Sending with SendGrid is Fun');
240
+ msg.set_global_subject('Sending with Twilio SendGrid is Fun');
241
241
 
242
242
  msg.add_content(MimeType::Text, 'and easy to do anywhere, even with Ruby')
243
243
  msg.add_content(MimeType::Html, '<strong>and easy to do anywhere, even with Ruby</strong>')
@@ -263,7 +263,7 @@ attachments = [
263
263
  'base64 encoded content',
264
264
  'image/png',
265
265
  'inline',
266
- 'Banner 2'),
266
+ 'Banner 2'),
267
267
  ]
268
268
  msg.add_attachments(attachments)
269
269
 
@@ -279,7 +279,7 @@ msg.set_global_headers(global_headers)
279
279
  msg.add_section('%section1%', 'Substitution for Section 1 Tag')
280
280
  sections = [
281
281
  '%section2%' => 'Substitution for Section 2 Tag',
282
- '%section3%' => 'Substitution for Section 3 Tag'
282
+ '%section3%' => 'Substitution for Section 3 Tag'
283
283
  ]
284
284
  msg.add_sections(sections)
285
285
 
@@ -295,14 +295,14 @@ puts response.headers
295
295
 
296
296
  # Attachments
297
297
 
298
- The following code assumes you are storing the API key in an [environment variable (recommended)](https://github.com/sendgrid/sendgrid-ruby/blob/master/TROUBLESHOOTING.md#environment-variables-and-your-sendgrid-api-key). If you don't have your key stored in an environment variable, you can assign it directly to `api_key` for testing purposes.
298
+ The following code assumes you are storing the API key in an [environment variable (recommended)](TROUBLESHOOTING.md#environment-variables-and-your-sendgrid-api-key). If you don't have your key stored in an environment variable, you can assign it directly to `api_key` for testing purposes.
299
299
 
300
300
  ```ruby
301
301
  client = SendGrid::Client.new(api_key: ENV['SENDGRID_API_KEY'])
302
302
 
303
303
  from = SendGrid::Email.new('test@example.com', 'Example User')
304
304
  to = SendGrid::Email.new('test@example.com', 'Example User')
305
- subject = 'Sending with SendGrid is Fun'
305
+ subject = 'Sending with Twilio SendGrid is Fun'
306
306
  plain_text_content = 'and easy to do anywhere, even with Ruby'
307
307
  html_content = '<strong>and easy to do anywhere, even with Ruby</strong>'
308
308
  msg = SendGrid::Message.new(from, to, subject, plain_text_content, html_content)
@@ -326,9 +326,9 @@ puts response.headers
326
326
 
327
327
  # Transactional Templates
328
328
 
329
- The following code assumes you are storing the API key in an [environment variable (recommended)](https://github.com/sendgrid/sendgrid-ruby/blob/master/TROUBLESHOOTING.md#environment-variables-and-your-sendgrid-api-key). If you don't have your key stored in an environment variable, you can assign it directly to `api_key` for testing purposes.
329
+ The following code assumes you are storing the API key in an [environment variable (recommended)](TROUBLESHOOTING.md#environment-variables-and-your-sendgrid-api-key). If you don't have your key stored in an environment variable, you can assign it directly to `api_key` for testing purposes.
330
330
 
331
- For this example, we assume you have created a [transactional template](https://sendgrid.com/docs/User_Guide/Transactional_Templates/index.html). Following is the template content we used for testing.
331
+ For this example, we assume you have created a [legacy transactional template](https://sendgrid.com/docs/User_Guide/Transactional_Templates/index.html) in the UI or via the API. Following is the template content we used for testing.
332
332
 
333
333
  Template ID (replace with your own):
334
334
 
@@ -347,7 +347,7 @@ Template Body:
347
347
  ```html
348
348
  <html>
349
349
  <head>
350
- <title></title>
350
+ <title></title>
351
351
  </head>
352
352
  <body>
353
353
  Hello -name-,
@@ -367,7 +367,7 @@ client = SendGrid::Client.new(api_key: ENV['SENDGRID_API_KEY'])
367
367
 
368
368
  from = SendGrid::Email.new('test@example.com', 'Example User')
369
369
  to = SendGrid::Email.new('test@example.com', 'Example User')
370
- subject = 'Sending with SendGrid is Fun'
370
+ subject = 'Sending with Twilio SendGrid is Fun'
371
371
  plain_text_content = 'and easy to do anywhere, even with Ruby'
372
372
  html_content = '<strong>and easy to do anywhere, even with Ruby</strong>'
373
373
  msg = SendGrid::Message.new(from, to, subject, plain_text_content, html_content)
@@ -1,5 +1,4 @@
1
- # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
1
+ lib = File.expand_path('lib', __dir__)
3
2
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
3
  require 'sendgrid/version'
5
4
 
@@ -7,24 +6,25 @@ Gem::Specification.new do |spec|
7
6
  spec.name = 'sendgrid-ruby'
8
7
  spec.version = SendGrid::VERSION
9
8
  spec.authors = ['Elmer Thomas', 'Robin Johnson', 'Eddie Zaneski']
10
- spec.email = 'dx@sendgrid.com'
11
- spec.summary = 'Official SendGrid Gem'
12
- spec.description = 'Official SendGrid Gem to Interact with SendGrids API in native Ruby'
9
+ spec.email = 'help@twilio.com'
10
+ spec.summary = 'Official Twilio SendGrid Gem'
11
+ spec.description = 'Official Twilio SendGrid Gem to Interact with Twilio SendGrids API in native Ruby'
13
12
  spec.homepage = 'http://github.com/sendgrid/sendgrid-ruby'
14
13
 
15
14
  spec.required_ruby_version = '>= 2.2'
16
15
 
17
- spec.license = 'MIT'
16
+ spec.license = 'MIT'
18
17
  spec.files = `git ls-files -z`.split("\x0")
19
18
  spec.executables = spec.files.grep(/^bin/) { |f| File.basename(f) }
20
19
  spec.test_files = spec.files.grep(/^(test|spec|features)/)
21
20
  spec.require_paths = ['lib']
22
- spec.add_dependency 'ruby_http_client', '~> 3.3.0'
23
- spec.add_dependency 'sinatra', '>= 1.4.7', '< 3'
24
- spec.add_development_dependency 'rake', '~> 0'
25
- spec.add_development_dependency 'rspec'
26
- spec.add_development_dependency 'pry'
21
+ spec.add_dependency 'ruby_http_client', '~> 3.4'
27
22
  spec.add_development_dependency 'faker'
28
- spec.add_development_dependency 'rubocop'
29
23
  spec.add_development_dependency 'minitest', '~> 5.9'
24
+ spec.add_development_dependency 'pry'
25
+ spec.add_development_dependency 'rack'
26
+ spec.add_development_dependency 'rake', '~> 13.0'
27
+ spec.add_development_dependency 'rspec'
28
+ spec.add_development_dependency 'simplecov', '~> 0.18.5'
29
+ spec.add_development_dependency 'sinatra', '>= 1.4.7', '< 3'
30
30
  end
@@ -0,0 +1,22 @@
1
+ require "json"
2
+
3
+ module Fixtures
4
+ module EventWebhook
5
+ PUBLIC_KEY = 'MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE83T4O/n84iotIvIW4mdBgQ/7dAfSmpqIM8kF9mN1flpVKS3GRqe62gw+2fNNRaINXvVpiglSI8eNEc6wEA3F+g=='.freeze
6
+ FAILING_PUBLIC_KEY = 'MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEqTxd43gyp8IOEto2LdIfjRQrIbsd4SXZkLW6jDutdhXSJCWHw8REntlo7aNDthvj+y7GjUuFDb/R1NGe1OPzpA=='.freeze
7
+ SIGNATURE = 'MEUCIGHQVtGj+Y3LkG9fLcxf3qfI10QysgDWmMOVmxG0u6ZUAiEAyBiXDWzM+uOe5W0JuG+luQAbPIqHh89M15TluLtEZtM='.freeze
8
+ FAILING_SIGNATURE = 'MEUCIQCtIHJeH93Y+qpYeWrySphQgpNGNr/U+UyUlBkU6n7RAwIgJTz2C+8a8xonZGi6BpSzoQsbVRamr2nlxFDWYNH3j/0='.freeze
9
+ TIMESTAMP = '1600112502'.freeze
10
+ PAYLOAD = "#{[
11
+ {
12
+ email: 'hello@world.com',
13
+ event: 'dropped',
14
+ reason: 'Bounced Address',
15
+ sg_event_id: 'ZHJvcC0xMDk5NDkxOS1MUnpYbF9OSFN0T0doUTRrb2ZTbV9BLTA',
16
+ sg_message_id: 'LRzXl_NHStOGhQ4kofSm_A.filterdrecv-p3mdw1-756b745b58-kmzbl-18-5F5FC76C-9.0',
17
+ 'smtp-id': '<LRzXl_NHStOGhQ4kofSm_A@ismtpd0039p1iad1.sendgrid.net>',
18
+ timestamp: 1_600_112_492
19
+ }
20
+ ].to_json}\r\n".freeze # Be sure to include the trailing carriage return and newline!
21
+ end
22
+ end
@@ -0,0 +1,142 @@
1
+ require 'spec_helper'
2
+ require 'rack/mock'
3
+ require './spec/fixtures/event_webhook'
4
+
5
+ unless RUBY_PLATFORM == 'java'
6
+ describe Rack::SendGridWebhookVerification do
7
+ let(:public_key) { Fixtures::EventWebhook::PUBLIC_KEY }
8
+ before do
9
+ @app = ->(_env) { [200, { 'Content-Type' => 'text/plain' }, ['Hello']] }
10
+ end
11
+
12
+ describe 'new' do
13
+ it 'should initialize with an app, public key and a path' do
14
+ expect do
15
+ Rack::SendGridWebhookVerification.new(@app, 'ABC', %r{/email})
16
+ end.not_to raise_error
17
+ end
18
+
19
+ it 'should initialize with an app, public key and paths' do
20
+ expect do
21
+ Rack::SendGridWebhookVerification.new(@app, 'ABC', %r{/email}, %r{/event})
22
+ end.not_to raise_error
23
+ end
24
+ end
25
+
26
+ describe 'calling against one path' do
27
+ let(:middleware) { Rack::SendGridWebhookVerification.new(@app, public_key, %r{/email}) }
28
+
29
+ it "should not intercept when the path doesn't match" do
30
+ expect(SendGrid::EventWebhook).to_not receive(:new)
31
+ request = Rack::MockRequest.env_for('/login')
32
+ status, headers, body = middleware.call(request)
33
+ expect(status).to eq(200)
34
+ end
35
+
36
+ it 'should allow a request through if it is verified' do
37
+ options = {
38
+ :input => Fixtures::EventWebhook::PAYLOAD,
39
+ 'Content-Type' => "application/json"
40
+ }
41
+ options[SendGrid::EventWebhookHeader::SIGNATURE] = Fixtures::EventWebhook::SIGNATURE
42
+ options[SendGrid::EventWebhookHeader::TIMESTAMP] = Fixtures::EventWebhook::TIMESTAMP
43
+ request = Rack::MockRequest.env_for('/email', options)
44
+ status, headers, body = middleware.call(request)
45
+ expect(status).to eq(200)
46
+ end
47
+
48
+ it 'should short circuit a request to 403 if there is no signature or timestamp' do
49
+ options = {
50
+ :input => Fixtures::EventWebhook::PAYLOAD,
51
+ 'Content-Type' => "application/json"
52
+ }
53
+ request = Rack::MockRequest.env_for('/email', options)
54
+ status, headers, body = middleware.call(request)
55
+ expect(status).to eq(403)
56
+ end
57
+
58
+ it 'should short circuit a request to 403 if the signature is incorrect' do
59
+ options = {
60
+ :input => Fixtures::EventWebhook::PAYLOAD,
61
+ 'Content-Type' => "application/json"
62
+ }
63
+ options[SendGrid::EventWebhookHeader::SIGNATURE] = Fixtures::EventWebhook::FAILING_SIGNATURE
64
+ options[SendGrid::EventWebhookHeader::TIMESTAMP] = Fixtures::EventWebhook::TIMESTAMP
65
+ request = Rack::MockRequest.env_for('/email', options)
66
+ status, headers, body = middleware.call(request)
67
+ expect(status).to eq(403)
68
+ end
69
+
70
+ it 'should short circuit a request to 403 if the payload is incorrect' do
71
+ options = {
72
+ :input => 'payload',
73
+ 'Content-Type' => "application/json"
74
+ }
75
+ options[SendGrid::EventWebhookHeader::SIGNATURE] = Fixtures::EventWebhook::SIGNATURE
76
+ options[SendGrid::EventWebhookHeader::TIMESTAMP] = Fixtures::EventWebhook::TIMESTAMP
77
+ request = Rack::MockRequest.env_for('/email', options)
78
+ status, headers, body = middleware.call(request)
79
+ expect(status).to eq(403)
80
+ end
81
+ end
82
+
83
+ describe 'calling with multiple paths' do
84
+ let(:middleware) { Rack::SendGridWebhookVerification.new(@app, public_key, %r{/email}, %r{/events}) }
85
+
86
+ it "should not intercept when the path doesn't match" do
87
+ expect(SendGrid::EventWebhook).to_not receive(:new)
88
+ request = Rack::MockRequest.env_for('/sms_events')
89
+ status, headers, body = middleware.call(request)
90
+ expect(status).to eq(200)
91
+ end
92
+
93
+ it 'should allow a request through if it is verified' do
94
+ options = {
95
+ :input => Fixtures::EventWebhook::PAYLOAD,
96
+ 'Content-Type' => "application/json"
97
+ }
98
+ options[SendGrid::EventWebhookHeader::SIGNATURE] = Fixtures::EventWebhook::SIGNATURE
99
+ options[SendGrid::EventWebhookHeader::TIMESTAMP] = Fixtures::EventWebhook::TIMESTAMP
100
+ request = Rack::MockRequest.env_for('/events', options)
101
+ status, headers, body = middleware.call(request)
102
+ expect(status).to eq(200)
103
+ end
104
+
105
+ it 'should short circuit a request to 403 if there is no signature or timestamp' do
106
+ options = {
107
+ :input => Fixtures::EventWebhook::PAYLOAD,
108
+ 'Content-Type' => "application/json"
109
+ }
110
+ request = Rack::MockRequest.env_for('/events', options)
111
+ status, headers, body = middleware.call(request)
112
+ expect(status).to eq(403)
113
+ end
114
+ end
115
+
116
+ describe 'request body which passed to an app' do
117
+ before do
118
+ @payload = nil
119
+ @spy_app = lambda do |env|
120
+ @payload = Rack::Request.new(env).body
121
+ [200, { 'Content-Type' => 'text/plain' }, ['Hello']]
122
+ end
123
+ end
124
+
125
+ let(:middleware) { Rack::SendGridWebhookVerification.new(@spy_app, public_key, %r{/email}) }
126
+
127
+ it 'keeps orignal reading position' do
128
+ options = {
129
+ :input => Fixtures::EventWebhook::PAYLOAD,
130
+ 'Content-Type' => "application/json"
131
+ }
132
+ options[SendGrid::EventWebhookHeader::SIGNATURE] = Fixtures::EventWebhook::SIGNATURE
133
+ options[SendGrid::EventWebhookHeader::TIMESTAMP] = Fixtures::EventWebhook::TIMESTAMP
134
+ request = Rack::MockRequest.env_for('/email', options)
135
+ status, headers, body = middleware.call(request)
136
+ expect(status).to eq(200)
137
+ expect(@payload).not_to be_nil
138
+ expect(@payload.pos).to be_zero
139
+ end
140
+ end
141
+ end
142
+ end
@@ -0,0 +1,105 @@
1
+ require 'spec_helper'
2
+ require './spec/fixtures/event_webhook'
3
+
4
+ describe SendGrid::EventWebhook do
5
+ describe '.verify_signature' do
6
+ it 'verifies a valid signature' do
7
+ unless skip_jruby
8
+ expect(verify(
9
+ Fixtures::EventWebhook::PUBLIC_KEY,
10
+ Fixtures::EventWebhook::PAYLOAD,
11
+ Fixtures::EventWebhook::SIGNATURE,
12
+ Fixtures::EventWebhook::TIMESTAMP
13
+ )).to be true
14
+ end
15
+ end
16
+
17
+ it 'rejects a bad key' do
18
+ unless skip_jruby
19
+ expect(verify(
20
+ Fixtures::EventWebhook::FAILING_PUBLIC_KEY,
21
+ Fixtures::EventWebhook::PAYLOAD,
22
+ Fixtures::EventWebhook::SIGNATURE,
23
+ Fixtures::EventWebhook::TIMESTAMP
24
+ )).to be false
25
+ end
26
+ end
27
+
28
+ it 'rejects a bad payload' do
29
+ unless skip_jruby
30
+ expect(verify(
31
+ Fixtures::EventWebhook::PUBLIC_KEY,
32
+ 'payload',
33
+ Fixtures::EventWebhook::SIGNATURE,
34
+ Fixtures::EventWebhook::TIMESTAMP
35
+ )).to be false
36
+ end
37
+ end
38
+
39
+ it 'rejects a bad signature' do
40
+ unless skip_jruby
41
+ expect(verify(
42
+ Fixtures::EventWebhook::PUBLIC_KEY,
43
+ Fixtures::EventWebhook::PAYLOAD,
44
+ Fixtures::EventWebhook::FAILING_SIGNATURE,
45
+ Fixtures::EventWebhook::TIMESTAMP
46
+ )).to be false
47
+ end
48
+ end
49
+
50
+ it 'rejects a bad timestamp' do
51
+ unless skip_jruby
52
+ expect(verify(
53
+ Fixtures::EventWebhook::PUBLIC_KEY,
54
+ Fixtures::EventWebhook::PAYLOAD,
55
+ Fixtures::EventWebhook::SIGNATURE,
56
+ 'timestamp'
57
+ )).to be false
58
+ end
59
+ end
60
+
61
+ it 'rejects a missing signature' do
62
+ unless skip_jruby
63
+ expect(verify(
64
+ Fixtures::EventWebhook::PUBLIC_KEY,
65
+ Fixtures::EventWebhook::PAYLOAD,
66
+ nil,
67
+ Fixtures::EventWebhook::TIMESTAMP
68
+ )).to be false
69
+ end
70
+ end
71
+
72
+ it 'throws an error when using jruby' do
73
+ if skip_jruby
74
+ expect do
75
+ verify(
76
+ Fixtures::EventWebhook::PUBLIC_KEY,
77
+ Fixtures::EventWebhook::PAYLOAD,
78
+ Fixtures::EventWebhook::SIGNATURE,
79
+ Fixtures::EventWebhook::TIMESTAMP
80
+ )
81
+ end.to raise_error(SendGrid::EventWebhook::NotSupportedError)
82
+ end
83
+ end
84
+ end
85
+ end
86
+
87
+ describe SendGrid::EventWebhookHeader do
88
+ it 'sets the signature header constant' do
89
+ expect(SendGrid::EventWebhookHeader::SIGNATURE).to eq("HTTP_X_TWILIO_EMAIL_EVENT_WEBHOOK_SIGNATURE")
90
+ end
91
+
92
+ it 'sets the timestamp header constant' do
93
+ expect(SendGrid::EventWebhookHeader::TIMESTAMP).to eq("HTTP_X_TWILIO_EMAIL_EVENT_WEBHOOK_TIMESTAMP")
94
+ end
95
+ end
96
+
97
+ def verify(public_key, payload, signature, timestamp)
98
+ ew = SendGrid::EventWebhook.new
99
+ ec_public_key = ew.convert_public_key_to_ecdsa(public_key)
100
+ ew.verify_signature(ec_public_key, payload, signature, timestamp)
101
+ end
102
+
103
+ def skip_jruby
104
+ RUBY_PLATFORM == 'java'
105
+ end
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+
3
+ describe SendGrid::IpManagement do
4
+ let(:sendgrid_client) { SendGrid::API.new(api_key: 'fake_key').client }
5
+ let(:ip_management) { SendGrid::IpManagement.new(sendgrid_client: sendgrid_client) }
6
+
7
+ describe '.new' do
8
+ it 'initializes correctly' do
9
+ expect(ip_management).to be_a SendGrid::IpManagement
10
+ end
11
+ end
12
+ end
@@ -4,7 +4,7 @@ describe SendGrid::MailSettingsDto do
4
4
  let(:sendgrid_client) { SendGrid::API.new(api_key: 'fake_key').client }
5
5
  let(:mail_settings) { SendGrid::MailSettingsDto }
6
6
  let(:setting_name) { 'bcc' }
7
- let(:setting_params) { {email: Faker::Internet.email, enabled: rand(1..100).even?} }
7
+ let(:setting_params) { { email: Faker::Internet.email, enabled: rand(1..100).even? } }
8
8
 
9
9
  it { should respond_to :bcc }
10
10
  it { should respond_to :address_whitelist }
@@ -19,14 +19,14 @@ describe SendGrid::MailSettingsDto do
19
19
  describe '.fetch' do
20
20
  it 'calls get on sendgrid_client' do
21
21
  args = { sendgrid_client: sendgrid_client, name: setting_name, query_params: {} }
22
- expect(mail_settings.fetch(args)).to be_a SendGrid::Response
22
+ expect(mail_settings.fetch(**args)).to be_a SendGrid::Response
23
23
  end
24
24
  end
25
25
 
26
26
  describe '.update' do
27
27
  it 'calls patch on sendgrid_client' do
28
28
  args = { sendgrid_client: sendgrid_client, name: setting_name, request_body: setting_params }
29
- expect(mail_settings.update(args)).to be_a SendGrid::Response
29
+ expect(mail_settings.update(**args)).to be_a SendGrid::Response
30
30
  end
31
31
  end
32
32
  end
@@ -4,21 +4,21 @@ describe SendGrid::PartnerSettingsDto do
4
4
  let(:sendgrid_client) { SendGrid::API.new(api_key: 'fake_key').client }
5
5
  let(:partner_settings) { SendGrid::PartnerSettingsDto }
6
6
  let(:setting_name) { 'new_relic' }
7
- let(:setting_params) { {license_key: 'key', enabled: rand(1..100).even?} }
7
+ let(:setting_params) { { license_key: 'key', enabled: rand(1..100).even? } }
8
8
 
9
9
  it { should respond_to :new_relic }
10
10
 
11
11
  describe '.fetch' do
12
12
  it 'calls get on sendgrid_client' do
13
13
  args = { sendgrid_client: sendgrid_client, name: setting_name, query_params: {} }
14
- expect(partner_settings.fetch(args)).to be_a SendGrid::Response
14
+ expect(partner_settings.fetch(**args)).to be_a SendGrid::Response
15
15
  end
16
16
  end
17
17
 
18
18
  describe '.update' do
19
19
  it 'calls patch on sendgrid_client' do
20
20
  args = { sendgrid_client: sendgrid_client, name: setting_name, request_body: setting_params }
21
- expect(partner_settings.update(args)).to be_a SendGrid::Response
21
+ expect(partner_settings.update(**args)).to be_a SendGrid::Response
22
22
  end
23
23
  end
24
24
  end
@@ -18,8 +18,8 @@ describe SendGrid::Settings do
18
18
 
19
19
  describe '.update_bcc' do
20
20
  it 'updates bcc' do
21
- bcc_response = settings.update_bcc(enabled: true, email: "email@example.com")
21
+ bcc_response = settings.update_bcc(enabled: true, email: 'email@example.com')
22
22
  expect(bcc_response).to be_a SendGrid::Response
23
23
  end
24
24
  end
25
- end
25
+ end
@@ -4,7 +4,7 @@ describe SendGrid::TrackingSettingsDto do
4
4
  let(:sendgrid_client) { SendGrid::API.new(api_key: 'fake_key').client }
5
5
  let(:tracking_settings) { SendGrid::TrackingSettingsDto }
6
6
  let(:setting_name) { 'open_tracking' }
7
- let(:setting_params) { {enabled: rand(1..100).even?} }
7
+ let(:setting_params) { { enabled: rand(1..100).even? } }
8
8
 
9
9
  it { should respond_to :open_tracking }
10
10
  it { should respond_to :click_tracking }
@@ -14,14 +14,14 @@ describe SendGrid::TrackingSettingsDto do
14
14
  describe '.fetch' do
15
15
  it 'calls get on sendgrid_client' do
16
16
  args = { sendgrid_client: sendgrid_client, name: setting_name, query_params: {} }
17
- expect(tracking_settings.fetch(args)).to be_a SendGrid::Response
17
+ expect(tracking_settings.fetch(**args)).to be_a SendGrid::Response
18
18
  end
19
19
  end
20
20
 
21
21
  describe '.update' do
22
22
  it 'calls patch on sendgrid_client' do
23
23
  args = { sendgrid_client: sendgrid_client, name: setting_name, request_body: setting_params }
24
- expect(tracking_settings.update(args)).to be_a SendGrid::Response
24
+ expect(tracking_settings.update(**args)).to be_a SendGrid::Response
25
25
  end
26
26
  end
27
27
  end
@@ -4,21 +4,21 @@ describe SendGrid::UserSettingsDto do
4
4
  let(:sendgrid_client) { SendGrid::API.new(api_key: 'fake_key').client }
5
5
  let(:user_settings) { SendGrid::UserSettingsDto }
6
6
  let(:setting_name) { 'enforced_tls' }
7
- let(:setting_params) { {require_tls: rand(1..100).even?} }
7
+ let(:setting_params) { { require_tls: rand(1..100).even? } }
8
8
 
9
9
  it { should respond_to :enforced_tls }
10
10
 
11
11
  describe '.fetch' do
12
12
  it 'calls get on sendgrid_client' do
13
13
  args = { sendgrid_client: sendgrid_client, name: setting_name, query_params: {} }
14
- expect(user_settings.fetch(args)).to be_a SendGrid::Response
14
+ expect(user_settings.fetch(**args)).to be_a SendGrid::Response
15
15
  end
16
16
  end
17
17
 
18
18
  describe '.update' do
19
19
  it 'calls patch on sendgrid_client' do
20
20
  args = { sendgrid_client: sendgrid_client, name: setting_name, request_body: setting_params }
21
- expect(user_settings.update(args)).to be_a SendGrid::Response
21
+ expect(user_settings.update(**args)).to be_a SendGrid::Response
22
22
  end
23
23
  end
24
24
  end
@@ -7,37 +7,36 @@ describe SendGrid::EmailStats do
7
7
 
8
8
  let(:sample_response) do
9
9
  [{
10
- "date" => "2017-10-01",
11
- "stats" => [
12
- {"metrics" =>
10
+ 'date' => '2017-10-01',
11
+ 'stats' => [
12
+ { 'metrics' =>
13
13
  {
14
- "blocks" => 101,
15
- "bounce_drops" => 102,
16
- "bounces" => 103,
17
- "clicks" => 104,
18
- "deferred" => 105,
19
- "delivered" => 106,
20
- "invalid_emails" => 107,
21
- "opens" => 108,
22
- "processed" => 109,
23
- "requests" => 110,
24
- "spam_report_drops" => 111,
25
- "spam_reports" => 112,
26
- "unique_clicks" => 113,
27
- "unique_opens" => 114,
28
- "unsubscribe_drops" => 115,
29
- "unsubscribes" => 116
30
- }
31
- }
14
+ 'blocks' => 101,
15
+ 'bounce_drops' => 102,
16
+ 'bounces' => 103,
17
+ 'clicks' => 104,
18
+ 'deferred' => 105,
19
+ 'delivered' => 106,
20
+ 'invalid_emails' => 107,
21
+ 'opens' => 108,
22
+ 'processed' => 109,
23
+ 'requests' => 110,
24
+ 'spam_report_drops' => 111,
25
+ 'spam_reports' => 112,
26
+ 'unique_clicks' => 113,
27
+ 'unique_opens' => 114,
28
+ 'unsubscribe_drops' => 115,
29
+ 'unsubscribes' => 116
30
+ } }
32
31
  ]
33
32
  }]
34
33
  end
35
34
 
36
35
  let(:error_response) do
37
36
  {
38
- "errors" => [
37
+ 'errors' => [
39
38
  {
40
- "message" => "end_date should be a YYYY-MM-DD formatted date"
39
+ 'message' => 'end_date should be a YYYY-MM-DD formatted date'
41
40
  }
42
41
  ]
43
42
  }