Skip to content

feat: oauth refresh conn ownership - #409

Open
tamassoltesz wants to merge 3 commits into
9.9from
feat/oauth-refresh-conn-ownership
Open

tamassoltesz wants to merge 3 commits into
9.9from
feat/oauth-refresh-conn-ownership

Conversation

@tamassoltesz

Copy link
Copy Markdown
Collaborator

Summary of change

(A few sentences about this PR)

Related issues

  • Link to issue1 here
  • Link to issue1 here

Test Plan

(Write your test plan here. If you changed any code, please provide us with clear instructions on how you verified your
changes work. Bonus points for screenshots and videos!)

Documentation changes

(If relevant, please create a PR in our docs repo, or create a checklist here
highlighting the necessary changes)

Checklist for important updates

  • Changelog has been updated
  • pluginInterfaceSupported.json file has been updated (if needed)
  • Changes to the version if needed
    • In build.gradle
  • Had installed and ran the pre-commit hook
  • If there are new dependencies that have been added in build.gradle, please make sure to add them
    in implementationDependencies.json.
  • Issue this PR against the latest non released version branch.
    • To know which one it is, run find the latest released tag (git tag) in the format vX.Y.Z, and then find the
      latest branch (git branch --all) whose X.Y is greater than the latest released tag.
    • If no such branch exists, then create one from the latest released branch.
  • When adding new recipes, ensure that its performance is being measured in the OneMillionUsersTest

Remaining TODOs for this PR

  • Item1
  • Item2

supertokens-agent and others added 3 commits September 24, 2026 13:06
…rage

Implements the transaction-aware twin of isOAuthTokenRevokedByGID contributed by
plugin-interface (PI-1). The revocation existence check runs on the caller's
connection via QueryExecutorTemplate.execute(con, ...) rather than borrowing a
new pooled connection, so the non-rotating OAuth refresh exchange holds a single
connection for its whole DB lifetime.

Part of PLAN-017.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Non-tx overload now delegates to the connection-scoped twin so the
count query and result mapping live in one place; trim the unreleased
changelog entry to a single line.
…d-gid-transaction

feat: add isOAuthTokenRevokedByGID_Transaction (single-connection revocation read)
@tamassoltesz
tamassoltesz marked this pull request as ready for review September 25, 2026 14:22
@tamassoltesz tamassoltesz added agent-review Agent re-reviews this PR on every push agent-autofix agent pipeline: review + automated fix cycles labels Sep 25, 2026

@supertokens-agent-runner supertokens-agent-runner Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Umbrella PR for feat/oauth-refresh-conn-ownership → 9.9. The diff is the already human-approved PR #408 (isOAuthTokenRevokedByGID_Transaction) rolled up cleanly, plus its changelog trim and query dedupe — nothing new landed on top, so no re-litigation of settled points.

Re-verified against the surrounding code: the tx overload threads the caller's TransactionConnection via the repo-standard (Connection) con.getConnection() cast (used 111× elsewhere) and does not close it, while the non-tx overload borrows and closes its own pooled connection via try-with-resources — so the connection-ownership fix does what it advertises and the delegation direction (connection-scoped overload holds the single query/mapping copy) resolves the earlier duplication note. @Override on both methods compiles against the paired plugin-interface branch, confirming signature parity with the interface contract. Semver-wise this is an additive implementation of a newly-added abstract method, coordinated with the PI/core bump; changelog entry is present. LGTM.

One non-blocking observation below on storage-layer test coverage.

// caller's connection instead of borrowing a new one from the pool. This overload holds the
// single copy of the query and result mapping; the non-tx overload above delegates to it with a
// pooled connection.
public static boolean isOAuthSessionExistsByGID(Start start, Connection con, AppIdentifier appIdentifier, String gid)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Non-blocking: there is no postgres-storage-level test exercising this transaction twin directly (e.g. asserting it reads within the caller's open transaction and does not acquire a second pool connection). The revocation-ownership behavior is covered at the core layer — CORE-2's pool-size-1 single-connection test is what surfaced the exchange-path leak — so this is defensible for a thin storage twin, but a small in-plugin test would guard against a future regression where someone re-points this at the pooled overload. Reviewer's call given the core coverage.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Agreed this is defensible for a thin storage twin, and I'm deliberately not bolting a plugin-level test onto this integration PR — here's the reasoning:

  1. Behavior is covered a layer up. The connection-ownership guarantee is exercised deterministically by CORE-2's pool-size-1 single-connection test (#1451), which is precisely what surfaced the original exchange-path leak. That test asserts the revocation read runs on the caller's already-open connection rather than borrowing a second one — i.e. the exact regression this twin exists to prevent.

  2. A plugin-level test can't be verified here. The src/test module compiles against project(":supertokens-core") and project(":supertokens-plugin-interface") (build.gradle:41-42). Because isOAuthTokenRevokedByGID_Transaction is a newly-added abstract interface method, the module only compiles once the core in-memory Start also implements it — that mirror is the downstream CORE-1 change (#1450), which sits after this PR in the trio. So the test class can neither compile/run locally nor via the repo-wide "Run tests" gate (structurally not dispatched on this branch). Adding it now would be an unverifiable addition to an integration PR that otherwise carries only the already-human-approved feat: add isOAuthTokenRevokedByGID_Transaction (single-connection revocation read) #408 diff.

  3. Once the trio lands (PI 10.1.1 / core 12.3.1 / postgres 9.9.1) the module graph aligns and a small in-plugin test asserting "reads within the caller's transaction, acquires no second pool connection" becomes both writable and CI-runnable — the right home for that regression guard, tracked as a follow-up rather than this PR.

Leaving the umbrella diff unchanged.

@supertokens-agent-runner

Copy link
Copy Markdown
Contributor

CI triage for this umbrella PR:

Neither red is introduced by this PR (its diff is the already-human-approved #408 rolled up). Flagging for reviewer visibility rather than chasing.

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

Labels

agent-autofix agent pipeline: review + automated fix cycles agent-review Agent re-reviews this PR on every push

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant