feat: implemented auth - #1
Conversation
📝 WalkthroughWalkthroughAdds Clerk-backed authentication with social-provider discovery, reusable auth UI, sign-in/sign-up/verification routes, session synchronization, protected-route handling, root provider wiring, and improved onboarding completion error handling. ChangesClerk authentication
Estimated code review effort: 5 (Critical) | ~90+ minutes Sequence Diagram(s)sequenceDiagram
participant AuthScreen
participant Clerk
participant VerifyScreen
AuthScreen->>Clerk: submit credentials or start SSO
Clerk-->>AuthScreen: completion status or verification requirement
AuthScreen->>VerifyScreen: navigate with mode and returnTo
VerifyScreen->>Clerk: verify code or submit new password
Clerk-->>VerifyScreen: completed session state
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (5)
lib/auth/clerk.ts (1)
35-65: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick winConsider caching the environment fetch result.
fetchEnabledSocialStrategies()hits Clerk's/v1/environmentendpoint on every call with no memoization. SinceAuthSheetmounts on both the sign-in and sign-up routes, a user bouncing between those screens re-triggers the network round trip each time. A simple module-level cache (with a short TTL or single in-flight promise reuse) would avoid redundant calls without changing the fail-closed behavior.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@lib/auth/clerk.ts` around lines 35 - 65, Update fetchEnabledSocialStrategies to cache the Clerk environment result at module scope, reusing a recent result or an in-flight promise for concurrent calls. Preserve the existing fail-closed UNAVAILABLE behavior and ensure cached failures do not prevent a later retry, using a short TTL or equivalent bounded caching strategy.src/app/(auth)/sign-in.tsx (1)
84-100: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winDuplicate sheet-view scaffold shared with
sign-up.tsx.The "sheet" view block (
AuthSheet+socialErrorcaption insideAppScreen) is nearly identical to the equivalent block insign-up.tsx(lines 63-79 there), differing only bymodeand the target view name. Consider extracting a sharedAuthSheetScreenwrapper to avoid maintaining two copies of this markup as the auth UI evolves.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/app/`(auth)/sign-in.tsx around lines 84 - 100, The sheet-view scaffold in sign-in duplicates the equivalent sign-up markup. Extract a shared AuthSheetScreen wrapper for the AppScreen, AuthSheet, and socialError caption, then update the sign-in and sign-up sheet branches to pass their mode, callbacks, and target view behavior through it while preserving existing functionality.components/auth/SocialAuthButton.tsx (1)
94-110: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winButton base/focus styles duplicated with
AuthSheet.tsx'semailButtonStyles.
styles.base/styles.focusedhere are structurally identical toemailButtonStyles.base/emailButtonStyles.focusedincomponents/auth/AuthSheet.tsx(Lines 159-175). Consider extracting a sharedauthButtonBase/authButtonFocusedstyle (or a sharedPressableAuthButtonwrapper) to avoid drift when one is tweaked and the other isn't.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@components/auth/SocialAuthButton.tsx` around lines 94 - 110, The button base and focus styles are duplicated between SocialAuthButton’s styles and AuthSheet’s emailButtonStyles. Extract shared auth button base and focused styles, then reuse them in both components while preserving their current appearance and behavior.features/auth/accountDeletion.ts (1)
1-8: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winConsider a discriminated union for
AccountDeletionResult.
{ ok: boolean; error?: AccountDeletionError }allows nonsensical states (ok: truewitherrorset, orok: falsewith noerror). A discriminated union ({ ok: true } | { ok: false; error: AccountDeletionError }) would make invalid states unrepresentable once a real backend consumer is wired in (prompts/16/21).♻️ Suggested type
-export interface AccountDeletionResult {- ok: boolean;- error?: AccountDeletionError;-}+export type AccountDeletionResult =+ | { ok: true }+ | { ok: false; error: AccountDeletionError };🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@features/auth/accountDeletion.ts` around lines 1 - 8, Replace the boolean-and-optional-error shape in AccountDeletionResult with a discriminated union: successful results must be { ok: true } and failed results must be { ok: false; error: AccountDeletionError }. Keep AccountDeletionError unchanged and update any AccountDeletionResult construction or handling to satisfy the required variant fields.components/auth/AuthSheet.tsx (1)
40-40: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win
useSocialStrategyAvailabilityrefetches on everyAuthSheetmount, with no cross-screen cache.Per the hook's implementation shown in context (
features/auth/useSocialStrategyAvailability.ts), each mount callsfetchEnabledSocialStrategies()fresh via a localuseEffect/useState, defaulting to an "unknown" (hidden) state until it resolves. Sincesign-in.tsxandsign-up.tsxare separate routes that each mount their ownAuthSheet, navigating between "Sign in"/"Sign up" (or back to either) re-triggers the network call to Clerk's/v1/environmentendpoint and re-flashes hidden social buttons until it resolves again. Consider caching the result (module-level singleton,SWR/react-query, or a context provider mounted once near the root) so repeated navigations reuse the last known availability instead of refetching and re-flickering.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@components/auth/AuthSheet.tsx` at line 40, The useSocialStrategyAvailability hook refetches and resets availability on every AuthSheet mount, causing repeated requests and button flicker across sign-in and sign-up navigation. Update useSocialStrategyAvailability to cache the resolved fetchEnabledSocialStrategies result across component mounts, preserving the cached availability immediately while avoiding redundant network requests; use the existing hook as the change point without altering AuthSheet.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@features/auth/useSignOutFlow.ts`:
- Around line 16-24: Update the signOutFlow callback to catch signOut()
failures, map them with the existing mapUnexpectedAuthError pattern, and expose
the resulting error through the hook’s error state so callers receive user
feedback without an unhandled rejection. Preserve the loading-state reset and
successful router.replace behavior.
In `@src/app/`(onboarding)/demo.tsx:
- Around line 100-106: Update the “Try it with my audio” AppButton using
handleTryOwnAudio so it is disabled while isCompleting is true, preventing
navigation during handleExploreFirst’s pending completion flow; leave the
existing loading behavior on the sibling button unchanged.
---
Nitpick comments:
In `@components/auth/AuthSheet.tsx`:
- Line 40: The useSocialStrategyAvailability hook refetches and resets
availability on every AuthSheet mount, causing repeated requests and button
flicker across sign-in and sign-up navigation. Update
useSocialStrategyAvailability to cache the resolved fetchEnabledSocialStrategies
result across component mounts, preserving the cached availability immediately
while avoiding redundant network requests; use the existing hook as the change
point without altering AuthSheet.
In `@components/auth/SocialAuthButton.tsx`:
- Around line 94-110: The button base and focus styles are duplicated between
SocialAuthButton’s styles and AuthSheet’s emailButtonStyles. Extract shared auth
button base and focused styles, then reuse them in both components while
preserving their current appearance and behavior.
In `@features/auth/accountDeletion.ts`:
- Around line 1-8: Replace the boolean-and-optional-error shape in
AccountDeletionResult with a discriminated union: successful results must be {
ok: true } and failed results must be { ok: false; error: AccountDeletionError
}. Keep AccountDeletionError unchanged and update any AccountDeletionResult
construction or handling to satisfy the required variant fields.
In `@lib/auth/clerk.ts`:
- Around line 35-65: Update fetchEnabledSocialStrategies to cache the Clerk
environment result at module scope, reusing a recent result or an in-flight
promise for concurrent calls. Preserve the existing fail-closed UNAVAILABLE
behavior and ensure cached failures do not prevent a later retry, using a short
TTL or equivalent bounded caching strategy.
In `@src/app/`(auth)/sign-in.tsx:
- Around line 84-100: The sheet-view scaffold in sign-in duplicates the
equivalent sign-up markup. Extract a shared AuthSheetScreen wrapper for the
AppScreen, AuthSheet, and socialError caption, then update the sign-in and
sign-up sheet branches to pass their mode, callbacks, and target view behavior
through it while preserving existing functionality.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: db5b8c71-5b7d-4bc8-a9f5-8f3761cc0b8b
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (28)
app.jsoncomponents/auth/AuthSheet.tsxcomponents/auth/SocialAuthButton.tsxcomponents/common/AppTextInput.tsxcomponents/index.tsconstants/images.tsdocs/implementation-status.mdfeatures/auth/accountDeletion.tsfeatures/auth/identitySync.tsfeatures/auth/navigation.tsfeatures/auth/useAuthGate.tsfeatures/auth/useAuthStatus.tsfeatures/auth/useIdentitySync.tsfeatures/auth/useRequireAuth.tsfeatures/auth/useSignOutFlow.tsfeatures/auth/useSocialSignIn.tsfeatures/auth/useSocialStrategyAvailability.tslib/auth/clerk.tslib/auth/mapClerkError.tspackage.jsonsrc/app/(auth)/sign-in.tsxsrc/app/(auth)/sign-up.tsxsrc/app/(auth)/verify.tsxsrc/app/(onboarding)/demo.tsxsrc/app/_layout.tsxsrc/app/export/[projectId].tsxsrc/app/subscription.tsxtypes/auth.ts
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
components/auth/AuthSheet.tsx (1)
77-87: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win"Terms of Service" / "Privacy Policy" text is styled as a link but isn't tappable.
Both are rendered as plain
AppTextwithcolor="brand"(visually implying a link) but have noonPress/Linking.openURL. Users can't actually view either document from this screen, which can also be an App Store/Play Store compliance issue for account-creation flows.🔗 Suggested fix
- <AppText variant="caption" color="brand">- Terms of Service- </AppText>{" "}+ <AppText+ variant="caption"+ color="brand"+ onPress={() => Linking.openURL(TERMS_OF_SERVICE_URL)}+ >+ Terms of Service+ </AppText>{" "} and{" "} - <AppText variant="caption" color="brand">- Privacy Policy- </AppText>+ <AppText+ variant="caption"+ color="brand"+ onPress={() => Linking.openURL(PRIVACY_POLICY_URL)}+ >+ Privacy Policy+ </AppText>🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@components/auth/AuthSheet.tsx` around lines 77 - 87, Update the footer in AuthSheet so the “Terms of Service” and “Privacy Policy” AppText elements are tappable and open their corresponding documents via the existing navigation or URL-linking pattern. Preserve their current brand styling and ensure each label has a distinct destination.
🧹 Nitpick comments (2)
lib/auth/clerk.ts (2)
51-52: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winDuplicate publishable-key access bypasses
getClerkPublishableKey().
fetchEnabledSocialStrategiesre-readsprocess.env.EXPO_PUBLIC_CLERK_PUBLISHABLE_KEYdirectly instead of going throughgetClerkPublishableKey()(lines 1-16 per the change details), which centralizes the env-var name and validation. If the variable name or validation logic ever changes, this call site can silently drift out of sync.♻️ Suggested consolidation
- const publishableKey = process.env.EXPO_PUBLIC_CLERK_PUBLISHABLE_KEY;- if (!publishableKey) return UNAVAILABLE;+ let publishableKey: string;+ try {+ publishableKey = getClerkPublishableKey();+ } catch {+ return UNAVAILABLE;+ }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@lib/auth/clerk.ts` around lines 51 - 52, Update fetchEnabledSocialStrategies to obtain the publishable key through getClerkPublishableKey() instead of reading process.env.EXPO_PUBLIC_CLERK_PUBLISHABLE_KEY directly, while preserving the existing UNAVAILABLE behavior when no key is available.
57-93: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick winFailed/non-OK fetches aren't cached, so every call re-hits the network with no backoff.
On non-OK response, JSON error, or abort, the function returns
UNAVAILABLEbut never populatessocialStrategyCache. The in-flight dedup only protects concurrent callers; sequential remounts (e.g., navigating between sign-in/sign-up) will each trigger a fresh 5s-timeout request if the endpoint is flaky or unreachable, with no backoff.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@lib/auth/clerk.ts` around lines 57 - 93, Update the socialStrategyRequest failure paths in lib/auth/clerk.ts to cache UNAVAILABLE with an expiration using the existing socialStrategyCache and TTL mechanism. Apply this for non-OK responses, JSON parsing errors, and abort/network failures, while preserving successful result caching and in-flight request cleanup.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@lib/auth/clerk.ts`:
- Around line 61-65: Add warning or telemetry in the Clerk social-strategy
lookup flow after the environment response is parsed, specifically when the
expected user_settings.social.oauth_* payload is missing and the fallback path
is used. Preserve the existing UNAVAILABLE handling for unsuccessful responses
while making the fallback observable through the established logging or
telemetry mechanism.
---
Outside diff comments:
In `@components/auth/AuthSheet.tsx`:
- Around line 77-87: Update the footer in AuthSheet so the “Terms of Service”
and “Privacy Policy” AppText elements are tappable and open their corresponding
documents via the existing navigation or URL-linking pattern. Preserve their
current brand styling and ensure each label has a distinct destination.
---
Nitpick comments:
In `@lib/auth/clerk.ts`:
- Around line 51-52: Update fetchEnabledSocialStrategies to obtain the
publishable key through getClerkPublishableKey() instead of reading
process.env.EXPO_PUBLIC_CLERK_PUBLISHABLE_KEY directly, while preserving the
existing UNAVAILABLE behavior when no key is available.
- Around line 57-93: Update the socialStrategyRequest failure paths in
lib/auth/clerk.ts to cache UNAVAILABLE with an expiration using the existing
socialStrategyCache and TTL mechanism. Apply this for non-OK responses, JSON
parsing errors, and abort/network failures, while preserving successful result
caching and in-flight request cleanup.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 76cbb7a8-b022-499b-869f-1f9dd6a6ec2e
📒 Files selected for processing (12)
app.jsoncomponents/auth/AuthSheet.tsxcomponents/auth/AuthSheetScreen.tsxcomponents/auth/SocialAuthButton.tsxcomponents/auth/authButtonStyles.tsfeatures/auth/accountDeletion.tsfeatures/auth/useSignOutFlow.tsfeatures/auth/useSocialStrategyAvailability.tslib/auth/clerk.tssrc/app/(auth)/sign-in.tsxsrc/app/(auth)/sign-up.tsxsrc/app/(onboarding)/demo.tsx
✅ Files skipped from review due to trivial changes (1)
- components/auth/authButtonStyles.ts
🚧 Files skipped from review as they are similar to previous changes (7)
- features/auth/useSocialStrategyAvailability.ts
- features/auth/useSignOutFlow.ts
- features/auth/accountDeletion.ts
- src/app/(auth)/sign-up.tsx
- app.json
- src/app/(auth)/sign-in.tsx
- src/app/(onboarding)/demo.tsx
| const response = await fetch( | ||
| `https://${parsed.frontendApi}/v1/environment?_is_native=true`, | ||
| { signal: controller.signal } | ||
| ); | ||
| if (!response.ok) return UNAVAILABLE; |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🌐 Web query:
Does Clerk's official Expo/React Native SDK expose a public API to check which social OAuth strategies are enabled for an instance?
💡 Result:
No, Clerk's official Expo/React Native SDK does not expose a public, client-side API to programmatically check which social OAuth strategies are enabled for a specific Clerk instance [1][2]. The configuration of social OAuth providers is managed centrally via the Clerk Dashboard [1][3][4]. Because this configuration is intended to be controlled by the developer in the Dashboard rather than dynamically discovered by the client, there is no supported hook or method in @clerk/expo for fetching the list of enabled providers at runtime [1][3][2]. Developers commonly encounter this limitation when attempting to build custom UI components that dynamically render buttons based on enabled strategies [5]. While Clerk provides extensive documentation on configuring these strategies [1][6], the SDK design assumes that the developer is aware of which providers they have enabled and will hard-code or explicitly manage the UI for those specific strategies [3]. If you require this information for automation or infrastructure purposes, it is recommended to manage your instance configuration via the Clerk Backend API or Clerk CLI, rather than the client-side SDK [7][8].
Citations:
- 1: https://clerk.com/docs/expo/guides/configure/auth-strategies/social-connections/overview
- 2: https://clerk.com/docs/reference/expo/overview
- 3: https://clerk.com/articles/how-to-set-up-clerk-authentication-with-expo-router
- 4: https://clerk.com/articles/how-to-implement-social-sign-on
- 5: Expo: supportedFirstFactors is always empty clerk/javascript#6918
- 6: https://clerk.com/docs/expo/guides/configure/auth-strategies/sign-in-with-google
- 7: https://clerk.com/docs/expressjs/guides/configure/auth-strategies/social-connections/overview
- 8: https://clerk.com/docs/guides/configure/auth-strategies/oauth/how-clerk-implements-oauth
🏁 Script executed:
#!/bin/bashset -euo pipefail
# Inspect the target file and nearby context.
wc -l lib/auth/clerk.ts
cat -n lib/auth/clerk.ts | sed -n '1,220p'# Find related Clerk auth usage and any other references to the endpoint or enabled strategies.
rg -n "frontendApi|_is_native|social\.oauth_|oauth_apple|oauth_google|UNAVAILABLE|clerk" lib . --glob '!node_modules' --glob '!dist' --glob '!build'Repository: victornwoke/CleanAudio
Length of output: 17132
🏁 Script executed:
#!/bin/bashset -euo pipefail
# Find the file if the path differs and inspect only the relevant segment.
git ls-files | rg '^lib/auth/clerk\.ts$|clerk\.ts$'Repository: victornwoke/CleanAudio
Length of output: 178
🌐 Web query:
Clerk JS SDK /v1/environment _is_native true user_settings.social oauth_apple oauth_google documentation
💡 Result:
In the context of the Clerk JS SDK, environment configuration for native applications and social connections is primarily managed through the Clerk Dashboard and SDK initialization, rather than a single direct _is_native property in the SDK settings. 1. Native Environment Configuration: When developing native applications (e.g., via Expo, iOS, or Android), you must ensure that your Clerk instance is configured for native support. Specifically, you must navigate to the Native Applications page in the Clerk Dashboard and ensure the Native API is enabled [1]. For Clerk JS/Expo SDKs, sensitive data storage is handled by appropriate secure storage mechanisms (e.g., expo-secure-store) [1]. In general SDK configuration (such as in React or Web environments), native-like behavior or specific platform configurations may be controlled via options like standardBrowser (which should be set to false for native platforms) [2]. 2. Social Connection Configuration (OAuth): Clerk manages OAuth social connections (such as Apple and Google) centrally within the Clerk Dashboard [3][4]. - To enable these providers, navigate to the SSO Connections page in your Clerk Dashboard [4]. - You can enable specific providers like Apple or Google for sign-up and sign-in [3][4]. - For development instances, Clerk provides pre-configured shared credentials [3][5]. For production instances, you are required to provide custom OAuth credentials (e.g., Apple Services ID/Key, Google Client ID/Secret) within the dashboard [3][4]. - If building a custom OAuth flow, you can initiate the authentication process using the signInWith method (e.g., signInWith('oauth_google') or signInWith('oauth_apple')) [6]. 3. SDK Metadata: The Clerk SDK uses sdkMetadata to identify the environment and package details (e.g., name, version, and NODE_ENV), but this is primarily for internal SDK tracking and reporting, not for manual user-level configuration of native status [2][7]. If you are encountering references to _is_native or similar internal flags, these are often internal SDK state markers used by the Clerk library to handle platform-specific behaviors (like cookie handling or redirect logic) and should not be manually manipulated [8][2]. Ensure your application is correctly initialized with the appropriate SDK for your platform (e.g., @clerk/expo for React Native) to correctly handle native environment requirements [1].
Citations:
- 1: https://clerk.com/docs/expo/getting-started/quickstart
- 2: https://clerk.com/docs/nextjs/reference/objects/clerk
- 3: https://clerk.com/docs/js-frontend/guides/configure/auth-strategies/social-connections/overview
- 4: https://clerk.com/docs/guides/configure/auth-strategies/social-connections/apple
- 5: https://clerk.com/docs/react/guides/configure/auth-strategies/social-connections/overview
- 6: https://clerk.com/docs/guides/development/custom-flows/authentication/oauth-connections
- 7: https://clerk.com/docs/guides/development/sdk-development/backend-only
- 8: https://github.com/clerk/javascript/blob/4fae43c0/packages/clerk-js/src/core/clerk.ts
🌐 Web query:
site:clerk.com "/v1/environment" Clerk user_settings social oauth_apple oauth_google
💡 Result:
To configure social OAuth providers like Apple and Google in Clerk, you generally perform the setup through the Clerk Dashboard under the SSO Connections page [1][2][3][4]. While your query references a /v1/environment path, Clerk typically manages these settings via their Dashboard UI or by using the Clerk CLI for automated configuration [2][4]. Key aspects of configuring Apple and Google OAuth in Clerk include: 1. Dashboard Configuration: You navigate to the SSO connections page in your Clerk Dashboard, select the provider (e.g., Apple or Google), and enable it for your instance [3][4][5][6]. 2. Instance Types: - Development Instances: Clerk provides pre-configured, shared credentials by default, allowing you to get started quickly without immediate external configuration [1][2][3]. - Production Instances: You must provide your own custom OAuth credentials (e.g., Client ID, Client Secret) obtained from the respective provider's developer console [1][3][4]. 3. CLI Configuration: For programmatic or automated setups, you can use the Clerk CLI. For example, you can patch your configuration with: npx clerk@latest config patch --json '{"connection_oauth_google":{"enabled":true}}' [2][4] 4. Scopes: If you need additional OAuth scopes, you must enable "Use custom credentials" in the provider settings, which will expose a field for adding your required scopes [1][2][3]. For the most accurate and up-to-date implementation details, refer to the official Clerk documentation on Social Connections (OAuth), which provides provider-specific setup instructions for both Apple and Google [1][2].
Citations:
- 1: https://clerk.com/docs/js-frontend/guides/configure/auth-strategies/social-connections/overview
- 2: https://clerk.com/docs/nextjs/guides/configure/auth-strategies/social-connections/overview
- 3: https://clerk.com/docs/vue/guides/configure/auth-strategies/social-connections/overview
- 4: https://clerk.com/docs/expressjs/guides/configure/auth-strategies/social-connections/overview
- 5: https://clerk.com/docs/guides/configure/auth-strategies/social-connections/apple
- 6: https://clerk.com/docs/guides/configure/auth-strategies/social-connections/google
🌐 Web query:
Clerk JS SDK environment endpoint "/v1/environment?_is_native=true" github clerk-js source user_settings social oauth_apple oauth_google
💡 Result:
The /v1/environment endpoint in the Clerk JavaScript SDK is a fundamental call used to retrieve the configuration of a Clerk application [1][2]. When the _is_native=true query parameter is appended to this request, it signals to the Clerk backend that the request is originating from a native mobile environment (such as Expo or React Native) rather than a standard web browser [1][2][3]. Key aspects of this endpoint and parameter include: 1. Environment Configuration: Calling /v1/environment returns the "source of truth" regarding an application's enabled authentication strategies, such as social OAuth providers (e.g., Apple, Google) and other user settings [1][2]. 2. Custom Flow Requirement: For developers implementing custom authentication flows in mobile environments (like @clerk/expo), fetching this endpoint is mandatory [1][2]. The SDK uses the resulting payload to dynamically build an "enabled-factor checklist," ensuring the application only attempts to implement authentication methods that are explicitly enabled in the Clerk Dashboard [1][2]. 3. Native Identification: The _is_native=true parameter (or sometimes _is_native=1) helps the Clerk infrastructure correctly identify the client context, which is critical for handling native-specific behaviors, such as deep linking redirects or handling OAuth sessions that differ from standard web-based browser flows [1][2][3]. Developers are advised to derive the Frontend API URL from their publishable key and invoke this call before attempting any strategy selection or user authentication logic to ensure consistency with their current project configuration [1][2].
Citations:
- 1: clerk/skills@7f7b6ea
- 2: https://github.com/clerk/skills/blob/main/skills/mobile/clerk-expo/SKILL.md
- 3: feat(clerk-expo): Add expo data to request headers clerk/javascript#2528
🌐 Web query:
site:github.com/clerk/javascript "/v1/environment?_is_native=true" "oauth_apple" "oauth_google"
💡 Result:
The string /v1/environment?_is_native=true is a request to the Clerk Frontend API (FAPI), used by the Clerk SDKs (specifically @clerk/expo) to fetch the application's environment configuration [1][2]. Key details regarding this endpoint and its context: 1. Function: The /v1/environment endpoint provides the SDK with necessary configuration data, such as enabled authentication strategies, captcha requirements, and other instance-level settings [3][4][5]. 2. _is_native=true: This query parameter informs the Clerk backend that the request is originating from a native mobile environment (e.g., Expo) rather than a web browser [6][7]. This helps the backend tailor the response and logging for mobile-specific SDKs [7]. 3. OAuth Context: The inclusion of oauth_apple and oauth_google in your query refers to the authentication strategies supported by the application. In the Clerk Expo SDK, these are implemented via native modules: - Apple Authentication: Typically uses expo-apple-authentication, where the SDK manages the exchange of the Apple ID token with Clerk's backend using the oauth_token_apple strategy [8][9]. - Google Sign-In: Typically uses @react-native-google-signin/google-signin, which handles the Google ID token and interacts with Clerk's oauth strategies (such as google_one_tap) [8]. If you are encountering issues where this request is failing or hanging, it is often due to network connectivity issues [6], configuration errors in the Clerk project, or native module initialization problems within the Expo environment (e.g., issues with synchronous JSI calls blocking the JS thread) [1][2].
Citations:
- 1: @clerk/expo v3: useAuth().isLoaded permanently false - works in minimal app, fails in real app (physical device + simulator) clerk/javascript#8245
- 2: @clerk/expo v3: useSignIn().isLoaded stays false forever in iOS Simulator (Expo SDK 55) clerk/javascript#8236
- 3: feat(types,clerk-js): Bypass captcha for providers dynamically provided in environment clerk/javascript#4322
- 4: feat(clerk-js): Allow Environment init with defaults clerk/javascript#5287
- 5: [wip] chore(clerk-js,types): Handle task enablement from environment resource clerk/javascript#5344
- 6: Expo/JavaScript client fails in strange ways with poor or no network connectivity clerk/javascript#3563
- 7: feat(clerk-expo): Add expo data to request headers clerk/javascript#2528
- 8: feat(clerk-expo): Implement Google Sign-In support for Android and iOS (#7208) clerk/javascript#7538
- 9: https://github.com/clerk/javascript/blob/main/packages/expo/src/hooks/useSignInWithApple.ios.ts
🌐 Web query:
site:github.com/clerk/javascript "user_settings.social" "oauth_apple" "oauth_google" Clerk JS SDK environment response shape
💡 Result:
In the Clerk JS SDK, the settings for OAuth providers (such as Apple and Google) are managed within the user_settings resource, specifically under the social property [1]. This property contains the configuration for third-party OAuth providers enabled for your instance [1]. Regarding the response shape when interacting with a user's social accounts, the Clerk SDK uses an ExternalAccount resource to represent these connections [2]. Key details about the structure and fields associated with these accounts include: 1. User Settings: The UserSettings interface contains a social field (of type OAuthProviders), which defines the available OAuth strategies (e.g., oauth_google, oauth_apple) [1]. 2. ExternalAccount Resource: When you access a user's connected social accounts via user.externalAccounts, each entry is an ExternalAccount object [3][2]. This object typically includes: - id: The unique identification ID (often prefixed with idn_ for specific providers) [4][5]. - externalAccountId: The primary resource ID (prefixed with eac_) [5]. Note that for some providers, the external_account_id is required for administrative actions like deletions [4][5]. - provider: The name of the provider (e.g., 'google', 'apple') [2]. - providerUserId: The unique ID of the user within the specific provider's system [2]. - verification: An object indicating the status of the account verification [2]. - Basic Info: Fields such as emailAddress, firstName, lastName, and imageUrl [2]. When performing authentication flows via the SDK, strategies such as oauth_token_apple or oauth_google are used within signIn.create or signUp.create methods [6][7]. For backend operations, retrieving OAuth tokens is handled via clerkClient.users.getUserOauthAccessToken [8]. For the most accurate integration, ensure you are referencing the externalAccountId when performing operations that require a stable resource identifier, as the standard id field may vary in format depending on the provider [4][5].
Citations:
- 1: clerk/javascript@8a28d1f
- 2: https://github.com/clerk/javascript/blob/main/packages/backend/src/api/resources/ExternalAccount.ts
- 3: https://github.com/clerk/javascript/blob/4fae43c0/packages/clerk-js/src/core/resources/User.ts
- 4:
user.externalAccounts[].idreturnsidn_id, noteac_id.users.deleteUserExternalAccount()not working. clerk/javascript#7584 - 5: fix(backend): expose externalAccountId on ExternalAccount resource clerk/javascript#8982
- 6: https://github.com/clerk/javascript/blob/main/packages/expo/src/hooks/useSignInWithApple.ios.ts
- 7: clerk/javascript@fdac10e
- 8: chore(backend): Deprecate usage of the
oauth_prefix ingetUserOauthAccessToken()clerk/javascript#5097
🌐 Web query:
Clerk documentation environment endpoint social oauth_apple oauth_google user_settings social response shape
💡 Result:
In Clerk, social connections like Apple and Google are configured via the Clerk Dashboard under SSO connections [1][2]. Once enabled, these social identities are integrated into the Clerk User object, which manages authentication identifiers and external accounts [3][4]. Key details regarding your request are as follows: Social Connections Integration Users who sign up or sign in using social providers (like Google or Apple) have these identities stored in the User.externalAccounts array [3][4][5]. Each entry in this array is an ExternalAccountResource, which holds details about the specific connection [5][6]. Response Shape: OAuth User Info When you need to retrieve additional user information following an OAuth 2.0 flow, you can use the Clerk /oauth/userinfo endpoint [7]. This endpoint requires an OAuth access token in the Authorization header and returns a JSON object with the following structure [7]: { "object": "oauth_user_info", "instance_id": "string", "user_id": "string", "sub": "string", "email": "string", "email_verified": boolean, "family_name": "string", "given_name": "string", "name": "string", "username": "string", "preferred_username": "string", "picture": "string", "public_metadata": {}, "private_metadata": {}, "unsafe_metadata": {}, "org_id": "string", "org_name": "string", "org_slug": "string" } Properties like org_id, org_name, and org_slug are only populated if Organizations are enabled and the user belongs to an organization with the appropriate scopes granted [7]. Accessing Data in Backend Environments To programmatically manage social connections or access OAuth tokens for users (e.g., to fetch additional data from the provider's API), you should use the Clerk Backend API [8][2]. The getUserOauthAccessToken() method is the standard way to retrieve a valid OAuth access token in a server-side environment [2]. You can manage user attributes and metadata through the Clerk Dashboard or via the Backend API's updateUserMetadata methods [3][4].
Citations:
- 1: https://clerk.com/docs/guides/configure/auth-strategies/social-connections/apple
- 2: https://clerk.com/docs/fastify/guides/configure/auth-strategies/social-connections/overview
- 3: https://clerk.com/docs/vue/reference/objects/user
- 4: https://clerk.com/docs/guides/users/managing
- 5: https://clerk.com/docs/react/reference/objects/user
- 6: https://clerk.com/docs/react-router/reference/objects/user
- 7: https://clerk.com/docs/guides/configure/auth-strategies/oauth/single-sign-on
- 8: https://clerk.com/docs/reference/backend-api
Add a fallback signal for Clerk social-strategy lookupslib/auth/clerk.ts:61-75 still depends on Clerk's environment payload shape (user_settings.social.oauth_*), so a Clerk response change will hide Apple/Google buttons without any signal. Add a warning or telemetry on the fallback path.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@lib/auth/clerk.ts` around lines 61 - 65, Add warning or telemetry in the
Clerk social-strategy lookup flow after the environment response is parsed,
specifically when the expected user_settings.social.oauth_* payload is missing
and the fallback path is used. Preserve the existing UNAVAILABLE handling for
unsuccessful responses while making the fallback observable through the
established logging or telemetry mechanism.
Uh oh!
There was an error while loading. Please reload this page.
Summary by CodeRabbit