omniauth-quickbooks-oauth2-modern 1.0.0 → 1.1.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/.rubocop.yml +49 -1
- data/CHANGELOG.md +9 -0
- data/README.md +96 -0
- data/Rakefile +3 -3
- data/lib/omniauth/quickbooks_oauth2_modern/token_client.rb +186 -0
- data/lib/omniauth/quickbooks_oauth2_modern/version.rb +1 -1
- data/lib/omniauth/strategies/quickbooks_oauth2_modern.rb +20 -20
- data/lib/omniauth-quickbooks-oauth2-modern.rb +3 -2
- data/omniauth-quickbooks-oauth2-modern.gemspec +28 -27
- metadata +3 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b34af49e6a0c3fb18416a2f2375d4de6fbc9a8db55277776320c9b21aa0e44f3
|
|
4
|
+
data.tar.gz: 2cd785029a2b9a26fc7f3bdfe8fc5b716d6aeafab47e1ffeb297d7b0b837a1c7
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d411ec48a52dc0fb5f064273778025676637aab84e8c008d1127b342c5a60f834f539548cbaf955027bc7a2df7457dea6839f51799ee65611046c3eac9f77094
|
|
7
|
+
data.tar.gz: '09794199b6e906a18fd2091437262e1ea1a903ccced8347271bed6adb719f1925b43940c335fc1246a96ba85f674072450a7608f6a6d02e34c12690aa041d098'
|
data/.rubocop.yml
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
require:
|
|
2
|
+
- rubocop-rspec
|
|
3
|
+
|
|
1
4
|
AllCops:
|
|
2
5
|
TargetRubyVersion: 3.0
|
|
3
6
|
NewCops: enable
|
|
4
7
|
Exclude:
|
|
5
8
|
- "vendor/**/*"
|
|
6
|
-
- "spec/**/*"
|
|
7
9
|
|
|
8
10
|
Style/Documentation:
|
|
9
11
|
Enabled: false
|
|
@@ -12,3 +14,49 @@ Metrics/BlockLength:
|
|
|
12
14
|
Exclude:
|
|
13
15
|
- "spec/**/*"
|
|
14
16
|
- "*.gemspec"
|
|
17
|
+
|
|
18
|
+
Metrics/ClassLength:
|
|
19
|
+
Max: 150
|
|
20
|
+
|
|
21
|
+
Metrics/MethodLength:
|
|
22
|
+
Max: 25
|
|
23
|
+
|
|
24
|
+
Metrics/AbcSize:
|
|
25
|
+
Max: 25
|
|
26
|
+
|
|
27
|
+
Gemspec/DevelopmentDependencies:
|
|
28
|
+
Enabled: false
|
|
29
|
+
|
|
30
|
+
RSpec/SubjectStub:
|
|
31
|
+
Enabled: false
|
|
32
|
+
|
|
33
|
+
RSpec/VerifiedDoubles:
|
|
34
|
+
Enabled: false
|
|
35
|
+
|
|
36
|
+
RSpec/FilePath:
|
|
37
|
+
Enabled: false
|
|
38
|
+
|
|
39
|
+
RSpec/SpecFilePathFormat:
|
|
40
|
+
Enabled: false
|
|
41
|
+
|
|
42
|
+
RSpec/MultipleExpectations:
|
|
43
|
+
Max: 5
|
|
44
|
+
|
|
45
|
+
RSpec/ExampleLength:
|
|
46
|
+
Max: 15
|
|
47
|
+
|
|
48
|
+
RSpec/NestedGroups:
|
|
49
|
+
Max: 5
|
|
50
|
+
|
|
51
|
+
RSpec/MessageSpies:
|
|
52
|
+
Enabled: false
|
|
53
|
+
|
|
54
|
+
RSpec/DescribedClass:
|
|
55
|
+
Enabled: false
|
|
56
|
+
|
|
57
|
+
Naming/FileName:
|
|
58
|
+
Exclude:
|
|
59
|
+
- 'lib/omniauth-quickbooks-oauth2-modern.rb'
|
|
60
|
+
|
|
61
|
+
Metrics/ParameterLists:
|
|
62
|
+
Max: 8
|
data/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,15 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.1.0] - 2026-01-31
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- TokenClient class for easy token refresh in Rails apps
|
|
13
|
+
- `refresh_token` method with result object pattern
|
|
14
|
+
- `token_expired?` helper with configurable buffer
|
|
15
|
+
- Comprehensive RSpec tests for TokenClient (26 new tests)
|
|
16
|
+
|
|
8
17
|
## [1.0.0] - 2026-01-31
|
|
9
18
|
|
|
10
19
|
### Added
|
data/README.md
CHANGED
|
@@ -201,6 +201,102 @@ def self.from_omniauth(auth)
|
|
|
201
201
|
end
|
|
202
202
|
```
|
|
203
203
|
|
|
204
|
+
## Token Refresh
|
|
205
|
+
|
|
206
|
+
This gem includes a `TokenClient` class to easily refresh tokens in your Rails app.
|
|
207
|
+
|
|
208
|
+
### Basic Usage
|
|
209
|
+
|
|
210
|
+
```ruby
|
|
211
|
+
# Create a client instance
|
|
212
|
+
client = OmniAuth::QuickbooksOauth2Modern::TokenClient.new(
|
|
213
|
+
client_id: ENV['QBO_CLIENT_ID'],
|
|
214
|
+
client_secret: ENV['QBO_CLIENT_SECRET']
|
|
215
|
+
)
|
|
216
|
+
|
|
217
|
+
# Refresh an expired token
|
|
218
|
+
result = client.refresh_token(account.qbo_refresh_token)
|
|
219
|
+
|
|
220
|
+
if result.success?
|
|
221
|
+
account.update!(
|
|
222
|
+
qbo_access_token: result.access_token,
|
|
223
|
+
qbo_refresh_token: result.refresh_token,
|
|
224
|
+
qbo_token_expires_at: Time.at(result.expires_at)
|
|
225
|
+
)
|
|
226
|
+
else
|
|
227
|
+
Rails.logger.error "Token refresh failed: #{result.error}"
|
|
228
|
+
end
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
### Check Token Expiration
|
|
232
|
+
|
|
233
|
+
```ruby
|
|
234
|
+
# Check if token is expired (with 5-minute buffer by default)
|
|
235
|
+
client.token_expired?(account.qbo_token_expires_at)
|
|
236
|
+
|
|
237
|
+
# Custom buffer (e.g., refresh 1 hour before expiry)
|
|
238
|
+
client.token_expired?(account.qbo_token_expires_at, buffer_seconds: 3600)
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
### Rails Service Example
|
|
242
|
+
|
|
243
|
+
```ruby
|
|
244
|
+
# app/services/quickbooks_api_service.rb
|
|
245
|
+
class QuickBooksApiService
|
|
246
|
+
def initialize(account)
|
|
247
|
+
@account = account
|
|
248
|
+
@client = OmniAuth::QuickbooksOauth2Modern::TokenClient.new(
|
|
249
|
+
client_id: ENV['QBO_CLIENT_ID'],
|
|
250
|
+
client_secret: ENV['QBO_CLIENT_SECRET']
|
|
251
|
+
)
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
def with_valid_token
|
|
255
|
+
refresh_if_expired!
|
|
256
|
+
yield @account.qbo_access_token
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
private
|
|
260
|
+
|
|
261
|
+
def refresh_if_expired!
|
|
262
|
+
return unless @client.token_expired?(@account.qbo_token_expires_at)
|
|
263
|
+
|
|
264
|
+
result = @client.refresh_token(@account.qbo_refresh_token)
|
|
265
|
+
raise "Token refresh failed: #{result.error}" unless result.success?
|
|
266
|
+
|
|
267
|
+
@account.update!(
|
|
268
|
+
qbo_access_token: result.access_token,
|
|
269
|
+
qbo_refresh_token: result.refresh_token,
|
|
270
|
+
qbo_token_expires_at: Time.at(result.expires_at)
|
|
271
|
+
)
|
|
272
|
+
end
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
# Usage
|
|
276
|
+
QuickBooksApiService.new(current_account).with_valid_token do |token|
|
|
277
|
+
# Make API calls with valid token
|
|
278
|
+
response = Faraday.get("https://quickbooks.api.intuit.com/v3/company/#{realm_id}/query") do |req|
|
|
279
|
+
req.headers['Authorization'] = "Bearer #{token}"
|
|
280
|
+
req.params['query'] = "SELECT * FROM Customer"
|
|
281
|
+
end
|
|
282
|
+
end
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
### TokenResult Object
|
|
286
|
+
|
|
287
|
+
The `refresh_token` method returns a `TokenResult` object with:
|
|
288
|
+
|
|
289
|
+
| Method | Description |
|
|
290
|
+
|--------|-------------|
|
|
291
|
+
| `success?` | Returns `true` if refresh succeeded |
|
|
292
|
+
| `failure?` | Returns `true` if refresh failed |
|
|
293
|
+
| `access_token` | The new access token |
|
|
294
|
+
| `refresh_token` | The new refresh token |
|
|
295
|
+
| `expires_at` | Unix timestamp when token expires |
|
|
296
|
+
| `expires_in` | Seconds until token expires |
|
|
297
|
+
| `error` | Error message if failed |
|
|
298
|
+
| `raw_response` | Full response hash from Intuit |
|
|
299
|
+
|
|
204
300
|
## Scopes
|
|
205
301
|
|
|
206
302
|
Common QuickBooks scopes:
|
data/Rakefile
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
4
|
-
require
|
|
3
|
+
require 'bundler/gem_tasks'
|
|
4
|
+
require 'rspec/core/rake_task'
|
|
5
5
|
|
|
6
6
|
RSpec::Core::RakeTask.new(:spec)
|
|
7
7
|
|
|
8
|
-
require
|
|
8
|
+
require 'rubocop/rake_task'
|
|
9
9
|
RuboCop::RakeTask.new
|
|
10
10
|
|
|
11
11
|
task default: %i[spec rubocop]
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'faraday'
|
|
4
|
+
require 'json'
|
|
5
|
+
require 'base64'
|
|
6
|
+
|
|
7
|
+
module OmniAuth
|
|
8
|
+
module QuickbooksOauth2Modern
|
|
9
|
+
# Client for managing QuickBooks OAuth2 tokens
|
|
10
|
+
#
|
|
11
|
+
# This class provides an easy way to refresh expired tokens in your Rails app.
|
|
12
|
+
#
|
|
13
|
+
# @example Basic usage
|
|
14
|
+
# client = OmniAuth::QuickbooksOauth2Modern::TokenClient.new(
|
|
15
|
+
# client_id: ENV['QBO_CLIENT_ID'],
|
|
16
|
+
# client_secret: ENV['QBO_CLIENT_SECRET']
|
|
17
|
+
# )
|
|
18
|
+
#
|
|
19
|
+
# # Refresh an expired token
|
|
20
|
+
# result = client.refresh_token(user.qbo_refresh_token)
|
|
21
|
+
# if result.success?
|
|
22
|
+
# user.update!(
|
|
23
|
+
# qbo_access_token: result.access_token,
|
|
24
|
+
# qbo_refresh_token: result.refresh_token,
|
|
25
|
+
# qbo_token_expires_at: result.expires_at
|
|
26
|
+
# )
|
|
27
|
+
# end
|
|
28
|
+
#
|
|
29
|
+
# @example With automatic token refresh in a service
|
|
30
|
+
# class QuickBooksApiService
|
|
31
|
+
# def initialize(account)
|
|
32
|
+
# @account = account
|
|
33
|
+
# @client = OmniAuth::QuickbooksOauth2Modern::TokenClient.new(
|
|
34
|
+
# client_id: ENV['QBO_CLIENT_ID'],
|
|
35
|
+
# client_secret: ENV['QBO_CLIENT_SECRET']
|
|
36
|
+
# )
|
|
37
|
+
# end
|
|
38
|
+
#
|
|
39
|
+
# def with_valid_token
|
|
40
|
+
# refresh_if_expired!
|
|
41
|
+
# yield @account.access_token
|
|
42
|
+
# end
|
|
43
|
+
#
|
|
44
|
+
# private
|
|
45
|
+
#
|
|
46
|
+
# def refresh_if_expired!
|
|
47
|
+
# return unless @client.token_expired?(@account.token_expires_at)
|
|
48
|
+
#
|
|
49
|
+
# result = @client.refresh_token(@account.refresh_token)
|
|
50
|
+
# raise "Token refresh failed: #{result.error}" unless result.success?
|
|
51
|
+
#
|
|
52
|
+
# @account.update!(
|
|
53
|
+
# access_token: result.access_token,
|
|
54
|
+
# refresh_token: result.refresh_token,
|
|
55
|
+
# token_expires_at: result.expires_at
|
|
56
|
+
# )
|
|
57
|
+
# end
|
|
58
|
+
# end
|
|
59
|
+
#
|
|
60
|
+
class TokenClient
|
|
61
|
+
# Result object for token operations
|
|
62
|
+
class TokenResult
|
|
63
|
+
attr_reader :access_token, :refresh_token, :expires_at, :expires_in, :error, :raw_response
|
|
64
|
+
|
|
65
|
+
def initialize(success:, access_token: nil, refresh_token: nil, expires_at: nil, expires_in: nil,
|
|
66
|
+
error: nil, raw_response: nil)
|
|
67
|
+
@success = success
|
|
68
|
+
@access_token = access_token
|
|
69
|
+
@refresh_token = refresh_token
|
|
70
|
+
@expires_at = expires_at
|
|
71
|
+
@expires_in = expires_in
|
|
72
|
+
@error = error
|
|
73
|
+
@raw_response = raw_response
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def success?
|
|
77
|
+
@success
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def failure?
|
|
81
|
+
!@success
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# Intuit OAuth2 token endpoint
|
|
86
|
+
TOKEN_URL = 'https://oauth.platform.intuit.com/oauth2/v1/tokens/bearer'
|
|
87
|
+
|
|
88
|
+
attr_reader :client_id, :client_secret
|
|
89
|
+
|
|
90
|
+
# Initialize a new TokenClient
|
|
91
|
+
#
|
|
92
|
+
# @param client_id [String] Your QuickBooks App Client ID
|
|
93
|
+
# @param client_secret [String] Your QuickBooks App Client Secret
|
|
94
|
+
def initialize(client_id:, client_secret:)
|
|
95
|
+
@client_id = client_id
|
|
96
|
+
@client_secret = client_secret
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# Refresh an access token using a refresh token
|
|
100
|
+
#
|
|
101
|
+
# @param refresh_token [String] The refresh token to use
|
|
102
|
+
# @return [TokenResult] Result object with new tokens or error
|
|
103
|
+
def refresh_token(refresh_token)
|
|
104
|
+
if refresh_token.nil? || refresh_token.empty?
|
|
105
|
+
return TokenResult.new(success: false,
|
|
106
|
+
error: 'Refresh token is required')
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
response = make_refresh_request(refresh_token)
|
|
110
|
+
|
|
111
|
+
if response.success?
|
|
112
|
+
parse_success_response(response)
|
|
113
|
+
else
|
|
114
|
+
parse_error_response(response)
|
|
115
|
+
end
|
|
116
|
+
rescue Faraday::Error => e
|
|
117
|
+
TokenResult.new(success: false, error: "Network error: #{e.message}")
|
|
118
|
+
rescue JSON::ParserError => e
|
|
119
|
+
TokenResult.new(success: false, error: "Invalid JSON response: #{e.message}")
|
|
120
|
+
rescue StandardError => e
|
|
121
|
+
TokenResult.new(success: false, error: "Unexpected error: #{e.message}")
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
# Check if a token is expired or about to expire
|
|
125
|
+
#
|
|
126
|
+
# @param expires_at [Time, Integer] Token expiration time
|
|
127
|
+
# @param buffer_seconds [Integer] Buffer before expiration (default: 300 = 5 minutes)
|
|
128
|
+
# @return [Boolean] True if token is expired or will expire within buffer
|
|
129
|
+
def token_expired?(expires_at, buffer_seconds: 300)
|
|
130
|
+
return true if expires_at.nil?
|
|
131
|
+
|
|
132
|
+
expires_at_time = expires_at.is_a?(Integer) ? Time.at(expires_at) : expires_at
|
|
133
|
+
Time.now >= (expires_at_time - buffer_seconds)
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
private
|
|
137
|
+
|
|
138
|
+
def make_refresh_request(refresh_token)
|
|
139
|
+
# QuickBooks uses Basic Auth with base64 encoded client_id:client_secret
|
|
140
|
+
credentials = Base64.strict_encode64("#{client_id}:#{client_secret}")
|
|
141
|
+
|
|
142
|
+
Faraday.post(TOKEN_URL) do |req|
|
|
143
|
+
req.headers['Authorization'] = "Basic #{credentials}"
|
|
144
|
+
req.headers['Content-Type'] = 'application/x-www-form-urlencoded'
|
|
145
|
+
req.headers['Accept'] = 'application/json'
|
|
146
|
+
req.body = URI.encode_www_form(
|
|
147
|
+
grant_type: 'refresh_token',
|
|
148
|
+
refresh_token: refresh_token
|
|
149
|
+
)
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def parse_success_response(response)
|
|
154
|
+
data = JSON.parse(response.body)
|
|
155
|
+
|
|
156
|
+
expires_in = data['expires_in']&.to_i
|
|
157
|
+
expires_at = expires_in ? Time.now.to_i + expires_in : nil
|
|
158
|
+
|
|
159
|
+
TokenResult.new(
|
|
160
|
+
success: true,
|
|
161
|
+
access_token: data['access_token'],
|
|
162
|
+
refresh_token: data['refresh_token'],
|
|
163
|
+
expires_in: expires_in,
|
|
164
|
+
expires_at: expires_at,
|
|
165
|
+
raw_response: data
|
|
166
|
+
)
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def parse_error_response(response)
|
|
170
|
+
error_data = begin
|
|
171
|
+
JSON.parse(response.body)
|
|
172
|
+
rescue JSON::ParserError
|
|
173
|
+
{ 'error' => response.body }
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
error_message = error_data['error_description'] || error_data['error'] || "HTTP #{response.status}"
|
|
177
|
+
|
|
178
|
+
TokenResult.new(
|
|
179
|
+
success: false,
|
|
180
|
+
error: error_message,
|
|
181
|
+
raw_response: error_data
|
|
182
|
+
)
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
end
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
4
|
-
require
|
|
5
|
-
require
|
|
3
|
+
require 'omniauth-oauth2'
|
|
4
|
+
require 'faraday'
|
|
5
|
+
require 'json'
|
|
6
6
|
|
|
7
7
|
module OmniAuth
|
|
8
8
|
module Strategies
|
|
@@ -24,15 +24,15 @@ module OmniAuth
|
|
|
24
24
|
option :name, :quickbooks_oauth2_modern
|
|
25
25
|
|
|
26
26
|
# Default scopes for QuickBooks accounting access with OpenID
|
|
27
|
-
option :scope,
|
|
27
|
+
option :scope, 'com.intuit.quickbooks.accounting openid profile email'
|
|
28
28
|
|
|
29
29
|
# Sandbox mode (default: true for safety)
|
|
30
30
|
option :sandbox, true
|
|
31
31
|
|
|
32
32
|
option :client_options, {
|
|
33
|
-
site:
|
|
34
|
-
authorize_url:
|
|
35
|
-
token_url:
|
|
33
|
+
site: 'https://appcenter.intuit.com',
|
|
34
|
+
authorize_url: '/connect/oauth2',
|
|
35
|
+
token_url: 'https://oauth.platform.intuit.com/oauth2/v1/tokens/bearer'
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
# Use realmId (company ID) as the unique identifier
|
|
@@ -40,20 +40,20 @@ module OmniAuth
|
|
|
40
40
|
|
|
41
41
|
info do
|
|
42
42
|
{
|
|
43
|
-
email: raw_info[
|
|
44
|
-
first_name: raw_info[
|
|
45
|
-
last_name: raw_info[
|
|
43
|
+
email: raw_info['email'],
|
|
44
|
+
first_name: raw_info['givenName'],
|
|
45
|
+
last_name: raw_info['familyName'],
|
|
46
46
|
name: full_name,
|
|
47
|
-
phone: raw_info[
|
|
47
|
+
phone: raw_info['phoneNumber'],
|
|
48
48
|
realm_id: realm_id
|
|
49
49
|
}
|
|
50
50
|
end
|
|
51
51
|
|
|
52
52
|
credentials do
|
|
53
|
-
hash = {
|
|
54
|
-
hash[
|
|
55
|
-
hash[
|
|
56
|
-
hash[
|
|
53
|
+
hash = { 'token' => access_token.token }
|
|
54
|
+
hash['refresh_token'] = access_token.refresh_token if access_token.refresh_token
|
|
55
|
+
hash['expires_at'] = access_token.expires_at if access_token.expires_at
|
|
56
|
+
hash['expires'] = access_token.expires?
|
|
57
57
|
hash
|
|
58
58
|
end
|
|
59
59
|
|
|
@@ -78,12 +78,12 @@ module OmniAuth
|
|
|
78
78
|
|
|
79
79
|
# The QuickBooks company ID (realmId)
|
|
80
80
|
def realm_id
|
|
81
|
-
request.params[
|
|
81
|
+
request.params['realmId']
|
|
82
82
|
end
|
|
83
83
|
|
|
84
84
|
# Construct full name from OpenID info
|
|
85
85
|
def full_name
|
|
86
|
-
name = [raw_info[
|
|
86
|
+
name = [raw_info['givenName'], raw_info['familyName']].compact.join(' ')
|
|
87
87
|
name.empty? ? nil : name
|
|
88
88
|
end
|
|
89
89
|
|
|
@@ -101,13 +101,13 @@ module OmniAuth
|
|
|
101
101
|
|
|
102
102
|
# Check if OpenID scopes were requested
|
|
103
103
|
def openid_scope_requested?
|
|
104
|
-
scope = options[:scope] ||
|
|
105
|
-
scope.split(/\s+/).include?(
|
|
104
|
+
scope = options[:scope] || ''
|
|
105
|
+
scope.split(/\s+/).include?('openid')
|
|
106
106
|
end
|
|
107
107
|
|
|
108
108
|
# Get the appropriate userinfo URL based on environment
|
|
109
109
|
def userinfo_url
|
|
110
|
-
domain = options[:sandbox] ?
|
|
110
|
+
domain = options[:sandbox] ? 'sandbox-accounts.platform.intuit.com' : 'accounts.platform.intuit.com'
|
|
111
111
|
"https://#{domain}/v1/openid_connect/userinfo"
|
|
112
112
|
end
|
|
113
113
|
end
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
4
|
-
require
|
|
3
|
+
require 'omniauth/quickbooks_oauth2_modern/version'
|
|
4
|
+
require 'omniauth/quickbooks_oauth2_modern/token_client'
|
|
5
|
+
require 'omniauth/strategies/quickbooks_oauth2_modern'
|
|
@@ -1,24 +1,25 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative
|
|
3
|
+
require_relative 'lib/omniauth/quickbooks_oauth2_modern/version'
|
|
4
4
|
|
|
5
5
|
Gem::Specification.new do |spec|
|
|
6
|
-
spec.name =
|
|
6
|
+
spec.name = 'omniauth-quickbooks-oauth2-modern'
|
|
7
7
|
spec.version = OmniAuth::QuickbooksOauth2Modern::VERSION
|
|
8
|
-
spec.authors = [
|
|
9
|
-
spec.email = [
|
|
8
|
+
spec.authors = ['dan1d']
|
|
9
|
+
spec.email = ['dan@theowner.me']
|
|
10
10
|
|
|
11
|
-
spec.summary =
|
|
12
|
-
spec.description =
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
spec.homepage =
|
|
16
|
-
spec.license =
|
|
17
|
-
spec.required_ruby_version =
|
|
11
|
+
spec.summary = 'OmniAuth strategy for QuickBooks Online OAuth 2.0 (OmniAuth 2.0+ compatible)'
|
|
12
|
+
spec.description = 'An OmniAuth strategy for authenticating with QuickBooks Online using OAuth 2.0. ' \
|
|
13
|
+
'Compatible with OmniAuth 2.0+ and supports both sandbox and production environments ' \
|
|
14
|
+
'with OpenID Connect userinfo fetching.'
|
|
15
|
+
spec.homepage = 'https://github.com/dan1d/omniauth-quickbooks-oauth2-modern'
|
|
16
|
+
spec.license = 'MIT'
|
|
17
|
+
spec.required_ruby_version = '>= 3.0.0'
|
|
18
18
|
|
|
19
|
-
spec.metadata[
|
|
20
|
-
spec.metadata[
|
|
21
|
-
spec.metadata[
|
|
19
|
+
spec.metadata['homepage_uri'] = spec.homepage
|
|
20
|
+
spec.metadata['source_code_uri'] = spec.homepage
|
|
21
|
+
spec.metadata['changelog_uri'] = "#{spec.homepage}/blob/main/CHANGELOG.md"
|
|
22
|
+
spec.metadata['rubygems_mfa_required'] = 'true'
|
|
22
23
|
|
|
23
24
|
spec.files = Dir.chdir(__dir__) do
|
|
24
25
|
`git ls-files -z`.split("\x0").reject do |f|
|
|
@@ -26,22 +27,22 @@ Gem::Specification.new do |spec|
|
|
|
26
27
|
f.start_with?(*%w[bin/ test/ spec/ features/ .git .github appveyor Gemfile])
|
|
27
28
|
end
|
|
28
29
|
end
|
|
29
|
-
spec.bindir =
|
|
30
|
+
spec.bindir = 'exe'
|
|
30
31
|
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
|
31
|
-
spec.require_paths = [
|
|
32
|
+
spec.require_paths = ['lib']
|
|
32
33
|
|
|
33
34
|
# Runtime dependencies
|
|
34
|
-
spec.add_dependency
|
|
35
|
-
spec.add_dependency
|
|
36
|
-
spec.add_dependency
|
|
35
|
+
spec.add_dependency 'faraday', '>= 1.0', '< 3.0'
|
|
36
|
+
spec.add_dependency 'omniauth', '~> 2.0'
|
|
37
|
+
spec.add_dependency 'omniauth-oauth2', '~> 1.8'
|
|
37
38
|
|
|
38
39
|
# Development dependencies
|
|
39
|
-
spec.add_development_dependency
|
|
40
|
-
spec.add_development_dependency
|
|
41
|
-
spec.add_development_dependency
|
|
42
|
-
spec.add_development_dependency
|
|
43
|
-
spec.add_development_dependency
|
|
44
|
-
spec.add_development_dependency
|
|
45
|
-
spec.add_development_dependency
|
|
46
|
-
spec.add_development_dependency
|
|
40
|
+
spec.add_development_dependency 'bundler', '~> 2.0'
|
|
41
|
+
spec.add_development_dependency 'rack-test', '~> 2.1'
|
|
42
|
+
spec.add_development_dependency 'rake', '~> 13.0'
|
|
43
|
+
spec.add_development_dependency 'rspec', '~> 3.12'
|
|
44
|
+
spec.add_development_dependency 'rubocop', '~> 1.50'
|
|
45
|
+
spec.add_development_dependency 'rubocop-rspec', '~> 2.20'
|
|
46
|
+
spec.add_development_dependency 'simplecov', '~> 0.22'
|
|
47
|
+
spec.add_development_dependency 'webmock', '~> 3.18'
|
|
47
48
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: omniauth-quickbooks-oauth2-modern
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- dan1d
|
|
@@ -185,6 +185,7 @@ files:
|
|
|
185
185
|
- README.md
|
|
186
186
|
- Rakefile
|
|
187
187
|
- lib/omniauth-quickbooks-oauth2-modern.rb
|
|
188
|
+
- lib/omniauth/quickbooks_oauth2_modern/token_client.rb
|
|
188
189
|
- lib/omniauth/quickbooks_oauth2_modern/version.rb
|
|
189
190
|
- lib/omniauth/strategies/quickbooks_oauth2_modern.rb
|
|
190
191
|
- omniauth-quickbooks-oauth2-modern.gemspec
|
|
@@ -195,6 +196,7 @@ metadata:
|
|
|
195
196
|
homepage_uri: https://github.com/dan1d/omniauth-quickbooks-oauth2-modern
|
|
196
197
|
source_code_uri: https://github.com/dan1d/omniauth-quickbooks-oauth2-modern
|
|
197
198
|
changelog_uri: https://github.com/dan1d/omniauth-quickbooks-oauth2-modern/blob/main/CHANGELOG.md
|
|
199
|
+
rubygems_mfa_required: 'true'
|
|
198
200
|
rdoc_options: []
|
|
199
201
|
require_paths:
|
|
200
202
|
- lib
|