nubank_sdk 0.5.0 → 0.5.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 +4 -4
- data/.github/workflows/gem-push.yml +31 -0
- data/.rubocop.yml +5 -0
- data/.vscode/settings.json +3 -1
- data/Gemfile +1 -1
- data/Gemfile.lock +43 -3
- data/README.md +37 -1
- data/Rakefile +20 -0
- data/certificates/.gitkeep +0 -0
- data/lib/nubank_sdk/account.rb +10 -1
- data/lib/nubank_sdk/api_routes.rb +39 -14
- data/lib/nubank_sdk/auth.rb +83 -2
- data/lib/nubank_sdk/certificate.rb +40 -4
- data/lib/nubank_sdk/client.rb +45 -8
- data/lib/nubank_sdk/user.rb +25 -2
- data/lib/nubank_sdk/version.rb +1 -1
- data/nubank_sdk.gemspec +5 -2
- metadata +63 -6
- data/usage_example.rb +0 -19
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 88e935ce5affb735e7676f0dd93a213658308ce205f837028172bac24d0ceb0e
|
4
|
+
data.tar.gz: dc9bd5c2cc72d965a2cfa0bb20e81eb3e43e6f4077806cfcab04532c1db00181
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7a3217000244778e41aa31f56df110888cedae14efcdcd39b88a7e6fc430bb53bac67eee8a9570a0a67de8035a9d7e2f892bc9413c65e3198772ebe92b4039b9
|
7
|
+
data.tar.gz: bf2509cbf0b73934c5e490fb146e499c286b658ab4050417ac47f9b17b7dc851829c31bbf9a58c265c00a9ff27714d0d3ba8ddf063186b17562e11c618d6da09
|
@@ -0,0 +1,31 @@
|
|
1
|
+
name: Ruby Gem
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches: [ "main" ]
|
6
|
+
|
7
|
+
jobs:
|
8
|
+
build:
|
9
|
+
name: Build + Publish
|
10
|
+
runs-on: ubuntu-latest
|
11
|
+
permissions:
|
12
|
+
contents: read
|
13
|
+
packages: write
|
14
|
+
|
15
|
+
steps:
|
16
|
+
- uses: actions/checkout@v3
|
17
|
+
- name: Set up Ruby 2.6
|
18
|
+
uses: actions/setup-ruby@v1
|
19
|
+
with:
|
20
|
+
ruby-version: 2.6.x
|
21
|
+
|
22
|
+
- name: Publish to RubyGems
|
23
|
+
run: |
|
24
|
+
mkdir -p $HOME/.gem
|
25
|
+
touch $HOME/.gem/credentials
|
26
|
+
chmod 0600 $HOME/.gem/credentials
|
27
|
+
printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
|
28
|
+
gem build *.gemspec
|
29
|
+
gem push *.gem
|
30
|
+
env:
|
31
|
+
GEM_HOST_API_KEY: "${{secrets.RUBYGEMS_AUTH_TOKEN}}"
|
data/.rubocop.yml
ADDED
data/.vscode/settings.json
CHANGED
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,18 +1,36 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
nubank_sdk (0.5.
|
4
|
+
nubank_sdk (0.5.1)
|
5
5
|
faraday (~> 0.15.0)
|
6
|
-
json (~> 2.
|
6
|
+
json (~> 2.3)
|
7
7
|
|
8
8
|
GEM
|
9
9
|
remote: https://rubygems.org/
|
10
10
|
specs:
|
11
|
+
activesupport (5.2.8.1)
|
12
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
13
|
+
i18n (>= 0.7, < 2)
|
14
|
+
minitest (~> 5.1)
|
15
|
+
tzinfo (~> 1.1)
|
16
|
+
ast (2.4.2)
|
17
|
+
concurrent-ruby (1.1.10)
|
11
18
|
diff-lcs (1.5.0)
|
19
|
+
factory_bot (4.8.2)
|
20
|
+
activesupport (>= 3.0.0)
|
12
21
|
faraday (0.15.4)
|
13
22
|
multipart-post (>= 1.2, < 3)
|
14
|
-
|
23
|
+
i18n (1.12.0)
|
24
|
+
concurrent-ruby (~> 1.0)
|
25
|
+
jaro_winkler (1.5.4)
|
26
|
+
json (2.6.1)
|
27
|
+
minitest (5.15.0)
|
15
28
|
multipart-post (2.2.3)
|
29
|
+
parallel (1.19.2)
|
30
|
+
parser (3.1.2.1)
|
31
|
+
ast (~> 2.4.1)
|
32
|
+
powerpack (0.1.3)
|
33
|
+
rainbow (3.1.1)
|
16
34
|
rake (10.5.0)
|
17
35
|
rspec (3.11.0)
|
18
36
|
rspec-core (~> 3.11.0)
|
@@ -27,15 +45,37 @@ GEM
|
|
27
45
|
diff-lcs (>= 1.2.0, < 2.0)
|
28
46
|
rspec-support (~> 3.11.0)
|
29
47
|
rspec-support (3.11.1)
|
48
|
+
rubocop (0.57.2)
|
49
|
+
jaro_winkler (~> 1.5.1)
|
50
|
+
parallel (~> 1.10)
|
51
|
+
parser (>= 2.5)
|
52
|
+
powerpack (~> 0.1)
|
53
|
+
rainbow (>= 2.2.2, < 4.0)
|
54
|
+
ruby-progressbar (~> 1.7)
|
55
|
+
unicode-display_width (~> 1.0, >= 1.0.1)
|
56
|
+
rubocop-rspec (1.27.0)
|
57
|
+
rubocop (>= 0.56.0)
|
58
|
+
ruby-progressbar (1.11.0)
|
59
|
+
thread_safe (0.3.6)
|
60
|
+
tzinfo (1.2.10)
|
61
|
+
thread_safe (~> 0.1)
|
62
|
+
unicode-display_width (1.8.0)
|
63
|
+
webrick (1.7.0)
|
64
|
+
yard (0.9.28)
|
65
|
+
webrick (~> 1.7.0)
|
30
66
|
|
31
67
|
PLATFORMS
|
32
68
|
ruby
|
33
69
|
|
34
70
|
DEPENDENCIES
|
35
71
|
bundler (~> 1.17)
|
72
|
+
factory_bot (~> 4.8.2)
|
36
73
|
nubank_sdk!
|
37
74
|
rake (~> 10.0)
|
38
75
|
rspec (~> 3.0)
|
76
|
+
rubocop (~> 0.57.2)
|
77
|
+
rubocop-rspec (~> 1.27.0)
|
78
|
+
yard (~> 0.9.12)
|
39
79
|
|
40
80
|
BUNDLED WITH
|
41
81
|
1.17.3
|
data/README.md
CHANGED
@@ -24,7 +24,43 @@ Or install it yourself as:
|
|
24
24
|
|
25
25
|
## Usage
|
26
26
|
|
27
|
-
|
27
|
+
```ruby
|
28
|
+
require 'nubank_sdk'
|
29
|
+
|
30
|
+
# instance a nubank account object
|
31
|
+
user = NubankSdk::User.new(cpf: '12345678909')
|
32
|
+
password = 'dracarys'
|
33
|
+
```
|
34
|
+
|
35
|
+
> First time?
|
36
|
+
>
|
37
|
+
> authenticate the account
|
38
|
+
>
|
39
|
+
> ```ruby
|
40
|
+
> # request an email code
|
41
|
+
> account_email = user.auth.request_email_code(password)
|
42
|
+
>
|
43
|
+
> # get the email code from the user
|
44
|
+
> puts "Enter the code sent to #{account_email}: "
|
45
|
+
> email_code = gets.chomp
|
46
|
+
> user.auth.exchange_certs(email_code, password)
|
47
|
+
> ```
|
48
|
+
>
|
49
|
+
---
|
50
|
+
>
|
51
|
+
> Has a certificate?
|
52
|
+
>
|
53
|
+
> generate a access token
|
54
|
+
>
|
55
|
+
> ```ruby
|
56
|
+
> user.auth.authenticate_with_certificate(password)
|
57
|
+
> ```
|
58
|
+
|
59
|
+
get the account balance
|
60
|
+
|
61
|
+
```ruby
|
62
|
+
user.account.balance # => 77.0
|
63
|
+
```
|
28
64
|
|
29
65
|
## Development
|
30
66
|
|
data/Rakefile
CHANGED
@@ -2,5 +2,25 @@ require "bundler/gem_tasks"
|
|
2
2
|
require "rspec/core/rake_task"
|
3
3
|
|
4
4
|
RSpec::Core::RakeTask.new(:spec)
|
5
|
+
Bundler::GemHelper.install_tasks
|
5
6
|
|
6
7
|
task :default => :spec
|
8
|
+
|
9
|
+
task :start_new_release do
|
10
|
+
# TODO: add guard clean
|
11
|
+
bump = ENV['BUMP'] || 'patch'
|
12
|
+
|
13
|
+
sh 'gem install gem-release'
|
14
|
+
sh "gem bump --version #{bump}"
|
15
|
+
|
16
|
+
Rake::Task[:build].invoke
|
17
|
+
|
18
|
+
sh 'git add .'
|
19
|
+
sh "git commit -m \"build(version): :bookmark: bump #{bump}\""
|
20
|
+
sh 'git push'
|
21
|
+
|
22
|
+
version = NubankSdk::VERSION
|
23
|
+
version_tag = "v#{version}"
|
24
|
+
sh "git tag -a #{version_tag} -m \"Version #{version}\""
|
25
|
+
sh 'git push --tags'
|
26
|
+
end
|
data/certificates/.gitkeep
CHANGED
File without changes
|
data/lib/nubank_sdk/account.rb
CHANGED
@@ -1,10 +1,19 @@
|
|
1
1
|
module NubankSdk
|
2
2
|
class Account
|
3
|
+
#
|
4
|
+
# Returns the account statement
|
5
|
+
#
|
6
|
+
# @param [NubankSdk::Client::HTTPS] connection
|
7
|
+
# @param [NubankSdk::ApiRoutes] api_routes
|
3
8
|
def initialize(connection:, api_routes:)
|
4
9
|
@connection = connection
|
5
10
|
@api_routes = api_routes
|
6
11
|
end
|
7
12
|
|
13
|
+
#
|
14
|
+
# Returns the account balance
|
15
|
+
#
|
16
|
+
# @return [Float]
|
8
17
|
def balance
|
9
18
|
query_url = @api_routes.entrypoint(path: :ssl, entrypoint: :query)
|
10
19
|
|
@@ -19,4 +28,4 @@ module NubankSdk
|
|
19
28
|
data[:data][:viewer][:savingsAccount][:currentSavingsBalance][:netAmount]
|
20
29
|
end
|
21
30
|
end
|
22
|
-
end
|
31
|
+
end
|
@@ -1,37 +1,52 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
require 'faraday'
|
4
2
|
require 'json'
|
5
3
|
|
6
4
|
module NubankSdk
|
7
5
|
class ApiRoutes
|
8
|
-
DISCOVERY_URI =
|
6
|
+
DISCOVERY_URI = 'https://prod-s0-webapp-proxy.nubank.com.br'.freeze
|
9
7
|
PROXY_PATHS = {
|
10
8
|
default: '/api/discovery',
|
11
9
|
app: '/api/app/discovery',
|
12
|
-
ssl: ''
|
13
|
-
}
|
10
|
+
ssl: ''
|
11
|
+
}.freeze
|
14
12
|
|
13
|
+
#
|
14
|
+
# Controller for the ApiRoutes class
|
15
|
+
#
|
16
|
+
# @param [Hash] url_discovery_map
|
17
|
+
# @param [[Symbol, Faraday::Adapter::Test::Stubs]] connection_adapter
|
15
18
|
def initialize(url_discovery_map: {}, connection_adapter: nil)
|
16
19
|
@url_discovery_map = url_discovery_map
|
17
20
|
@connection_adapter = connection_adapter
|
18
21
|
end
|
19
22
|
|
20
|
-
#
|
23
|
+
#
|
24
|
+
# Return the url for a given path and entrypoint
|
25
|
+
#
|
26
|
+
# @param [Symbol] path
|
27
|
+
# @param [Symbol] entrypoint
|
28
|
+
# @param [Symbol] type, :splitted or :full
|
29
|
+
#
|
30
|
+
# @return [String, Array]
|
21
31
|
def entrypoint(path: :default, entrypoint:, type: :full)
|
22
32
|
discovery(path) if @url_discovery_map[path].nil?
|
23
33
|
|
24
34
|
url = @url_discovery_map[path][entrypoint]
|
25
|
-
|
26
|
-
if type == :full
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
return [url_splitted.first, "/api#{url_splitted.last}"]
|
32
|
-
end
|
35
|
+
|
36
|
+
return url if type == :full
|
37
|
+
|
38
|
+
url_splitted = url.split('/api')
|
39
|
+
[url_splitted.first, "/api#{url_splitted.last}"]
|
33
40
|
end
|
34
41
|
|
42
|
+
#
|
43
|
+
# Add new entrypoint to url discovery map
|
44
|
+
#
|
45
|
+
# @param [Symbol] path
|
46
|
+
# @param [Symbol] entrypoint
|
47
|
+
# @param [String] url
|
48
|
+
#
|
49
|
+
# @return [Hash]
|
35
50
|
def add_entrypoint(path: :default, entrypoint:, url:)
|
36
51
|
path_map = @url_discovery_map[path] || {}
|
37
52
|
path_map[entrypoint] = url
|
@@ -41,6 +56,12 @@ module NubankSdk
|
|
41
56
|
|
42
57
|
private
|
43
58
|
|
59
|
+
# @!visibility private
|
60
|
+
# Request to the nubank api to get the url discovery map
|
61
|
+
#
|
62
|
+
# @param [Symbol] path
|
63
|
+
#
|
64
|
+
# @return [Hash]
|
44
65
|
def discovery(path = :default)
|
45
66
|
return @url_discovery_map[path] if @url_discovery_map[path]
|
46
67
|
|
@@ -50,6 +71,10 @@ module NubankSdk
|
|
50
71
|
@url_discovery_map[path] = url_map
|
51
72
|
end
|
52
73
|
|
74
|
+
# @!visibility private
|
75
|
+
# Return a default connection with the nubank api
|
76
|
+
#
|
77
|
+
# @return [Client::HTTP]
|
53
78
|
def connection
|
54
79
|
@connection ||= Client::HTTP.new(DISCOVERY_URI, @connection_adapter)
|
55
80
|
end
|
data/lib/nubank_sdk/auth.rb
CHANGED
@@ -1,9 +1,14 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
module NubankSdk
|
4
2
|
class Auth
|
5
3
|
attr_reader :refresh_token, :refresh_before, :access_token
|
6
4
|
|
5
|
+
#
|
6
|
+
# Auth method to connect with the nubank api
|
7
|
+
#
|
8
|
+
# @param [String] cpf the cpf to authenticate
|
9
|
+
# @param [String] device_id the device id to authenticate
|
10
|
+
# @param [NubankSdk::ApiRoutes] api_routes the api routes to connect
|
11
|
+
# @param [[Symbol, Faraday::Adapter::Test::Stubs]] adapter the adapter to connect
|
7
12
|
def initialize(cpf:, device_id: nil, api_routes: nil, connection_adapter: nil)
|
8
13
|
@cpf = cpf
|
9
14
|
@device_id = device_id || generate_device_id
|
@@ -12,10 +17,20 @@ module NubankSdk
|
|
12
17
|
@connection_adapter = connection_adapter
|
13
18
|
end
|
14
19
|
|
20
|
+
#
|
21
|
+
# Return the instance of user certificate
|
22
|
+
#
|
23
|
+
# @return [NubankSdk::Certificate] the certificate instance
|
15
24
|
def certificate
|
16
25
|
@certificate ||= NubankSdk::Certificate.new(@cpf)
|
17
26
|
end
|
18
27
|
|
28
|
+
#
|
29
|
+
# Authenticate with the nubank api to get a new access token
|
30
|
+
#
|
31
|
+
# @param [String] password the password to authenticate
|
32
|
+
#
|
33
|
+
# @return [NubankSdk::ApiRoutes] the api routes with the new links
|
19
34
|
def authenticate_with_certificate(password)
|
20
35
|
token_url = @api_routes.entrypoint(path: :app, entrypoint: :token)
|
21
36
|
response = ssl_connection.post(token_url, token_payload(password))
|
@@ -29,6 +44,12 @@ module NubankSdk
|
|
29
44
|
update_api_routes(response_hash[:_links])
|
30
45
|
end
|
31
46
|
|
47
|
+
#
|
48
|
+
# Request to nubank api to generate a new certificate
|
49
|
+
#
|
50
|
+
# @param [String] password the password to authenticate
|
51
|
+
#
|
52
|
+
# @return [String] email was has been received the code
|
32
53
|
def request_email_code(password)
|
33
54
|
response = default_connection.post(@gen_certificate_path, payload(password))
|
34
55
|
|
@@ -38,6 +59,10 @@ module NubankSdk
|
|
38
59
|
response_parsed[:sent_to]
|
39
60
|
end
|
40
61
|
|
62
|
+
#
|
63
|
+
# Verify communication with the nubank api
|
64
|
+
#
|
65
|
+
# @return [File] the certificate file
|
41
66
|
def exchange_certs(email_code, password)
|
42
67
|
response = default_connection.post(@gen_certificate_path, payload(password).merge({
|
43
68
|
code: email_code,
|
@@ -51,6 +76,12 @@ module NubankSdk
|
|
51
76
|
|
52
77
|
private
|
53
78
|
|
79
|
+
# @!visibility private
|
80
|
+
# parse the headers of the authenticate response
|
81
|
+
#
|
82
|
+
# @param [String] header_content the headers to parse
|
83
|
+
#
|
84
|
+
# @return [Hash] the parsed header
|
54
85
|
def parse_authenticate_headers(header_content)
|
55
86
|
chunks = header_content.split(',')
|
56
87
|
parsed = {}
|
@@ -65,6 +96,12 @@ module NubankSdk
|
|
65
96
|
parsed
|
66
97
|
end
|
67
98
|
|
99
|
+
# @!visibility private
|
100
|
+
# Create a payload to generate a new certificate
|
101
|
+
#
|
102
|
+
# @param [String] password the password to authenticate
|
103
|
+
#
|
104
|
+
# @return [Hash] the payload to generate a new certificate
|
68
105
|
def payload(password)
|
69
106
|
{
|
70
107
|
login: @cpf,
|
@@ -75,6 +112,12 @@ module NubankSdk
|
|
75
112
|
}
|
76
113
|
end
|
77
114
|
|
115
|
+
# @!visibility private
|
116
|
+
# Create a payload to authenticate with the nubank api
|
117
|
+
#
|
118
|
+
# @param [String] password the password to authenticate
|
119
|
+
#
|
120
|
+
# @return [Hash] the payload to authenticate
|
78
121
|
def token_payload(password)
|
79
122
|
{
|
80
123
|
'grant_type': 'password',
|
@@ -85,10 +128,20 @@ module NubankSdk
|
|
85
128
|
}
|
86
129
|
end
|
87
130
|
|
131
|
+
# @!visibility private
|
132
|
+
# Generates a new key for the certificate communication
|
133
|
+
#
|
134
|
+
# @return [OpenSSL::PKey::RSA] a new key
|
88
135
|
def generate_key
|
89
136
|
OpenSSL::PKey::RSA.new 2048
|
90
137
|
end
|
91
138
|
|
139
|
+
# @!visibility private
|
140
|
+
# Add the new links to the api routes
|
141
|
+
#
|
142
|
+
# @param [Hash] links the new links to add
|
143
|
+
#
|
144
|
+
# @return [NubankSdk::ApiRoutes] the api routes with the new links
|
92
145
|
def update_api_routes(links)
|
93
146
|
feed_url_keys = ['events', 'magnitude']
|
94
147
|
bills_url_keys = ['bills_summary']
|
@@ -100,8 +153,16 @@ module NubankSdk
|
|
100
153
|
@api_routes.add_entrypoint(path: :ssl, entrypoint: :bills, url: find_url(bills_url_keys, links))
|
101
154
|
@api_routes.add_entrypoint(path: :ssl, entrypoint: :customer, url: find_url(customer_url_keys, links))
|
102
155
|
@api_routes.add_entrypoint(path: :ssl, entrypoint: :account, url: find_url(account_url_keys, links))
|
156
|
+
@api_routes
|
103
157
|
end
|
104
158
|
|
159
|
+
# @!visibility private
|
160
|
+
# Return the url of the first key found in the links
|
161
|
+
#
|
162
|
+
# @param [Array] keys the keys to search in the links
|
163
|
+
# @param [Hash] list of the links to search in
|
164
|
+
#
|
165
|
+
# @return [String] the url of the first key found
|
105
166
|
def find_url(keys, list)
|
106
167
|
links_keys = list.keys
|
107
168
|
|
@@ -111,6 +172,10 @@ module NubankSdk
|
|
111
172
|
''
|
112
173
|
end
|
113
174
|
|
175
|
+
# @!visibility private
|
176
|
+
# Generates a new connection with certificate
|
177
|
+
#
|
178
|
+
# @return [Client::HTTPS] a new connection with certificate
|
114
179
|
def prepare_default_connection
|
115
180
|
uri, @gen_certificate_path = @api_routes.entrypoint(
|
116
181
|
path: :app,
|
@@ -121,18 +186,34 @@ module NubankSdk
|
|
121
186
|
Client::HTTP.new(uri, @connection_adapter)
|
122
187
|
end
|
123
188
|
|
189
|
+
# @!visibility private
|
190
|
+
# Create a new default connection to the nubank api
|
191
|
+
#
|
192
|
+
# @return [Client::HTTP] a new default connection
|
124
193
|
def default_connection
|
125
194
|
@default_connection ||= prepare_default_connection
|
126
195
|
end
|
127
196
|
|
197
|
+
# @!visibility private
|
198
|
+
# Create a new ssl connection to the nubank api
|
199
|
+
#
|
200
|
+
# @return [Client::HTTPS] a new ssl connection
|
128
201
|
def ssl_connection
|
129
202
|
@ssl_connection ||= Client::HTTPS.new(certificate.encoded, @connection_adapter)
|
130
203
|
end
|
131
204
|
|
205
|
+
# @!visibility private
|
206
|
+
# return the key of the certificate communication
|
207
|
+
#
|
208
|
+
# @return [OpenSSL::PKey::RSA] the key of the certificate
|
132
209
|
def key
|
133
210
|
@key ||= generate_key
|
134
211
|
end
|
135
212
|
|
213
|
+
# @!visibility private
|
214
|
+
# Generates a random device id
|
215
|
+
#
|
216
|
+
# @return [String] a random device id
|
136
217
|
def generate_device_id
|
137
218
|
SecureRandom.uuid.split('-').last
|
138
219
|
end
|
@@ -1,15 +1,24 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
require 'openssl'
|
4
2
|
|
5
3
|
module NubankSdk
|
6
4
|
class Certificate
|
7
|
-
FILES_PATH = './certificates/'
|
5
|
+
FILES_PATH = './certificates/'.freeze
|
8
6
|
|
7
|
+
#
|
8
|
+
# Controller of certifications
|
9
|
+
#
|
10
|
+
# @param [String] cpf
|
9
11
|
def initialize(cpf)
|
10
12
|
@cpf = cpf
|
11
13
|
end
|
12
14
|
|
15
|
+
#
|
16
|
+
# Create a certificate file
|
17
|
+
#
|
18
|
+
# @param [OpenSSL::PKey::RSA] key
|
19
|
+
# @param [String] certificate
|
20
|
+
#
|
21
|
+
# @return [File]
|
13
22
|
def process_decoded(key, certificate)
|
14
23
|
encoded = encode certificate
|
15
24
|
|
@@ -17,26 +26,53 @@ module NubankSdk
|
|
17
26
|
save p12
|
18
27
|
end
|
19
28
|
|
29
|
+
#
|
30
|
+
# Load the certificate file
|
31
|
+
#
|
32
|
+
# @return [OpenSSL::PKCS12]
|
20
33
|
def encoded
|
21
34
|
@encoded ||= OpenSSL::PKCS12.new(file.read, 'password')
|
22
35
|
end
|
23
36
|
|
24
37
|
private
|
25
38
|
|
39
|
+
# @!visibility private
|
40
|
+
# Open the encrypted certificate file
|
41
|
+
#
|
42
|
+
# @return [OpenSSL::PKCS12]
|
26
43
|
def file
|
27
44
|
File.open("#{FILES_PATH}#{@cpf}.p12", 'rb')
|
28
45
|
end
|
29
46
|
|
47
|
+
# @!visibility private
|
48
|
+
# Create a file with the encrypted certificate
|
49
|
+
#
|
50
|
+
# @param [OpenSSL::PKCS12] p12
|
51
|
+
#
|
52
|
+
# @return [File]
|
30
53
|
def save(p12)
|
31
54
|
File.open("#{FILES_PATH}#{@cpf}.p12", 'wb') do |file|
|
32
55
|
file.write p12.to_der
|
33
56
|
end
|
34
57
|
end
|
35
58
|
|
59
|
+
# @!visibility private
|
60
|
+
# crypt key and certificate to pkcs12
|
61
|
+
#
|
62
|
+
# @param [OpenSSL::PKey::RSA] key
|
63
|
+
# @param [OpenSSL::X509::Certificate] certificate
|
64
|
+
#
|
65
|
+
# @return [OpenSSL::PKCS12]
|
36
66
|
def create_pkcs12_from(key, certificate)
|
37
|
-
OpenSSL::PKCS12.create(
|
67
|
+
OpenSSL::PKCS12.create('password', 'key', key, certificate)
|
38
68
|
end
|
39
69
|
|
70
|
+
# @!visibility private
|
71
|
+
# Enconde certificate string to certificate object
|
72
|
+
#
|
73
|
+
# @param [String] certificate
|
74
|
+
#
|
75
|
+
# @return [OpenSSL::X509::Certificate]
|
40
76
|
def encode(certificate)
|
41
77
|
OpenSSL::X509::Certificate.new certificate
|
42
78
|
end
|
data/lib/nubank_sdk/client.rb
CHANGED
@@ -1,22 +1,38 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
require 'faraday'
|
4
2
|
require 'json'
|
5
3
|
|
6
4
|
module NubankSdk
|
7
5
|
module Client
|
6
|
+
#
|
7
|
+
# Parse the response body symbolizing keys
|
8
|
+
#
|
9
|
+
# @param [Faraday::Response] response
|
10
|
+
#
|
11
|
+
# @return [Hash]
|
8
12
|
def self.get_body(response)
|
9
13
|
JSON.parse(response.body, symbolize_names: true)
|
10
14
|
end
|
11
15
|
|
12
16
|
class HTTP
|
17
|
+
#
|
18
|
+
# create a new connection with the given url in Faraday
|
19
|
+
#
|
20
|
+
# @param [String] base_url
|
21
|
+
# @param [[Symbol, Faraday::Adapter::Test::Stubs]] connection_adapter
|
13
22
|
def initialize(base_url, connection_adapter = nil)
|
14
23
|
@connection = Faraday.new(url: base_url) do |faraday|
|
15
|
-
faraday.adapter
|
24
|
+
faraday.adapter(*connection_adapter) if connection_adapter
|
16
25
|
faraday.adapter Faraday.default_adapter unless connection_adapter
|
17
26
|
end
|
18
27
|
end
|
19
28
|
|
29
|
+
#
|
30
|
+
# make put on connection with the given path
|
31
|
+
#
|
32
|
+
# @param [String] path
|
33
|
+
# @param [Hash] body
|
34
|
+
#
|
35
|
+
# @return [Faraday::Response]
|
20
36
|
def post(path, body)
|
21
37
|
@connection.post(path) do |req|
|
22
38
|
req.headers['Content-Type'] = 'application/json'
|
@@ -24,6 +40,12 @@ module NubankSdk
|
|
24
40
|
end
|
25
41
|
end
|
26
42
|
|
43
|
+
#
|
44
|
+
# make get on connection with the given path
|
45
|
+
#
|
46
|
+
# @param [String] path
|
47
|
+
#
|
48
|
+
# @return [Faraday::Response]
|
27
49
|
def get(path)
|
28
50
|
@connection.get(path)
|
29
51
|
end
|
@@ -32,16 +54,31 @@ module NubankSdk
|
|
32
54
|
class HTTPS
|
33
55
|
attr_accessor :headers
|
34
56
|
|
57
|
+
#
|
58
|
+
# Create a new instance of Faraday::Connection with client certificate
|
59
|
+
#
|
60
|
+
# @param [OpenSSL::PKCS12] certificate
|
61
|
+
# @param [[Symbol, Faraday::Adapter::Test::Stubs]] connection_adapter
|
35
62
|
def initialize(certificate, connection_adapter = nil)
|
36
63
|
client_cert = OpenSSL::X509::Certificate.new(certificate.certificate)
|
37
64
|
client_key = OpenSSL::PKey::RSA.new(certificate.key)
|
38
65
|
|
39
|
-
@connection = Faraday.new(
|
40
|
-
|
41
|
-
|
42
|
-
|
66
|
+
@connection = Faraday.new(
|
67
|
+
ssl: {
|
68
|
+
client_cert: client_cert,
|
69
|
+
client_key: client_key
|
70
|
+
}
|
71
|
+
) { |faraday| faraday.adapter(*connection_adapter) if connection_adapter }
|
72
|
+
@headers = {}
|
43
73
|
end
|
44
74
|
|
75
|
+
#
|
76
|
+
# Make a post request on connection
|
77
|
+
#
|
78
|
+
# @param [String] url
|
79
|
+
# @param [Hash] body
|
80
|
+
#
|
81
|
+
# @return [Faraday::Response]
|
45
82
|
def post(url, body)
|
46
83
|
@connection.post(url) do |req|
|
47
84
|
req.headers['Content-Type'] = 'application/json'
|
@@ -50,7 +87,7 @@ module NubankSdk
|
|
50
87
|
|
51
88
|
@headers.each do |header_key, value|
|
52
89
|
req.headers[header_key] = value
|
53
|
-
end
|
90
|
+
end
|
54
91
|
|
55
92
|
req.body = body.to_json
|
56
93
|
end
|
data/lib/nubank_sdk/user.rb
CHANGED
@@ -1,12 +1,19 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
module NubankSdk
|
4
2
|
class User
|
3
|
+
#
|
4
|
+
# Controller of user actions in nubank
|
5
|
+
#
|
6
|
+
# @param [String] cpf
|
7
|
+
# @param [[Symbol, Faraday::Adapter::Test::Stubs]] connection_adapter
|
5
8
|
def initialize(cpf:, connection_adapter: nil)
|
6
9
|
@cpf = cpf
|
7
10
|
@connection_adapter = connection_adapter
|
8
11
|
end
|
9
12
|
|
13
|
+
#
|
14
|
+
# Returns instance of authentications methods
|
15
|
+
#
|
16
|
+
# @return [NubankSdk::Auth]
|
10
17
|
def auth
|
11
18
|
@auth ||= NubankSdk::Auth.new(
|
12
19
|
cpf: @cpf,
|
@@ -15,20 +22,36 @@ module NubankSdk
|
|
15
22
|
)
|
16
23
|
end
|
17
24
|
|
25
|
+
#
|
26
|
+
# Returns instance of account methods
|
27
|
+
#
|
28
|
+
# @return [NubankSdk::Account]
|
18
29
|
def account
|
19
30
|
@account ||= NubankSdk::Account.new(connection: connection, api_routes: api_routes)
|
20
31
|
end
|
21
32
|
|
33
|
+
#
|
34
|
+
# An instance of apis routes
|
35
|
+
#
|
36
|
+
# @return [NubankSdk::ApiRoutes]
|
22
37
|
def api_routes
|
23
38
|
@api_routes ||= NubankSdk::ApiRoutes.new
|
24
39
|
end
|
25
40
|
|
26
41
|
private
|
27
42
|
|
43
|
+
# @!visibility private
|
44
|
+
# Returns connection with client https certificate and authorized
|
45
|
+
#
|
46
|
+
# @return [Faraday::Connection]
|
28
47
|
def connection
|
29
48
|
@connection ||= setup_connection
|
30
49
|
end
|
31
50
|
|
51
|
+
# @!visibility private
|
52
|
+
# Setup connection with client https certificate and authorized
|
53
|
+
#
|
54
|
+
# @return [Faraday::Connection]
|
32
55
|
def setup_connection
|
33
56
|
connection = Client::HTTPS.new(
|
34
57
|
auth.certificate.encoded,
|
data/lib/nubank_sdk/version.rb
CHANGED
data/nubank_sdk.gemspec
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
|
2
1
|
lib = File.expand_path("../lib", __FILE__)
|
3
2
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
3
|
require "nubank_sdk/version"
|
@@ -25,7 +24,11 @@ Gem::Specification.new do |spec|
|
|
25
24
|
spec.add_development_dependency "bundler", "~> 1.17"
|
26
25
|
spec.add_development_dependency "rake", "~> 10.0"
|
27
26
|
spec.add_development_dependency "rspec", "~> 3.0"
|
27
|
+
spec.add_development_dependency "rubocop", "~> 0.57.2"
|
28
|
+
spec.add_development_dependency "rubocop-rspec", "~> 1.27.0"
|
29
|
+
spec.add_development_dependency "factory_bot", "~> 4.8.2"
|
30
|
+
spec.add_development_dependency "yard", "~> 0.9.12"
|
28
31
|
|
29
32
|
spec.add_dependency "faraday", "~> 0.15.0"
|
30
|
-
spec.add_dependency "json", "~> 2.
|
33
|
+
spec.add_dependency "json", "~> 2.3"
|
31
34
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nubank_sdk
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Viserion77
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-11-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -52,6 +52,62 @@ dependencies:
|
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '3.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rubocop
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.57.2
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 0.57.2
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rubocop-rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 1.27.0
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 1.27.0
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: factory_bot
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 4.8.2
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 4.8.2
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: yard
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: 0.9.12
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 0.9.12
|
55
111
|
- !ruby/object:Gem::Dependency
|
56
112
|
name: faraday
|
57
113
|
requirement: !ruby/object:Gem::Requirement
|
@@ -72,14 +128,14 @@ dependencies:
|
|
72
128
|
requirements:
|
73
129
|
- - "~>"
|
74
130
|
- !ruby/object:Gem::Version
|
75
|
-
version: 2.
|
131
|
+
version: '2.3'
|
76
132
|
type: :runtime
|
77
133
|
prerelease: false
|
78
134
|
version_requirements: !ruby/object:Gem::Requirement
|
79
135
|
requirements:
|
80
136
|
- - "~>"
|
81
137
|
- !ruby/object:Gem::Version
|
82
|
-
version: 2.
|
138
|
+
version: '2.3'
|
83
139
|
description: Monitorize balances, recent transactions, credit limit etc...
|
84
140
|
email:
|
85
141
|
- jeferson.a.oficial@gmail.com
|
@@ -87,8 +143,10 @@ executables: []
|
|
87
143
|
extensions: []
|
88
144
|
extra_rdoc_files: []
|
89
145
|
files:
|
146
|
+
- ".github/workflows/gem-push.yml"
|
90
147
|
- ".gitignore"
|
91
148
|
- ".rspec"
|
149
|
+
- ".rubocop.yml"
|
92
150
|
- ".travis.yml"
|
93
151
|
- ".vscode/settings.json"
|
94
152
|
- Gemfile
|
@@ -108,7 +166,6 @@ files:
|
|
108
166
|
- lib/nubank_sdk/user.rb
|
109
167
|
- lib/nubank_sdk/version.rb
|
110
168
|
- nubank_sdk.gemspec
|
111
|
-
- usage_example.rb
|
112
169
|
homepage: https://github.com/Viserion77/nubank_sdk
|
113
170
|
licenses: []
|
114
171
|
metadata: {}
|
@@ -127,7 +184,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
127
184
|
- !ruby/object:Gem::Version
|
128
185
|
version: '0'
|
129
186
|
requirements: []
|
130
|
-
rubygems_version: 3.0.
|
187
|
+
rubygems_version: 3.0.3.1
|
131
188
|
signing_key:
|
132
189
|
specification_version: 4
|
133
190
|
summary: A gem to make it ease to monitorize your Nubank account.
|
data/usage_example.rb
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
require 'nubank_sdk'
|
2
|
-
|
3
|
-
# instance a nubank account object
|
4
|
-
user = NubankSdk::User.new(cpf: '12345678909')
|
5
|
-
password = 'dracarys'
|
6
|
-
# authenticate the account
|
7
|
-
|
8
|
-
# request an email code
|
9
|
-
account_email = user.auth.request_email_code(password)
|
10
|
-
|
11
|
-
# get the email code from the user
|
12
|
-
puts "Enter the code sent to #{account_email}: "
|
13
|
-
email_code = gets.chomp
|
14
|
-
user.auth.exchange_certs(email_code, password)
|
15
|
-
|
16
|
-
user.auth.authenticate_with_certificate(password)
|
17
|
-
|
18
|
-
# get the account balance
|
19
|
-
user.account.balance
|