Skip to content

Fix Airtable OAuth State#717

Open
jeffrey-martinez wants to merge 4 commits intomasterfrom
oauth_actions_poc
Open

Fix Airtable OAuth State#717
jeffrey-martinez wants to merge 4 commits intomasterfrom
oauth_actions_poc

Conversation

@jeffrey-martinez
Copy link
Copy Markdown
Contributor

  • Implemented oauthMaybeEncryptTokens and oauthExtractTokensFromStateJson in form() and execute()
  • Fixed double-stringification bugs during token serialization
  • Updated AirtableTokens to preserve redirectUri across refresh loops
  • Added backward compatibility in oauthCheck() for legacy, unencrypted state_json formats
  • Ensured 100% test coverage and addressed all linter warnings

Improves on changes in Brian's WIP, and includes his refactor of Google Drive / Sheets oauth changes

  • Refactor the oauth changes so we can extract some of the encryption
  • logic for use with the remaining oauth actions.

bgraves-lo and others added 3 commits February 12, 2026 14:33
Refactor the oauth changes so we can extract some of the encryption
logic for use with the remaining oauth actions.
- Implemented oauthMaybeEncryptTokens and oauthExtractTokensFromStateJson in form() and execute()
- Fixed double-stringification bugs during token serialization
- Updated AirtableTokens to preserve redirectUri across refresh loops
- Added backward compatibility in oauthCheck() for legacy, unencrypted state_json formats
- Ensured 100% test coverage and addressed all linter warnings
@jeffrey-martinez jeffrey-martinez requested a review from a team as a code owner February 26, 2026 21:52
@gemini-code-assist
Copy link
Copy Markdown

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly refactors the OAuth state management across multiple actions to enhance security, improve maintainability, and standardize token handling. By centralizing encryption and decryption logic within the base OAuthAction class, it ensures sensitive OAuth tokens are securely stored and processed. The changes also introduce a more robust token payload abstraction and maintain backward compatibility with existing unencrypted states, streamlining the integration of new and existing OAuth providers.

Highlights

  • Centralized OAuth State Management: Introduced oauthExtractTokensFromStateJson, oauthMaybeEncryptTokens, and oauthDecryptTokens methods to the base OAuthAction class, centralizing the logic for handling OAuth state parsing, encryption, and decryption across various actions.
  • OAuth State Encryption: Implemented encryption for OAuth tokens stored in state_json using a new EncryptedPayload class and ActionCrypto, enhancing security for sensitive token data. Encryption can be enabled per action via environment variables.
  • Backward Compatibility: The oauthExtractTokensFromStateJson method now supports both newly encrypted state formats and legacy unencrypted state_json formats, ensuring seamless transitions for existing integrations.
  • Token Payload Abstraction: Created an abstract TokenPayload class and specific implementations like AirtableTokens and DriveTokens to provide a standardized and type-safe structure for managing OAuth tokens and their associated metadata, such as redirectUri.
  • Serialization Fixes: Addressed double-stringification bugs during token serialization, ensuring that OAuth state data is correctly formatted when stored and retrieved.
  • Google Drive OAuth Refactor: Refactored Google Drive OAuth handling to utilize the new DriveTokens class and the centralized encryption/decryption methods, removing the generic ActionToken.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • lib/actions/airtable/airtable.js
    • Updated execute and form methods to use oauthExtractTokensFromStateJson and oauthMaybeEncryptTokens for token handling.
    • Modified oauthCheck to validate state using oauthExtractTokensFromStateJson.
    • Adjusted oauthFetchInfo to use AirtableTokens and oauthMaybeEncryptTokens for token storage.
  • lib/actions/dropbox/dropbox.d.ts
    • Updated dropboxClientFromRequest return type to Promise<Dropbox>.
  • lib/actions/dropbox/dropbox.js
    • Updated execute, form, oauthCheck, and dropboxClientFromRequest to use oauthExtractTokensFromStateJson.
    • Modified form to use oauthMaybeEncryptTokens for state data.
  • lib/actions/facebook/facebook_custom_audiences.js
    • Updated oauthFetchInfo to use oauthMaybeEncryptTokens for state data.
    • Modified getAccessTokenFromRequest to use oauthExtractTokensFromStateJson.
  • lib/actions/google/ads/customer_match.js
    • Updated execute and form methods to use oauthMaybeEncryptTokens for user state.
  • lib/actions/google/ads/lib/ads_request.d.ts
    • Updated constructor signature to include userState parameter.
  • lib/actions/google/ads/lib/ads_request.js
    • Removed safeParseJson utility import.
    • Modified fromHub to extract user state using oauthExtractTokensFromStateJson.
    • Updated constructor to accept userState directly.
  • lib/actions/google/analytics/data_import.js
    • Updated execute method to use oauthMaybeEncryptTokens for user state.
  • lib/actions/google/analytics/lib/ga_worker.d.ts
    • Updated constructor signature to include userState parameter.
  • lib/actions/google/analytics/lib/ga_worker.js
    • Removed safeParseJson utility import.
    • Modified fromHubRequest to extract user state using oauthExtractTokensFromStateJson.
    • Updated constructor to accept userState directly.
  • lib/actions/google/common/oauth_helper.js
    • Updated oauthFetchInfo to use oauthMaybeEncryptTokens for user state.
  • lib/actions/google/common/utils.d.ts
    • Removed safeParseJson and isMochaRunning declarations.
  • lib/actions/google/common/utils.js
    • Removed safeParseJson and isMochaRunning implementations.
  • lib/actions/google/common/wrapped_response.js
    • Updated setUserState to handle both encrypted string and JSON stringification.
  • lib/actions/google/drive/drive_tokens.d.ts
    • Added DriveTokens class declaration, extending TokenPayload.
  • lib/actions/google/drive/drive_tokens.js
    • Added DriveTokens class implementation, extending TokenPayload.
  • lib/actions/google/drive/google_drive.d.ts
    • Imported DriveTokens.
    • Updated return types for oauthFetchAccessToken, oauthExtractTokensFromStateJson, oauthMaybeEncryptTokens, and oauthDecryptTokens to use DriveTokens or EncryptedPayload.
  • lib/actions/google/drive/google_drive.js
    • Imported DriveTokens.
    • Updated form, oauthFetchAccessToken, oauthExtractTokensFromStateJson, oauthMaybeEncryptTokens, oauthDecryptTokens, and oauthFetchAndStoreInfo to use DriveTokens and the new encryption methods.
  • lib/actions/salesforce/campaigns/salesforce_campaigns.js
    • Updated execute and form methods to use oauthExtractTokensFromStateJson and oauthMaybeEncryptTokens for token handling.
  • lib/crypto/aes_transit_crypto.js
    • Changed error throws from string literals to new Error() instances for consistency.
  • lib/hub/action_token.d.ts
    • Removed ActionToken class declaration.
  • lib/hub/action_token.js
    • Renamed to lib/actions/google/drive/drive_tokens.js.
  • lib/hub/encrypted_payload.d.ts
    • Added static crypto, currentCipherId, and encrypt methods.
    • Added instance decrypt method.
  • lib/hub/encrypted_payload.js
    • Added static crypto, currentCipherId, and encrypt methods.
    • Added instance decrypt method.
    • Updated decrypt to return TokenPayload.
  • lib/hub/index.d.ts
    • Removed action_token export and added token_payload export.
    • Re-exported encrypted_payload.
  • lib/hub/index.js
    • Removed action_token export and added token_payload export.
    • Re-exported encrypted_payload.
  • lib/hub/oauth_action.d.ts
    • Added oauthExtractTokensFromStateJson, oauthMaybeEncryptTokens, and oauthDecryptTokens method declarations.
  • lib/hub/oauth_action.js
    • Implemented oauthExtractTokensFromStateJson, oauthMaybeEncryptTokens, and oauthDecryptTokens methods, including logic for encryption based on per-action environment variables and backward compatibility.
  • lib/hub/oauth_action_v2.d.ts
    • Updated oauthFetchAccessToken return type from ActionToken to TokenPayload.
  • lib/hub/token_payload.d.ts
    • Added abstract TokenPayload class declaration.
  • lib/hub/token_payload.js
    • Added abstract TokenPayload class implementation.
  • src/actions/airtable/airtable.ts
    • Updated execute and form methods to use oauthExtractTokensFromStateJson and oauthMaybeEncryptTokens for token handling.
    • Modified oauthCheck to validate state using oauthExtractTokensFromStateJson.
    • Adjusted oauthFetchInfo to use AirtableTokens and oauthMaybeEncryptTokens for token storage.
  • src/actions/airtable/airtable_tokens.ts
    • Added AirtableTokens class, extending TokenPayload, to manage Airtable-specific OAuth tokens.
  • src/actions/airtable/test_airtable.ts
    • Added unit tests for oauthCheck method, including legacy unencrypted state.
  • src/actions/dropbox/dropbox.ts
    • Updated execute, form, oauthCheck, and dropboxClientFromRequest to use oauthExtractTokensFromStateJson.
    • Modified form to use oauthMaybeEncryptTokens for state data.
  • src/actions/facebook/facebook_custom_audiences.ts
    • Updated oauthFetchInfo to use oauthMaybeEncryptTokens for state data.
    • Modified getAccessTokenFromRequest to use oauthExtractTokensFromStateJson.
  • src/actions/facebook/test_facebook_custom_audiences.ts
    • Updated test expectation for oauthFetchInfo to reflect JSON stringification of data.
  • src/actions/google/ads/customer_match.ts
    • Updated execute and form methods to use oauthMaybeEncryptTokens for user state.
  • src/actions/google/ads/lib/ads_request.ts
    • Removed safeParseJson utility import.
    • Modified fromHub to extract user state using oauthExtractTokensFromStateJson.
    • Updated constructor to accept userState directly.
  • src/actions/google/ads/test_customer_match.ts
    • Updated test expectation for oauthFetchInfo to reflect JSON stringification of data.
  • src/actions/google/analytics/data_import.ts
    • Updated execute method to use oauthMaybeEncryptTokens for user state.
  • src/actions/google/analytics/lib/ga_worker.ts
    • Removed safeParseJson utility import.
    • Modified fromHubRequest to extract user state using oauthExtractTokensFromStateJson.
    • Updated constructor to accept userState directly.
  • src/actions/google/analytics/test_data_import.ts
    • Updated test expectation for oauthFetchInfo to reflect JSON stringification of data.
  • src/actions/google/common/oauth_helper.ts
    • Updated oauthFetchInfo to use oauthMaybeEncryptTokens for user state.
  • src/actions/google/common/wrapped_response.ts
    • Updated setUserState to handle both encrypted string and JSON stringification.
  • src/actions/google/drive/drive_tokens.ts
    • Added DriveTokens class, extending TokenPayload, to manage Google Drive-specific OAuth tokens.
  • src/actions/google/drive/google_drive.ts
    • Imported DriveTokens.
    • Updated form, oauthFetchAccessToken, oauthExtractTokensFromStateJson, oauthMaybeEncryptTokens, oauthDecryptTokens, and oauthFetchAndStoreInfo to use DriveTokens and the new encryption methods.
  • src/actions/salesforce/campaigns/salesforce_campaigns.ts
    • Updated execute and form methods to use oauthExtractTokensFromStateJson and oauthMaybeEncryptTokens for token handling.
  • src/crypto/aes_transit_crypto.ts
    • Changed error throws from string literals to new Error() instances for consistency.
  • src/hub/action_token.ts
    • Removed ActionToken class.
  • src/hub/encrypted_payload.ts
    • Added static crypto, currentCipherId, and encrypt methods.
    • Added instance decrypt method.
    • Updated decrypt to return TokenPayload.
  • src/hub/index.ts
    • Removed action_token export and added token_payload export.
    • Re-exported encrypted_payload.
  • src/hub/oauth_action.ts
    • Implemented oauthExtractTokensFromStateJson, oauthMaybeEncryptTokens, and oauthDecryptTokens methods, including logic for encryption based on per-action environment variables and backward compatibility.
  • src/hub/oauth_action_v2.ts
    • Updated oauthFetchAccessToken return type from ActionToken to TokenPayload.
  • src/hub/token_payload.ts
    • Added abstract TokenPayload class.
  • test/test.ts
    • Added import for test_oauth_action.
  • test/test_oauth_action.ts
    • Added new test file for OAuthAction encryption/decryption logic, covering oauthMaybeEncryptTokens and oauthExtractTokensFromStateJson.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a significant and valuable refactoring of the OAuth token handling and encryption logic across multiple actions. The introduction of oauthExtractTokensFromStateJson and oauthMaybeEncryptTokens in the base OAuthAction class centralizes this functionality, improving consistency and maintainability. The changes correctly address double-stringification issues and add backward compatibility for legacy unencrypted states. The new TokenPayload abstraction and specific token classes like AirtableTokens and DriveTokens are also great improvements. Overall, this is a well-executed refactoring that enhances the robustness of the OAuth implementation. I have one minor suggestion regarding a redundant conditional.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants