@danhachuel/thunderbolt 0.5.5 → 0.5.7

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.
package/app/main.py CHANGED
@@ -7105,14 +7105,17 @@ def _render_media_provider_card(settings: dict[str, Any], cards: list[dict[str,
7105
7105
  if card.get("provider") == "canva":
7106
7106
  callback_code = str(st.query_params.get("code") or "").strip()
7107
7107
  callback_state = str(st.query_params.get("state") or "").strip()
7108
- pending_state = str(st.session_state.get(f"canva_state_{card_id}") or "")
7108
+ oauth_pending = card.get("oauth_pending") if isinstance(card.get("oauth_pending"), dict) else {}
7109
+ pending_state = str(st.session_state.get(f"canva_state_{card_id}") or oauth_pending.get("state") or "")
7110
+ pending_verifier = str(st.session_state.get(f"canva_verifier_{card_id}") or oauth_pending.get("code_verifier") or "")
7109
7111
  if callback_code:
7110
- if callback_state != pending_state:
7112
+ if not pending_state or callback_state != pending_state:
7111
7113
  st.error("Canva OAuth rejeitado: state inválido. Inicie a autorização novamente.")
7112
7114
  else:
7113
7115
  try:
7114
- token = exchange_code(str(card.get("client_id") or ""), str(card.get("client_secret") or ""), callback_code, str(card.get("redirect_uri") or ""), str(st.session_state.get(f"canva_verifier_{card_id}") or ""))
7116
+ token = exchange_code(str(card.get("client_id") or ""), str(card.get("client_secret") or ""), callback_code, str(card.get("redirect_uri") or ""), pending_verifier)
7115
7117
  card["oauth_token"] = token
7118
+ card.pop("oauth_pending", None)
7116
7119
  cards[index] = card
7117
7120
  _persist_media_cards(settings, cards, str(settings.get(MEDIA_IMAGE_ACTIVE_CARD_KEY) or ""), str(settings.get(MEDIA_VIDEO_ACTIVE_CARD_KEY) or ""))
7118
7121
  st.session_state.pop(f"canva_state_{card_id}", None)
@@ -7201,6 +7204,7 @@ def _render_media_provider_card(settings: dict[str, Any], cards: list[dict[str,
7201
7204
  st.session_state[f"canva_verifier_{card_id}"] = verifier
7202
7205
  st.session_state[f"canva_state_{card_id}"] = state
7203
7206
  st.session_state[f"canva_authorization_url_{card_id}"] = authorization_url(client_id, redirect_uri, state=state, code_challenge=challenge)
7207
+ extra_values["oauth_pending"] = {"state": state, "code_verifier": verifier}
7204
7208
  authorization_link = str(st.session_state.get(f"canva_authorization_url_{card_id}") or "")
7205
7209
  if authorization_link:
7206
7210
  st.markdown(f"[Abrir autorização Canva]({authorization_link})")
@@ -61,7 +61,10 @@ def authorization_url(client_id: str, redirect_uri: str, scope: str | list[str]
61
61
  scope_string = " ".join(scope_value) if isinstance(scope_value, (list, tuple)) else " ".join(str(scope_value or "").split())
62
62
  params = {
63
63
  "code_challenge": code_challenge,
64
- "code_challenge_method": "s256",
64
+ # A Canva e a RFC 7636 definem o identificador do método com esta
65
+ # capitalização exacta: S256. O valor minúsculo pode abrir o
66
+ # consentimento, mas impedir a conclusão do fluxo OAuth.
67
+ "code_challenge_method": "S256",
65
68
  "scope": scope_string,
66
69
  "response_type": "code",
67
70
  "client_id": str(client_id).strip(),
@@ -232,6 +232,12 @@ def normalize_media_card(card: Any, index: int = 0) -> dict[str, Any]:
232
232
  result["thumbnail_width"] = raw_width if raw_width in {"1280", "1792"} else "1280"
233
233
  result["thumbnail_height"] = raw_height if raw_height in {"720", "1024"} else ("1024" if result["thumbnail_width"] == "1792" else "720")
234
234
  result["oauth_token"] = dict(source.get("oauth_token") or {}) if isinstance(source.get("oauth_token"), Mapping) else {}
235
+ pending = source.get("oauth_pending")
236
+ if isinstance(pending, Mapping) and pending.get("state") and pending.get("code_verifier"):
237
+ result["oauth_pending"] = {
238
+ "state": str(pending.get("state")),
239
+ "code_verifier": str(pending.get("code_verifier")),
240
+ }
235
241
  if provider == "nano_banana":
236
242
  result["aspect_ratio"] = str(source.get("aspect_ratio") or INTERNAL_IMAGE_ASPECT_RATIO).strip()
237
243
  result["image_size"] = str(source.get("image_size") or INTERNAL_IMAGE_SIZE).strip()
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@danhachuel/thunderbolt",
3
- "version": "0.5.5",
3
+ "version": "0.5.7",
4
4
  "description": "Thunderbolt — interface local para operação de canais faceless e motor MoneyPrinterTurbo",
5
5
  "license": "MIT",
6
6
  "main": "scripts/cli.mjs",