Skip to content

Cap mobile app#1845

Merged
richiemcilroy merged 38 commits into
mainfrom
mobile-app
Jun 30, 2026
Merged

Cap mobile app#1845
richiemcilroy merged 38 commits into
mainfrom
mobile-app

Conversation

@richiemcilroy

@richiemcilroy richiemcilroy commented May 19, 2026

Copy link
Copy Markdown
Member

Implements v1 of the Cap mobile app for iOS

Greptile Summary

This PR adds the first iOS version of the Cap mobile app. The main changes are:

  • New Expo mobile app screens for auth, library browsing, account settings, uploads, and cap details.
  • Mobile API contract and server routes for sessions, caps, comments, downloads, folders, and uploads.
  • Database and backend updates for mobile API keys, upload state, and mobile-facing data shapes.
  • Desktop and web integration updates for mobile sign-in and related type/config changes.

Confidence Score: 5/5

This looks safe to merge.

  • No blocking issues found in the changed code.

Important Files Changed

Filename Overview
apps/web/app/api/mobile/[...route]/route.ts Adds the mobile API route, including session creation, OTP verification, cap access, comments, downloads, folders, and upload lifecycle handlers.
apps/web/app/(org)/login/form.tsx Adds mobile-provider login redirects for Google and WorkOS sign-in flows.
apps/mobile/src/caps/saveCapVideo.ts Adds mobile video download and save-to-Photos behavior with cleanup after saving.

Comments Outside Diff (3)

  1. apps/web/app/api/mobile/[...route]/route.ts, line 1586-1591 (link)

    P1 security Unvalidated redirectUri leaks API key to arbitrary URLs

    The requestSession handler appends the freshly-minted api_key and user_id to whatever redirectUri the caller provides, with no allowlist check. An attacker who tricks an authenticated user into opening https://cap.so/api/mobile/session/request?redirectUri=https://attacker.com will receive that user's permanent API key in the redirect. The redirectUri should be validated against the app's registered deep-link scheme (e.g., only cap:// or the deployment-specific scheme from app.config.js) before any credentials are appended.

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: apps/web/app/api/mobile/[...route]/route.ts
    Line: 1586-1591
    
    Comment:
    **Unvalidated `redirectUri` leaks API key to arbitrary URLs**
    
    The `requestSession` handler appends the freshly-minted `api_key` and `user_id` to whatever `redirectUri` the caller provides, with no allowlist check. An attacker who tricks an authenticated user into opening `https://cap.so/api/mobile/session/request?redirectUri=https://attacker.com` will receive that user's permanent API key in the redirect. The `redirectUri` should be validated against the app's registered deep-link scheme (e.g., only `cap://` or the deployment-specific scheme from `app.config.js`) before any credentials are appended.
    
    How can I resolve this? If you propose a fix, please make it concise.
  2. apps/web/app/api/mobile/[...route]/route.ts, line 1413-1450 (link)

    P2 getPlayback has no ownership check on the video

    getCapById enforces eq(Db.videos.ownerId, user.id), but getPlayback bypasses it and calls videos.getByIdForViewing directly. If getByIdForViewing returns records for public or org-shared videos that do not belong to the authenticated user, any authenticated mobile user can retrieve signed playback URLs for those videos. Confirm whether this broader access is intentional for the mobile app, or whether an ownership/membership check should be added here.

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: apps/web/app/api/mobile/[...route]/route.ts
    Line: 1413-1450
    
    Comment:
    **`getPlayback` has no ownership check on the video**
    
    `getCapById` enforces `eq(Db.videos.ownerId, user.id)`, but `getPlayback` bypasses it and calls `videos.getByIdForViewing` directly. If `getByIdForViewing` returns records for public or org-shared videos that do not belong to the authenticated user, any authenticated mobile user can retrieve signed playback URLs for those videos. Confirm whether this broader access is intentional for the mobile app, or whether an ownership/membership check should be added here.
    
    How can I resolve this? If you propose a fix, please make it concise.
  3. apps/web/app/(org)/login/form.tsx, line 143-162 (link)

    P2 Auto-triggered Google sign-in fires on every searchParams identity change

    The new useEffect calls handleGoogleSignIn() whenever mobileProvider=google is present in the query string. Because searchParams is a new reference on every navigation update, this effect can fire multiple times during the session redirect lifecycle, potentially triggering extra signIn("google", ...) calls. Guard the effect with a useRef flag (or router-replace the URL after the first trigger) so it fires exactly once per page load.

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: apps/web/app/(org)/login/form.tsx
    Line: 143-162
    
    Comment:
    **Auto-triggered Google sign-in fires on every `searchParams` identity change**
    
    The new `useEffect` calls `handleGoogleSignIn()` whenever `mobileProvider=google` is present in the query string. Because `searchParams` is a new reference on every navigation update, this effect can fire multiple times during the session redirect lifecycle, potentially triggering extra `signIn("google", ...)` calls. Guard the effect with a `useRef` flag (or router-replace the URL after the first trigger) so it fires exactly once per page load.
    
    How can I resolve this? If you propose a fix, please make it concise.

Reviews (18): Last reviewed commit: "fix: clarify typecheck cleanup" | Re-trigger Greptile

Context used:

  • Context used - CLAUDE.md (source)
  • Context used - AGENTS.md (source)

@superagent-security superagent-security Bot added the contributor:verified Contributor passed trust analysis. label May 19, 2026
@polarityinc

polarityinc Bot commented May 19, 2026

Copy link
Copy Markdown

Paragon Review Skipped

Hi @richiemcilroy! Your Polarity credit balance is insufficient to complete this review.

Please visit https://app.paragon.run to finish your review.

Comment thread apps/web/app/api/mobile/[...route]/route.ts
Comment thread apps/web/app/api/mobile/[...route]/route.ts
Comment thread apps/web/app/api/mobile/[...route]/route.ts Outdated
Comment thread apps/web/app/api/mobile/[...route]/route.ts
Comment thread apps/mobile/src/api/mobile.ts
@superagent-security superagent-security Bot removed the contributor:verified Contributor passed trust analysis. label May 28, 2026
Comment thread apps/web/app/api/mobile/[...route]/route.ts
Comment thread apps/web/app/(org)/login/form.tsx
@superagent-security superagent-security Bot added the pr:flagged PR flagged for review by security analysis. label May 28, 2026
@richiemcilroy

Copy link
Copy Markdown
Member Author

hey @greptileai please re-review the pr

@superagent-security superagent-security Bot removed the pr:flagged PR flagged for review by security analysis. label Jun 30, 2026
Comment thread packages/web-domain/src/Mobile.ts
@richiemcilroy

Copy link
Copy Markdown
Member Author

hey @greptileai, please re-review the PR

@richiemcilroy

Copy link
Copy Markdown
Member Author

hey @greptileai, please re-review the PR

@richiemcilroy

Copy link
Copy Markdown
Member Author

hey @greptileai, please re-review the PR

Comment thread packages/database/migrations/0033_fluffy_gamora.sql
Comment thread packages/database/schema.ts Outdated
Comment thread packages/database/schema.ts Outdated
Comment thread apps/mobile/src/auth/session.ts
Comment thread apps/mobile/src/uploads/runMobileUpload.ts Outdated
@richiemcilroy

Copy link
Copy Markdown
Member Author

hey @greptileai, please re-review the PR

Comment thread packages/database/migrations/0034_fluffy_falcon.sql Outdated
@richiemcilroy

Copy link
Copy Markdown
Member Author

hey @greptileai, please re-review the PR

Comment thread apps/web/app/api/mobile/[...route]/route.ts
@richiemcilroy

Copy link
Copy Markdown
Member Author

hey @greptileai, please re-review the PR

Comment thread apps/web/app/api/mobile/[...route]/route.ts Outdated
@richiemcilroy

Copy link
Copy Markdown
Member Author

hey @greptileai, please re-review the PR

Comment thread apps/web/app/api/mobile/[...route]/route.ts Outdated
@richiemcilroy

Copy link
Copy Markdown
Member Author

hey @greptileai, please re-review the PR

@richiemcilroy

Copy link
Copy Markdown
Member Author

hey @greptileai, please re-review the PR

Comment thread apps/web/app/(site)/Footer.tsx Outdated
Comment thread packages/database/crypto.ts Outdated
@richiemcilroy

Copy link
Copy Markdown
Member Author

hey @greptileai, please re-review the PR

@richiemcilroy richiemcilroy merged commit 2a47dcd into main Jun 30, 2026
20 of 21 checks passed
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