Skip to content

feat(api): fill the Clerk.auth gaps the prebuilt UI needs - #1035

Merged
swolfand merged 3 commits into
mike/auth-facade-delegationfrom
mike/auth-facade-ui-gaps
Oct 5, 2026
Merged

swolfand merged 3 commits into
mike/auth-facade-delegationfrom
mike/auth-facade-ui-gaps

Conversation

@swolfand

@swolfand swolfand commented Oct 2, 2026 •

Copy link
Copy Markdown
Collaborator

Why

Architecture review finding #9 recommends making Clerk.auth the primary auth API and moving the prebuilt UI onto it. Today the UI can't make that move: signInWithOAuth takes neither transferable nor redirectUrl, and several other UI calls have no facade equivalent. This PR adds every missing piece, so the UI migration PR becomes a mechanical swap.

Stack: #1026 (drift fixes) → #1034 (one implementation per operation + matrix) → this PR.

Scope

I grepped source/ui for every old-layer auth call. The full mapping table is in #1034. Added here:

  • Clerk.auth.signInWithOAuth(provider, transferable = true, redirectUrl = default)
  • Clerk.auth.signUpWithOAuth(provider, redirectUrl = default, unsafeMetadata = null)
  • Clerk.auth.signInWithPasskey(preferImmediatelyAvailableCredentials = false), for the UI's automatic passkey attempt
  • Clerk.auth.signInWithGoogleOneTap(transferable = true). It is now the implementation behind SignIn.authenticateWithGoogleOneTap and Clerk.auth.signUpWithGoogleOneTap (which keeps its sign-in-first behaviour from Expose organization switcher sheet and add org list previews #665).
  • SignInIdentifierBuilder.identifier, so a single "email, phone or username" field can call Clerk.auth.signIn { identifier = text }
  • SignIn.authenticateWithOAuth(provider, transferable, redirectUrl) and SignIn.authenticateWithEnterpriseSso(transferable, redirectUrl) continue an existing sign-in through a redirect factor (prepare + launch). These replace the UI's prepareFirstFactor(OAuth / EnterpriseSSO) + authenticateWithPreparedRedirect pairs.
  • SignIn.sendResetPasswordEmailCode(emailAddressId) / sendResetPasswordPhoneCode(phoneNumberId) take factor ids, which is what the UI has. sendResetPasswordCode { } now resolves the factor and delegates to them.
  • SignIn.create(Passkey, preferImmediatelyAvailableCredentials) and SignIn.authenticateWithGoogleOneTap now delegate to the facade methods above.

No UI call sites change here, and nothing is deprecated. The deprecation of the old layer with ReplaceWith follows once the UI migration lands. Deprecating now would flood :source:ui with warnings.

Blast Radius

Testing

  • AuthFacadeUiGapsTest (new, 10 cases): each new parameter or method reaches the right service with the right arguments. It also checks the reset-by-id local failure, the existing-sign-in redirect continuation, and that the old JVM signatures still exist. Against refactor(api): route both auth API layers through one implementation per operation #1034 the file doesn't compile, because the APIs it tests don't exist yet.
  • AuthTest: the two Google One Tap tests now mock GoogleSignInService, since the facade no longer goes through SignIn.authenticateWithGoogleOneTap.
  • ./gradlew :source:api:spotlessApply :source:api:detekt :source:api:testDebugUnitTest: all pass.
  • ./gradlew :source:ui:testDebugUnitTest :source:ui:detekt: all pass.
  • ./gradlew :samples:linear-clone:compileDebugKotlin: compiles. It calls signInWithOAuth / signInWithPasskey.

🤖 Generated with Claude Code

Review follow-ups

"Guard the new identifier field and clarify facade redirect and reset docs":

  • signIn { identifier = … } now rejects identifier combined with email / phone / username. Before, the identifier silently lost.
  • The redirectUrl KDoc on signInWithOAuth / signUpWithOAuth / authenticateWithOAuth / authenticateWithEnterpriseSso now says a custom value must be routed to SSOReceiverActivity, because Clerk.auth.handle() only completes clerk-scheme OAuth callbacks. Changing handle() to route any URI while SSO is pending would cancel the flow on unrelated deep links, so I documented it instead.
  • sendResetPasswordEmailCode / PhoneCode KDoc says a null id picks the first reset factor whatever its address, and an explicit id is sent as given.
  • New tests: SignIn.create(Passkey, preferImmediatelyAvailableCredentials = true), no redirect after a failed prepare, and the null-id reset fallback.

"Add facade transfers, custom email-link redirects and Enterprise SSO options" closes the gaps that kept old entry points in #1039 without a replacement:

  • Clerk.auth.transferToSignIn() / transferToSignUp() complete a transfer after signUpWithIdToken / signInWithIdToken, which don't transfer on their own.
  • SignIn.sendEmailLink(emailAddressId, redirectUri) and SignUp.sendEmailLink(redirectUrl) take a custom callback.
  • EnterpriseSsoBuilder.redirectUrl and signInWithEnterpriseSso(transferable) { } match what signInWithOAuth already takes.
  • The widened functions keep hidden overloads with their previous JVM signatures, and a test checks for them.

Summary by CodeRabbit

  • New Features

    • Added support for a general identifier when starting sign-in, alongside email, phone number, and username.
    • Added OAuth and Enterprise SSO sign-in continuation with configurable redirect URLs and transferable settings.
    • Added email and phone reset-code options, including selection of a specific address or phone number.
    • Added Google One Tap sign-in, passkey credential preferences, and configurable OAuth sign-up options.
    • Added custom redirect URLs for email-link sign-in and sign-up, and Enterprise SSO sign-up.
  • Bug Fixes

    • Reset-code requests now return a clear failure when no matching email or phone factor is available.

@coderabbitai

coderabbitai Bot commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: clerk/clerk-android/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Team
  • Run ID: 6d858a86-4d28-45a5-a8d2-8811d5a90065
📥 Commits

Reviewing files that changed from the base of the PR and between 2f59745 and 889e262.

📒 Files selected for processing (8)
  • source/api/src/main/kotlin/com/clerk/api/auth/Auth.kt
  • source/api/src/main/kotlin/com/clerk/api/auth/builders/CommonBuilders.kt
  • source/api/src/main/kotlin/com/clerk/api/magiclink/NativeMagicLinkManager.kt
  • source/api/src/main/kotlin/com/clerk/api/signin/SignInExtensions.kt
  • source/api/src/main/kotlin/com/clerk/api/signup/SignUp.kt
  • source/api/src/test/java/com/clerk/api/auth/AuthFacadeUiGapsTest.kt
  • source/api/src/test/java/com/clerk/api/magiclink/NativeMagicLinkServiceTest.kt
  • source/api/src/test/java/com/clerk/api/signup/SignUpEmailVerificationStrategyTest.kt

Included review availability: This review used your included allowance. 7 included reviews remain after this review. Your included PR review attempts over the past 7 days set your current allowance at 8 reviews per hour.


📝 Walkthrough

Walkthrough

Auth adds configurable OAuth and Enterprise SSO redirects, transfer options, passkey preferences, and transfer methods. SignIn adds general identifier input, redirect authentication, custom email-link redirects, and dedicated email and phone reset-code methods. Deprecated overloads retain selected prior method signatures.

Changes

Authentication API extensions

Layer / File(s) Summary
Auth options and delegation
source/api/src/main/kotlin/com/clerk/api/auth/Auth.kt, source/api/src/main/kotlin/com/clerk/api/auth/AuthFlows.kt, source/api/src/main/kotlin/com/clerk/api/signin/SignIn.kt, source/api/src/test/java/com/clerk/api/auth/AuthFacadeUiGapsTest.kt, source/api/src/test/java/com/clerk/api/auth/AuthTest.kt
Auth accepts redirect and transferability options for OAuth and Enterprise SSO, metadata for OAuth sign-up, and an immediate-credential preference for passkey sign-in. It adds Google One Tap sign-in and transfer methods. SignIn and AuthFlows delegate passkey and Google One Tap calls through Auth. Tests check forwarding, transfer requests, and selected JVM signatures.
Identifier input support
source/api/src/main/kotlin/com/clerk/api/auth/builders/SignInBuilders.kt, source/api/src/test/java/com/clerk/api/auth/AuthFacadeUiGapsTest.kt, source/api/src/test/java/com/clerk/api/signup/SignUpEmailVerificationStrategyTest.kt
SignInIdentifierBuilder accepts identifier as an alternative to email, phone, and username. It rejects identifier when combined with one of those fields and falls back to it after the existing typed fields. Tests cover identifier input and rejection.
Redirect authentication and email-link and reset-code methods
source/api/src/main/kotlin/com/clerk/api/signin/SignInExtensions.kt, source/api/src/main/kotlin/com/clerk/api/magiclink/NativeMagicLinkManager.kt, source/api/src/main/kotlin/com/clerk/api/signup/SignUp.kt, source/api/src/test/java/com/clerk/api/auth/AuthFacadeUiGapsTest.kt, source/api/src/test/java/com/clerk/api/magiclink/NativeMagicLinkServiceTest.kt, source/api/src/test/java/com/clerk/api/signup/SignUpEmailVerificationStrategyTest.kt
SignIn adds OAuth and Enterprise SSO redirect authentication and custom email-link redirects. Dedicated reset-code methods select a supplied factor ID or the first matching factor, and return a failure when no factor is available. SignUp and the native magic-link manager accept custom redirect URLs. Tests cover redirect forwarding, reset-factor selection, and method signatures.

Priority: ➖ Normal

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Feature

Suggested reviewers: mikepitre

Merge Risk: ⚪ Minimal · up to 889e2

This change adds Clerk.auth facade options and keeps the earlier method signatures through hidden deprecated overloads. No merge-blocking issue was identified.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 30.77% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 65 functions across 12 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly identifies the API changes that fill gaps needed by the prebuilt UI.
Description check ✅ Passed The description explains the motivation, scope, compatibility, testing, and follow-up changes. It does not include the template’s explicit “What to focus on” or “Screenshots / video” headings, but the…
  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

Every old-layer call the prebuilt UI makes now has a Clerk.auth equivalent:

- signInWithOAuth(provider, transferable, redirectUrl)
- signUpWithOAuth(provider, redirectUrl, unsafeMetadata)
- signInWithPasskey(preferImmediatelyAvailableCredentials)
- signInWithGoogleOneTap(transferable), now the implementation behind
  SignIn.authenticateWithGoogleOneTap and signUpWithGoogleOneTap
- signIn { identifier = ... } for single-field identifier input
- SignIn.authenticateWithOAuth / authenticateWithEnterpriseSso, which continue
  an existing sign-in through a redirect factor
- SignIn.sendResetPasswordEmailCode / sendResetPasswordPhoneCode by factor id;
  sendResetPasswordCode {} now delegates to them

Each widened method keeps its previous JVM signature as a hidden overload.
SignIn.create(Passkey, prefer...) and SignIn.authenticateWithGoogleOneTap
delegate to the new facade methods.
…and reset docs

identifier silently lost to email, phone or username when combined with
them; signIn now rejects the combination. The OAuth redirectUrl KDoc now
says a custom value must be routed to SSOReceiverActivity, since handle()
only completes clerk-scheme OAuth callbacks. The reset-code KDoc now says
a null id picks the first reset factor regardless of address, and an
explicit id is sent as given.

Add tests for SignIn.create(Passkey, preferImmediatelyAvailableCredentials),
no redirect after a failed prepare, and the null-id reset fallback.
…rprise SSO options

Close the gaps that kept old entry points without a replacement:
- Clerk.auth.transferToSignIn() / transferToSignUp() complete a transfer
  after signUpWithIdToken / signInWithIdToken, which don't transfer on
  their own.
- SignIn.sendEmailLink(emailAddressId, redirectUri) and
  SignUp.sendEmailLink(redirectUrl) take a custom callback.
- EnterpriseSsoBuilder.redirectUrl, and signInWithEnterpriseSso(transferable),
  match what signInWithOAuth already takes.

The widened functions keep hidden overloads with their previous JVM
signatures.
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.

1 participant