Skip to content

Dev - #83

Merged
Retsomm merged 4 commits into
mainfrom
dev
Aug 3, 2026
Merged

Dev#83
Retsomm merged 4 commits into
mainfrom
dev

Conversation

@Retsomm

@Retsomm Retsomm commented Aug 3, 2026 •

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • New Features

    • Mobile Google and Line sign-in now use a unified OAuth SSO flow.
    • Added native Google sign-in support for a smoother mobile authentication experience.
    • Added support for passkey and Apple authentication capabilities.
  • Bug Fixes

    • Improved authentication session handling and correctly treats cancelled sign-ins without showing an error.
  • Documentation

    • Updated privacy, setup, and API documentation to reflect the current mobile authentication flow.

Retsomm and others added 2 commits August 3, 2026 14:00
這支後端 endpoint 是 v3.0.0 手機端 Google 登入「後端代理 ticket 策略」的殘留,
隔天就因為 Android webClientId 啟動錯誤改用 Clerk OAuth SSO,endpoint 本身沒有
一併移除。稽核發現它的 audience 驗證是 fail-open(缺環境變數就跳過檢查),且
proxy.ts 結構上會擋住未登入呼叫,導致它既是攻擊面、又已經打不通。

多方查證確認是死碼後移除:原始碼歷史(所有分支自 2026-06-23 起無呼叫點)、
proxy.ts runtime 行為、production 近期零流量。README/learning-path/隱私權
政策頁一併移除或修正過時描述。

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
舊版 useSSO(瀏覽器 OAuth)建立的 session,會被 @clerk/expo 內建的原生↔JS
同步機制判定跟原生端對不上而覆蓋掉,登入後 isSignedIn 又自動變回 false。

- @clerk/expo 3.3.0 → 4.2.0(Core 3),改用官方拆出的 @clerk/expo-google-signin
  做 Android/iOS 原生 Google 登入,取代 useGoogleSignIn 裡的 useSSO 呼叫
- useOAuthSignIn(Line 登入用)改用 @clerk/expo/experimental 的新版 useSSO,
  session 建立後自動 setActive,不用再手動呼叫、不會撞上同步時序問題
- _layout.tsx 的 tokenCache 換成官方現成的 @clerk/expo/token-cache
- 新增 @clerk/expo-passkeys、expo-apple-authentication、expo-crypto(4.x 必要
  peer dependency),app.json plugins 加上 @clerk/expo-google-signin
- 需另外在 Google Cloud Console 註冊 Android 類型 OAuth Client(package name +
  SHA-1)並在 Clerk Dashboard 設定 custom credentials,才能通過原生登入驗證

已實機測試 Google 與 Line 登入皆成功。

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Aug 3, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
self-map Ready Ready Preview Aug 3, 2026 6:47am

@coderabbitai

coderabbitai Bot commented Aug 3, 2026 •

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@Retsomm, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 16 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 7cfadf7b-c871-4246-862c-e3149b6c1db4

📥 Commits

Reviewing files that changed from the base of the PR and between 9e1acbf and cab6c96.

📒 Files selected for processing (3)
  • mobile/app/_layout.tsx
  • mobile/hooks/useGoogleSignIn.ts
  • mobile/hooks/useOAuthSignIn.ts
📝 Walkthrough

Walkthrough

Mobile authentication now uses Clerk Expo native Google authentication and OAuth SSO. The custom Google token-exchange route and related validation logic were removed. Expo configuration, session caching, route protection, and documentation were updated.

Changes

Mobile authentication migration

Layer / File(s) Summary
Clerk Expo authentication hooks
mobile/package.json, mobile/app.json, mobile/hooks/*
Clerk Expo dependencies and the Google Sign-In plugin were added. useGoogleSignIn now uses native Clerk authentication. useOAuthSignIn now uses useSSO with automatic session activation.
Clerk token cache and route guard
mobile/app/_layout.tsx
The root layout now uses Clerk Expo tokenCache, validates publishableKey, and updates AuthGuard route checks and effect dependencies.
Backend endpoint removal and documentation
app/api/auth/mobile/google/route.ts, README.md, app/private/PrivateClient.tsx, docs/learning-path.md
The mobile Google authentication route was removed. Documentation now describes Clerk Expo SSO and removes references to the backend token-exchange endpoint.

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

Sequence Diagram(s)

sequenceDiagram
  participant useGoogleSignIn
  participant NativeGoogleAuthentication
  participant ClerkSession
  participant useOAuthSignIn
  participant ClerkSSO
  useGoogleSignIn->>NativeGoogleAuthentication: start native Google authentication
  NativeGoogleAuthentication-->>useGoogleSignIn: return created session ID
  useGoogleSignIn->>ClerkSession: activate session
  useOAuthSignIn->>ClerkSSO: start SSO flow
  ClerkSSO-->>useOAuthSignIn: return redirect URL and created session ID
  ClerkSSO->>ClerkSession: automatically activate session
Loading

Possibly related PRs

  • Retsomm/SelfMap#56: This PR removes the backend Google token-exchange flow introduced there.
  • Retsomm/SelfMap#57: This PR extends the Clerk OAuth SSO migration in the same mobile authentication areas.
  • Retsomm/SelfMap#59: Both PRs update the mobile Google and OAuth authentication hooks.
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title "Dev" is too generic and does not identify the Clerk OAuth SSO and mobile authentication changes. Replace "Dev" with a concise title that describes the mobile authentication migration to Clerk OAuth SSO.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch dev

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@coderabbitai coderabbitai Bot 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: 3

🤖 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 `@mobile/app.json`:
- Line 36: Add the required Google native-flow configuration under expo.extra in
mobile/app.json: expose the inlined EXPO_PUBLIC_CLERK_GOOGLE_WEB_CLIENT_ID,
EXPO_PUBLIC_CLERK_GOOGLE_IOS_CLIENT_ID,
EXPO_PUBLIC_CLERK_GOOGLE_ANDROID_CLIENT_ID, and
EXPO_PUBLIC_CLERK_GOOGLE_IOS_URL_SCHEME values alongside the existing
`@clerk/expo-google-signin` plugin configuration.

In `@mobile/hooks/useGoogleSignIn.ts`:
- Around line 10-19: Update handleGoogleSignIn to catch rejections from
startGoogleAuthenticationFlow: silently ignore errors with codes
SIGN_IN_CANCELLED or -5, and log plus display a user-friendly error for all
other failures. Preserve the existing success handling and createdSessionId
cancellation path.

In `@mobile/hooks/useOAuthSignIn.ts`:
- Around line 15-21: Update handleSignIn to destructure setActive from
startSSOFlow and, when createdSessionId exists, await setActive with that
session ID before invoking onSuccess?. Preserve the existing redirect and
success flow, ensuring navigation only occurs after Clerk activation completes.
🪄 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: b477f3e6-4e1d-43ed-89d5-c6317b7df75e

📥 Commits

Reviewing files that changed from the base of the PR and between d1fdcdc and 9e1acbf.

⛔ Files ignored due to path filters (1)
  • mobile/yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (9)
  • README.md
  • app/api/auth/mobile/google/route.ts
  • app/private/PrivateClient.tsx
  • docs/learning-path.md
  • mobile/app.json
  • mobile/app/_layout.tsx
  • mobile/hooks/useGoogleSignIn.ts
  • mobile/hooks/useOAuthSignIn.ts
  • mobile/package.json
💤 Files with no reviewable changes (1)
  • app/api/auth/mobile/google/route.ts

Comment thread mobile/app.json
"expo-router",
"expo-secure-store",
"@clerk/expo",
"@clerk/expo-google-signin",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

jq -e '
  .expo.extra
  | .EXPO_PUBLIC_CLERK_GOOGLE_WEB_CLIENT_ID
  and .EXPO_PUBLIC_CLERK_GOOGLE_IOS_CLIENT_ID
  and .EXPO_PUBLIC_CLERK_GOOGLE_ANDROID_CLIENT_ID
' mobile/app.json

Repository: Retsomm/SelfMap

Length of output: 159


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '--- mobile/app.json relevant config ---\n'
jq -n 'load("mobile/app.json")' | jq '.expo.extra'

printf '\n--- Clerk Google plugin usage ---\n'
rg -n "useGoogleSignIn|googleSignIn|`@clerk/expo-google-signin`|EXPO_PUBLIC_CLERK_GOOGLE_|GoogleSignIn" mobile || true

printf '\n--- package references ---\n'
for f in mobile/package.json package.json pnpm-lock.yaml package-lock.json yarn.lock; do
  if [ -f "$f" ]; then
    printf '\n### %s\n' "$f"
    rg -n "`@clerk/expo-google-signin`|clerk" "$f" || true
  fi
done

printf '\n--- Clerk config docs availability ---\n'
if [ -d node_modules/next/dist/docs/ ]; then
  fd -i 'next' node_modules/next/dist/docs/ | head -20 || true
  rg -n "publishable|environment|app config|client id" node_modules/next/dist/docs/ | head -80 || true
else
  printf 'node_modules/next/dist/docs not present\n'
fi

Repository: Retsomm/SelfMap

Length of output: 244


🌐 Web query:

Clerk Expo Google Sign-In Google client IDs EXPO_PUBLIC_CLERK_GOOGLE_WEB_CLIENT_ID configuration

💡 Result:

To configure Google Sign-In with Clerk in an Expo project, you must provide specific Google OAuth client IDs as environment variables. These variables allow Clerk to manage authentication across different platforms while providing a native user experience [1][2]. Required Environment Variables Add the following variables to your project's.env file [1][3]: EXPO_PUBLIC_CLERK_GOOGLE_WEB_CLIENT_ID: Your Web Client ID from the Google Cloud Console. This is required for all flows to enable backend token verification [1][2]. EXPO_PUBLIC_CLERK_GOOGLE_IOS_CLIENT_ID: Your iOS Client ID [1]. EXPO_PUBLIC_CLERK_GOOGLE_IOS_URL_SCHEME: The reversed client ID scheme for iOS native callbacks (e.g., com.googleusercontent.apps.your-client-id) [1][4]. EXPO_PUBLIC_CLERK_GOOGLE_ANDROID_CLIENT_ID: Your Android Client ID [1]. Configuration and Requirements 1. Google Cloud Console: You must create three separate OAuth 2.0 credentials in the Google Cloud Console: one for Web, one for iOS, and one for Android [5][3][2]. 2. Clerk Dashboard: Enable Google as a social connection (with custom credentials) and register your native applications (iOS Bundle ID and Android package name/SHA-256 fingerprint) in the Clerk Dashboard [5][2]. 3. Native Builds: Native Google Sign-In (which avoids browser pop-ups) requires a development build; it does not function in Expo Go [2][6][7]. 4. Plugin Setup: Ensure the @clerk/expo plugin is included in your app.json or app.config.ts. The plugin automatically configures the iOS URL scheme and applies necessary native SDK settings when these environment variables are detected [1][4][7]. 5. Security: Since EXPO_PUBLIC_ variables are inlined into your app bundle at build time, never include sensitive secret keys (such as the Google Client Secret) in these variables [2]. Only the public client IDs should be used [3]. When properly configured, using hooks like useSignInWithGoogle enables a native experience—using Credential Manager on Android and ASAuthorization on iOS [6][8][7]. If the iOS URL scheme is missing, iOS will fall back to a system browser sheet [8][7].

Citations:


Add the required Google client IDs to Expo configuration.

mobile/app.json includes the Clerk Google Sign-In plugin, but expo.extra does not expose the native Google client IDs. Add the inlined EXPO_PUBLIC_CLERK_GOOGLE_WEB_CLIENT_ID, EXPO_PUBLIC_CLERK_GOOGLE_IOS_CLIENT_ID, EXPO_PUBLIC_CLERK_GOOGLE_ANDROID_CLIENT_ID, and EXPO_PUBLIC_CLERK_GOOGLE_IOS_URL_SCHEME values for the native Google flow.

🤖 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 `@mobile/app.json` at line 36, Add the required Google native-flow
configuration under expo.extra in mobile/app.json: expose the inlined
EXPO_PUBLIC_CLERK_GOOGLE_WEB_CLIENT_ID, EXPO_PUBLIC_CLERK_GOOGLE_IOS_CLIENT_ID,
EXPO_PUBLIC_CLERK_GOOGLE_ANDROID_CLIENT_ID, and
EXPO_PUBLIC_CLERK_GOOGLE_IOS_URL_SCHEME values alongside the existing
`@clerk/expo-google-signin` plugin configuration.

Comment on lines +10 to +19
async function handleGoogleSignIn() {
const { createdSessionId, setActive } = await startGoogleAuthenticationFlow()
console.log(`[OAuth debug][GoogleSignIn-native] createdSessionId=${createdSessionId}`)
if (createdSessionId && setActive) {
await setActive({ session: createdSessionId })
console.log('[OAuth debug][GoogleSignIn-native] setActive 完成')
onSuccess?.()
}
// createdSessionId 為 null 代表使用者取消,不視為錯誤
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

rg -n -C 4 'startGoogleAuthenticationFlow|SIGN_IN_CANCELLED|-5|catch' \
  mobile/hooks/useGoogleSignIn.ts

Repository: Retsomm/SelfMap

Length of output: 847


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== file context =="
sed -n '1,60p' mobile/hooks/useGoogleSignIn.ts

echo
echo "== package references =="
node - <<'JS'
const fs = require('fs');
for (const f of ['./package.json', './mobile/package.json']) {
  if (fs.existsSync(f)) {
    const j = JSON.parse(fs.readFileSync(f, 'utf8'));
    console.log(f);
    const deps = {...(j.dependencies||{}), ...(j.devDependencies||{})};
    for (const [k,v] of Object.entries(deps)) {
      if (k.includes('clerk') || k.includes('expo') || k.includes('google')) console.log(`${k}: ${v}`);
    }
  }
}
JS

echo
echo "== nearby hook usage =="
rg -n "useGoogleSignIn|handleGoogleSignIn|Google 登入|Google sign-in|SIGN_IN_CANCELLED|startGoogleAuthenticationFlow|useSignInWithGoogle" mobile --glob '*.{ts,tsx,js,jsx}'

Repository: Retsomm/SelfMap

Length of output: 3008


🌐 Web query:

Clerk Expo Google sign in native useSignInWithGoogle SIGN_IN_CANCELLED -5

💡 Result:

When using the native useSignInWithGoogle hook in a Clerk Expo application, the SIGN_IN_CANCELLED error code—and sometimes -5 on Android—indicates that the user has manually dismissed the Google sign-in prompt [1][2][3]. This is expected behavior rather than a functional error [3]. To handle this gracefully, you should explicitly catch these codes in your try/catch block and return early to prevent showing an error alert to the user [1][4]. ### Implementation Pattern Wrap your startGoogleAuthenticationFlow() call in a try/catch block and check for these specific error codes [1][5]: tsx const { startGoogleAuthenticationFlow } = useSignInWithGoogle(); const handleGoogleSignIn = async () => { try { const { createdSessionId, setActive } = await startGoogleAuthenticationFlow(); if (createdSessionId && setActive) { await setActive({ session: createdSessionId }); // Redirect or complete sign-in } } catch (err: any) { // Check for user cancellation codes if (err.code === 'SIGN_IN_CANCELLED' || err.code === '-5') { return; // Silently exit on cancellation } // Handle legitimate errors (e.g., network, configuration) console.error('Google sign-in error:', err); Alert.alert('Error', err.message || 'An error occurred during Google sign-in'); } }; ### Important Setup Notes * Package Requirement: As of recent updates, the native Google Sign-In functionality requires the @clerk/expo-google-signin package [6]. Ensure you have installed it (npx expo install @clerk/expo-google-signin``) and added it to your app.json plugins alongside `@clerk/expo` [6]. * Development Builds: Native Google sign-in requires a custom development build; it does not work within the standard Expo Go app [3][7]. * Platform Behavior: On Android, this uses the native Credential Manager. On iOS, it uses `ASAuthorization` when the `EXPO_PUBLIC_CLERK_GOOGLE_IOS_URL_SCHEME` is configured; otherwise, it falls back to a system browser sheet [2][7].

Citations:


Handle native Google authentication errors.

startGoogleAuthenticationFlow() rejects on cancellation and native failures. createdSessionId === null only covers the callback path, not rejected cancellations. Catch SIGN_IN_CANCELLED and -5 silently, then log and show a user-friendly error for all other failures.

🤖 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 `@mobile/hooks/useGoogleSignIn.ts` around lines 10 - 19, Update
handleGoogleSignIn to catch rejections from startGoogleAuthenticationFlow:
silently ignore errors with codes SIGN_IN_CANCELLED or -5, and log plus display
a user-friendly error for all other failures. Preserve the existing success
handling and createdSessionId cancellation path.

Source: Coding guidelines

Comment on lines 15 to 21
async function handleSignIn() {
try {
const redirectUrl = AuthSession.makeRedirectUri({ path: 'oauth-native-callback' })
const { createdSessionId, setActive } = await startSSOFlow({ strategy, redirectUrl })
if (createdSessionId && setActive) {
await setActive({ session: createdSessionId })
const { createdSessionId } = await startSSOFlow({ strategy, redirectUrl })
console.log(`[OAuth debug][${label}] redirectUrl=${redirectUrl} createdSessionId=${createdSessionId}`)
if (createdSessionId) {
onSuccess?.()

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

rg -n -C 4 '"`@clerk/expo`"|startSSOFlow|setActive' \
  mobile/package.json mobile/hooks/useOAuthSignIn.ts

fd -HI 'package-lock.json|yarn.lock|pnpm-lock.yaml' mobile -d 2 \
  -x rg -n '"`@clerk/expo`"|`@clerk/expo`@' {} \; || true

Repository: Retsomm/SelfMap

Length of output: 2229


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== mobile/hooks/useOAuthSignIn.ts =="
cat -n mobile/hooks/useOAuthSignIn.ts | sed -n '1,120p'

echo
echo "== relevant Clerk docs/package artifacts if available =="
if [ -d mobile/node_modules/@clerk/expo ]; then
  rg -n "function startSSOFlow|const startSSOFlow|setActive|handleOAuthRedirect|export.*startSSOFlow" mobile/node_modules/@clerk/expo mobile/node_modules/@clerk -S || true
  fd -HI 'package.json|package-lock.json|yarn.lock|pnpm-lock.yaml|index.*|use-sso.*|sso.*' mobile/node_modules/@clerk mobile -d 2 \
    -x rg -n '"`@clerk/expo`"|`@clerk/expo`@|startSSOFlow|setActive' {} \; || true
else
  echo "mobile/node_modules/@clerk/expo not present"
  fd -HI 'package.json|package-lock.json|yarn.lock|pnpm-lock.yaml' . \
    -x rg -n '"`@clerk/expo`"@|`@clerk/expo`@|startSSOFlow|setActive' {} \; || true
fi

echo
echo "== Clerk NPM type/package data =="
npm view `@clerk/expo`@4.2.0 version dist.name --json 2>/dev/null || true
npm view `@clerk/expo`@4.2.0 dist.tarball --json 2>/dev/null || true
python3 - <<'PY'
import json, urllib.request
url='https://registry.npmjs.org/@clerk%2fexpo/4.2.0'
try:
    with urllib.request.urlopen(url, timeout=20) as r:
        data=json.load(r)
        print('version', data.get('version'))
        for k in data.get('typesVersions',{}):
            if isinstance(data['typesVersions'][k], dict):
                print('typesVersions', k, list(data['typesVersions'][k].keys())[:20])
        for f in data.get('types',[]):
            if f:
                try:
                    import urllib.request, io, tarfile
                    base=data.get('dist',{}).get('tarball','')
                    # not doing fetch here to avoid hidden web; leave empty
                    print('type file', f)
                except Exception as e:
                    print('error', f, e)
except Exception as e:
    print('ERR', e)
PY

Repository: Retsomm/SelfMap

Length of output: 1893


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== useSSO imports/usages =="
rg -n "useSSO|startSSOFlow|onSuccess|oauth-native-callback|setActive|isSignedIn" mobile -S --glob '*.{ts,tsx,js,jsx}' | sed -n '1,220p'

echo
echo "== TypeScript package/version metadata from manifests =="
for f in mobile/package.json mobile/package-lock.json mobile/yarn.lock mobile/pnpm-lock.yaml; do
  [ -f "$f" ] || continue
  echo "--- $f ---"
  rg -n '"`@clerk/expo`"|"`@clerk/expo`@|startSSOFlow|setActive' "$f" -S || true
done

echo
echo "== package tarball source scan for startSSOFlow/setActive =="
tmp="$(mktemp -d)"
curl -fsSL https://registry.npmjs.org/@clerk/expo/4.2.0 -o "$tmp/clerk-4.2.0.tar.gz" 2>/dev/null || true
if [ -s "$tmp/clerk-4.2.0.tar.gz" ]; then
  tar -tzf "$tmp/clerk-4.2.0.tar.gz" | grep -Ei 'packages?|dist|src|expo/.+.(ts|tsx|d\.ts)$' | grep -Ei 'sso|startSSOFlow|useSSO|setActive' | head -n 80 || true
  tar -xzf "$tmp/clerk-4.2.0.tar.gz" -C "$tmp" --no-same-owner 2>/dev/null || true
  rg -n "function startSSOFlow|const startSSOFlow|setActive|handleOAuthRedirect|createdSessionId|return.*createSession|startSSOFlow" "$tmp" -S | sed -n '1,220p' || true
fi

Repository: Retsomm/SelfMap

Length of output: 4037


🌐 Web query:

Clerk Expo 4 startSSOFlow createdSessionId setActive documentation

💡 Result:

In the Clerk Expo SDK, specifically when using browser-based SSO via the useSSO hook, the startSSOFlow method is used to initiate the authentication process [1][2]. This method returns an object containing createdSessionId and the setActive function [1][3]. Once the authentication flow completes successfully, you must use the returned setActive function to establish the session [3][4]. Key details: 1. startSSOFlow: This method is called with a configuration object that includes the authentication strategy (e.g., 'oauth_google', 'oauth_github') and an optional redirectUrl [1][5]. 2. createdSessionId: This is the ID of the session that was successfully created by the SSO flow [1]. 3. setActive: This function is used to set the current session as active in your application [1][6]. It accepts a SetActiveParams object, commonly used as follows: await setActive({ session: createdSessionId }) [3][4][5]. Example usage: const { startSSOFlow } = useSSO; const handleSignIn = async => { try { const { createdSessionId, setActive } = await startSSOFlow({ strategy: 'oauth_google', }); if (createdSessionId && setActive) { await setActive({ session: createdSessionId }); } } catch (err) { console.error('SSO flow error:', err); } }; Note that native hooks like useSignInWithGoogle and useSignInWithApple also follow this same setActive pattern to complete authentication [7][4]. In newer Clerk SDK versions (Core 3+), while some password-based flows have moved to a signIn.finalize pattern, the native and browser-based OAuth flows documented in the Clerk Expo SDK continue to use the setActive pattern [4].

Citations:


Activate the SSO session before redirecting.

startSSOFlow() returns setActive for the created session, but this handler calls onSuccess without activating it. Activate the returned session and await completion before returning to /(tabs), otherwise Clerk can still report the user as signed out after the OAuth flow.

Proposed session activation
-      const { createdSessionId } = await startSSOFlow({ strategy, redirectUrl })
+      const { createdSessionId, setActive } = await startSSOFlow({ strategy, redirectUrl })
       console.log(`[OAuth debug][${label}] redirectUrl=${redirectUrl} createdSessionId=${createdSessionId}`)
-      if (createdSessionId) {
+      if (createdSessionId && setActive) {
+        await setActive({ session: createdSessionId })
         onSuccess?.()
       }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
async function handleSignIn() {
try {
const redirectUrl = AuthSession.makeRedirectUri({ path: 'oauth-native-callback' })
const { createdSessionId, setActive } = await startSSOFlow({ strategy, redirectUrl })
if (createdSessionId && setActive) {
await setActive({ session: createdSessionId })
const { createdSessionId } = await startSSOFlow({ strategy, redirectUrl })
console.log(`[OAuth debug][${label}] redirectUrl=${redirectUrl} createdSessionId=${createdSessionId}`)
if (createdSessionId) {
onSuccess?.()
async function handleSignIn() {
try {
const redirectUrl = AuthSession.makeRedirectUri({ path: 'oauth-native-callback' })
const { createdSessionId, setActive } = await startSSOFlow({ strategy, redirectUrl })
console.log(`[OAuth debug][${label}] redirectUrl=${redirectUrl} createdSessionId=${createdSessionId}`)
if (createdSessionId && setActive) {
await setActive({ session: createdSessionId })
onSuccess?.()
🤖 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 `@mobile/hooks/useOAuthSignIn.ts` around lines 15 - 21, Update handleSignIn to
destructure setActive from startSSOFlow and, when createdSessionId exists, await
setActive with that session ID before invoking onSuccess?. Preserve the existing
redirect and success flow, ensuring navigation only occurs after Clerk
activation completes.

Retsomm and others added 2 commits August 3, 2026 14:19
Google/Line 登入重寫過程中加的 [OAuth debug] 追蹤 log,功能已驗證完成,清掉正式碼裡的除錯輸出。

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
useGoogleSignIn 原本沒有任何錯誤 log,出錯時除了 Alert 顯示「登入失敗」外
完全沒有除錯線索,跟 useOAuthSignIn 的處理方式不一致,統一補上。

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@Retsomm
Retsomm merged commit 2ec2e2c into main Aug 3, 2026
3 checks passed

This branch was successfully deployed

1 active deployment
Preview — cab6c969 Deployed Aug 3, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant