assinafy 1.5.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 +7 -0
- data/CHANGELOG.md +168 -0
- data/LICENSE +19 -0
- data/README.md +463 -0
- data/lib/assinafy/client.rb +245 -0
- data/lib/assinafy/configuration.rb +157 -0
- data/lib/assinafy/errors.rb +83 -0
- data/lib/assinafy/null_logger.rb +9 -0
- data/lib/assinafy/resources/account_resource.rb +267 -0
- data/lib/assinafy/resources/assignment_resource.rb +476 -0
- data/lib/assinafy/resources/auth_resource.rb +251 -0
- data/lib/assinafy/resources/base_resource.rb +250 -0
- data/lib/assinafy/resources/document_resource.rb +912 -0
- data/lib/assinafy/resources/field_resource.rb +274 -0
- data/lib/assinafy/resources/signer_document_resource.rb +222 -0
- data/lib/assinafy/resources/signer_resource.rb +422 -0
- data/lib/assinafy/resources/tag_resource.rb +183 -0
- data/lib/assinafy/resources/template_resource.rb +215 -0
- data/lib/assinafy/resources/user_resource.rb +182 -0
- data/lib/assinafy/resources/webhook_resource.rb +222 -0
- data/lib/assinafy/support/webhook_verifier.rb +129 -0
- data/lib/assinafy/utils.rb +122 -0
- data/lib/assinafy/version.rb +5 -0
- data/lib/assinafy.rb +25 -0
- metadata +195 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'openssl'
|
|
4
|
+
require 'json'
|
|
5
|
+
|
|
6
|
+
module Assinafy
|
|
7
|
+
module Support
|
|
8
|
+
# Defensive helper for verifying webhook deliveries when your gateway or
|
|
9
|
+
# proxy signs the body with an HMAC-SHA256 secret.
|
|
10
|
+
#
|
|
11
|
+
# The Assinafy v1 API itself does not currently document a
|
|
12
|
+
# request-signing scheme for webhook deliveries, so this class is opt-in:
|
|
13
|
+
# construct it with a secret only if you have one configured in front
|
|
14
|
+
# of your webhook receiver (e.g. via API Gateway / Cloudflare).
|
|
15
|
+
# HMAC verifies authenticity, not freshness; the receiver must separately
|
|
16
|
+
# reject replayed event IDs or enforce its gateway's timestamp policy.
|
|
17
|
+
#
|
|
18
|
+
# @example Verify and dispatch a webhook
|
|
19
|
+
# verifier = Assinafy::Support::WebhookVerifier.new(ENV['WEBHOOK_SECRET'])
|
|
20
|
+
# raw_body = request.body.read
|
|
21
|
+
# # NOTE: the header below is one YOUR gateway injects (e.g. Cloudflare /
|
|
22
|
+
# # API Gateway). Assinafy v1 does not send a signature header itself.
|
|
23
|
+
# if verifier.verify(raw_body, request.headers['X-Webhook-Signature'])
|
|
24
|
+
# event = verifier.extract_event(raw_body)
|
|
25
|
+
# verifier.event_type(event) # => "assignment_created"
|
|
26
|
+
# verifier.event_payload(event) # => { "user_name" => "John", ... } (or nil)
|
|
27
|
+
# verifier.event_object(event) # => { "id" => "doc2", "type" => "Document", ... }
|
|
28
|
+
# verifier.event_subject(event) # => { "id" => "...", "type" => "User", ... }
|
|
29
|
+
# end
|
|
30
|
+
class WebhookVerifier
|
|
31
|
+
# @param webhook_secret [String, nil] shared secret. When nil/empty,
|
|
32
|
+
# {#verify} always returns false (safe-by-default).
|
|
33
|
+
def initialize(webhook_secret = nil)
|
|
34
|
+
@webhook_secret = webhook_secret
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Constant-time compare the provided signature to the expected
|
|
38
|
+
# HMAC-SHA256 of the raw payload.
|
|
39
|
+
#
|
|
40
|
+
# @param payload [String] raw HTTP body
|
|
41
|
+
# @param signature [String] hex-encoded signature header value
|
|
42
|
+
# @return [Boolean]
|
|
43
|
+
def verify(payload, signature)
|
|
44
|
+
return false unless @webhook_secret && !@webhook_secret.empty?
|
|
45
|
+
return false unless signature && !signature.to_s.strip.empty?
|
|
46
|
+
|
|
47
|
+
body = payload.is_a?(String) ? payload : payload.to_s
|
|
48
|
+
expected = OpenSSL::HMAC.hexdigest('SHA256', @webhook_secret, body)
|
|
49
|
+
provided = signature.to_s.strip
|
|
50
|
+
|
|
51
|
+
OpenSSL.fixed_length_secure_compare(expected, provided)
|
|
52
|
+
rescue StandardError
|
|
53
|
+
false
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Parse a JSON webhook body into a Hash, returning nil on malformed or
|
|
57
|
+
# non-object payloads.
|
|
58
|
+
#
|
|
59
|
+
# @param payload [String]
|
|
60
|
+
# @return [Hash, nil]
|
|
61
|
+
def extract_event(payload)
|
|
62
|
+
text = payload.is_a?(String) ? payload : payload.to_s
|
|
63
|
+
parsed = JSON.parse(text)
|
|
64
|
+
parsed.is_a?(Hash) ? parsed : nil
|
|
65
|
+
rescue JSON::ParserError
|
|
66
|
+
nil
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Pull the event-type code from a parsed event Hash. The canonical key in
|
|
70
|
+
# the Assinafy v1 delivery envelope is `event` (e.g. `assignment_created`).
|
|
71
|
+
#
|
|
72
|
+
# @param event [Hash, nil]
|
|
73
|
+
# @return [String, nil]
|
|
74
|
+
# @example
|
|
75
|
+
# verifier.event_type({ 'event' => 'document_ready' }) # => "document_ready"
|
|
76
|
+
def event_type(event)
|
|
77
|
+
return nil unless event.is_a?(Hash)
|
|
78
|
+
|
|
79
|
+
event['event']
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# The event-specific data snapshot (the documented top-level `payload`).
|
|
83
|
+
# May be `nil` for events that carry no extra params (e.g.
|
|
84
|
+
# `document_uploaded`).
|
|
85
|
+
#
|
|
86
|
+
# @param event [Hash, nil]
|
|
87
|
+
# @return [Hash, nil]
|
|
88
|
+
def event_payload(event)
|
|
89
|
+
return nil unless event.is_a?(Hash)
|
|
90
|
+
|
|
91
|
+
event['payload']
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# The entity the event acted on (the documented top-level `object`),
|
|
95
|
+
# e.g. the Document. Includes a `type` discriminator.
|
|
96
|
+
#
|
|
97
|
+
# @param event [Hash, nil]
|
|
98
|
+
# @return [Hash]
|
|
99
|
+
def event_object(event)
|
|
100
|
+
return {} unless event.is_a?(Hash)
|
|
101
|
+
|
|
102
|
+
event['object'] || {}
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# The actor that triggered the event (the documented top-level `subject`),
|
|
106
|
+
# e.g. the User. Includes a `type` discriminator.
|
|
107
|
+
#
|
|
108
|
+
# @param event [Hash, nil]
|
|
109
|
+
# @return [Hash]
|
|
110
|
+
def event_subject(event)
|
|
111
|
+
return {} unless event.is_a?(Hash)
|
|
112
|
+
|
|
113
|
+
event['subject'] || {}
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# @deprecated Prefer {#event_payload} (event params) and {#event_object}
|
|
117
|
+
# (acted-on entity). The Assinafy envelope has no top-level `data` key;
|
|
118
|
+
# this returns `payload` and falls back to `object` for convenience.
|
|
119
|
+
#
|
|
120
|
+
# @param event [Hash, nil]
|
|
121
|
+
# @return [Hash]
|
|
122
|
+
def event_data(event)
|
|
123
|
+
return {} unless event.is_a?(Hash)
|
|
124
|
+
|
|
125
|
+
event['payload'] || event['object'] || {}
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Assinafy
|
|
4
|
+
# Small, stateless helpers shared across resources. Intentionally private
|
|
5
|
+
# by convention — callers should reach for these via the resource methods,
|
|
6
|
+
# not directly.
|
|
7
|
+
module Utils
|
|
8
|
+
MAX_NORMALIZATION_DEPTH = 100
|
|
9
|
+
|
|
10
|
+
class << self
|
|
11
|
+
# Unwrap an Assinafy envelope — a Hash with a numeric `status` and an
|
|
12
|
+
# optional `data` key. Returns `data` (or nil) for 2xx, raises {ApiError}
|
|
13
|
+
# otherwise, and passes through non-envelope bodies.
|
|
14
|
+
#
|
|
15
|
+
# @param body [Hash, Object]
|
|
16
|
+
# @return [Object]
|
|
17
|
+
def handle_assinafy_response(body)
|
|
18
|
+
return body unless body.is_a?(Hash)
|
|
19
|
+
return body unless body.key?('status')
|
|
20
|
+
|
|
21
|
+
status = Integer(body['status'], exception: false)
|
|
22
|
+
return body unless status
|
|
23
|
+
|
|
24
|
+
if status >= 200 && status < 300
|
|
25
|
+
body['data'] if body.key?('data')
|
|
26
|
+
else
|
|
27
|
+
raise ApiError.from_response(status, body)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Drop nil values (but keep `false`).
|
|
32
|
+
#
|
|
33
|
+
# @param hash [Hash, nil]
|
|
34
|
+
# @return [Hash]
|
|
35
|
+
def clean_params(hash)
|
|
36
|
+
return {} if hash.nil?
|
|
37
|
+
raise ValidationError.new('Parameters must be a Hash') unless hash.is_a?(Hash)
|
|
38
|
+
|
|
39
|
+
hash.each_with_object({}) do |(key, value), result|
|
|
40
|
+
result[key] = value unless value.nil?
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Build a query-string Hash, translating the Ruby-friendly snake_case
|
|
45
|
+
# aliases in {query_key_map} to the hyphenated forms documented in the
|
|
46
|
+
# Assinafy API (e.g. `per_page` → `per-page`).
|
|
47
|
+
#
|
|
48
|
+
# @param hash [Hash, nil]
|
|
49
|
+
# @return [Hash{String=>Object}]
|
|
50
|
+
def query_params(hash)
|
|
51
|
+
normalize_keys(clean_params(hash), query_key_map)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Build a body Hash, translating documented hyphenated body keys
|
|
55
|
+
# (`signer-access-code`, `verification-code`) while passing everything
|
|
56
|
+
# else through as-is.
|
|
57
|
+
#
|
|
58
|
+
# @param hash [Hash, nil]
|
|
59
|
+
# @return [Hash{String=>Object}]
|
|
60
|
+
def body_params(hash)
|
|
61
|
+
normalize_keys(clean_params(hash), body_key_map)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
private
|
|
65
|
+
|
|
66
|
+
def normalize_keys(hash, key_map, seen = {}.compare_by_identity, depth = 0)
|
|
67
|
+
if depth > MAX_NORMALIZATION_DEPTH || seen.key?(hash)
|
|
68
|
+
raise ValidationError.new('Parameters are nested too deeply or contain a cycle')
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
seen[hash] = true
|
|
72
|
+
hash.each_with_object({}) do |(key, value), result|
|
|
73
|
+
result[normalize_key(key, key_map)] = normalize_value(value, key_map, seen, depth)
|
|
74
|
+
end
|
|
75
|
+
ensure
|
|
76
|
+
seen.delete(hash)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def normalize_value(value, key_map, seen, depth)
|
|
80
|
+
case value
|
|
81
|
+
when Hash
|
|
82
|
+
normalize_keys(value, key_map, seen, depth + 1)
|
|
83
|
+
when Array
|
|
84
|
+
normalize_array(value, key_map, seen, depth + 1)
|
|
85
|
+
else
|
|
86
|
+
value
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def normalize_array(array, key_map, seen, depth)
|
|
91
|
+
if depth > MAX_NORMALIZATION_DEPTH || seen.key?(array)
|
|
92
|
+
raise ValidationError.new('Parameters are nested too deeply or contain a cycle')
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
seen[array] = true
|
|
96
|
+
array.map { |item| normalize_value(item, key_map, seen, depth) }
|
|
97
|
+
ensure
|
|
98
|
+
seen.delete(array)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def normalize_key(key, key_map)
|
|
102
|
+
raw = key.to_s
|
|
103
|
+
key_map.fetch(raw, raw)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def query_key_map
|
|
107
|
+
{
|
|
108
|
+
'access_token' => 'access-token',
|
|
109
|
+
'per_page' => 'per-page',
|
|
110
|
+
'signer_access_code' => 'signer-access-code'
|
|
111
|
+
}
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def body_key_map
|
|
115
|
+
{
|
|
116
|
+
'signer_access_code' => 'signer-access-code',
|
|
117
|
+
'verification_code' => 'verification-code'
|
|
118
|
+
}
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|
data/lib/assinafy.rb
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'faraday'
|
|
4
|
+
require 'faraday/multipart'
|
|
5
|
+
require 'stringio'
|
|
6
|
+
|
|
7
|
+
require_relative 'assinafy/version'
|
|
8
|
+
require_relative 'assinafy/errors'
|
|
9
|
+
require_relative 'assinafy/null_logger'
|
|
10
|
+
require_relative 'assinafy/configuration'
|
|
11
|
+
require_relative 'assinafy/utils'
|
|
12
|
+
require_relative 'assinafy/resources/base_resource'
|
|
13
|
+
require_relative 'assinafy/resources/auth_resource'
|
|
14
|
+
require_relative 'assinafy/resources/account_resource'
|
|
15
|
+
require_relative 'assinafy/resources/user_resource'
|
|
16
|
+
require_relative 'assinafy/resources/document_resource'
|
|
17
|
+
require_relative 'assinafy/resources/signer_resource'
|
|
18
|
+
require_relative 'assinafy/resources/signer_document_resource'
|
|
19
|
+
require_relative 'assinafy/resources/assignment_resource'
|
|
20
|
+
require_relative 'assinafy/resources/webhook_resource'
|
|
21
|
+
require_relative 'assinafy/resources/template_resource'
|
|
22
|
+
require_relative 'assinafy/resources/field_resource'
|
|
23
|
+
require_relative 'assinafy/resources/tag_resource'
|
|
24
|
+
require_relative 'assinafy/support/webhook_verifier'
|
|
25
|
+
require_relative 'assinafy/client'
|
metadata
ADDED
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: assinafy
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 1.5.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Assinafy SDK Contributors
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: faraday
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: 2.14.3
|
|
19
|
+
- - "<"
|
|
20
|
+
- !ruby/object:Gem::Version
|
|
21
|
+
version: '3.0'
|
|
22
|
+
type: :runtime
|
|
23
|
+
prerelease: false
|
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
25
|
+
requirements:
|
|
26
|
+
- - ">="
|
|
27
|
+
- !ruby/object:Gem::Version
|
|
28
|
+
version: 2.14.3
|
|
29
|
+
- - "<"
|
|
30
|
+
- !ruby/object:Gem::Version
|
|
31
|
+
version: '3.0'
|
|
32
|
+
- !ruby/object:Gem::Dependency
|
|
33
|
+
name: faraday-multipart
|
|
34
|
+
requirement: !ruby/object:Gem::Requirement
|
|
35
|
+
requirements:
|
|
36
|
+
- - ">="
|
|
37
|
+
- !ruby/object:Gem::Version
|
|
38
|
+
version: '1.0'
|
|
39
|
+
- - "<"
|
|
40
|
+
- !ruby/object:Gem::Version
|
|
41
|
+
version: '2.0'
|
|
42
|
+
type: :runtime
|
|
43
|
+
prerelease: false
|
|
44
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
45
|
+
requirements:
|
|
46
|
+
- - ">="
|
|
47
|
+
- !ruby/object:Gem::Version
|
|
48
|
+
version: '1.0'
|
|
49
|
+
- - "<"
|
|
50
|
+
- !ruby/object:Gem::Version
|
|
51
|
+
version: '2.0'
|
|
52
|
+
- !ruby/object:Gem::Dependency
|
|
53
|
+
name: bundler-audit
|
|
54
|
+
requirement: !ruby/object:Gem::Requirement
|
|
55
|
+
requirements:
|
|
56
|
+
- - "~>"
|
|
57
|
+
- !ruby/object:Gem::Version
|
|
58
|
+
version: '0.9'
|
|
59
|
+
type: :development
|
|
60
|
+
prerelease: false
|
|
61
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
62
|
+
requirements:
|
|
63
|
+
- - "~>"
|
|
64
|
+
- !ruby/object:Gem::Version
|
|
65
|
+
version: '0.9'
|
|
66
|
+
- !ruby/object:Gem::Dependency
|
|
67
|
+
name: rake
|
|
68
|
+
requirement: !ruby/object:Gem::Requirement
|
|
69
|
+
requirements:
|
|
70
|
+
- - "~>"
|
|
71
|
+
- !ruby/object:Gem::Version
|
|
72
|
+
version: '13.0'
|
|
73
|
+
type: :development
|
|
74
|
+
prerelease: false
|
|
75
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
76
|
+
requirements:
|
|
77
|
+
- - "~>"
|
|
78
|
+
- !ruby/object:Gem::Version
|
|
79
|
+
version: '13.0'
|
|
80
|
+
- !ruby/object:Gem::Dependency
|
|
81
|
+
name: rspec
|
|
82
|
+
requirement: !ruby/object:Gem::Requirement
|
|
83
|
+
requirements:
|
|
84
|
+
- - "~>"
|
|
85
|
+
- !ruby/object:Gem::Version
|
|
86
|
+
version: '3.0'
|
|
87
|
+
type: :development
|
|
88
|
+
prerelease: false
|
|
89
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
90
|
+
requirements:
|
|
91
|
+
- - "~>"
|
|
92
|
+
- !ruby/object:Gem::Version
|
|
93
|
+
version: '3.0'
|
|
94
|
+
- !ruby/object:Gem::Dependency
|
|
95
|
+
name: rubocop
|
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
|
97
|
+
requirements:
|
|
98
|
+
- - "~>"
|
|
99
|
+
- !ruby/object:Gem::Version
|
|
100
|
+
version: '1.86'
|
|
101
|
+
type: :development
|
|
102
|
+
prerelease: false
|
|
103
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
104
|
+
requirements:
|
|
105
|
+
- - "~>"
|
|
106
|
+
- !ruby/object:Gem::Version
|
|
107
|
+
version: '1.86'
|
|
108
|
+
- !ruby/object:Gem::Dependency
|
|
109
|
+
name: rubocop-rspec
|
|
110
|
+
requirement: !ruby/object:Gem::Requirement
|
|
111
|
+
requirements:
|
|
112
|
+
- - "~>"
|
|
113
|
+
- !ruby/object:Gem::Version
|
|
114
|
+
version: '3.6'
|
|
115
|
+
type: :development
|
|
116
|
+
prerelease: false
|
|
117
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
118
|
+
requirements:
|
|
119
|
+
- - "~>"
|
|
120
|
+
- !ruby/object:Gem::Version
|
|
121
|
+
version: '3.6'
|
|
122
|
+
- !ruby/object:Gem::Dependency
|
|
123
|
+
name: webmock
|
|
124
|
+
requirement: !ruby/object:Gem::Requirement
|
|
125
|
+
requirements:
|
|
126
|
+
- - "~>"
|
|
127
|
+
- !ruby/object:Gem::Version
|
|
128
|
+
version: '3.0'
|
|
129
|
+
type: :development
|
|
130
|
+
prerelease: false
|
|
131
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
132
|
+
requirements:
|
|
133
|
+
- - "~>"
|
|
134
|
+
- !ruby/object:Gem::Version
|
|
135
|
+
version: '3.0'
|
|
136
|
+
description: Ruby SDK for Assinafy. Covers the documented authentication, account,
|
|
137
|
+
user, document, signer, assignment, webhook, template, tag, and field APIs, plus
|
|
138
|
+
the high-level upload_and_request_signatures helper.
|
|
139
|
+
email:
|
|
140
|
+
- sdk@assinafy.com.br
|
|
141
|
+
executables: []
|
|
142
|
+
extensions: []
|
|
143
|
+
extra_rdoc_files: []
|
|
144
|
+
files:
|
|
145
|
+
- CHANGELOG.md
|
|
146
|
+
- LICENSE
|
|
147
|
+
- README.md
|
|
148
|
+
- lib/assinafy.rb
|
|
149
|
+
- lib/assinafy/client.rb
|
|
150
|
+
- lib/assinafy/configuration.rb
|
|
151
|
+
- lib/assinafy/errors.rb
|
|
152
|
+
- lib/assinafy/null_logger.rb
|
|
153
|
+
- lib/assinafy/resources/account_resource.rb
|
|
154
|
+
- lib/assinafy/resources/assignment_resource.rb
|
|
155
|
+
- lib/assinafy/resources/auth_resource.rb
|
|
156
|
+
- lib/assinafy/resources/base_resource.rb
|
|
157
|
+
- lib/assinafy/resources/document_resource.rb
|
|
158
|
+
- lib/assinafy/resources/field_resource.rb
|
|
159
|
+
- lib/assinafy/resources/signer_document_resource.rb
|
|
160
|
+
- lib/assinafy/resources/signer_resource.rb
|
|
161
|
+
- lib/assinafy/resources/tag_resource.rb
|
|
162
|
+
- lib/assinafy/resources/template_resource.rb
|
|
163
|
+
- lib/assinafy/resources/user_resource.rb
|
|
164
|
+
- lib/assinafy/resources/webhook_resource.rb
|
|
165
|
+
- lib/assinafy/support/webhook_verifier.rb
|
|
166
|
+
- lib/assinafy/utils.rb
|
|
167
|
+
- lib/assinafy/version.rb
|
|
168
|
+
homepage: https://github.com/assinafy/ruby-sdk
|
|
169
|
+
licenses:
|
|
170
|
+
- MIT
|
|
171
|
+
metadata:
|
|
172
|
+
source_code_uri: https://github.com/assinafy/ruby-sdk
|
|
173
|
+
bug_tracker_uri: https://github.com/assinafy/ruby-sdk/issues
|
|
174
|
+
changelog_uri: https://github.com/assinafy/ruby-sdk/blob/main/CHANGELOG.md
|
|
175
|
+
documentation_uri: https://api.assinafy.com.br/v1/docs
|
|
176
|
+
github_repo: ssh://github.com/assinafy/ruby-sdk
|
|
177
|
+
rubygems_mfa_required: 'true'
|
|
178
|
+
rdoc_options: []
|
|
179
|
+
require_paths:
|
|
180
|
+
- lib
|
|
181
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
182
|
+
requirements:
|
|
183
|
+
- - ">="
|
|
184
|
+
- !ruby/object:Gem::Version
|
|
185
|
+
version: '3.2'
|
|
186
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
187
|
+
requirements:
|
|
188
|
+
- - ">="
|
|
189
|
+
- !ruby/object:Gem::Version
|
|
190
|
+
version: '0'
|
|
191
|
+
requirements: []
|
|
192
|
+
rubygems_version: 4.0.16
|
|
193
|
+
specification_version: 4
|
|
194
|
+
summary: Ruby SDK for the Assinafy digital signature API
|
|
195
|
+
test_files: []
|