jbr 3.7.0 → 3.7.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a8a11f9cbda31f995ef0aa78f55db8502f7f5077fa1703db261f9a7705fea971
4
- data.tar.gz: 6d178b20c67e47c33e5d4617b0fc1c8cc5637794de9ce3b4a94c0af407b8bab6
3
+ metadata.gz: 28dde29d20aa9063e6e24e2226d81bf69ec7593ba99efd8a6f335d9fd83c8a10
4
+ data.tar.gz: 106b0db3001c4aa10c6ef449d4204c6ad2e4574494b6033e7eadf1d13f3ccc59
5
5
  SHA512:
6
- metadata.gz: c2696a88809c0e13f8da7b7b49a7cedb59bde16d695f233a5719cac00ff83af779a1aeca7ee106d518b0301ef89bb46049ed54fc86a9b4e6a28c216a5e6c57d7
7
- data.tar.gz: 2a50c2a089b340ff61d0723a845d12abc653ef7606e80c9963e20ff62c830ec7541039becb9e4999b883dba6e61b5edb323f96435eca25d2ce1ae6f63866719f
6
+ metadata.gz: 49a59576a7951bc00a29f4ec861576be2e28e448e53c1be2911dd094ebea9a7715a5e98eb34a2d208538ee63a8bd83b402f71b461e390d38aeb7a8885b816bd1
7
+ data.tar.gz: d20c5ee0c9ddb0927649b884c45f84b7d7e97e315c54a2fd29c779a1b51c3f3691b5417d79e2dc4297d86f4795966703eb3462794ad0f867a0392cc9e9e4411d
data/CHANGELOG.md CHANGED
@@ -1,3 +1,15 @@
1
+ ## [3.7.1] - 2026-08-17
2
+
3
+ - [Fix] A refresh token Jobber will not take gives the credentials up, as it always should
4
+ have. Jobber answers that one in prose and with a 401 — `The provided refresh token is not
5
+ valid.` — where this gem only recognised the OAuth 2 `invalid_grant` in a JSON body, so it
6
+ read a dead grant as a bad moment: `invalid_at` was never set, the error escaped to the
7
+ caller, and an app that persists what it is told kept an authentication that could never work
8
+ again and retried it forever
9
+ - [Change] Read the body rather than the status, deliberately. Jobber answers 401 to an app
10
+ whose own client id and secret are wrong just as readily, and giving credentials up over that
11
+ would disconnect every account at once over one misconfigured app
12
+
1
13
  ## [3.7.0] - 2026-08-17
2
14
 
3
15
  - [New] `store:`, for credentials several processes hold copies of. A queue of workers each
data/README.md CHANGED
@@ -67,10 +67,11 @@ Revoke credentials:
67
67
  oauth.delete
68
68
  ```
69
69
 
70
- Credentials go bad only when Jobber says so. A refused refresh the `invalid_grant` Jobber
71
- names sets `invalid_at` and answers queries with nothing. Anything else that goes wrong,
72
- including a 500 or a rate limit, raises `Jbr::Error` instead, because a token that may still
73
- work is worth more than a tidy failure:
70
+ Credentials go bad only when Jobber says so of the grant itself: the `invalid_grant` it names,
71
+ or the 401 it answers a refresh token it will not take. Either sets `invalid_at` and answers
72
+ queries with nothing. Anything else that goes wrong raises `Jbr::Error` instead a 500, a rate
73
+ limit, and the 401 Jobber answers an app whose own client id and secret are wrong, which is
74
+ every account's grant at once rather than this one's:
74
75
 
75
76
  ```ruby
76
77
  oauth.invalid_at # => 2026-08-13 11:02:41, or nil while the credentials are good
data/lib/jbr/token.rb CHANGED
@@ -7,6 +7,10 @@ module Jbr
7
7
  # What Jobber calls a grant that is no good, in the OAuth 2 word for it.
8
8
  REFUSAL = 'invalid_grant'
9
9
 
10
+ # And what it calls one in the prose it answers a refresh token with instead. Specific to
11
+ # the token rather than to the app, which is the whole reason for reading the body.
12
+ REFUSAL_TEXT = /refresh token is not valid/
13
+
10
14
  # Trade a grant for credentials.
11
15
  # @param params [Hash] the grant, and the app making the exchange.
12
16
  # @raise [Refused] where Jobber says the grant itself is no good.
@@ -23,13 +27,21 @@ module Jbr
23
27
  }
24
28
  end
25
29
 
30
+ # Refused where Jobber turns the grant down rather than failing to answer about it: it names
31
+ # the word, or it names the token. Never the status on its own — Jobber answers 401 to a
32
+ # refresh token it will not take and 401 to an app whose own credentials are wrong, and
33
+ # acting on the second as though it were the first would disconnect every account at once.
26
34
  def self.refused?(response)
27
35
  return false if response.is_a? Net::HTTPSuccess
28
36
 
29
- JSON.parse(response.body)['error'] == REFUSAL
37
+ coded_refusal?(response.body) || REFUSAL_TEXT.match?(response.body.to_s)
38
+ end
39
+
40
+ def self.coded_refusal?(body)
41
+ JSON.parse(body)['error'] == REFUSAL
30
42
  rescue JSON::ParserError
31
43
  false
32
44
  end
33
- private_class_method :refused?
45
+ private_class_method :refused?, :coded_refusal?
34
46
  end
35
47
  end
data/lib/jbr/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # A Ruby client for the Jobber API.
2
2
  module Jbr
3
3
  # The version of this gem.
4
- VERSION = '3.7.0'
4
+ VERSION = '3.7.1'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jbr
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.7.0
4
+ version: 3.7.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Claudio Baccigalupo