instagram_connect 0.3.11 → 0.3.12

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: 34e72217b3285a05cf86874ad6d225bc92304f0f496381b86707b257d6e25571
4
- data.tar.gz: 77fc696bff514db7f944596595a9f6e9773f14cf4993975e4933e9805bf0ab76
3
+ metadata.gz: 8e2491421a8ef87f13bdf5713bb30b07c92f12dc9abeffdf985ec8c4a2db04b5
4
+ data.tar.gz: 13dc408e540367da45330ca0d17ee785cda564312e865752d4e9635c75cd1b27
5
5
  SHA512:
6
- metadata.gz: bdf866209e683e9dd48942da0027d8ee008abe7bce256dbc37cdf4809a4394a1a6ce990d5e8d38b3f08222e216d72a814445757144dc9c619938a71a682788c1
7
- data.tar.gz: f6ffb8669960514dbe4a914a7f6a6f104a902cd746168e6e4e5dfc2140d5034434fd701ed9bb484eea035708940ed04bf10340e24c9aac88659c2f3df08d1d4a
6
+ metadata.gz: 331c2f1c32aac22c0270d59b17a0ce189bb3ceb96bd5cc389b7e4a0cb7c06e85ffbe9d14970a4362d8b0d7eaf0b07b609b14b5ae918ae0048a404743fcaf57cc
7
+ data.tar.gz: 824e82804b90ae2bd9f887d109e1945ddffd549e1f1e92852a985465b1cd484a29993139fb9ce474f9a14195d895aafdf2e2a4fac0351857192078bebfb1ae58
data/CHANGELOG.md CHANGED
@@ -6,6 +6,19 @@ All notable changes to this project are documented here. The format follows
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [0.3.12] - 2026-07-27
10
+
11
+ ### Fixed
12
+
13
+ - **An undecryptable access token is caught here, not by Meta.** Tokens are encrypted at rest;
14
+ with `support_unencrypted_data` on, a decrypt that fails (rotated or missing keys) hands the
15
+ ENVELOPE back instead of raising, and every Graph call then sent that JSON blob as the bearer
16
+ token — Meta answered `Invalid OAuth access token - Cannot parse access token` and nothing said
17
+ the cause was local. `Account#client` now refuses to build, stamps `readiness_error` with the
18
+ fix ("reconnect this Instagram account"), and raises `TokenUnreadableError`, which jobs log and
19
+ stop on rather than retrying forever. `Account#token_readable?` is public for host health screens.
20
+
21
+
9
22
  ## [0.3.11] - 2026-07-27
10
23
 
11
24
  ### Fixed
@@ -1,4 +1,11 @@
1
1
  module InstagramConnect
2
2
  class ApplicationJob < ActiveJob::Base
3
+ # A token this process cannot decrypt is a configuration fault, not a
4
+ # transient one: retrying re-raises forever and Meta only ever answers
5
+ # "Cannot parse access token". Log the actionable message once and stop —
6
+ # Account#client has already stamped readiness_error for the health screen.
7
+ rescue_from InstagramConnect::TokenUnreadableError do |error|
8
+ logger.error("[instagram_connect] #{self.class.name} aborted: #{error.message}")
9
+ end
3
10
  end
4
11
  end
@@ -24,6 +24,13 @@ module InstagramConnect
24
24
  encrypts :page_access_token
25
25
  end
26
26
 
27
+ # An Active Record Encryption envelope, as stored. With
28
+ # support_unencrypted_data on, a decrypt that FAILS (rotated or missing
29
+ # keys) hands the envelope back instead of raising — so an unreadable
30
+ # token reaches Meta as this JSON blob and comes back as the baffling
31
+ # "Cannot parse access token", with every call dead and nothing saying why.
32
+ ENCRYPTED_ENVELOPE = /\A\{"p":/
33
+
27
34
  # Every Instagram messaging call and the webhook subscription are Page-token
28
35
  # operations. Falling back to the user token keeps a freshly connected
29
36
  # account working until the readiness pass swaps in the Page one.
@@ -31,10 +38,30 @@ module InstagramConnect
31
38
  page_access_token.presence || access_token
32
39
  end
33
40
 
41
+ # False when the stored token cannot be decrypted with the keys this
42
+ # process has. Recovery is always the same: reconnect the account, which
43
+ # writes fresh tokens under the current keys.
44
+ def token_readable?
45
+ token = api_token.to_s
46
+ token.present? && !token.match?(ENCRYPTED_ENVELOPE)
47
+ end
48
+
49
+ TOKEN_UNREADABLE_MESSAGE =
50
+ "Stored access token cannot be decrypted with the current encryption " \
51
+ "keys — reconnect this Instagram account to store a fresh one.".freeze
52
+
34
53
  # The only place a Client should be built. Constructing one directly picks
35
54
  # up the *global* auth path, which is wrong for any host with accounts on
36
55
  # both paths — and wrong silently, which is worse.
37
56
  def client
57
+ # Refuse to build a client around a token Meta can only reject, and
58
+ # record WHY on the row so the host's health screen can say it out loud
59
+ # instead of every screen quietly rendering empty.
60
+ unless token_readable?
61
+ update_columns(readiness_error: TOKEN_UNREADABLE_MESSAGE.truncate(255))
62
+ raise InstagramConnect::TokenUnreadableError, TOKEN_UNREADABLE_MESSAGE
63
+ end
64
+
38
65
  InstagramConnect::Client.new(
39
66
  access_token: api_token,
40
67
  ig_user_id: ig_user_id,
@@ -22,4 +22,10 @@ module InstagramConnect
22
22
 
23
23
  # Raised when an inbound webhook fails HMAC signature verification.
24
24
  class SignatureError < Error; end
25
+
26
+ # The stored token could not be decrypted with this process's encryption
27
+ # keys, so it is an envelope rather than a token. Raised before any Graph
28
+ # call, because sending it produces only Meta's opaque "Cannot parse access
29
+ # token" with no hint that the cause is local.
30
+ class TokenUnreadableError < Error; end
25
31
  end
@@ -1,3 +1,3 @@
1
1
  module InstagramConnect
2
- VERSION = "0.3.11"
2
+ VERSION = "0.3.12"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: instagram_connect
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.11
4
+ version: 0.3.12
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kshitiz Sinha