[PR #4573] [CLOSED] fix(lastLoginMethod): add fallback support for customResolveMethod #5456

Closed
opened 2026-03-13 12:23:24 -05:00 by GiteaMirror · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/better-auth/better-auth/pull/4573
Author: @lumpinif
Created: 9/10/2025
Status: Closed

Base: canaryHead: fix-last-login-method-custom-resolve-fallback


📝 Commits (9)

  • d3f4057 fix: add fallback support for customResolveMethod in lastLoginMethod plugin
  • 1a799c1 Update docs/content/docs/plugins/last-login-method.mdx
  • cf3147a Update docs/content/docs/plugins/last-login-method.mdx
  • 4e378c7 Update docs/content/docs/plugins/last-login-method.mdx
  • c9668e0 fix(lastLoginMethod): correct fallback logic in customResolveMethod for lastLoginMethod plugin
  • 32d2f5d Merge branch 'canary' into fix-last-login-method-custom-resolve-fallback
  • a6f85c0 Merge branch 'canary' into fix-last-login-method-custom-resolve-fallback
  • a049261 Merge branch 'canary' into fix-last-login-method-custom-resolve-fallback
  • 61bebdd Merge branch 'canary' into fix-last-login-method-custom-resolve-fallback

📊 Changes

2 files changed (+231 additions, -8 deletions)

View changed files

📝 docs/content/docs/plugins/last-login-method.mdx (+11 -8)
packages/better-auth/src/plugins/last-login-method/custom-resolve-fallback.test.ts (+220 -0)

📄 Description

Summary

Previously, when users provided a customResolveMethod, it completely replaced the default resolution logic, causing them to lose built-in functionality for standard authentication paths like /sign-in/email and OAuth callbacks (/callback/google,
/oauth2/callback/github, etc.).

Problem

Users who wanted to track custom authentication methods (like SAML, magic links, phone auth) had to choose between:

  • Option A: No customResolveMethod → only built-in paths work
  • Option B: Use customResolveMethod → lose ALL built-in path detection

This forced users to reimplement all the default logic manually, which was error-prone and defeated the purpose of having built-in detection.

Solution

Implement a fallback pattern where:

  1. Try the user's customResolveMethod first
  2. If it returns null, fall back to the default resolution logic
  3. This allows extending functionality without losing built-in behavior

Changes

  • Add fallback logic that preserves default path detection
  • Users can return null from customResolveMethod to use built-in detection
  • Comprehensive test suite covering all fallback scenarios
  • Updated documentation with improved examples and behavior explanation

Test Plan

  • All existing tests pass
  • Added 5 new test cases covering:
    • Default behavior when no custom method provided
    • Custom method completely overriding (returns non-null always)
    • Custom method with fallback (returns null for standard paths)
    • Mixed custom + default path handling
    • Database storage compatibility with fallback

Before/After

Before (Broken):

// User loses ALL built-in detection
lastLoginMethod({
  customResolveMethod: (ctx) => {
    if (ctx.path === "/custom-auth") return "custom";
    return null; // ❌ Standard paths like /sign-in/email return null
  }
})

After (Fixed):
// User gets custom paths + built-in detection
lastLoginMethod({
  customResolveMethod: (ctx) => {
    if (ctx.path === "/custom-auth") return "custom";
    return null; // ✅ Falls back to built-in: /sign-in/email → "email"
  }
})

Benefits

  • Extend without breaking: Add custom auth methods while keeping built-in functionality
  • No reimplementation needed: Users don't have to rewrite email/OAuth detection
  • Backward compatible: Existing custom methods that handle all paths still work
  • Intuitive behavior: Returning null means "use default logic" (expected behavior)

Summary by cubic

Fixes lastLoginMethod so customResolveMethod now falls back to default detection when it returns null. Users can add custom auth methods without losing built-in email/OAuth detection.

  • Bug Fixes
    • Implement fallback: try customResolveMethod first; if it returns null, use default resolver.
    • Preserve built-in paths like /sign-in/email and /callback/:provider.
    • Remains backward compatible when custom methods always return a value.
    • Add tests for no custom method, full override, fallback, mixed paths, and DB storage.
    • Update docs with examples and clearer behavior.

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/better-auth/better-auth/pull/4573 **Author:** [@lumpinif](https://github.com/lumpinif) **Created:** 9/10/2025 **Status:** ❌ Closed **Base:** `canary` ← **Head:** `fix-last-login-method-custom-resolve-fallback` --- ### 📝 Commits (9) - [`d3f4057`](https://github.com/better-auth/better-auth/commit/d3f4057ac347fa531bed528b42ebaefcf4feaf4a) fix: add fallback support for customResolveMethod in lastLoginMethod plugin - [`1a799c1`](https://github.com/better-auth/better-auth/commit/1a799c12f5bff08b6a5d865e05ee70c65babbdc4) Update docs/content/docs/plugins/last-login-method.mdx - [`cf3147a`](https://github.com/better-auth/better-auth/commit/cf3147a31a3454c5bb9491a4a7ab033d9a51b27f) Update docs/content/docs/plugins/last-login-method.mdx - [`4e378c7`](https://github.com/better-auth/better-auth/commit/4e378c7a9cc414a2a359e06753703a92d6dcbd25) Update docs/content/docs/plugins/last-login-method.mdx - [`c9668e0`](https://github.com/better-auth/better-auth/commit/c9668e0e790529ddb64f22fe09e4378e0691a52b) fix(lastLoginMethod): correct fallback logic in customResolveMethod for lastLoginMethod plugin - [`32d2f5d`](https://github.com/better-auth/better-auth/commit/32d2f5d82ba08ff7ff822601c96cc77c41b70b00) Merge branch 'canary' into fix-last-login-method-custom-resolve-fallback - [`a6f85c0`](https://github.com/better-auth/better-auth/commit/a6f85c01c94a14fec4bcb6e51f6b7f6801a66adb) Merge branch 'canary' into fix-last-login-method-custom-resolve-fallback - [`a049261`](https://github.com/better-auth/better-auth/commit/a04926110102581ff0308b167fa9a7a1dc4af0f4) Merge branch 'canary' into fix-last-login-method-custom-resolve-fallback - [`61bebdd`](https://github.com/better-auth/better-auth/commit/61bebdd01342c4cbf932d0417e01310db0335588) Merge branch 'canary' into fix-last-login-method-custom-resolve-fallback ### 📊 Changes **2 files changed** (+231 additions, -8 deletions) <details> <summary>View changed files</summary> 📝 `docs/content/docs/plugins/last-login-method.mdx` (+11 -8) ➕ `packages/better-auth/src/plugins/last-login-method/custom-resolve-fallback.test.ts` (+220 -0) </details> ### 📄 Description ## Summary Previously, when users provided a `customResolveMethod`, it completely replaced the default resolution logic, causing them to lose built-in functionality for standard authentication paths like `/sign-in/email` and OAuth callbacks (`/callback/google`, `/oauth2/callback/github`, etc.). ## Problem Users who wanted to track custom authentication methods (like SAML, magic links, phone auth) had to choose between: - **Option A**: No `customResolveMethod` → only built-in paths work - **Option B**: Use `customResolveMethod` → lose ALL built-in path detection This forced users to reimplement all the default logic manually, which was error-prone and defeated the purpose of having built-in detection. ## Solution Implement a **fallback pattern** where: 1. Try the user's `customResolveMethod` first 2. If it returns `null`, fall back to the default resolution logic 3. This allows extending functionality without losing built-in behavior ## Changes - Add fallback logic that preserves default path detection - Users can return `null` from `customResolveMethod` to use built-in detection - Comprehensive test suite covering all fallback scenarios - Updated documentation with improved examples and behavior explanation ## Test Plan - [x] All existing tests pass - [x] Added 5 new test cases covering: - Default behavior when no custom method provided - Custom method completely overriding (returns non-null always) - Custom method with fallback (returns null for standard paths) - Mixed custom + default path handling - Database storage compatibility with fallback ## Before/After **Before (Broken):** ```typescript // User loses ALL built-in detection lastLoginMethod({ customResolveMethod: (ctx) => { if (ctx.path === "/custom-auth") return "custom"; return null; // ❌ Standard paths like /sign-in/email return null } }) After (Fixed): // User gets custom paths + built-in detection lastLoginMethod({ customResolveMethod: (ctx) => { if (ctx.path === "/custom-auth") return "custom"; return null; // ✅ Falls back to built-in: /sign-in/email → "email" } }) ``` Benefits - ✅ Extend without breaking: Add custom auth methods while keeping built-in functionality - ✅ No reimplementation needed: Users don't have to rewrite email/OAuth detection - ✅ Backward compatible: Existing custom methods that handle all paths still work - ✅ Intuitive behavior: Returning null means "use default logic" (expected behavior) <!-- This is an auto-generated description by cubic. --> --- ## Summary by cubic Fixes lastLoginMethod so customResolveMethod now falls back to default detection when it returns null. Users can add custom auth methods without losing built-in email/OAuth detection. - **Bug Fixes** - Implement fallback: try customResolveMethod first; if it returns null, use default resolver. - Preserve built-in paths like /sign-in/email and /callback/:provider. - Remains backward compatible when custom methods always return a value. - Add tests for no custom method, full override, fallback, mixed paths, and DB storage. - Update docs with examples and clearer behavior. <!-- End of auto-generated description by cubic. --> --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
GiteaMirror added the pull-request label 2026-03-13 12:23:24 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#5456