webpush 0.3.8 → 1.0.0

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