Skip to content

feat: implemented auth - #1

Merged
victornwoke merged 2 commits into
mainfrom
feature/auth
Jul 11, 2026
Merged

feat: implemented auth#1
victornwoke merged 2 commits into
mainfrom
feature/auth

Conversation

@victornwoke

@victornwokevictornwoke commented Jul 11, 2026

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • New Features
    • Added complete Clerk-based sign-in, sign-up, verification, password reset, and sign-out flows.
    • Introduced provider-choice authentication UI with availability-aware Apple/Google buttons plus email sign-in.
    • Added validated, labeled text input component and shared auth navigation/guards with return-to support.
    • Added identity sync on auth state changes and social strategy discovery with caching.
    • Improved demo onboarding completion with proper loading/error handling.
  • Bug Fixes
    • Tightened protected-screen gating to render only when fully authenticated (prevents premature access/flash).
  • Documentation
    • Updated authentication implementation status and verification notes.

@coderabbitai

coderabbitaiBot commented Jul 11, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds 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.

Changes

Clerk authentication

Layer / File(s)Summary
Auth configuration and contracts
package.json, app.json, types/auth.ts, lib/auth/*, features/auth/navigation.ts
Adds Clerk and Expo auth dependencies, iOS deployment configuration, social-provider types and discovery, safe error mapping, and typed return-to navigation.
Session and auth hooks
features/auth/*
Derives auth status from Clerk, adds auth gating, identity synchronization, sign-out, social sign-in, and typed account-deletion handling.
Authentication UI components
components/auth/*, components/common/AppTextInput.tsx, components/index.ts, constants/images.ts
Adds provider-choice, social-auth, and labeled text-input components with loading, focus, accessibility, validation, and provider-specific styling.
Sign-in, sign-up, and verification routes
src/app/(auth)/*
Implements Clerk email/password, social sign-in, password reset, email verification, resend, start-over, and return-navigation flows.
Root integration and onboarding handling
src/app/_layout.tsx, src/app/export/[projectId].tsx, src/app/subscription.tsx, src/app/(onboarding)/demo.tsx, docs/implementation-status.md
Mounts Clerk and identity synchronization, adds the verification route, makes protected screens wait for authenticated state, and adds onboarding completion loading/error handling and verification notes.

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
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 62.86% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title is directly related to the main change: adding a full authentication implementation.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/auth

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

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (5)
lib/auth/clerk.ts (1)

35-65: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Consider caching the environment fetch result.

fetchEnabledSocialStrategies() hits Clerk's /v1/environment endpoint on every call with no memoization. Since AuthSheet mounts 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 win

Duplicate sheet-view scaffold shared with sign-up.tsx.

The "sheet" view block (AuthSheet + socialError caption inside AppScreen) is nearly identical to the equivalent block in sign-up.tsx (lines 63-79 there), differing only by mode and the target view name. Consider extracting a shared AuthSheetScreen wrapper 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 win

Button base/focus styles duplicated with AuthSheet.tsx's emailButtonStyles.

styles.base/styles.focused here are structurally identical to emailButtonStyles.base/emailButtonStyles.focused in components/auth/AuthSheet.tsx (Lines 159-175). Consider extracting a shared authButtonBase/authButtonFocused style (or a shared PressableAuthButton wrapper) 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 win

Consider a discriminated union for AccountDeletionResult.

{ ok: boolean; error?: AccountDeletionError } allows nonsensical states (ok: true with error set, or ok: false with no error). 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

useSocialStrategyAvailability refetches on every AuthSheet mount, with no cross-screen cache.

Per the hook's implementation shown in context (features/auth/useSocialStrategyAvailability.ts), each mount calls fetchEnabledSocialStrategies() fresh via a local useEffect/useState, defaulting to an "unknown" (hidden) state until it resolves. Since sign-in.tsx and sign-up.tsx are separate routes that each mount their own AuthSheet, navigating between "Sign in"/"Sign up" (or back to either) re-triggers the network call to Clerk's /v1/environment endpoint 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

📥 Commits

Reviewing files that changed from the base of the PR and between 3dfd1ad and fe63e26.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (28)
  • app.json
  • components/auth/AuthSheet.tsx
  • components/auth/SocialAuthButton.tsx
  • components/common/AppTextInput.tsx
  • components/index.ts
  • constants/images.ts
  • docs/implementation-status.md
  • features/auth/accountDeletion.ts
  • features/auth/identitySync.ts
  • features/auth/navigation.ts
  • features/auth/useAuthGate.ts
  • features/auth/useAuthStatus.ts
  • features/auth/useIdentitySync.ts
  • features/auth/useRequireAuth.ts
  • features/auth/useSignOutFlow.ts
  • features/auth/useSocialSignIn.ts
  • features/auth/useSocialStrategyAvailability.ts
  • lib/auth/clerk.ts
  • lib/auth/mapClerkError.ts
  • package.json
  • src/app/(auth)/sign-in.tsx
  • src/app/(auth)/sign-up.tsx
  • src/app/(auth)/verify.tsx
  • src/app/(onboarding)/demo.tsx
  • src/app/_layout.tsx
  • src/app/export/[projectId].tsx
  • src/app/subscription.tsx
  • types/auth.ts

Comment threadfeatures/auth/useSignOutFlow.ts
Comment threadsrc/app/(onboarding)/demo.tsx Outdated

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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 AppText with color="brand" (visually implying a link) but have no onPress/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 win

Duplicate publishable-key access bypasses getClerkPublishableKey().

fetchEnabledSocialStrategies re-reads process.env.EXPO_PUBLIC_CLERK_PUBLISHABLE_KEY directly instead of going through getClerkPublishableKey() (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 win

Failed/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 UNAVAILABLE but never populates socialStrategyCache. 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

📥 Commits

Reviewing files that changed from the base of the PR and between fe63e26 and 400301a.

📒 Files selected for processing (12)
  • app.json
  • components/auth/AuthSheet.tsx
  • components/auth/AuthSheetScreen.tsx
  • components/auth/SocialAuthButton.tsx
  • components/auth/authButtonStyles.ts
  • features/auth/accountDeletion.ts
  • features/auth/useSignOutFlow.ts
  • features/auth/useSocialStrategyAvailability.ts
  • lib/auth/clerk.ts
  • src/app/(auth)/sign-in.tsx
  • src/app/(auth)/sign-up.tsx
  • src/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

Comment threadlib/auth/clerk.ts
Comment on lines +61 to +65
const response = await fetch(
`https://${parsed.frontendApi}/v1/environment?_is_native=true`,
{ signal: controller.signal }
);
if (!response.ok) return UNAVAILABLE;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 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:


🏁 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:


🌐 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:


🌐 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:


🌐 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:


🌐 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:


🌐 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:


Add a fallback signal for Clerk social-strategy lookups
lib/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.

@victornwoke
victornwoke merged commit 08b34f3 into mainJul 11, 2026
1 check passed
This was referenced Jul 11, 2026
Sign up for freeto 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

@victornwoke
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
feat: implemented auth by victornwoke · Pull Request #1 · victornwoke/CleanAudio · GitHub
Skip to content

feat: implemented auth - #1

Merged
victornwoke merged 2 commits into
mainfrom
feature/auth
Jul 11, 2026
Merged

feat: implemented auth#1
victornwoke merged 2 commits into
mainfrom
feature/auth

Conversation

@victornwoke

@victornwokevictornwoke commented Jul 11, 2026

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • New Features
    • Added complete Clerk-based sign-in, sign-up, verification, password reset, and sign-out flows.
    • Introduced provider-choice authentication UI with availability-aware Apple/Google buttons plus email sign-in.
    • Added validated, labeled text input component and shared auth navigation/guards with return-to support.
    • Added identity sync on auth state changes and social strategy discovery with caching.
    • Improved demo onboarding completion with proper loading/error handling.
  • Bug Fixes
    • Tightened protected-screen gating to render only when fully authenticated (prevents premature access/flash).
  • Documentation
    • Updated authentication implementation status and verification notes.

@coderabbitai

coderabbitaiBot commented Jul 11, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds 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.

Changes

Clerk authentication

Layer / File(s)Summary
Auth configuration and contracts
package.json, app.json, types/auth.ts, lib/auth/*, features/auth/navigation.ts
Adds Clerk and Expo auth dependencies, iOS deployment configuration, social-provider types and discovery, safe error mapping, and typed return-to navigation.
Session and auth hooks
features/auth/*
Derives auth status from Clerk, adds auth gating, identity synchronization, sign-out, social sign-in, and typed account-deletion handling.
Authentication UI components
components/auth/*, components/common/AppTextInput.tsx, components/index.ts, constants/images.ts
Adds provider-choice, social-auth, and labeled text-input components with loading, focus, accessibility, validation, and provider-specific styling.
Sign-in, sign-up, and verification routes
src/app/(auth)/*
Implements Clerk email/password, social sign-in, password reset, email verification, resend, start-over, and return-navigation flows.
Root integration and onboarding handling
src/app/_layout.tsx, src/app/export/[projectId].tsx, src/app/subscription.tsx, src/app/(onboarding)/demo.tsx, docs/implementation-status.md
Mounts Clerk and identity synchronization, adds the verification route, makes protected screens wait for authenticated state, and adds onboarding completion loading/error handling and verification notes.

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
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 62.86% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title is directly related to the main change: adding a full authentication implementation.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/auth

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

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (5)
lib/auth/clerk.ts (1)

35-65: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Consider caching the environment fetch result.

fetchEnabledSocialStrategies() hits Clerk's /v1/environment endpoint on every call with no memoization. Since AuthSheet mounts 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 win

Duplicate sheet-view scaffold shared with sign-up.tsx.

The "sheet" view block (AuthSheet + socialError caption inside AppScreen) is nearly identical to the equivalent block in sign-up.tsx (lines 63-79 there), differing only by mode and the target view name. Consider extracting a shared AuthSheetScreen wrapper 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 win

Button base/focus styles duplicated with AuthSheet.tsx's emailButtonStyles.

styles.base/styles.focused here are structurally identical to emailButtonStyles.base/emailButtonStyles.focused in components/auth/AuthSheet.tsx (Lines 159-175). Consider extracting a shared authButtonBase/authButtonFocused style (or a shared PressableAuthButton wrapper) 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 win

Consider a discriminated union for AccountDeletionResult.

{ ok: boolean; error?: AccountDeletionError } allows nonsensical states (ok: true with error set, or ok: false with no error). 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

useSocialStrategyAvailability refetches on every AuthSheet mount, with no cross-screen cache.

Per the hook's implementation shown in context (features/auth/useSocialStrategyAvailability.ts), each mount calls fetchEnabledSocialStrategies() fresh via a local useEffect/useState, defaulting to an "unknown" (hidden) state until it resolves. Since sign-in.tsx and sign-up.tsx are separate routes that each mount their own AuthSheet, navigating between "Sign in"/"Sign up" (or back to either) re-triggers the network call to Clerk's /v1/environment endpoint 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

📥 Commits

Reviewing files that changed from the base of the PR and between 3dfd1ad and fe63e26.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (28)
  • app.json
  • components/auth/AuthSheet.tsx
  • components/auth/SocialAuthButton.tsx
  • components/common/AppTextInput.tsx
  • components/index.ts
  • constants/images.ts
  • docs/implementation-status.md
  • features/auth/accountDeletion.ts
  • features/auth/identitySync.ts
  • features/auth/navigation.ts
  • features/auth/useAuthGate.ts
  • features/auth/useAuthStatus.ts
  • features/auth/useIdentitySync.ts
  • features/auth/useRequireAuth.ts
  • features/auth/useSignOutFlow.ts
  • features/auth/useSocialSignIn.ts
  • features/auth/useSocialStrategyAvailability.ts
  • lib/auth/clerk.ts
  • lib/auth/mapClerkError.ts
  • package.json
  • src/app/(auth)/sign-in.tsx
  • src/app/(auth)/sign-up.tsx
  • src/app/(auth)/verify.tsx
  • src/app/(onboarding)/demo.tsx
  • src/app/_layout.tsx
  • src/app/export/[projectId].tsx
  • src/app/subscription.tsx
  • types/auth.ts

Comment threadfeatures/auth/useSignOutFlow.ts
Comment threadsrc/app/(onboarding)/demo.tsx Outdated

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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 AppText with color="brand" (visually implying a link) but have no onPress/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 win

Duplicate publishable-key access bypasses getClerkPublishableKey().

fetchEnabledSocialStrategies re-reads process.env.EXPO_PUBLIC_CLERK_PUBLISHABLE_KEY directly instead of going through getClerkPublishableKey() (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 win

Failed/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 UNAVAILABLE but never populates socialStrategyCache. 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

📥 Commits

Reviewing files that changed from the base of the PR and between fe63e26 and 400301a.

📒 Files selected for processing (12)
  • app.json
  • components/auth/AuthSheet.tsx
  • components/auth/AuthSheetScreen.tsx
  • components/auth/SocialAuthButton.tsx
  • components/auth/authButtonStyles.ts
  • features/auth/accountDeletion.ts
  • features/auth/useSignOutFlow.ts
  • features/auth/useSocialStrategyAvailability.ts
  • lib/auth/clerk.ts
  • src/app/(auth)/sign-in.tsx
  • src/app/(auth)/sign-up.tsx
  • src/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

Comment threadlib/auth/clerk.ts
Comment on lines +61 to +65
const response = await fetch(
`https://${parsed.frontendApi}/v1/environment?_is_native=true`,
{ signal: controller.signal }
);
if (!response.ok) return UNAVAILABLE;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 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:


🏁 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:


🌐 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:


🌐 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:


🌐 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:


🌐 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:


🌐 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:


Add a fallback signal for Clerk social-strategy lookups
lib/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.

@victornwoke
victornwoke merged commit 08b34f3 into mainJul 11, 2026
1 check passed
This was referenced Jul 11, 2026
Sign up for freeto 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

@victornwoke
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' feat: implemented auth by victornwoke · Pull Request #1 · victornwoke/CleanAudio · GitHub
Skip to content

feat: implemented auth - #1

Merged
victornwoke merged 2 commits into
mainfrom
feature/auth
Jul 11, 2026
Merged

feat: implemented auth#1
victornwoke merged 2 commits into
mainfrom
feature/auth

Conversation

@victornwoke

@victornwokevictornwoke commented Jul 11, 2026

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • New Features
    • Added complete Clerk-based sign-in, sign-up, verification, password reset, and sign-out flows.
    • Introduced provider-choice authentication UI with availability-aware Apple/Google buttons plus email sign-in.
    • Added validated, labeled text input component and shared auth navigation/guards with return-to support.
    • Added identity sync on auth state changes and social strategy discovery with caching.
    • Improved demo onboarding completion with proper loading/error handling.
  • Bug Fixes
    • Tightened protected-screen gating to render only when fully authenticated (prevents premature access/flash).
  • Documentation
    • Updated authentication implementation status and verification notes.

@coderabbitai

coderabbitaiBot commented Jul 11, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds 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.

Changes

Clerk authentication

Layer / File(s)Summary
Auth configuration and contracts
package.json, app.json, types/auth.ts, lib/auth/*, features/auth/navigation.ts
Adds Clerk and Expo auth dependencies, iOS deployment configuration, social-provider types and discovery, safe error mapping, and typed return-to navigation.
Session and auth hooks
features/auth/*
Derives auth status from Clerk, adds auth gating, identity synchronization, sign-out, social sign-in, and typed account-deletion handling.
Authentication UI components
components/auth/*, components/common/AppTextInput.tsx, components/index.ts, constants/images.ts
Adds provider-choice, social-auth, and labeled text-input components with loading, focus, accessibility, validation, and provider-specific styling.
Sign-in, sign-up, and verification routes
src/app/(auth)/*
Implements Clerk email/password, social sign-in, password reset, email verification, resend, start-over, and return-navigation flows.
Root integration and onboarding handling
src/app/_layout.tsx, src/app/export/[projectId].tsx, src/app/subscription.tsx, src/app/(onboarding)/demo.tsx, docs/implementation-status.md
Mounts Clerk and identity synchronization, adds the verification route, makes protected screens wait for authenticated state, and adds onboarding completion loading/error handling and verification notes.

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
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 62.86% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title is directly related to the main change: adding a full authentication implementation.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/auth

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

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (5)
lib/auth/clerk.ts (1)

35-65: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Consider caching the environment fetch result.

fetchEnabledSocialStrategies() hits Clerk's /v1/environment endpoint on every call with no memoization. Since AuthSheet mounts 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 win

Duplicate sheet-view scaffold shared with sign-up.tsx.

The "sheet" view block (AuthSheet + socialError caption inside AppScreen) is nearly identical to the equivalent block in sign-up.tsx (lines 63-79 there), differing only by mode and the target view name. Consider extracting a shared AuthSheetScreen wrapper 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 win

Button base/focus styles duplicated with AuthSheet.tsx's emailButtonStyles.

styles.base/styles.focused here are structurally identical to emailButtonStyles.base/emailButtonStyles.focused in components/auth/AuthSheet.tsx (Lines 159-175). Consider extracting a shared authButtonBase/authButtonFocused style (or a shared PressableAuthButton wrapper) 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 win

Consider a discriminated union for AccountDeletionResult.

{ ok: boolean; error?: AccountDeletionError } allows nonsensical states (ok: true with error set, or ok: false with no error). 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

useSocialStrategyAvailability refetches on every AuthSheet mount, with no cross-screen cache.

Per the hook's implementation shown in context (features/auth/useSocialStrategyAvailability.ts), each mount calls fetchEnabledSocialStrategies() fresh via a local useEffect/useState, defaulting to an "unknown" (hidden) state until it resolves. Since sign-in.tsx and sign-up.tsx are separate routes that each mount their own AuthSheet, navigating between "Sign in"/"Sign up" (or back to either) re-triggers the network call to Clerk's /v1/environment endpoint 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

📥 Commits

Reviewing files that changed from the base of the PR and between 3dfd1ad and fe63e26.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (28)
  • app.json
  • components/auth/AuthSheet.tsx
  • components/auth/SocialAuthButton.tsx
  • components/common/AppTextInput.tsx
  • components/index.ts
  • constants/images.ts
  • docs/implementation-status.md
  • features/auth/accountDeletion.ts
  • features/auth/identitySync.ts
  • features/auth/navigation.ts
  • features/auth/useAuthGate.ts
  • features/auth/useAuthStatus.ts
  • features/auth/useIdentitySync.ts
  • features/auth/useRequireAuth.ts
  • features/auth/useSignOutFlow.ts
  • features/auth/useSocialSignIn.ts
  • features/auth/useSocialStrategyAvailability.ts
  • lib/auth/clerk.ts
  • lib/auth/mapClerkError.ts
  • package.json
  • src/app/(auth)/sign-in.tsx
  • src/app/(auth)/sign-up.tsx
  • src/app/(auth)/verify.tsx
  • src/app/(onboarding)/demo.tsx
  • src/app/_layout.tsx
  • src/app/export/[projectId].tsx
  • src/app/subscription.tsx
  • types/auth.ts

Comment threadfeatures/auth/useSignOutFlow.ts
Comment threadsrc/app/(onboarding)/demo.tsx Outdated

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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 AppText with color="brand" (visually implying a link) but have no onPress/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 win

Duplicate publishable-key access bypasses getClerkPublishableKey().

fetchEnabledSocialStrategies re-reads process.env.EXPO_PUBLIC_CLERK_PUBLISHABLE_KEY directly instead of going through getClerkPublishableKey() (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 win

Failed/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 UNAVAILABLE but never populates socialStrategyCache. 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

📥 Commits

Reviewing files that changed from the base of the PR and between fe63e26 and 400301a.

📒 Files selected for processing (12)
  • app.json
  • components/auth/AuthSheet.tsx
  • components/auth/AuthSheetScreen.tsx
  • components/auth/SocialAuthButton.tsx
  • components/auth/authButtonStyles.ts
  • features/auth/accountDeletion.ts
  • features/auth/useSignOutFlow.ts
  • features/auth/useSocialStrategyAvailability.ts
  • lib/auth/clerk.ts
  • src/app/(auth)/sign-in.tsx
  • src/app/(auth)/sign-up.tsx
  • src/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

Comment threadlib/auth/clerk.ts
Comment on lines +61 to +65
const response = await fetch(
`https://${parsed.frontendApi}/v1/environment?_is_native=true`,
{ signal: controller.signal }
);
if (!response.ok) return UNAVAILABLE;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 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:


🏁 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:


🌐 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:


🌐 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:


🌐 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:


🌐 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:


🌐 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:


Add a fallback signal for Clerk social-strategy lookups
lib/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.

@victornwoke
victornwoke merged commit 08b34f3 into mainJul 11, 2026
1 check passed
This was referenced Jul 11, 2026
Sign up for freeto 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

@victornwoke
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' feat: implemented auth by victornwoke · Pull Request #1 · victornwoke/CleanAudio · GitHub
Skip to content

feat: implemented auth - #1

Merged
victornwoke merged 2 commits into
mainfrom
feature/auth
Jul 11, 2026
Merged

feat: implemented auth#1
victornwoke merged 2 commits into
mainfrom
feature/auth

Conversation

@victornwoke

@victornwokevictornwoke commented Jul 11, 2026

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • New Features
    • Added complete Clerk-based sign-in, sign-up, verification, password reset, and sign-out flows.
    • Introduced provider-choice authentication UI with availability-aware Apple/Google buttons plus email sign-in.
    • Added validated, labeled text input component and shared auth navigation/guards with return-to support.
    • Added identity sync on auth state changes and social strategy discovery with caching.
    • Improved demo onboarding completion with proper loading/error handling.
  • Bug Fixes
    • Tightened protected-screen gating to render only when fully authenticated (prevents premature access/flash).
  • Documentation
    • Updated authentication implementation status and verification notes.

@coderabbitai

coderabbitaiBot commented Jul 11, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds 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.

Changes

Clerk authentication

Layer / File(s)Summary
Auth configuration and contracts
package.json, app.json, types/auth.ts, lib/auth/*, features/auth/navigation.ts
Adds Clerk and Expo auth dependencies, iOS deployment configuration, social-provider types and discovery, safe error mapping, and typed return-to navigation.
Session and auth hooks
features/auth/*
Derives auth status from Clerk, adds auth gating, identity synchronization, sign-out, social sign-in, and typed account-deletion handling.
Authentication UI components
components/auth/*, components/common/AppTextInput.tsx, components/index.ts, constants/images.ts
Adds provider-choice, social-auth, and labeled text-input components with loading, focus, accessibility, validation, and provider-specific styling.
Sign-in, sign-up, and verification routes
src/app/(auth)/*
Implements Clerk email/password, social sign-in, password reset, email verification, resend, start-over, and return-navigation flows.
Root integration and onboarding handling
src/app/_layout.tsx, src/app/export/[projectId].tsx, src/app/subscription.tsx, src/app/(onboarding)/demo.tsx, docs/implementation-status.md
Mounts Clerk and identity synchronization, adds the verification route, makes protected screens wait for authenticated state, and adds onboarding completion loading/error handling and verification notes.

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
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 62.86% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title is directly related to the main change: adding a full authentication implementation.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/auth

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

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (5)
lib/auth/clerk.ts (1)

35-65: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Consider caching the environment fetch result.

fetchEnabledSocialStrategies() hits Clerk's /v1/environment endpoint on every call with no memoization. Since AuthSheet mounts 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 win

Duplicate sheet-view scaffold shared with sign-up.tsx.

The "sheet" view block (AuthSheet + socialError caption inside AppScreen) is nearly identical to the equivalent block in sign-up.tsx (lines 63-79 there), differing only by mode and the target view name. Consider extracting a shared AuthSheetScreen wrapper 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 win

Button base/focus styles duplicated with AuthSheet.tsx's emailButtonStyles.

styles.base/styles.focused here are structurally identical to emailButtonStyles.base/emailButtonStyles.focused in components/auth/AuthSheet.tsx (Lines 159-175). Consider extracting a shared authButtonBase/authButtonFocused style (or a shared PressableAuthButton wrapper) 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 win

Consider a discriminated union for AccountDeletionResult.

{ ok: boolean; error?: AccountDeletionError } allows nonsensical states (ok: true with error set, or ok: false with no error). 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

useSocialStrategyAvailability refetches on every AuthSheet mount, with no cross-screen cache.

Per the hook's implementation shown in context (features/auth/useSocialStrategyAvailability.ts), each mount calls fetchEnabledSocialStrategies() fresh via a local useEffect/useState, defaulting to an "unknown" (hidden) state until it resolves. Since sign-in.tsx and sign-up.tsx are separate routes that each mount their own AuthSheet, navigating between "Sign in"/"Sign up" (or back to either) re-triggers the network call to Clerk's /v1/environment endpoint 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

📥 Commits

Reviewing files that changed from the base of the PR and between 3dfd1ad and fe63e26.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (28)
  • app.json
  • components/auth/AuthSheet.tsx
  • components/auth/SocialAuthButton.tsx
  • components/common/AppTextInput.tsx
  • components/index.ts
  • constants/images.ts
  • docs/implementation-status.md
  • features/auth/accountDeletion.ts
  • features/auth/identitySync.ts
  • features/auth/navigation.ts
  • features/auth/useAuthGate.ts
  • features/auth/useAuthStatus.ts
  • features/auth/useIdentitySync.ts
  • features/auth/useRequireAuth.ts
  • features/auth/useSignOutFlow.ts
  • features/auth/useSocialSignIn.ts
  • features/auth/useSocialStrategyAvailability.ts
  • lib/auth/clerk.ts
  • lib/auth/mapClerkError.ts
  • package.json
  • src/app/(auth)/sign-in.tsx
  • src/app/(auth)/sign-up.tsx
  • src/app/(auth)/verify.tsx
  • src/app/(onboarding)/demo.tsx
  • src/app/_layout.tsx
  • src/app/export/[projectId].tsx
  • src/app/subscription.tsx
  • types/auth.ts

Comment threadfeatures/auth/useSignOutFlow.ts
Comment threadsrc/app/(onboarding)/demo.tsx Outdated

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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 AppText with color="brand" (visually implying a link) but have no onPress/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 win

Duplicate publishable-key access bypasses getClerkPublishableKey().

fetchEnabledSocialStrategies re-reads process.env.EXPO_PUBLIC_CLERK_PUBLISHABLE_KEY directly instead of going through getClerkPublishableKey() (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 win

Failed/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 UNAVAILABLE but never populates socialStrategyCache. 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

📥 Commits

Reviewing files that changed from the base of the PR and between fe63e26 and 400301a.

📒 Files selected for processing (12)
  • app.json
  • components/auth/AuthSheet.tsx
  • components/auth/AuthSheetScreen.tsx
  • components/auth/SocialAuthButton.tsx
  • components/auth/authButtonStyles.ts
  • features/auth/accountDeletion.ts
  • features/auth/useSignOutFlow.ts
  • features/auth/useSocialStrategyAvailability.ts
  • lib/auth/clerk.ts
  • src/app/(auth)/sign-in.tsx
  • src/app/(auth)/sign-up.tsx
  • src/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

Comment threadlib/auth/clerk.ts
Comment on lines +61 to +65
const response = await fetch(
`https://${parsed.frontendApi}/v1/environment?_is_native=true`,
{ signal: controller.signal }
);
if (!response.ok) return UNAVAILABLE;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 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:


🏁 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:


🌐 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:


🌐 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:


🌐 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:


🌐 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:


🌐 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:


Add a fallback signal for Clerk social-strategy lookups
lib/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.

@victornwoke
victornwoke merged commit 08b34f3 into mainJul 11, 2026
1 check passed
This was referenced Jul 11, 2026
Sign up for freeto 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

@victornwoke
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' feat: implemented auth by victornwoke · Pull Request #1 · victornwoke/CleanAudio · GitHub
Skip to content

feat: implemented auth - #1

Merged
victornwoke merged 2 commits into
mainfrom
feature/auth
Jul 11, 2026
Merged

feat: implemented auth#1
victornwoke merged 2 commits into
mainfrom
feature/auth

Conversation

@victornwoke

@victornwokevictornwoke commented Jul 11, 2026

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • New Features
    • Added complete Clerk-based sign-in, sign-up, verification, password reset, and sign-out flows.
    • Introduced provider-choice authentication UI with availability-aware Apple/Google buttons plus email sign-in.
    • Added validated, labeled text input component and shared auth navigation/guards with return-to support.
    • Added identity sync on auth state changes and social strategy discovery with caching.
    • Improved demo onboarding completion with proper loading/error handling.
  • Bug Fixes
    • Tightened protected-screen gating to render only when fully authenticated (prevents premature access/flash).
  • Documentation
    • Updated authentication implementation status and verification notes.

@coderabbitai

coderabbitaiBot commented Jul 11, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds 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.

Changes

Clerk authentication

Layer / File(s)Summary
Auth configuration and contracts
package.json, app.json, types/auth.ts, lib/auth/*, features/auth/navigation.ts
Adds Clerk and Expo auth dependencies, iOS deployment configuration, social-provider types and discovery, safe error mapping, and typed return-to navigation.
Session and auth hooks
features/auth/*
Derives auth status from Clerk, adds auth gating, identity synchronization, sign-out, social sign-in, and typed account-deletion handling.
Authentication UI components
components/auth/*, components/common/AppTextInput.tsx, components/index.ts, constants/images.ts
Adds provider-choice, social-auth, and labeled text-input components with loading, focus, accessibility, validation, and provider-specific styling.
Sign-in, sign-up, and verification routes
src/app/(auth)/*
Implements Clerk email/password, social sign-in, password reset, email verification, resend, start-over, and return-navigation flows.
Root integration and onboarding handling
src/app/_layout.tsx, src/app/export/[projectId].tsx, src/app/subscription.tsx, src/app/(onboarding)/demo.tsx, docs/implementation-status.md
Mounts Clerk and identity synchronization, adds the verification route, makes protected screens wait for authenticated state, and adds onboarding completion loading/error handling and verification notes.

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
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 62.86% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title is directly related to the main change: adding a full authentication implementation.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/auth

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

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (5)
lib/auth/clerk.ts (1)

35-65: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Consider caching the environment fetch result.

fetchEnabledSocialStrategies() hits Clerk's /v1/environment endpoint on every call with no memoization. Since AuthSheet mounts 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 win

Duplicate sheet-view scaffold shared with sign-up.tsx.

The "sheet" view block (AuthSheet + socialError caption inside AppScreen) is nearly identical to the equivalent block in sign-up.tsx (lines 63-79 there), differing only by mode and the target view name. Consider extracting a shared AuthSheetScreen wrapper 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 win

Button base/focus styles duplicated with AuthSheet.tsx's emailButtonStyles.

styles.base/styles.focused here are structurally identical to emailButtonStyles.base/emailButtonStyles.focused in components/auth/AuthSheet.tsx (Lines 159-175). Consider extracting a shared authButtonBase/authButtonFocused style (or a shared PressableAuthButton wrapper) 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 win

Consider a discriminated union for AccountDeletionResult.

{ ok: boolean; error?: AccountDeletionError } allows nonsensical states (ok: true with error set, or ok: false with no error). 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

useSocialStrategyAvailability refetches on every AuthSheet mount, with no cross-screen cache.

Per the hook's implementation shown in context (features/auth/useSocialStrategyAvailability.ts), each mount calls fetchEnabledSocialStrategies() fresh via a local useEffect/useState, defaulting to an "unknown" (hidden) state until it resolves. Since sign-in.tsx and sign-up.tsx are separate routes that each mount their own AuthSheet, navigating between "Sign in"/"Sign up" (or back to either) re-triggers the network call to Clerk's /v1/environment endpoint 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

📥 Commits

Reviewing files that changed from the base of the PR and between 3dfd1ad and fe63e26.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (28)
  • app.json
  • components/auth/AuthSheet.tsx
  • components/auth/SocialAuthButton.tsx
  • components/common/AppTextInput.tsx
  • components/index.ts
  • constants/images.ts
  • docs/implementation-status.md
  • features/auth/accountDeletion.ts
  • features/auth/identitySync.ts
  • features/auth/navigation.ts
  • features/auth/useAuthGate.ts
  • features/auth/useAuthStatus.ts
  • features/auth/useIdentitySync.ts
  • features/auth/useRequireAuth.ts
  • features/auth/useSignOutFlow.ts
  • features/auth/useSocialSignIn.ts
  • features/auth/useSocialStrategyAvailability.ts
  • lib/auth/clerk.ts
  • lib/auth/mapClerkError.ts
  • package.json
  • src/app/(auth)/sign-in.tsx
  • src/app/(auth)/sign-up.tsx
  • src/app/(auth)/verify.tsx
  • src/app/(onboarding)/demo.tsx
  • src/app/_layout.tsx
  • src/app/export/[projectId].tsx
  • src/app/subscription.tsx
  • types/auth.ts

Comment threadfeatures/auth/useSignOutFlow.ts
Comment threadsrc/app/(onboarding)/demo.tsx Outdated

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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 AppText with color="brand" (visually implying a link) but have no onPress/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 win

Duplicate publishable-key access bypasses getClerkPublishableKey().

fetchEnabledSocialStrategies re-reads process.env.EXPO_PUBLIC_CLERK_PUBLISHABLE_KEY directly instead of going through getClerkPublishableKey() (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 win

Failed/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 UNAVAILABLE but never populates socialStrategyCache. 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

📥 Commits

Reviewing files that changed from the base of the PR and between fe63e26 and 400301a.

📒 Files selected for processing (12)
  • app.json
  • components/auth/AuthSheet.tsx
  • components/auth/AuthSheetScreen.tsx
  • components/auth/SocialAuthButton.tsx
  • components/auth/authButtonStyles.ts
  • features/auth/accountDeletion.ts
  • features/auth/useSignOutFlow.ts
  • features/auth/useSocialStrategyAvailability.ts
  • lib/auth/clerk.ts
  • src/app/(auth)/sign-in.tsx
  • src/app/(auth)/sign-up.tsx
  • src/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

Comment threadlib/auth/clerk.ts
Comment on lines +61 to +65
const response = await fetch(
`https://${parsed.frontendApi}/v1/environment?_is_native=true`,
{ signal: controller.signal }
);
if (!response.ok) return UNAVAILABLE;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 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:


🏁 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:


🌐 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:


🌐 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:


🌐 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:


🌐 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:


🌐 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:


Add a fallback signal for Clerk social-strategy lookups
lib/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.

@victornwoke
victornwoke merged commit 08b34f3 into mainJul 11, 2026
1 check passed
This was referenced Jul 11, 2026
Sign up for freeto 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

@victornwoke
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' feat: implemented auth by victornwoke · Pull Request #1 · victornwoke/CleanAudio · GitHub
Skip to content

feat: implemented auth - #1

Merged
victornwoke merged 2 commits into
mainfrom
feature/auth
Jul 11, 2026
Merged

feat: implemented auth#1
victornwoke merged 2 commits into
mainfrom
feature/auth

Conversation

@victornwoke

@victornwokevictornwoke commented Jul 11, 2026

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • New Features
    • Added complete Clerk-based sign-in, sign-up, verification, password reset, and sign-out flows.
    • Introduced provider-choice authentication UI with availability-aware Apple/Google buttons plus email sign-in.
    • Added validated, labeled text input component and shared auth navigation/guards with return-to support.
    • Added identity sync on auth state changes and social strategy discovery with caching.
    • Improved demo onboarding completion with proper loading/error handling.
  • Bug Fixes
    • Tightened protected-screen gating to render only when fully authenticated (prevents premature access/flash).
  • Documentation
    • Updated authentication implementation status and verification notes.

@coderabbitai

coderabbitaiBot commented Jul 11, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds 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.

Changes

Clerk authentication

Layer / File(s)Summary
Auth configuration and contracts
package.json, app.json, types/auth.ts, lib/auth/*, features/auth/navigation.ts
Adds Clerk and Expo auth dependencies, iOS deployment configuration, social-provider types and discovery, safe error mapping, and typed return-to navigation.
Session and auth hooks
features/auth/*
Derives auth status from Clerk, adds auth gating, identity synchronization, sign-out, social sign-in, and typed account-deletion handling.
Authentication UI components
components/auth/*, components/common/AppTextInput.tsx, components/index.ts, constants/images.ts
Adds provider-choice, social-auth, and labeled text-input components with loading, focus, accessibility, validation, and provider-specific styling.
Sign-in, sign-up, and verification routes
src/app/(auth)/*
Implements Clerk email/password, social sign-in, password reset, email verification, resend, start-over, and return-navigation flows.
Root integration and onboarding handling
src/app/_layout.tsx, src/app/export/[projectId].tsx, src/app/subscription.tsx, src/app/(onboarding)/demo.tsx, docs/implementation-status.md
Mounts Clerk and identity synchronization, adds the verification route, makes protected screens wait for authenticated state, and adds onboarding completion loading/error handling and verification notes.

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
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 62.86% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title is directly related to the main change: adding a full authentication implementation.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/auth

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

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (5)
lib/auth/clerk.ts (1)

35-65: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Consider caching the environment fetch result.

fetchEnabledSocialStrategies() hits Clerk's /v1/environment endpoint on every call with no memoization. Since AuthSheet mounts 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 win

Duplicate sheet-view scaffold shared with sign-up.tsx.

The "sheet" view block (AuthSheet + socialError caption inside AppScreen) is nearly identical to the equivalent block in sign-up.tsx (lines 63-79 there), differing only by mode and the target view name. Consider extracting a shared AuthSheetScreen wrapper 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 win

Button base/focus styles duplicated with AuthSheet.tsx's emailButtonStyles.

styles.base/styles.focused here are structurally identical to emailButtonStyles.base/emailButtonStyles.focused in components/auth/AuthSheet.tsx (Lines 159-175). Consider extracting a shared authButtonBase/authButtonFocused style (or a shared PressableAuthButton wrapper) 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 win

Consider a discriminated union for AccountDeletionResult.

{ ok: boolean; error?: AccountDeletionError } allows nonsensical states (ok: true with error set, or ok: false with no error). 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

useSocialStrategyAvailability refetches on every AuthSheet mount, with no cross-screen cache.

Per the hook's implementation shown in context (features/auth/useSocialStrategyAvailability.ts), each mount calls fetchEnabledSocialStrategies() fresh via a local useEffect/useState, defaulting to an "unknown" (hidden) state until it resolves. Since sign-in.tsx and sign-up.tsx are separate routes that each mount their own AuthSheet, navigating between "Sign in"/"Sign up" (or back to either) re-triggers the network call to Clerk's /v1/environment endpoint 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

📥 Commits

Reviewing files that changed from the base of the PR and between 3dfd1ad and fe63e26.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (28)
  • app.json
  • components/auth/AuthSheet.tsx
  • components/auth/SocialAuthButton.tsx
  • components/common/AppTextInput.tsx
  • components/index.ts
  • constants/images.ts
  • docs/implementation-status.md
  • features/auth/accountDeletion.ts
  • features/auth/identitySync.ts
  • features/auth/navigation.ts
  • features/auth/useAuthGate.ts
  • features/auth/useAuthStatus.ts
  • features/auth/useIdentitySync.ts
  • features/auth/useRequireAuth.ts
  • features/auth/useSignOutFlow.ts
  • features/auth/useSocialSignIn.ts
  • features/auth/useSocialStrategyAvailability.ts
  • lib/auth/clerk.ts
  • lib/auth/mapClerkError.ts
  • package.json
  • src/app/(auth)/sign-in.tsx
  • src/app/(auth)/sign-up.tsx
  • src/app/(auth)/verify.tsx
  • src/app/(onboarding)/demo.tsx
  • src/app/_layout.tsx
  • src/app/export/[projectId].tsx
  • src/app/subscription.tsx
  • types/auth.ts

Comment threadfeatures/auth/useSignOutFlow.ts
Comment threadsrc/app/(onboarding)/demo.tsx Outdated

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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 AppText with color="brand" (visually implying a link) but have no onPress/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 win

Duplicate publishable-key access bypasses getClerkPublishableKey().

fetchEnabledSocialStrategies re-reads process.env.EXPO_PUBLIC_CLERK_PUBLISHABLE_KEY directly instead of going through getClerkPublishableKey() (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 win

Failed/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 UNAVAILABLE but never populates socialStrategyCache. 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

📥 Commits

Reviewing files that changed from the base of the PR and between fe63e26 and 400301a.

📒 Files selected for processing (12)
  • app.json
  • components/auth/AuthSheet.tsx
  • components/auth/AuthSheetScreen.tsx
  • components/auth/SocialAuthButton.tsx
  • components/auth/authButtonStyles.ts
  • features/auth/accountDeletion.ts
  • features/auth/useSignOutFlow.ts
  • features/auth/useSocialStrategyAvailability.ts
  • lib/auth/clerk.ts
  • src/app/(auth)/sign-in.tsx
  • src/app/(auth)/sign-up.tsx
  • src/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

Comment threadlib/auth/clerk.ts
Comment on lines +61 to +65
const response = await fetch(
`https://${parsed.frontendApi}/v1/environment?_is_native=true`,
{ signal: controller.signal }
);
if (!response.ok) return UNAVAILABLE;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 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:


🏁 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:


🌐 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:


🌐 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:


🌐 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:


🌐 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:


🌐 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:


Add a fallback signal for Clerk social-strategy lookups
lib/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.

@victornwoke
victornwoke merged commit 08b34f3 into mainJul 11, 2026
1 check passed
This was referenced Jul 11, 2026
Sign up for freeto 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

@victornwoke
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' feat: implemented auth by victornwoke · Pull Request #1 · victornwoke/CleanAudio · GitHub
Skip to content

feat: implemented auth - #1

Merged
victornwoke merged 2 commits into
mainfrom
feature/auth
Jul 11, 2026
Merged

feat: implemented auth#1
victornwoke merged 2 commits into
mainfrom
feature/auth

Conversation

@victornwoke

@victornwokevictornwoke commented Jul 11, 2026

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • New Features
    • Added complete Clerk-based sign-in, sign-up, verification, password reset, and sign-out flows.
    • Introduced provider-choice authentication UI with availability-aware Apple/Google buttons plus email sign-in.
    • Added validated, labeled text input component and shared auth navigation/guards with return-to support.
    • Added identity sync on auth state changes and social strategy discovery with caching.
    • Improved demo onboarding completion with proper loading/error handling.
  • Bug Fixes
    • Tightened protected-screen gating to render only when fully authenticated (prevents premature access/flash).
  • Documentation
    • Updated authentication implementation status and verification notes.

@coderabbitai

coderabbitaiBot commented Jul 11, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds 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.

Changes

Clerk authentication

Layer / File(s)Summary
Auth configuration and contracts
package.json, app.json, types/auth.ts, lib/auth/*, features/auth/navigation.ts
Adds Clerk and Expo auth dependencies, iOS deployment configuration, social-provider types and discovery, safe error mapping, and typed return-to navigation.
Session and auth hooks
features/auth/*
Derives auth status from Clerk, adds auth gating, identity synchronization, sign-out, social sign-in, and typed account-deletion handling.
Authentication UI components
components/auth/*, components/common/AppTextInput.tsx, components/index.ts, constants/images.ts
Adds provider-choice, social-auth, and labeled text-input components with loading, focus, accessibility, validation, and provider-specific styling.
Sign-in, sign-up, and verification routes
src/app/(auth)/*
Implements Clerk email/password, social sign-in, password reset, email verification, resend, start-over, and return-navigation flows.
Root integration and onboarding handling
src/app/_layout.tsx, src/app/export/[projectId].tsx, src/app/subscription.tsx, src/app/(onboarding)/demo.tsx, docs/implementation-status.md
Mounts Clerk and identity synchronization, adds the verification route, makes protected screens wait for authenticated state, and adds onboarding completion loading/error handling and verification notes.

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
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 62.86% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title is directly related to the main change: adding a full authentication implementation.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/auth

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

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (5)
lib/auth/clerk.ts (1)

35-65: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Consider caching the environment fetch result.

fetchEnabledSocialStrategies() hits Clerk's /v1/environment endpoint on every call with no memoization. Since AuthSheet mounts 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 win

Duplicate sheet-view scaffold shared with sign-up.tsx.

The "sheet" view block (AuthSheet + socialError caption inside AppScreen) is nearly identical to the equivalent block in sign-up.tsx (lines 63-79 there), differing only by mode and the target view name. Consider extracting a shared AuthSheetScreen wrapper 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 win

Button base/focus styles duplicated with AuthSheet.tsx's emailButtonStyles.

styles.base/styles.focused here are structurally identical to emailButtonStyles.base/emailButtonStyles.focused in components/auth/AuthSheet.tsx (Lines 159-175). Consider extracting a shared authButtonBase/authButtonFocused style (or a shared PressableAuthButton wrapper) 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 win

Consider a discriminated union for AccountDeletionResult.

{ ok: boolean; error?: AccountDeletionError } allows nonsensical states (ok: true with error set, or ok: false with no error). 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

useSocialStrategyAvailability refetches on every AuthSheet mount, with no cross-screen cache.

Per the hook's implementation shown in context (features/auth/useSocialStrategyAvailability.ts), each mount calls fetchEnabledSocialStrategies() fresh via a local useEffect/useState, defaulting to an "unknown" (hidden) state until it resolves. Since sign-in.tsx and sign-up.tsx are separate routes that each mount their own AuthSheet, navigating between "Sign in"/"Sign up" (or back to either) re-triggers the network call to Clerk's /v1/environment endpoint 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

📥 Commits

Reviewing files that changed from the base of the PR and between 3dfd1ad and fe63e26.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (28)
  • app.json
  • components/auth/AuthSheet.tsx
  • components/auth/SocialAuthButton.tsx
  • components/common/AppTextInput.tsx
  • components/index.ts
  • constants/images.ts
  • docs/implementation-status.md
  • features/auth/accountDeletion.ts
  • features/auth/identitySync.ts
  • features/auth/navigation.ts
  • features/auth/useAuthGate.ts
  • features/auth/useAuthStatus.ts
  • features/auth/useIdentitySync.ts
  • features/auth/useRequireAuth.ts
  • features/auth/useSignOutFlow.ts
  • features/auth/useSocialSignIn.ts
  • features/auth/useSocialStrategyAvailability.ts
  • lib/auth/clerk.ts
  • lib/auth/mapClerkError.ts
  • package.json
  • src/app/(auth)/sign-in.tsx
  • src/app/(auth)/sign-up.tsx
  • src/app/(auth)/verify.tsx
  • src/app/(onboarding)/demo.tsx
  • src/app/_layout.tsx
  • src/app/export/[projectId].tsx
  • src/app/subscription.tsx
  • types/auth.ts

Comment threadfeatures/auth/useSignOutFlow.ts
Comment threadsrc/app/(onboarding)/demo.tsx Outdated

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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 AppText with color="brand" (visually implying a link) but have no onPress/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 win

Duplicate publishable-key access bypasses getClerkPublishableKey().

fetchEnabledSocialStrategies re-reads process.env.EXPO_PUBLIC_CLERK_PUBLISHABLE_KEY directly instead of going through getClerkPublishableKey() (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 win

Failed/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 UNAVAILABLE but never populates socialStrategyCache. 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

📥 Commits

Reviewing files that changed from the base of the PR and between fe63e26 and 400301a.

📒 Files selected for processing (12)
  • app.json
  • components/auth/AuthSheet.tsx
  • components/auth/AuthSheetScreen.tsx
  • components/auth/SocialAuthButton.tsx
  • components/auth/authButtonStyles.ts
  • features/auth/accountDeletion.ts
  • features/auth/useSignOutFlow.ts
  • features/auth/useSocialStrategyAvailability.ts
  • lib/auth/clerk.ts
  • src/app/(auth)/sign-in.tsx
  • src/app/(auth)/sign-up.tsx
  • src/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

Comment threadlib/auth/clerk.ts
Comment on lines +61 to +65
const response = await fetch(
`https://${parsed.frontendApi}/v1/environment?_is_native=true`,
{ signal: controller.signal }
);
if (!response.ok) return UNAVAILABLE;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 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:


🏁 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:


🌐 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:


🌐 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:


🌐 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:


🌐 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:


🌐 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:


Add a fallback signal for Clerk social-strategy lookups
lib/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.

@victornwoke
victornwoke merged commit 08b34f3 into mainJul 11, 2026
1 check passed
This was referenced Jul 11, 2026
Sign up for freeto 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

@victornwoke
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); feat: implemented auth by victornwoke · Pull Request #1 · victornwoke/CleanAudio · GitHub
Skip to content

feat: implemented auth - #1

Merged
victornwoke merged 2 commits into
mainfrom
feature/auth
Jul 11, 2026
Merged

feat: implemented auth#1
victornwoke merged 2 commits into
mainfrom
feature/auth

Conversation

@victornwoke

@victornwokevictornwoke commented Jul 11, 2026

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • New Features
    • Added complete Clerk-based sign-in, sign-up, verification, password reset, and sign-out flows.
    • Introduced provider-choice authentication UI with availability-aware Apple/Google buttons plus email sign-in.
    • Added validated, labeled text input component and shared auth navigation/guards with return-to support.
    • Added identity sync on auth state changes and social strategy discovery with caching.
    • Improved demo onboarding completion with proper loading/error handling.
  • Bug Fixes
    • Tightened protected-screen gating to render only when fully authenticated (prevents premature access/flash).
  • Documentation
    • Updated authentication implementation status and verification notes.

@coderabbitai

coderabbitaiBot commented Jul 11, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds 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.

Changes

Clerk authentication

Layer / File(s)Summary
Auth configuration and contracts
package.json, app.json, types/auth.ts, lib/auth/*, features/auth/navigation.ts
Adds Clerk and Expo auth dependencies, iOS deployment configuration, social-provider types and discovery, safe error mapping, and typed return-to navigation.
Session and auth hooks
features/auth/*
Derives auth status from Clerk, adds auth gating, identity synchronization, sign-out, social sign-in, and typed account-deletion handling.
Authentication UI components
components/auth/*, components/common/AppTextInput.tsx, components/index.ts, constants/images.ts
Adds provider-choice, social-auth, and labeled text-input components with loading, focus, accessibility, validation, and provider-specific styling.
Sign-in, sign-up, and verification routes
src/app/(auth)/*
Implements Clerk email/password, social sign-in, password reset, email verification, resend, start-over, and return-navigation flows.
Root integration and onboarding handling
src/app/_layout.tsx, src/app/export/[projectId].tsx, src/app/subscription.tsx, src/app/(onboarding)/demo.tsx, docs/implementation-status.md
Mounts Clerk and identity synchronization, adds the verification route, makes protected screens wait for authenticated state, and adds onboarding completion loading/error handling and verification notes.

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
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 62.86% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title is directly related to the main change: adding a full authentication implementation.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/auth

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

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (5)
lib/auth/clerk.ts (1)

35-65: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Consider caching the environment fetch result.

fetchEnabledSocialStrategies() hits Clerk's /v1/environment endpoint on every call with no memoization. Since AuthSheet mounts 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 win

Duplicate sheet-view scaffold shared with sign-up.tsx.

The "sheet" view block (AuthSheet + socialError caption inside AppScreen) is nearly identical to the equivalent block in sign-up.tsx (lines 63-79 there), differing only by mode and the target view name. Consider extracting a shared AuthSheetScreen wrapper 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 win

Button base/focus styles duplicated with AuthSheet.tsx's emailButtonStyles.

styles.base/styles.focused here are structurally identical to emailButtonStyles.base/emailButtonStyles.focused in components/auth/AuthSheet.tsx (Lines 159-175). Consider extracting a shared authButtonBase/authButtonFocused style (or a shared PressableAuthButton wrapper) 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 win

Consider a discriminated union for AccountDeletionResult.

{ ok: boolean; error?: AccountDeletionError } allows nonsensical states (ok: true with error set, or ok: false with no error). 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

useSocialStrategyAvailability refetches on every AuthSheet mount, with no cross-screen cache.

Per the hook's implementation shown in context (features/auth/useSocialStrategyAvailability.ts), each mount calls fetchEnabledSocialStrategies() fresh via a local useEffect/useState, defaulting to an "unknown" (hidden) state until it resolves. Since sign-in.tsx and sign-up.tsx are separate routes that each mount their own AuthSheet, navigating between "Sign in"/"Sign up" (or back to either) re-triggers the network call to Clerk's /v1/environment endpoint 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

📥 Commits

Reviewing files that changed from the base of the PR and between 3dfd1ad and fe63e26.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (28)
  • app.json
  • components/auth/AuthSheet.tsx
  • components/auth/SocialAuthButton.tsx
  • components/common/AppTextInput.tsx
  • components/index.ts
  • constants/images.ts
  • docs/implementation-status.md
  • features/auth/accountDeletion.ts
  • features/auth/identitySync.ts
  • features/auth/navigation.ts
  • features/auth/useAuthGate.ts
  • features/auth/useAuthStatus.ts
  • features/auth/useIdentitySync.ts
  • features/auth/useRequireAuth.ts
  • features/auth/useSignOutFlow.ts
  • features/auth/useSocialSignIn.ts
  • features/auth/useSocialStrategyAvailability.ts
  • lib/auth/clerk.ts
  • lib/auth/mapClerkError.ts
  • package.json
  • src/app/(auth)/sign-in.tsx
  • src/app/(auth)/sign-up.tsx
  • src/app/(auth)/verify.tsx
  • src/app/(onboarding)/demo.tsx
  • src/app/_layout.tsx
  • src/app/export/[projectId].tsx
  • src/app/subscription.tsx
  • types/auth.ts

Comment threadfeatures/auth/useSignOutFlow.ts
Comment threadsrc/app/(onboarding)/demo.tsx Outdated

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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 AppText with color="brand" (visually implying a link) but have no onPress/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 win

Duplicate publishable-key access bypasses getClerkPublishableKey().

fetchEnabledSocialStrategies re-reads process.env.EXPO_PUBLIC_CLERK_PUBLISHABLE_KEY directly instead of going through getClerkPublishableKey() (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 win

Failed/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 UNAVAILABLE but never populates socialStrategyCache. 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

📥 Commits

Reviewing files that changed from the base of the PR and between fe63e26 and 400301a.

📒 Files selected for processing (12)
  • app.json
  • components/auth/AuthSheet.tsx
  • components/auth/AuthSheetScreen.tsx
  • components/auth/SocialAuthButton.tsx
  • components/auth/authButtonStyles.ts
  • features/auth/accountDeletion.ts
  • features/auth/useSignOutFlow.ts
  • features/auth/useSocialStrategyAvailability.ts
  • lib/auth/clerk.ts
  • src/app/(auth)/sign-in.tsx
  • src/app/(auth)/sign-up.tsx
  • src/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

Comment threadlib/auth/clerk.ts
Comment on lines +61 to +65
const response = await fetch(
`https://${parsed.frontendApi}/v1/environment?_is_native=true`,
{ signal: controller.signal }
);
if (!response.ok) return UNAVAILABLE;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 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:


🏁 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:


🌐 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:


🌐 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:


🌐 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:


🌐 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:


🌐 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:


Add a fallback signal for Clerk social-strategy lookups
lib/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.

@victornwoke
victornwoke merged commit 08b34f3 into mainJul 11, 2026
1 check passed
This was referenced Jul 11, 2026
Sign up for freeto 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

@victornwoke