Skip to content

fix(auth): Echo original session method on refresh_token#14

Merged
gjtorikian merged 1 commit into
mainfrom
fix/refresh-echoes-session-auth-method
Jul 14, 2026
Merged

fix(auth): Echo original session method on refresh_token#14
gjtorikian merged 1 commit into
mainfrom
fix/refresh-echoes-session-auth-method

Conversation

@gjtorikian

Copy link
Copy Markdown
Collaborator

Summary

Follow-up to #12. A Greptile review comment flagged that the refresh_token grant loses the original authentication method.

  • The refresh_token grant reuses an existing session but hard-coded its internal method category to 'OAuth' (auth.ts:389). After fix(auth): Emit spec-valid authentication_method #12 resolved that category to a spec-valid value, a refresh dropped authentication_method entirely for any non-OAuth session (e.g. a password login), because 'OAuth' resolves to the user's oauth_provider or nothing.
  • Real WorkOS echoes the session's original method on refresh — and the emulator already stores it: the reused session records auth_method (auth.ts:514).
  • Recover the truthful value from the reused session's stored auth_method (snake_case) via a new resolveSessionResponseAuthMethod: password → Password, magic_code → MagicAuth, sso → SSO, etc. Generic oauth still defers to oauth_provider (else omit); unknown/unmapped values are omitted rather than guessed — consistent with the fresh-login path.
  • Keeps the "never fabricate a method" principle from fix(auth): Emit spec-valid authentication_method #12: this recovers a value that was already persisted rather than inventing one.

Test plan

  • Extended the existing refresh_token test: a password login now asserts authentication_method: 'Password' on both the initial response and the refreshed response (previously the field was dropped on refresh).
  • authorization_code / device_code are genuinely provider-less fresh logins, so their omit-or-oauth_provider behavior is unchanged.
  • Full suite: 488 tests pass; typecheck, lint, and format clean.

Refs #11.

🤖 Generated with Claude Code

The refresh_token grant reuses an existing session but hard-coded its
internal method category to 'OAuth'. After #12 resolved that category to
a spec-valid value, a refresh dropped authentication_method entirely for
any non-OAuth session (e.g. a password login), since 'OAuth' resolves to
the user's oauth_provider or nothing. Real WorkOS echoes the session's
original method.

Recover the truthful value from the reused session's stored auth_method
(snake_case) via resolveSessionResponseAuthMethod — password → Password,
magic_code → MagicAuth, sso → SSO, etc. Generic 'oauth' still defers to
oauth_provider (else omit); 'unknown'/unmapped values are omitted rather
than guessed, consistent with the fresh-login path.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@greptile-apps

greptile-apps Bot commented Jul 14, 2026

Copy link
Copy Markdown

Greptile Summary

This PR keeps the original authentication method on refresh-token responses. The main changes are:

  • Added a helper that maps stored session auth_method values back to response authentication_method values.
  • Updated refresh-token handling to resolve authentication_method from the reused session instead of the internal OAuth grant category.
  • Extended the refresh-token test to verify password logins return Password before and after token rotation.

Confidence Score: 5/5

Safe to merge with minimal risk.

The change is narrow, preserves existing omission behavior for unknown or provider-less OAuth methods, and adds regression coverage for the refreshed password session path.

No files require special attention.

T-Rex T-Rex Logs

What T-Rex did

  • Validated that the authentication refresh test suite completed with 34 tests passing and exited with code 0.
  • Validated that the test named 'src/workos/routes/auth.spec.ts > Auth routes > refresh_token grant returns new tokens and invalidates old' passed.
  • Verified that the assertion checks required the authentication_method to be 'Password' for both initial login and the refreshed response.

View all artifacts

T-Rex Ran code and verified through T-Rex

Important Files Changed

Filename Overview
src/workos/helpers.ts Adds a helper to map stored session auth_method values back to response authentication_method values for refresh-token responses.
src/workos/routes/auth.ts Refresh-token responses now derive authentication_method from the reused session while fresh logins keep the existing resolver.
src/workos/routes/auth.spec.ts Extends the refresh-token test to assert password sessions preserve authentication_method across token rotation.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant Client
participant AuthRoute as /user_management/authenticate
participant Store as Session/Token Store
participant Helpers as Auth Method Resolver

Client->>AuthRoute: password grant
AuthRoute->>Store: "create session auth_method=password"
AuthRoute->>Helpers: resolveResponseAuthMethod(Password)
Helpers-->>AuthRoute: Password
AuthRoute-->>Client: "tokens + authentication_method=Password"

Client->>AuthRoute: refresh_token grant
AuthRoute->>Store: load refresh token and existing session
AuthRoute->>Store: rotate refresh token
AuthRoute->>Helpers: resolveSessionResponseAuthMethod(session.auth_method)
Helpers-->>AuthRoute: Password
AuthRoute-->>Client: new tokens + original authentication_method
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
participant Client
participant AuthRoute as /user_management/authenticate
participant Store as Session/Token Store
participant Helpers as Auth Method Resolver

Client->>AuthRoute: password grant
AuthRoute->>Store: "create session auth_method=password"
AuthRoute->>Helpers: resolveResponseAuthMethod(Password)
Helpers-->>AuthRoute: Password
AuthRoute-->>Client: "tokens + authentication_method=Password"

Client->>AuthRoute: refresh_token grant
AuthRoute->>Store: load refresh token and existing session
AuthRoute->>Store: rotate refresh token
AuthRoute->>Helpers: resolveSessionResponseAuthMethod(session.auth_method)
Helpers-->>AuthRoute: Password
AuthRoute-->>Client: new tokens + original authentication_method
Loading

Reviews (1): Last reviewed commit: "fix(auth): Echo original session method ..." | Re-trigger Greptile

@gjtorikian gjtorikian merged commit 97fb951 into main Jul 14, 2026
6 checks passed
@gjtorikian gjtorikian deleted the fix/refresh-echoes-session-auth-method branch July 14, 2026 20:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant