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:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8e2491421a8ef87f13bdf5713bb30b07c92f12dc9abeffdf985ec8c4a2db04b5
|
|
4
|
+
data.tar.gz: 13dc408e540367da45330ca0d17ee785cda564312e865752d4e9635c75cd1b27
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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
|