webpush 0.3.8 → 1.0.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e513fc59cd8322f780954d7ade13d9b5c9c5e480
4
- data.tar.gz: c12815199e3cd627869e2292fab29f234baa2611
3
+ metadata.gz: 5fbb0e5a0419639817533b0ce1b45c0b222fafa5
4
+ data.tar.gz: b3f72a12240ef2496c27aefc7a88a896fd1f2aa4
5
5
  SHA512:
6
- metadata.gz: 0b9233e5a9ed959fdcc4f7513b80195c55f56de6f9009b59be55bddf67174b77702470438dd04ae6827410dcc276601a58604ed42907f9fd481f25a4f5daa17d
7
- data.tar.gz: e86db0d9b0e30039ca67ae534b794c5408c7d4231c532f57948df3271dfdbe9676df84928fd8797aae96ee82405a09a16606a5edbb036361994ba6ab73a1fbf5
6
+ metadata.gz: 0ef773e38114e36f2d903ffcb892ffde10e5ca837908e76df1f2c95e31da9044f80e6add328e769ec70ddd8a43dcfcaff0122298346903dda8a730962e8e7f4c
7
+ data.tar.gz: 7e242909ab6e783f81a7553a193e384aa8b956537087de172838e50199d7dd37c7c78204248932b5574022c0624ef3ff7d6bc730f1e65b6f03858a993a7582e6
@@ -0,0 +1,30 @@
1
+ require: rubocop-performance
2
+
3
+ AllCops:
4
+ Exclude:
5
+ - 'bin/**/*'
6
+
7
+ Metrics/AbcSize:
8
+ Max: 20
9
+
10
+ Metrics/ClassLength:
11
+ Max: 100
12
+
13
+ Metrics/ModuleLength:
14
+ Max: 100
15
+
16
+ Metrics/LineLength:
17
+ Enabled: false
18
+
19
+ Metrics/BlockLength:
20
+ Exclude:
21
+ - spec/**/*_spec.rb
22
+
23
+ Lint/AmbiguousBlockAssociation:
24
+ Enabled: false
25
+
26
+ Style/Documentation:
27
+ Enabled: false
28
+
29
+ Style/IndentHeredoc:
30
+ Enabled: false
@@ -1,3 +1,6 @@
1
+ env:
2
+ global:
3
+ - CC_TEST_REPORTER_ID=155202524386dfebe0c3267a5c868b5417ff4cc2cde8ed301fb36b177d46a458
1
4
  language: ruby
2
5
  rvm:
3
6
  - 2.2
@@ -6,12 +9,15 @@ rvm:
6
9
  - 2.5
7
10
  - 2.6
8
11
  before_install:
9
- - |
10
- if [[ ${RUBY_VERSION} =~ ^ruby-2.3 ]]; then
11
- gem uninstall -i /home/travis/.rvm/gems/${RUBY_VERSION}@global bundler -x
12
- fi
12
+ - gem uninstall -v '>= 2' -i $(rvm gemdir)@global -ax bundler || true
13
13
  - gem install bundler -v 1.17.3
14
+ before_script:
15
+ - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
16
+ - chmod +x ./cc-test-reporter
17
+ - ./cc-test-reporter before-build
14
18
  script: "bundle exec rake spec"
19
+ after_script:
20
+ - ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
15
21
  addons:
16
22
  code_climate:
17
23
  repo_token: 155202524386dfebe0c3267a5c868b5417ff4cc2cde8ed301fb36b177d46a458
@@ -1,5 +1,12 @@
1
1
  # Change Log
2
2
 
3
+ ## [v0.3.8](https://github.com/zaru/webpush/tree/v0.3.8) (2019-04-16)
4
+ [Full Changelog](https://github.com/zaru/webpush/compare/v0.3.7...v0.3.8)
5
+
6
+ **Merged pull requests:**
7
+
8
+ - Fix authorization header [\#72](https://github.com/zaru/webpush/pull/72) ([xronos-i-am](https://github.com/xronos-i-am))
9
+
3
10
  ## [v0.3.7](https://github.com/zaru/webpush/tree/v0.3.7) (2019-03-06)
4
11
  [Full Changelog](https://github.com/zaru/webpush/compare/v0.3.6...v0.3.7)
5
12
 
data/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  # WebPush
2
2
 
3
3
  [![Code Climate](https://codeclimate.com/github/zaru/webpush/badges/gpa.svg)](https://codeclimate.com/github/zaru/webpush)
4
+ [![Test Coverage](https://codeclimate.com/github/zaru/webpush/badges/coverage.svg)](https://codeclimate.com/github/zaru/webpush/coverage)
4
5
  [![Build Status](https://travis-ci.org/zaru/webpush.svg?branch=master)](https://travis-ci.org/zaru/webpush)
5
6
  [![Gem Version](https://badge.fury.io/rb/webpush.svg)](https://badge.fury.io/rb/webpush)
6
7
 
data/Rakefile CHANGED
@@ -1,5 +1,5 @@
1
- require "bundler/gem_tasks"
2
- require "rspec/core/rake_task"
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
3
 
4
4
  RSpec::Core::RakeTask.new(:spec)
5
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'openssl'
2
4
  require 'base64'
3
5
  require 'hkdf'
@@ -11,6 +13,10 @@ require 'webpush/encryption'
11
13
  require 'webpush/request'
12
14
  require 'webpush/railtie' if defined?(Rails)
13
15
 
16
+ # Push API implementation
17
+ #
18
+ # https://tools.ietf.org/html/rfc8030
19
+ # https://www.w3.org/TR/push-api/
14
20
  module Webpush
15
21
  class << self
16
22
  # Deliver the payload to the required endpoint given by the JavaScript
@@ -28,21 +34,16 @@ module Webpush
28
34
  # @param options [Hash<Symbol,String>] additional options for the notification
29
35
  # @option options [#to_s] :ttl Time-to-live in seconds
30
36
  # @option options [#to_s] :urgency Urgency can be very-low, low, normal, high
31
- def payload_send(message: "", endpoint:, p256dh: "", auth: "", vapid: {}, **options)
32
- subscription = {
33
- endpoint: endpoint,
34
- keys: {
35
- p256dh: p256dh,
36
- auth: auth
37
- }
38
- }
37
+ # rubocop:disable Metrics/ParameterLists
38
+ def payload_send(message: '', endpoint:, p256dh: '', auth: '', vapid: {}, **options)
39
39
  Webpush::Request.new(
40
40
  message: message,
41
- subscription: subscription,
41
+ subscription: subscription(endpoint, p256dh, auth),
42
42
  vapid: vapid,
43
43
  **options
44
44
  ).perform
45
45
  end
46
+ # rubocop:enable Metrics/ParameterLists
46
47
 
47
48
  # Generate a VapidKey instance to obtain base64 encoded public and private keys
48
49
  # suitable for VAPID protocol JSON web token signing
@@ -59,11 +60,21 @@ module Webpush
59
60
  def decode64(str)
60
61
  # For Ruby < 2.3, Base64.urlsafe_decode64 strict decodes and will raise errors if encoded value is not properly padded
61
62
  # Implementation: http://ruby-doc.org/stdlib-2.3.0/libdoc/base64/rdoc/Base64.html#method-i-urlsafe_decode64
62
- if !str.end_with?("=") && str.length % 4 != 0
63
- str = str.ljust((str.length + 3) & ~3, "=")
64
- end
63
+ str = str.ljust((str.length + 3) & ~3, '=') if !str.end_with?('=') && str.length % 4 != 0
65
64
 
66
65
  Base64.urlsafe_decode64(str)
67
66
  end
67
+
68
+ private
69
+
70
+ def subscription(endpoint, p256dh, auth)
71
+ {
72
+ endpoint: endpoint,
73
+ keys: {
74
+ p256dh: p256dh,
75
+ auth: auth
76
+ }
77
+ }
78
+ end
68
79
  end
69
80
  end
@@ -1,11 +1,14 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Webpush
2
4
  module Encryption
3
5
  extend self
4
6
 
7
+ # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
5
8
  def encrypt(message, p256dh, auth)
6
9
  assert_arguments(message, p256dh, auth)
7
10
 
8
- group_name = "prime256v1"
11
+ group_name = 'prime256v1'
9
12
  salt = Random.new.bytes(16)
10
13
 
11
14
  server = OpenSSL::PKey::EC.new(group_name)
@@ -20,75 +23,55 @@ module Webpush
20
23
 
21
24
  client_auth_token = Webpush.decode64(auth)
22
25
 
23
- prk = HKDF.new(shared_secret, salt: client_auth_token, algorithm: 'SHA256', info: "Content-Encoding: auth\0").next_bytes(32)
26
+ info = "WebPush: info\0" + client_public_key_bn.to_s(2) + server_public_key_bn.to_s(2)
27
+ content_encryption_key_info = "Content-Encoding: aes128gcm\0"
28
+ nonce_info = "Content-Encoding: nonce\0"
24
29
 
25
- context = create_context(client_public_key_bn, server_public_key_bn)
30
+ prk = HKDF.new(shared_secret, salt: client_auth_token, algorithm: 'SHA256', info: info).next_bytes(32)
26
31
 
27
- content_encryption_key_info = create_info('aesgcm', context)
28
32
  content_encryption_key = HKDF.new(prk, salt: salt, info: content_encryption_key_info).next_bytes(16)
29
33
 
30
- nonce_info = create_info('nonce', context)
31
34
  nonce = HKDF.new(prk, salt: salt, info: nonce_info).next_bytes(12)
32
35
 
33
36
  ciphertext = encrypt_payload(message, content_encryption_key, nonce)
34
37
 
35
- {
36
- ciphertext: ciphertext,
37
- salt: salt,
38
- server_public_key_bn: convert16bit(server_public_key_bn),
39
- server_public_key: server_public_key_bn.to_s(2),
40
- shared_secret: shared_secret
41
- }
42
- end
38
+ serverkey16bn = convert16bit(server_public_key_bn)
39
+ rs = ciphertext.bytesize
40
+ raise ArgumentError, "encrypted payload is too big" if rs > 4096
43
41
 
44
- private
42
+ aes128gcmheader = "#{salt}" + [rs].pack('N*') + [serverkey16bn.bytesize].pack('C*') + serverkey16bn
45
43
 
46
- def create_context(client_public_key, server_public_key)
47
- c = convert16bit(client_public_key)
48
- s = convert16bit(server_public_key)
49
- context = "\0"
50
- context += [c.bytesize].pack("n*")
51
- context += c
52
- context += [s.bytesize].pack("n*")
53
- context += s
54
- context
44
+ aes128gcmheader + ciphertext
55
45
  end
46
+ # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
47
+
48
+ private
56
49
 
57
50
  def encrypt_payload(plaintext, content_encryption_key, nonce)
58
51
  cipher = OpenSSL::Cipher.new('aes-128-gcm')
59
52
  cipher.encrypt
60
53
  cipher.key = content_encryption_key
61
54
  cipher.iv = nonce
62
- padding = cipher.update("\0\0")
63
55
  text = cipher.update(plaintext)
64
-
65
- e_text = padding + text + cipher.final
56
+ padding = cipher.update("\2\0")
57
+ e_text = text + padding + cipher.final
66
58
  e_tag = cipher.auth_tag
67
59
 
68
60
  e_text + e_tag
69
61
  end
70
62
 
71
- def create_info(type, context)
72
- info = "Content-Encoding: "
73
- info += type
74
- info += "\0"
75
- info += "P-256"
76
- info += context
77
- info
78
- end
79
-
80
63
  def convert16bit(key)
81
- [key.to_s(16)].pack("H*")
64
+ [key.to_s(16)].pack('H*')
82
65
  end
83
66
 
84
67
  def assert_arguments(message, p256dh, auth)
85
- raise ArgumentError, "message cannot be blank" if blank?(message)
86
- raise ArgumentError, "p256dh cannot be blank" if blank?(p256dh)
87
- raise ArgumentError, "auth cannot be blank" if blank?(auth)
68
+ raise ArgumentError, 'message cannot be blank' if blank?(message)
69
+ raise ArgumentError, 'p256dh cannot be blank' if blank?(p256dh)
70
+ raise ArgumentError, 'auth cannot be blank' if blank?(auth)
88
71
  end
89
72
 
90
73
  def blank?(value)
91
74
  value.nil? || value.empty?
92
75
  end
93
76
  end
94
- end
77
+ end
@@ -1,9 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Webpush
2
4
  class Error < RuntimeError; end
3
5
 
4
6
  class ConfigurationError < Error; end
5
7
 
6
- class ResponseError < Error;
8
+ class ResponseError < Error
7
9
  attr_reader :response, :host
8
10
 
9
11
  def initialize(response, host)
@@ -24,5 +26,4 @@ module Webpush
24
26
  class TooManyRequests < ResponseError; end
25
27
 
26
28
  class PushServiceError < ResponseError; end
27
-
28
29
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Webpush
2
4
  class Railtie < Rails::Railtie
3
5
  rake_tasks do
@@ -1,13 +1,16 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'jwt'
2
4
  require 'base64'
3
5
 
4
6
  module Webpush
5
7
  # It is temporary URL until supported by the GCM server.
6
- GCM_URL = 'https://android.googleapis.com/gcm/send'
7
- TEMP_GCM_URL = 'https://gcm-http.googleapis.com/gcm'
8
+ GCM_URL = 'https://android.googleapis.com/gcm/send'.freeze
9
+ TEMP_GCM_URL = 'https://fcm.googleapis.com/fcm'.freeze
8
10
 
11
+ # rubocop:disable Metrics/ClassLength
9
12
  class Request
10
- def initialize(message: "", subscription:, vapid:, **options)
13
+ def initialize(message: '', subscription:, vapid:, **options)
11
14
  endpoint = subscription.fetch(:endpoint)
12
15
  @endpoint = endpoint.gsub(GCM_URL, TEMP_GCM_URL)
13
16
  @payload = build_payload(message, subscription)
@@ -15,6 +18,7 @@ module Webpush
15
18
  @options = default_options.merge(options)
16
19
  end
17
20
 
21
+ # rubocop:disable Metrics/AbcSize
18
22
  def perform
19
23
  http = Net::HTTP.new(uri.host, uri.port)
20
24
  http.use_ssl = true
@@ -25,63 +29,46 @@ module Webpush
25
29
  req = Net::HTTP::Post.new(uri.request_uri, headers)
26
30
  req.body = body
27
31
  resp = http.request(req)
28
-
29
- if resp.is_a?(Net::HTTPGone) # 410
30
- raise ExpiredSubscription.new(resp, uri.host)
31
- elsif resp.is_a?(Net::HTTPNotFound) # 404
32
- raise InvalidSubscription.new(resp, uri.host)
33
- elsif resp.is_a?(Net::HTTPUnauthorized) || resp.is_a?(Net::HTTPForbidden) || # 401, 403
34
- resp.is_a?(Net::HTTPBadRequest) && resp.message == "UnauthorizedRegistration" # 400, Google FCM
35
- raise Unauthorized.new(resp, uri.host)
36
- elsif resp.is_a?(Net::HTTPRequestEntityTooLarge) # 413
37
- raise PayloadTooLarge.new(resp, uri.host)
38
- elsif resp.is_a?(Net::HTTPTooManyRequests) # 429, try again later!
39
- raise TooManyRequests.new(resp, uri.host)
40
- elsif resp.is_a?(Net::HTTPServerError) # 5xx
41
- raise PushServiceError.new(resp, uri.host)
42
- elsif !resp.is_a?(Net::HTTPSuccess) # unknown/unhandled response error
43
- raise ResponseError.new(resp, uri.host)
44
- end
32
+ verify_response(resp)
45
33
 
46
34
  resp
47
35
  end
36
+ # rubocop:enable Metrics/AbcSize
48
37
 
38
+ # rubocop:disable Metrics/MethodLength
49
39
  def headers
50
40
  headers = {}
51
- headers["Content-Type"] = "application/octet-stream"
52
- headers["Ttl"] = ttl
53
- headers["Urgency"] = urgency
54
-
55
- if @payload.has_key?(:server_public_key)
56
- headers["Content-Encoding"] = "aesgcm"
57
- headers["Encryption"] = "salt=#{salt_param}"
58
- headers["Crypto-Key"] = "dh=#{dh_param}"
41
+ headers['Content-Type'] = 'application/octet-stream'
42
+ headers['Ttl'] = ttl
43
+ headers['Urgency'] = urgency
44
+
45
+ if @payload
46
+ headers['Content-Encoding'] = 'aes128gcm'
47
+ headers["Content-Length"] = @payload.length.to_s
59
48
  end
60
49
 
61
50
  if api_key?
62
- headers["Authorization"] = "key=#{api_key}"
51
+ headers['Authorization'] = "key=#{api_key}"
63
52
  elsif vapid?
64
- vapid_headers = build_vapid_headers
65
- headers["Authorization"] = vapid_headers["Authorization"]
66
- headers["Crypto-Key"] = [ headers["Crypto-Key"], vapid_headers["Crypto-Key"] ].compact.join(";")
53
+ headers["Authorization"] = build_vapid_header
67
54
  end
68
55
 
69
56
  headers
70
57
  end
58
+ # rubocop:enable Metrics/MethodLength
59
+
60
+ def build_vapid_header
61
+ # https://tools.ietf.org/id/draft-ietf-webpush-vapid-03.html
71
62
 
72
- def build_vapid_headers
73
63
  vapid_key = vapid_pem ? VapidKey.from_pem(vapid_pem) : VapidKey.from_keys(vapid_public_key, vapid_private_key)
74
64
  jwt = JWT.encode(jwt_payload, vapid_key.curve, 'ES256', jwt_header_fields)
75
65
  p256ecdsa = vapid_key.public_key_for_push_header
76
66
 
77
- {
78
- 'Authorization' => 'WebPush ' + jwt,
79
- 'Crypto-Key' => 'p256ecdsa=' + p256ecdsa,
80
- }
67
+ "vapid t=#{jwt},k=#{p256ecdsa}"
81
68
  end
82
69
 
83
70
  def body
84
- @payload.fetch(:ciphertext, "")
71
+ @payload || ''
85
72
  end
86
73
 
87
74
  private
@@ -98,32 +85,24 @@ module Webpush
98
85
  @options.fetch(:urgency).to_s
99
86
  end
100
87
 
101
- def dh_param
102
- trim_encode64(@payload.fetch(:server_public_key))
103
- end
104
-
105
- def salt_param
106
- trim_encode64(@payload.fetch(:salt))
107
- end
108
-
109
88
  def jwt_payload
110
89
  {
111
90
  aud: audience,
112
91
  exp: Time.now.to_i + expiration,
113
- sub: subject,
92
+ sub: subject
114
93
  }
115
94
  end
116
95
 
117
96
  def jwt_header_fields
118
- { 'typ' => 'JWT' }
97
+ { "typ": "JWT", "alg": "ES256" }
119
98
  end
120
99
 
121
100
  def audience
122
- uri.scheme + "://" + uri.host
101
+ uri.scheme + '://' + uri.host
123
102
  end
124
103
 
125
104
  def expiration
126
- @vapid_options.fetch(:expiration, 24*60*60)
105
+ @vapid_options.fetch(:expiration, 24 * 60 * 60)
127
106
  end
128
107
 
129
108
  def subject
@@ -144,13 +123,13 @@ module Webpush
144
123
 
145
124
  def default_options
146
125
  {
147
- ttl: 60*60*24*7*4, # 4 weeks
126
+ ttl: 60 * 60 * 24 * 7 * 4, # 4 weeks
148
127
  urgency: 'normal'
149
128
  }
150
129
  end
151
130
 
152
131
  def build_payload(message, subscription)
153
- return {} if message.nil? || message.empty?
132
+ return nil if message.nil? || message.empty?
154
133
 
155
134
  encrypt_payload(message, subscription.fetch(:keys))
156
135
  end
@@ -164,7 +143,7 @@ module Webpush
164
143
  end
165
144
 
166
145
  def api_key?
167
- !(api_key.nil? || api_key.empty?) && @endpoint =~ /\Ahttps:\/\/(android|gcm-http)\.googleapis\.com/
146
+ !(api_key.nil? || api_key.empty?) && @endpoint =~ %r{\Ahttps://(android|gcm-http|fcm)\.googleapis\.com}
168
147
  end
169
148
 
170
149
  def vapid?
@@ -174,5 +153,27 @@ module Webpush
174
153
  def trim_encode64(bin)
175
154
  Webpush.encode64(bin).delete('=')
176
155
  end
156
+
157
+ # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity, Style/GuardClause
158
+ def verify_response(resp)
159
+ if resp.is_a?(Net::HTTPGone) # 410
160
+ raise ExpiredSubscription.new(resp, uri.host)
161
+ elsif resp.is_a?(Net::HTTPNotFound) # 404
162
+ raise InvalidSubscription.new(resp, uri.host)
163
+ elsif resp.is_a?(Net::HTTPUnauthorized) || resp.is_a?(Net::HTTPForbidden) || # 401, 403
164
+ resp.is_a?(Net::HTTPBadRequest) && resp.message == 'UnauthorizedRegistration' # 400, Google FCM
165
+ raise Unauthorized.new(resp, uri.host)
166
+ elsif resp.is_a?(Net::HTTPRequestEntityTooLarge) # 413
167
+ raise PayloadTooLarge.new(resp, uri.host)
168
+ elsif resp.is_a?(Net::HTTPTooManyRequests) # 429, try again later!
169
+ raise TooManyRequests.new(resp, uri.host)
170
+ elsif resp.is_a?(Net::HTTPServerError) # 5xx
171
+ raise PushServiceError.new(resp, uri.host)
172
+ elsif !resp.is_a?(Net::HTTPSuccess) # unknown/unhandled response error
173
+ raise ResponseError.new(resp, uri.host)
174
+ end
175
+ end
176
+ # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity, Style/GuardClause
177
177
  end
178
+ # rubocop:enable Metrics/ClassLength
178
179
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Webpush
2
4
  # Class for abstracting the generation and encoding of elliptic curve public and private keys for use with the VAPID protocol
3
5
  #
@@ -78,12 +80,12 @@ module Webpush
78
80
  def to_pem
79
81
  public_key = OpenSSL::PKey::EC.new curve
80
82
  public_key.private_key = nil
81
-
83
+
82
84
  curve.to_pem + public_key.to_pem
83
85
  end
84
86
 
85
87
  def inspect
86
- "#<#{self.class}:#{object_id.to_s(16)} #{to_h.map { |k, v| ":#{k}=#{v}" }.join(" ")}>"
88
+ "#<#{self.class}:#{object_id.to_s(16)} #{to_h.map { |k, v| ":#{k}=#{v}" }.join(' ')}>"
87
89
  end
88
90
 
89
91
  private
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Webpush
2
- VERSION = "0.3.8"
4
+ VERSION = '1.0.0'.freeze
3
5
  end
@@ -1,29 +1,28 @@
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 'webpush/version'
5
4
 
6
5
  Gem::Specification.new do |spec|
7
- spec.name = "webpush"
6
+ spec.name = 'webpush'
8
7
  spec.version = Webpush::VERSION
9
- spec.authors = ["zaru@sakuraba"]
10
- spec.email = ["zarutofu@gmail.com"]
8
+ spec.authors = ['zaru@sakuraba']
9
+ spec.email = ['zarutofu@gmail.com']
11
10
 
12
- spec.summary = %q{Encryption Utilities for Web Push payload. }
13
- spec.homepage = "https://github.com/zaru/webpush"
11
+ spec.summary = 'Encryption Utilities for Web Push payload. '
12
+ spec.homepage = 'https://github.com/zaru/webpush'
14
13
 
15
14
  spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
16
- spec.bindir = "exe"
15
+ spec.bindir = 'exe'
17
16
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
18
- spec.require_paths = ["lib"]
17
+ spec.require_paths = ['lib']
19
18
 
20
- spec.add_dependency "hkdf", "~> 0.2"
21
- spec.add_dependency "jwt", "~> 2.0"
19
+ spec.add_dependency 'hkdf', '~> 0.2'
20
+ spec.add_dependency 'jwt', '~> 2.0'
22
21
 
23
- spec.add_development_dependency "bundler", "~> 1.17.3"
22
+ spec.add_development_dependency 'bundler', '~> 1.17.3'
24
23
  spec.add_development_dependency 'pry'
25
- spec.add_development_dependency "rake", "~> 10.0"
26
- spec.add_development_dependency "rspec", "~> 3.0"
27
- spec.add_development_dependency "webmock", "~> 1.24"
28
- spec.add_development_dependency "ece", "~> 0.2"
24
+ spec.add_development_dependency 'rake', '~> 10.0'
25
+ spec.add_development_dependency 'rspec', '~> 3.0'
26
+ spec.add_development_dependency 'simplecov'
27
+ spec.add_development_dependency 'webmock', '~> 1.24'
29
28
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: webpush
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.8
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - zaru@sakuraba
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-04-16 00:00:00.000000000 Z
11
+ date: 2019-08-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: hkdf
@@ -95,33 +95,33 @@ dependencies:
95
95
  - !ruby/object:Gem::Version
96
96
  version: '3.0'
97
97
  - !ruby/object:Gem::Dependency
98
- name: webmock
98
+ name: simplecov
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
- - - "~>"
101
+ - - ">="
102
102
  - !ruby/object:Gem::Version
103
- version: '1.24'
103
+ version: '0'
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - "~>"
108
+ - - ">="
109
109
  - !ruby/object:Gem::Version
110
- version: '1.24'
110
+ version: '0'
111
111
  - !ruby/object:Gem::Dependency
112
- name: ece
112
+ name: webmock
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
115
  - - "~>"
116
116
  - !ruby/object:Gem::Version
117
- version: '0.2'
117
+ version: '1.24'
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
- version: '0.2'
124
+ version: '1.24'
125
125
  description:
126
126
  email:
127
127
  - zarutofu@gmail.com
@@ -131,6 +131,7 @@ extra_rdoc_files: []
131
131
  files:
132
132
  - ".gitignore"
133
133
  - ".rspec"
134
+ - ".rubocop.yml"
134
135
  - ".travis.yml"
135
136
  - CHANGELOG.md
136
137
  - Gemfile