clicksign-ruby-sdk 0.1.1
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/README.md +535 -0
- data/lib/clicksign/client.rb +143 -0
- data/lib/clicksign/configuration.rb +29 -0
- data/lib/clicksign/error_handler.rb +56 -0
- data/lib/clicksign/errors.rb +53 -0
- data/lib/clicksign/instrumentation.rb +32 -0
- data/lib/clicksign/json_api/atomic_results_parser.rb +61 -0
- data/lib/clicksign/json_api/bulk_operations_client.rb +95 -0
- data/lib/clicksign/json_api/operations/bulk_requirement.rb +89 -0
- data/lib/clicksign/json_api/operations.rb +38 -0
- data/lib/clicksign/json_api/parser.rb +31 -0
- data/lib/clicksign/json_api/query_builder.rb +45 -0
- data/lib/clicksign/json_api/serializer.rb +14 -0
- data/lib/clicksign/resource.rb +263 -0
- data/lib/clicksign/resources/acceptance_term/whatsapp.rb +12 -0
- data/lib/clicksign/resources/access_control_list.rb +35 -0
- data/lib/clicksign/resources/auto_signature/term.rb +12 -0
- data/lib/clicksign/resources/envelope_bulk_creation.rb +9 -0
- data/lib/clicksign/resources/folder.rb +22 -0
- data/lib/clicksign/resources/group.rb +21 -0
- data/lib/clicksign/resources/membership.rb +21 -0
- data/lib/clicksign/resources/notarial/bulk_requirement.rb +67 -0
- data/lib/clicksign/resources/notarial/document.rb +40 -0
- data/lib/clicksign/resources/notarial/envelope.rb +80 -0
- data/lib/clicksign/resources/notarial/event.rb +20 -0
- data/lib/clicksign/resources/notarial/requirement.rb +63 -0
- data/lib/clicksign/resources/notarial/signature_watcher.rb +39 -0
- data/lib/clicksign/resources/notarial/signer.rb +56 -0
- data/lib/clicksign/resources/template.rb +13 -0
- data/lib/clicksign/resources/template_field.rb +9 -0
- data/lib/clicksign/resources/user.rb +15 -0
- data/lib/clicksign/resources/webhook.rb +9 -0
- data/lib/clicksign/services.rb +35 -0
- data/lib/clicksign/version.rb +5 -0
- data/lib/clicksign/webhook.rb +41 -0
- data/lib/clicksign.rb +73 -0
- metadata +81 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Clicksign
|
|
4
|
+
module Resources
|
|
5
|
+
module Notarial
|
|
6
|
+
class SignatureWatcher < Clicksign::Resource
|
|
7
|
+
self.resource_type = 'signature_watchers'
|
|
8
|
+
|
|
9
|
+
def self.retrieve(id, envelope_id:)
|
|
10
|
+
raw = client.get("/envelopes/#{envelope_id}/signature_watchers/#{id}")
|
|
11
|
+
parsed = JsonApi::Parser.parse(raw)
|
|
12
|
+
build_instance(parsed[:data].first, parent_id: envelope_id)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def self.create(envelope_id:, **attributes)
|
|
16
|
+
raw = client.post(
|
|
17
|
+
"/envelopes/#{envelope_id}/signature_watchers",
|
|
18
|
+
body: JsonApi::Serializer.dump(type: resource_type, attributes: attributes),
|
|
19
|
+
)
|
|
20
|
+
parsed = JsonApi::Parser.parse(raw)
|
|
21
|
+
build_instance(parsed[:data].first, parent_id: envelope_id)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def base_path
|
|
25
|
+
"/envelopes/#{@_parent_id || envelope_id}/signature_watchers"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def update(**)
|
|
29
|
+
raise NotImplementedError,
|
|
30
|
+
'SignatureWatcher does not support update (route: except: [:update])'
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def envelope_id
|
|
34
|
+
@_parent_id || relationships.dig('envelope', 'data', 'id')
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Clicksign
|
|
4
|
+
module Resources
|
|
5
|
+
module Notarial
|
|
6
|
+
class Signer < Clicksign::Resource
|
|
7
|
+
self.resource_type = 'signers'
|
|
8
|
+
|
|
9
|
+
def self.retrieve(id, envelope_id:)
|
|
10
|
+
raw = client.get("/envelopes/#{envelope_id}/signers/#{id}")
|
|
11
|
+
parsed = JsonApi::Parser.parse(raw)
|
|
12
|
+
build_instance(parsed[:data].first, parent_id: envelope_id)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def self.create(envelope_id:, **attributes)
|
|
16
|
+
raw = client.post(
|
|
17
|
+
"/envelopes/#{envelope_id}/signers",
|
|
18
|
+
body: JsonApi::Serializer.dump(type: resource_type, attributes: attributes),
|
|
19
|
+
)
|
|
20
|
+
parsed = JsonApi::Parser.parse(raw)
|
|
21
|
+
build_instance(parsed[:data].first, parent_id: envelope_id)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def self.notify(id, envelope_id:, message: nil, **email_customization)
|
|
25
|
+
attributes = {}
|
|
26
|
+
attributes[:message] = message if message
|
|
27
|
+
unless email_customization.empty?
|
|
28
|
+
attributes[:email_customization] =
|
|
29
|
+
email_customization
|
|
30
|
+
end
|
|
31
|
+
body = { data: { type: 'notifications', attributes: attributes } }
|
|
32
|
+
client.post("/envelopes/#{envelope_id}/signers/#{id}/notifications", body: body)
|
|
33
|
+
nil
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def notify(message: nil, **email_customization)
|
|
37
|
+
self.class.notify(@id, envelope_id: envelope_id, message: message,
|
|
38
|
+
**email_customization)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def update(**)
|
|
42
|
+
raise NotImplementedError,
|
|
43
|
+
'Signer does not support update (route: except: [:update])'
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def base_path
|
|
47
|
+
"/envelopes/#{@_parent_id || envelope_id}/signers"
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def envelope_id
|
|
51
|
+
@_parent_id || relationships.dig('envelope', 'data', 'id')
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Clicksign
|
|
4
|
+
module Resources
|
|
5
|
+
class Template < Clicksign::Resource
|
|
6
|
+
self.resource_type = 'templates'
|
|
7
|
+
|
|
8
|
+
def self.list_template_fields(template_id)
|
|
9
|
+
nested_list(template_id, nested_type: 'template_fields', as: TemplateField)
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Clicksign
|
|
4
|
+
module Resources
|
|
5
|
+
class User < Clicksign::Resource
|
|
6
|
+
self.resource_type = 'users'
|
|
7
|
+
|
|
8
|
+
def self.me
|
|
9
|
+
raw = client.get('/users/me')
|
|
10
|
+
parsed = JsonApi::Parser.parse(raw)
|
|
11
|
+
build_instance(parsed[:data].first)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Clicksign
|
|
4
|
+
class Services
|
|
5
|
+
def initialize(api_key:, environment: :production, base_url: nil,
|
|
6
|
+
open_timeout: 2, read_timeout: 10, write_timeout: 10, max_retries: 0)
|
|
7
|
+
resolved_url = base_url || resolve_environment(environment)
|
|
8
|
+
@client = Client.new(
|
|
9
|
+
api_key: api_key,
|
|
10
|
+
base_url: resolved_url,
|
|
11
|
+
open_timeout: open_timeout,
|
|
12
|
+
read_timeout: read_timeout,
|
|
13
|
+
write_timeout: write_timeout,
|
|
14
|
+
max_retries: max_retries,
|
|
15
|
+
)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def use
|
|
19
|
+
previous = Thread.current[:clicksign_client]
|
|
20
|
+
Thread.current[:clicksign_client] = @client
|
|
21
|
+
yield
|
|
22
|
+
ensure
|
|
23
|
+
Thread.current[:clicksign_client] = previous
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
|
|
28
|
+
def resolve_environment(env)
|
|
29
|
+
Configuration::ENVIRONMENTS.fetch(env.to_sym) do
|
|
30
|
+
valid = Configuration::ENVIRONMENTS.keys.join(', ')
|
|
31
|
+
raise ArgumentError, "Unknown environment: #{env}. Valid: #{valid}"
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'openssl'
|
|
4
|
+
|
|
5
|
+
module Clicksign
|
|
6
|
+
module Webhook
|
|
7
|
+
DIGEST = 'sha256'
|
|
8
|
+
|
|
9
|
+
# Raises WebhookSignatureError if the Content-HMAC header does not match.
|
|
10
|
+
def self.verify_signature!(payload, signature, secret:)
|
|
11
|
+
expected = compute_signature(payload, secret: secret)
|
|
12
|
+
raise WebhookSignatureError, 'Webhook signature mismatch' unless secure_compare?(
|
|
13
|
+
expected, signature
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
true
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Returns true/false instead of raising.
|
|
20
|
+
def self.verify_signature(payload, signature, secret:)
|
|
21
|
+
verify_signature!(payload, signature, secret: secret)
|
|
22
|
+
rescue WebhookSignatureError
|
|
23
|
+
false
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Computes the expected Content-HMAC value for a given payload and secret.
|
|
27
|
+
def self.compute_signature(payload, secret:)
|
|
28
|
+
"#{DIGEST}=#{OpenSSL::HMAC.hexdigest(DIGEST, secret, payload)}"
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Constant-time comparison to prevent timing attacks.
|
|
32
|
+
def self.secure_compare?(expected, actual)
|
|
33
|
+
digest_a = OpenSSL::Digest::SHA256.hexdigest(expected)
|
|
34
|
+
digest_b = OpenSSL::Digest::SHA256.hexdigest(actual)
|
|
35
|
+
result = 0
|
|
36
|
+
digest_a.bytes.zip(digest_b.bytes) { |x, y| result |= x ^ y }
|
|
37
|
+
result.zero?
|
|
38
|
+
end
|
|
39
|
+
private_class_method :secure_compare?
|
|
40
|
+
end
|
|
41
|
+
end
|
data/lib/clicksign.rb
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'json'
|
|
4
|
+
require 'net/http'
|
|
5
|
+
require 'uri'
|
|
6
|
+
|
|
7
|
+
require_relative 'clicksign/version'
|
|
8
|
+
require_relative 'clicksign/configuration'
|
|
9
|
+
require_relative 'clicksign/errors'
|
|
10
|
+
require_relative 'clicksign/error_handler'
|
|
11
|
+
require_relative 'clicksign/instrumentation'
|
|
12
|
+
require_relative 'clicksign/webhook'
|
|
13
|
+
require_relative 'clicksign/json_api/query_builder'
|
|
14
|
+
require_relative 'clicksign/json_api/serializer'
|
|
15
|
+
require_relative 'clicksign/json_api/parser'
|
|
16
|
+
require_relative 'clicksign/json_api/operations'
|
|
17
|
+
require_relative 'clicksign/json_api/operations/bulk_requirement'
|
|
18
|
+
require_relative 'clicksign/json_api/atomic_results_parser'
|
|
19
|
+
require_relative 'clicksign/client'
|
|
20
|
+
require_relative 'clicksign/json_api/bulk_operations_client'
|
|
21
|
+
require_relative 'clicksign/resource'
|
|
22
|
+
require_relative 'clicksign/services'
|
|
23
|
+
|
|
24
|
+
Dir[File.join(__dir__, 'clicksign', 'resources', '**', '*.rb')].each do |file|
|
|
25
|
+
require file
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
module Clicksign
|
|
29
|
+
class << self
|
|
30
|
+
# Must be called once at application startup, before any threads are spawned.
|
|
31
|
+
# Module-level memoisation (@client, @configuration) is not thread-safe for
|
|
32
|
+
# concurrent first-access; subsequent calls are safe once initialised.
|
|
33
|
+
def configure
|
|
34
|
+
yield configuration
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def configuration
|
|
38
|
+
@configuration ||= Configuration.new
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def client
|
|
42
|
+
@client ||= Client.new(
|
|
43
|
+
api_key: configuration.api_key,
|
|
44
|
+
base_url: configuration.base_url,
|
|
45
|
+
open_timeout: configuration.open_timeout,
|
|
46
|
+
read_timeout: configuration.read_timeout,
|
|
47
|
+
write_timeout: configuration.write_timeout,
|
|
48
|
+
max_retries: configuration.max_retries,
|
|
49
|
+
)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def bulk_operations_client
|
|
53
|
+
@bulk_operations_client ||= JsonApi::BulkOperationsClient.new(
|
|
54
|
+
api_key: configuration.api_key,
|
|
55
|
+
base_url: configuration.base_url,
|
|
56
|
+
open_timeout: configuration.open_timeout,
|
|
57
|
+
read_timeout: configuration.read_timeout,
|
|
58
|
+
write_timeout: configuration.write_timeout,
|
|
59
|
+
max_retries: configuration.max_retries,
|
|
60
|
+
)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def on_request(&block) = Instrumentation.on(:request, &block)
|
|
64
|
+
def on_retry(&block) = Instrumentation.on(:retry, &block)
|
|
65
|
+
def on_error(&block) = Instrumentation.on(:error, &block)
|
|
66
|
+
|
|
67
|
+
def reset!
|
|
68
|
+
@configuration = nil
|
|
69
|
+
@client = nil
|
|
70
|
+
@bulk_operations_client = nil
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: clicksign-ruby-sdk
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.1
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Clicksign
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies: []
|
|
12
|
+
description: Official Ruby SDK for the Clicksign e-signature API (v3). Supports envelope
|
|
13
|
+
management, signing workflows and webhooks. JSON:API compliant, no runtime dependencies
|
|
14
|
+
beyond the Ruby stdlib.
|
|
15
|
+
executables: []
|
|
16
|
+
extensions: []
|
|
17
|
+
extra_rdoc_files: []
|
|
18
|
+
files:
|
|
19
|
+
- README.md
|
|
20
|
+
- lib/clicksign.rb
|
|
21
|
+
- lib/clicksign/client.rb
|
|
22
|
+
- lib/clicksign/configuration.rb
|
|
23
|
+
- lib/clicksign/error_handler.rb
|
|
24
|
+
- lib/clicksign/errors.rb
|
|
25
|
+
- lib/clicksign/instrumentation.rb
|
|
26
|
+
- lib/clicksign/json_api/atomic_results_parser.rb
|
|
27
|
+
- lib/clicksign/json_api/bulk_operations_client.rb
|
|
28
|
+
- lib/clicksign/json_api/operations.rb
|
|
29
|
+
- lib/clicksign/json_api/operations/bulk_requirement.rb
|
|
30
|
+
- lib/clicksign/json_api/parser.rb
|
|
31
|
+
- lib/clicksign/json_api/query_builder.rb
|
|
32
|
+
- lib/clicksign/json_api/serializer.rb
|
|
33
|
+
- lib/clicksign/resource.rb
|
|
34
|
+
- lib/clicksign/resources/acceptance_term/whatsapp.rb
|
|
35
|
+
- lib/clicksign/resources/access_control_list.rb
|
|
36
|
+
- lib/clicksign/resources/auto_signature/term.rb
|
|
37
|
+
- lib/clicksign/resources/envelope_bulk_creation.rb
|
|
38
|
+
- lib/clicksign/resources/folder.rb
|
|
39
|
+
- lib/clicksign/resources/group.rb
|
|
40
|
+
- lib/clicksign/resources/membership.rb
|
|
41
|
+
- lib/clicksign/resources/notarial/bulk_requirement.rb
|
|
42
|
+
- lib/clicksign/resources/notarial/document.rb
|
|
43
|
+
- lib/clicksign/resources/notarial/envelope.rb
|
|
44
|
+
- lib/clicksign/resources/notarial/event.rb
|
|
45
|
+
- lib/clicksign/resources/notarial/requirement.rb
|
|
46
|
+
- lib/clicksign/resources/notarial/signature_watcher.rb
|
|
47
|
+
- lib/clicksign/resources/notarial/signer.rb
|
|
48
|
+
- lib/clicksign/resources/template.rb
|
|
49
|
+
- lib/clicksign/resources/template_field.rb
|
|
50
|
+
- lib/clicksign/resources/user.rb
|
|
51
|
+
- lib/clicksign/resources/webhook.rb
|
|
52
|
+
- lib/clicksign/services.rb
|
|
53
|
+
- lib/clicksign/version.rb
|
|
54
|
+
- lib/clicksign/webhook.rb
|
|
55
|
+
homepage: https://github.com/djosino/clicksign-ruby-sdk
|
|
56
|
+
licenses:
|
|
57
|
+
- MIT
|
|
58
|
+
metadata:
|
|
59
|
+
source_code_uri: https://github.com/djosino/clicksign-ruby-sdk
|
|
60
|
+
changelog_uri: https://github.com/djosino/clicksign-ruby-sdk/blob/main/CHANGELOG.md
|
|
61
|
+
bug_tracker_uri: https://github.com/djosino/clicksign-ruby-sdk/issues
|
|
62
|
+
documentation_uri: https://github.com/djosino/clicksign-ruby-sdk
|
|
63
|
+
rubygems_mfa_required: 'true'
|
|
64
|
+
rdoc_options: []
|
|
65
|
+
require_paths:
|
|
66
|
+
- lib
|
|
67
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
68
|
+
requirements:
|
|
69
|
+
- - ">="
|
|
70
|
+
- !ruby/object:Gem::Version
|
|
71
|
+
version: '3.0'
|
|
72
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
73
|
+
requirements:
|
|
74
|
+
- - ">="
|
|
75
|
+
- !ruby/object:Gem::Version
|
|
76
|
+
version: '0'
|
|
77
|
+
requirements: []
|
|
78
|
+
rubygems_version: 4.0.11
|
|
79
|
+
specification_version: 4
|
|
80
|
+
summary: Ruby SDK for the Clicksign API
|
|
81
|
+
test_files: []
|