sockudo 1.0.0 → 2.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 +4 -4
- data/README.md +25 -3
- data/lib/sockudo/channel.rb +79 -7
- data/lib/sockudo/client.rb +293 -79
- data/lib/sockudo/request.rb +72 -37
- data/lib/sockudo/resource.rb +11 -5
- data/lib/sockudo/utils.rb +5 -3
- data/lib/sockudo/version.rb +3 -1
- data/lib/sockudo/webhook.rb +24 -24
- data/lib/sockudo.rb +20 -4
- metadata +61 -35
data/lib/sockudo/request.rb
CHANGED
|
@@ -1,27 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'pusher-signature'
|
|
2
4
|
require 'digest/md5'
|
|
3
5
|
require 'multi_json'
|
|
6
|
+
require 'openssl'
|
|
4
7
|
|
|
5
8
|
module Sockudo
|
|
6
9
|
class Request
|
|
7
10
|
attr_reader :body, :params
|
|
8
11
|
|
|
9
12
|
def initialize(client, verb, uri, params, body = nil, extra_headers = {})
|
|
10
|
-
@client
|
|
13
|
+
@client = client
|
|
14
|
+
@verb = verb
|
|
15
|
+
@uri = uri
|
|
11
16
|
@head = {
|
|
12
|
-
'X-Pusher-Library' =>
|
|
17
|
+
'X-Pusher-Library' => "sockudo-http-ruby #{Sockudo::VERSION}"
|
|
13
18
|
}
|
|
14
19
|
@head.merge!(extra_headers) if extra_headers && !extra_headers.empty?
|
|
15
20
|
|
|
16
21
|
@body = body
|
|
22
|
+
params = params.each_with_object({}) { |(key, value), result| result[key.to_s] = value }
|
|
17
23
|
if body
|
|
18
|
-
params[
|
|
24
|
+
params['body_md5'] = Digest::MD5.hexdigest(body)
|
|
19
25
|
@head['Content-Type'] = 'application/json'
|
|
20
26
|
end
|
|
21
27
|
|
|
22
|
-
|
|
23
|
-
request.sign(client.authentication_token)
|
|
24
|
-
@params = request.signed_params
|
|
28
|
+
@params = signed_params(params)
|
|
25
29
|
end
|
|
26
30
|
|
|
27
31
|
def send_sync
|
|
@@ -36,9 +40,9 @@ module Sockudo
|
|
|
36
40
|
raise error
|
|
37
41
|
end
|
|
38
42
|
|
|
39
|
-
body = response.body
|
|
43
|
+
body = response.body&.chomp
|
|
40
44
|
|
|
41
|
-
|
|
45
|
+
handle_response(response.code.to_i, body)
|
|
42
46
|
end
|
|
43
47
|
|
|
44
48
|
def send_async
|
|
@@ -47,46 +51,65 @@ module Sockudo
|
|
|
47
51
|
df = EM::DefaultDeferrable.new
|
|
48
52
|
|
|
49
53
|
http = case @verb
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
54
|
+
when :post
|
|
55
|
+
http_client.post({
|
|
56
|
+
query: @params, body: @body, head: @head
|
|
57
|
+
})
|
|
58
|
+
when :get
|
|
59
|
+
http_client.get({
|
|
60
|
+
query: @params, head: @head
|
|
61
|
+
})
|
|
62
|
+
when :delete
|
|
63
|
+
http_client.delete({
|
|
64
|
+
query: @params, head: @head
|
|
65
|
+
})
|
|
66
|
+
else
|
|
67
|
+
raise 'Unsupported verb'
|
|
68
|
+
end
|
|
69
|
+
http.callback do
|
|
70
|
+
df.succeed(handle_response(http.response_header.status, http.response.chomp))
|
|
71
|
+
rescue StandardError => e
|
|
72
|
+
df.fail(e)
|
|
60
73
|
end
|
|
61
|
-
http.
|
|
62
|
-
begin
|
|
63
|
-
df.succeed(handle_response(http.response_header.status, http.response.chomp))
|
|
64
|
-
rescue => e
|
|
65
|
-
df.fail(e)
|
|
66
|
-
end
|
|
67
|
-
}
|
|
68
|
-
http.errback { |e|
|
|
74
|
+
http.errback do |_e|
|
|
69
75
|
message = "Network error connecting to sockudo (#{http.error})"
|
|
70
76
|
Sockudo.logger.debug(message)
|
|
71
77
|
df.fail(Error.new(message))
|
|
72
|
-
|
|
78
|
+
end
|
|
73
79
|
|
|
74
|
-
|
|
80
|
+
df
|
|
75
81
|
else
|
|
76
82
|
http = @client.sync_http_client
|
|
77
83
|
|
|
78
|
-
|
|
84
|
+
http.request_async(@verb, @uri, @params, @body, @head)
|
|
79
85
|
end
|
|
80
86
|
end
|
|
81
87
|
|
|
82
88
|
private
|
|
83
89
|
|
|
90
|
+
def signed_params(params)
|
|
91
|
+
@client.authentication_token
|
|
92
|
+
params = params.merge({
|
|
93
|
+
'auth_key' => @client.key,
|
|
94
|
+
'auth_timestamp' => Time.now.to_i.to_s,
|
|
95
|
+
'auth_version' => '1.0'
|
|
96
|
+
})
|
|
97
|
+
params_for_signing = params.each_with_object({}) do |(key, value), result|
|
|
98
|
+
result[key.downcase] = value
|
|
99
|
+
end
|
|
100
|
+
canonical_query = params_for_signing.sort.map { |key, value| "#{key}=#{value}" }.join('&')
|
|
101
|
+
string_to_sign = [@verb.to_s.upcase, @uri.path, canonical_query].join("\n")
|
|
102
|
+
params.merge('auth_signature' => OpenSSL::HMAC.hexdigest('sha256', @client.secret, string_to_sign))
|
|
103
|
+
end
|
|
104
|
+
|
|
84
105
|
def handle_response(status_code, body)
|
|
85
106
|
case status_code
|
|
86
|
-
when 200
|
|
87
|
-
|
|
107
|
+
when 200, 201
|
|
108
|
+
symbolize_first_level(MultiJson.decode(body))
|
|
88
109
|
when 202
|
|
89
|
-
|
|
110
|
+
body.empty? || symbolize_first_level(MultiJson.decode(body))
|
|
111
|
+
when 204
|
|
112
|
+
{}
|
|
90
113
|
when 400
|
|
91
114
|
raise Error, "Bad request: #{body}"
|
|
92
115
|
when 401
|
|
@@ -94,18 +117,30 @@ module Sockudo
|
|
|
94
117
|
when 404
|
|
95
118
|
raise Error, "404 Not found (#{@uri.path})"
|
|
96
119
|
when 407
|
|
97
|
-
raise Error,
|
|
120
|
+
raise Error, 'Proxy Authentication Required'
|
|
98
121
|
when 413
|
|
99
|
-
raise Error,
|
|
122
|
+
raise Error, 'Payload Too Large > 10KB'
|
|
100
123
|
else
|
|
101
124
|
raise Error, "Unknown error (status code #{status_code}): #{body}"
|
|
102
125
|
end
|
|
103
126
|
end
|
|
104
127
|
|
|
105
128
|
def symbolize_first_level(hash)
|
|
106
|
-
hash.
|
|
107
|
-
result[key.to_sym] = value
|
|
108
|
-
|
|
129
|
+
hash.each_with_object({}) do |(key, value), result|
|
|
130
|
+
result[key.to_sym] = deep_symbolize(value)
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def deep_symbolize(value)
|
|
135
|
+
case value
|
|
136
|
+
when Hash
|
|
137
|
+
value.each_with_object({}) do |(key, nested_value), result|
|
|
138
|
+
result[key.to_sym] = deep_symbolize(nested_value)
|
|
139
|
+
end
|
|
140
|
+
when Array
|
|
141
|
+
value.map { |item| deep_symbolize(item) }
|
|
142
|
+
else
|
|
143
|
+
value
|
|
109
144
|
end
|
|
110
145
|
end
|
|
111
146
|
end
|
data/lib/sockudo/resource.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Sockudo
|
|
2
4
|
class Resource
|
|
3
5
|
def initialize(client, path)
|
|
@@ -5,12 +7,12 @@ module Sockudo
|
|
|
5
7
|
@path = path
|
|
6
8
|
end
|
|
7
9
|
|
|
8
|
-
def get(params)
|
|
9
|
-
create_request(:get, params).send_sync
|
|
10
|
+
def get(params, headers = {})
|
|
11
|
+
create_request(:get, params, nil, headers).send_sync
|
|
10
12
|
end
|
|
11
13
|
|
|
12
|
-
def get_async(params)
|
|
13
|
-
create_request(:get, params).send_async
|
|
14
|
+
def get_async(params, headers = {})
|
|
15
|
+
create_request(:get, params, nil, headers).send_async
|
|
14
16
|
end
|
|
15
17
|
|
|
16
18
|
def post(params, headers = {})
|
|
@@ -23,6 +25,10 @@ module Sockudo
|
|
|
23
25
|
create_request(:post, {}, body, headers).send_async
|
|
24
26
|
end
|
|
25
27
|
|
|
28
|
+
def delete(params, headers = {})
|
|
29
|
+
create_request(:delete, params, nil, headers).send_sync
|
|
30
|
+
end
|
|
31
|
+
|
|
26
32
|
private
|
|
27
33
|
|
|
28
34
|
def create_request(verb, params, body = nil, extra_headers = {})
|
|
@@ -30,7 +36,7 @@ module Sockudo
|
|
|
30
36
|
end
|
|
31
37
|
|
|
32
38
|
def url
|
|
33
|
-
@
|
|
39
|
+
@url ||= @client.url(@path)
|
|
34
40
|
end
|
|
35
41
|
end
|
|
36
42
|
end
|
data/lib/sockudo/utils.rb
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Sockudo
|
|
2
4
|
module Utils
|
|
3
5
|
def validate_socket_id(socket_id)
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
6
|
+
return if socket_id && /\A\d+\.\d+\z/.match(socket_id)
|
|
7
|
+
|
|
8
|
+
raise Sockudo::Error, "Invalid socket ID #{socket_id.inspect}"
|
|
7
9
|
end
|
|
8
10
|
|
|
9
11
|
# Compute authentication string required as part of the user authentication
|
data/lib/sockudo/version.rb
CHANGED
data/lib/sockudo/webhook.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'multi_json'
|
|
2
4
|
require 'openssl'
|
|
3
5
|
|
|
@@ -33,7 +35,7 @@ module Sockudo
|
|
|
33
35
|
# For Rack::Request and ActionDispatch::Request
|
|
34
36
|
if request.respond_to?(:env) && request.respond_to?(:content_type)
|
|
35
37
|
@key = request.env['HTTP_X_PUSHER_KEY']
|
|
36
|
-
@signature = request.env[
|
|
38
|
+
@signature = request.env['HTTP_X_PUSHER_SIGNATURE']
|
|
37
39
|
@content_type = request.content_type
|
|
38
40
|
|
|
39
41
|
request.body.rewind
|
|
@@ -49,25 +51,27 @@ module Sockudo
|
|
|
49
51
|
# matches the configured key & secret. In the case that the webhook is
|
|
50
52
|
# invalid, the reason is logged
|
|
51
53
|
#
|
|
52
|
-
# @param extra_tokens [Hash] If you have extra tokens for your Sockudo app, you can specify them
|
|
54
|
+
# @param extra_tokens [Hash] If you have extra tokens for your Sockudo app, you can specify them
|
|
55
|
+
# so that they're used to attempt validation.
|
|
53
56
|
#
|
|
54
57
|
def valid?(extra_tokens = nil)
|
|
55
|
-
extra_tokens = [extra_tokens] if extra_tokens.
|
|
58
|
+
extra_tokens = [extra_tokens] if extra_tokens.is_a?(Hash)
|
|
56
59
|
if @key == @client.key
|
|
57
|
-
return
|
|
60
|
+
return signature_valid?(@client.secret)
|
|
58
61
|
elsif extra_tokens
|
|
59
62
|
extra_tokens.each do |token|
|
|
60
|
-
return
|
|
63
|
+
return signature_valid?(token[:secret]) if @key == token[:key]
|
|
61
64
|
end
|
|
62
65
|
end
|
|
66
|
+
|
|
63
67
|
Sockudo.logger.warn "Received webhook with unknown key: #{key}"
|
|
64
|
-
|
|
68
|
+
false
|
|
65
69
|
end
|
|
66
70
|
|
|
67
71
|
# Array of events (as Hashes) contained inside the webhook
|
|
68
72
|
#
|
|
69
73
|
def events
|
|
70
|
-
data[
|
|
74
|
+
data['events']
|
|
71
75
|
end
|
|
72
76
|
|
|
73
77
|
# The time at which the WebHook was initially triggered by Sockudo, i.e.
|
|
@@ -76,35 +80,31 @@ module Sockudo
|
|
|
76
80
|
# @return [Time]
|
|
77
81
|
#
|
|
78
82
|
def time
|
|
79
|
-
Time.at(data[
|
|
83
|
+
Time.at(data['time_ms'].to_f / 1000)
|
|
80
84
|
end
|
|
81
85
|
|
|
82
86
|
# Access the parsed WebHook body
|
|
83
87
|
#
|
|
84
88
|
def data
|
|
85
|
-
@data ||=
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
end
|
|
92
|
-
end
|
|
89
|
+
@data ||= case @content_type
|
|
90
|
+
when 'application/json'
|
|
91
|
+
MultiJson.decode(@body)
|
|
92
|
+
else
|
|
93
|
+
raise "Unknown Content-Type (#{@content_type})"
|
|
94
|
+
end
|
|
93
95
|
end
|
|
94
96
|
|
|
95
97
|
private
|
|
96
98
|
|
|
97
99
|
# Checks signature against secret and returns boolean
|
|
98
100
|
#
|
|
99
|
-
def
|
|
100
|
-
digest = OpenSSL::Digest
|
|
101
|
+
def signature_valid?(secret)
|
|
102
|
+
digest = OpenSSL::Digest.new('SHA256')
|
|
101
103
|
expected = OpenSSL::HMAC.hexdigest(digest, secret, @body)
|
|
102
|
-
if @signature == expected
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
return false
|
|
107
|
-
end
|
|
104
|
+
return true if @signature == expected
|
|
105
|
+
|
|
106
|
+
Sockudo.logger.warn "Received WebHook with invalid signature: got #{@signature}, expected #{expected}"
|
|
107
|
+
false
|
|
108
108
|
end
|
|
109
109
|
end
|
|
110
110
|
end
|
data/lib/sockudo.rb
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'logger'
|
|
2
4
|
require 'securerandom'
|
|
3
5
|
require 'uri'
|
|
4
6
|
require 'forwardable'
|
|
7
|
+
require 'pusher-signature'
|
|
5
8
|
|
|
6
9
|
require 'sockudo/utils'
|
|
7
10
|
require 'sockudo/client'
|
|
@@ -19,11 +22,13 @@ module Sockudo
|
|
|
19
22
|
# end
|
|
20
23
|
class Error < RuntimeError; end
|
|
21
24
|
class AuthenticationError < Error; end
|
|
25
|
+
|
|
22
26
|
class ConfigurationError < Error
|
|
23
27
|
def initialize(key)
|
|
24
|
-
super
|
|
28
|
+
super("missing key `#{key}' in the client configuration")
|
|
25
29
|
end
|
|
26
30
|
end
|
|
31
|
+
|
|
27
32
|
class HTTPError < Error; attr_accessor :original_error; end
|
|
28
33
|
|
|
29
34
|
class << self
|
|
@@ -36,10 +41,21 @@ module Sockudo
|
|
|
36
41
|
|
|
37
42
|
def_delegators :default_client, :authentication_token, :url, :cluster
|
|
38
43
|
def_delegators :default_client, :encrypted=, :url=, :cluster=
|
|
39
|
-
def_delegators :default_client, :timeout=, :connect_timeout=, :send_timeout=, :receive_timeout=,
|
|
44
|
+
def_delegators :default_client, :timeout=, :connect_timeout=, :send_timeout=, :receive_timeout=,
|
|
45
|
+
:keep_alive_timeout=
|
|
40
46
|
|
|
41
47
|
def_delegators :default_client, :get, :get_async, :post, :post_async
|
|
42
|
-
def_delegators :default_client, :channels, :channel_info, :channel_users
|
|
48
|
+
def_delegators :default_client, :channels, :channel_info, :channel_history, :channel_users
|
|
49
|
+
def_delegators :default_client, :get_message, :get_message_versions, :update_message,
|
|
50
|
+
:delete_message, :append_message
|
|
51
|
+
def_delegators :default_client, :activate_device, :create_device_activation, :update_device_registration,
|
|
52
|
+
:list_device_registrations, :get_device_registration, :delete_device_registration,
|
|
53
|
+
:remove_device_registrations_by_client, :upsert_channel_push_subscription,
|
|
54
|
+
:list_channel_push_subscriptions, :delete_channel_push_subscriptions,
|
|
55
|
+
:list_channel_push_subscription_channels, :list_push_credentials,
|
|
56
|
+
:put_push_credential, :publish_push, :publish_push_direct, :publish_push_batch,
|
|
57
|
+
:schedule_push, :get_publish_status, :cancel_scheduled_push,
|
|
58
|
+
:post_push_delivery_status
|
|
43
59
|
def_delegators :default_client, :trigger, :trigger_batch, :trigger_async, :trigger_batch_async
|
|
44
60
|
def_delegators :default_client, :authenticate, :webhook, :channel, :[]
|
|
45
61
|
def_delegators :default_client, :notify
|
metadata
CHANGED
|
@@ -1,85 +1,84 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: sockudo
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 2.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Sockudo
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
|
-
name:
|
|
13
|
+
name: httpclient
|
|
15
14
|
requirement: !ruby/object:Gem::Requirement
|
|
16
15
|
requirements:
|
|
17
16
|
- - "~>"
|
|
18
17
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: '
|
|
18
|
+
version: '2.8'
|
|
20
19
|
type: :runtime
|
|
21
20
|
prerelease: false
|
|
22
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
22
|
requirements:
|
|
24
23
|
- - "~>"
|
|
25
24
|
- !ruby/object:Gem::Version
|
|
26
|
-
version: '
|
|
25
|
+
version: '2.8'
|
|
27
26
|
- !ruby/object:Gem::Dependency
|
|
28
|
-
name:
|
|
27
|
+
name: logger
|
|
29
28
|
requirement: !ruby/object:Gem::Requirement
|
|
30
29
|
requirements:
|
|
31
30
|
- - "~>"
|
|
32
31
|
- !ruby/object:Gem::Version
|
|
33
|
-
version:
|
|
32
|
+
version: '1.7'
|
|
34
33
|
type: :runtime
|
|
35
34
|
prerelease: false
|
|
36
35
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
36
|
requirements:
|
|
38
37
|
- - "~>"
|
|
39
38
|
- !ruby/object:Gem::Version
|
|
40
|
-
version:
|
|
39
|
+
version: '1.7'
|
|
41
40
|
- !ruby/object:Gem::Dependency
|
|
42
|
-
name:
|
|
41
|
+
name: multi_json
|
|
43
42
|
requirement: !ruby/object:Gem::Requirement
|
|
44
43
|
requirements:
|
|
45
44
|
- - "~>"
|
|
46
45
|
- !ruby/object:Gem::Version
|
|
47
|
-
version: '
|
|
46
|
+
version: '1.15'
|
|
48
47
|
type: :runtime
|
|
49
48
|
prerelease: false
|
|
50
49
|
version_requirements: !ruby/object:Gem::Requirement
|
|
51
50
|
requirements:
|
|
52
51
|
- - "~>"
|
|
53
52
|
- !ruby/object:Gem::Version
|
|
54
|
-
version: '
|
|
53
|
+
version: '1.15'
|
|
55
54
|
- !ruby/object:Gem::Dependency
|
|
56
|
-
name:
|
|
55
|
+
name: pusher-signature
|
|
57
56
|
requirement: !ruby/object:Gem::Requirement
|
|
58
57
|
requirements:
|
|
59
58
|
- - "~>"
|
|
60
59
|
- !ruby/object:Gem::Version
|
|
61
|
-
version:
|
|
62
|
-
type: :
|
|
60
|
+
version: 0.1.8
|
|
61
|
+
type: :runtime
|
|
63
62
|
prerelease: false
|
|
64
63
|
version_requirements: !ruby/object:Gem::Requirement
|
|
65
64
|
requirements:
|
|
66
65
|
- - "~>"
|
|
67
66
|
- !ruby/object:Gem::Version
|
|
68
|
-
version:
|
|
67
|
+
version: 0.1.8
|
|
69
68
|
- !ruby/object:Gem::Dependency
|
|
70
|
-
name:
|
|
69
|
+
name: addressable
|
|
71
70
|
requirement: !ruby/object:Gem::Requirement
|
|
72
71
|
requirements:
|
|
73
72
|
- - "~>"
|
|
74
73
|
- !ruby/object:Gem::Version
|
|
75
|
-
version: '
|
|
74
|
+
version: '2.7'
|
|
76
75
|
type: :development
|
|
77
76
|
prerelease: false
|
|
78
77
|
version_requirements: !ruby/object:Gem::Requirement
|
|
79
78
|
requirements:
|
|
80
79
|
- - "~>"
|
|
81
80
|
- !ruby/object:Gem::Version
|
|
82
|
-
version: '
|
|
81
|
+
version: '2.7'
|
|
83
82
|
- !ruby/object:Gem::Dependency
|
|
84
83
|
name: em-http-request
|
|
85
84
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -95,19 +94,33 @@ dependencies:
|
|
|
95
94
|
- !ruby/object:Gem::Version
|
|
96
95
|
version: '1.1'
|
|
97
96
|
- !ruby/object:Gem::Dependency
|
|
98
|
-
name:
|
|
97
|
+
name: json
|
|
99
98
|
requirement: !ruby/object:Gem::Requirement
|
|
100
99
|
requirements:
|
|
101
100
|
- - "~>"
|
|
102
101
|
- !ruby/object:Gem::Version
|
|
103
|
-
version: '2.
|
|
102
|
+
version: '2.3'
|
|
104
103
|
type: :development
|
|
105
104
|
prerelease: false
|
|
106
105
|
version_requirements: !ruby/object:Gem::Requirement
|
|
107
106
|
requirements:
|
|
108
107
|
- - "~>"
|
|
109
108
|
- !ruby/object:Gem::Version
|
|
110
|
-
version: '2.
|
|
109
|
+
version: '2.3'
|
|
110
|
+
- !ruby/object:Gem::Dependency
|
|
111
|
+
name: rack
|
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
|
113
|
+
requirements:
|
|
114
|
+
- - "~>"
|
|
115
|
+
- !ruby/object:Gem::Version
|
|
116
|
+
version: '2.2'
|
|
117
|
+
type: :development
|
|
118
|
+
prerelease: false
|
|
119
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
120
|
+
requirements:
|
|
121
|
+
- - "~>"
|
|
122
|
+
- !ruby/object:Gem::Version
|
|
123
|
+
version: '2.2'
|
|
111
124
|
- !ruby/object:Gem::Dependency
|
|
112
125
|
name: rake
|
|
113
126
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -123,47 +136,61 @@ dependencies:
|
|
|
123
136
|
- !ruby/object:Gem::Version
|
|
124
137
|
version: '13.0'
|
|
125
138
|
- !ruby/object:Gem::Dependency
|
|
126
|
-
name:
|
|
139
|
+
name: rbnacl
|
|
127
140
|
requirement: !ruby/object:Gem::Requirement
|
|
128
141
|
requirements:
|
|
129
142
|
- - "~>"
|
|
130
143
|
- !ruby/object:Gem::Version
|
|
131
|
-
version: '
|
|
144
|
+
version: '7.1'
|
|
132
145
|
type: :development
|
|
133
146
|
prerelease: false
|
|
134
147
|
version_requirements: !ruby/object:Gem::Requirement
|
|
135
148
|
requirements:
|
|
136
149
|
- - "~>"
|
|
137
150
|
- !ruby/object:Gem::Version
|
|
138
|
-
version: '
|
|
151
|
+
version: '7.1'
|
|
139
152
|
- !ruby/object:Gem::Dependency
|
|
140
|
-
name:
|
|
153
|
+
name: rspec
|
|
141
154
|
requirement: !ruby/object:Gem::Requirement
|
|
142
155
|
requirements:
|
|
143
156
|
- - "~>"
|
|
144
157
|
- !ruby/object:Gem::Version
|
|
145
|
-
version: '
|
|
158
|
+
version: '3.9'
|
|
146
159
|
type: :development
|
|
147
160
|
prerelease: false
|
|
148
161
|
version_requirements: !ruby/object:Gem::Requirement
|
|
149
162
|
requirements:
|
|
150
163
|
- - "~>"
|
|
151
164
|
- !ruby/object:Gem::Version
|
|
152
|
-
version: '
|
|
165
|
+
version: '3.9'
|
|
153
166
|
- !ruby/object:Gem::Dependency
|
|
154
|
-
name:
|
|
167
|
+
name: rubocop
|
|
155
168
|
requirement: !ruby/object:Gem::Requirement
|
|
156
169
|
requirements:
|
|
157
170
|
- - "~>"
|
|
158
171
|
- !ruby/object:Gem::Version
|
|
159
|
-
version: '
|
|
172
|
+
version: '1.80'
|
|
160
173
|
type: :development
|
|
161
174
|
prerelease: false
|
|
162
175
|
version_requirements: !ruby/object:Gem::Requirement
|
|
163
176
|
requirements:
|
|
164
177
|
- - "~>"
|
|
165
178
|
- !ruby/object:Gem::Version
|
|
166
|
-
version: '
|
|
179
|
+
version: '1.80'
|
|
180
|
+
- !ruby/object:Gem::Dependency
|
|
181
|
+
name: webmock
|
|
182
|
+
requirement: !ruby/object:Gem::Requirement
|
|
183
|
+
requirements:
|
|
184
|
+
- - "~>"
|
|
185
|
+
- !ruby/object:Gem::Version
|
|
186
|
+
version: '3.9'
|
|
187
|
+
type: :development
|
|
188
|
+
prerelease: false
|
|
189
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
190
|
+
requirements:
|
|
191
|
+
- - "~>"
|
|
192
|
+
- !ruby/object:Gem::Version
|
|
193
|
+
version: '3.9'
|
|
167
194
|
description: Wrapper for Sockudo REST API
|
|
168
195
|
email:
|
|
169
196
|
- support@sockudo.com
|
|
@@ -185,8 +212,8 @@ files:
|
|
|
185
212
|
homepage: http://github.com/sockudo/sockudo-http-ruby
|
|
186
213
|
licenses:
|
|
187
214
|
- MIT
|
|
188
|
-
metadata:
|
|
189
|
-
|
|
215
|
+
metadata:
|
|
216
|
+
rubygems_mfa_required: 'true'
|
|
190
217
|
rdoc_options: []
|
|
191
218
|
require_paths:
|
|
192
219
|
- lib
|
|
@@ -201,8 +228,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
201
228
|
- !ruby/object:Gem::Version
|
|
202
229
|
version: '0'
|
|
203
230
|
requirements: []
|
|
204
|
-
rubygems_version: 3.
|
|
205
|
-
signing_key:
|
|
231
|
+
rubygems_version: 3.6.9
|
|
206
232
|
specification_version: 4
|
|
207
233
|
summary: Sockudo API client
|
|
208
234
|
test_files: []
|