Skip to content

fix(app): truthful Drive OAuth errors, visible backup-enable failures, frozen backup path (SELF-3934, SELF-3935) - #2278

Open
seshanthS wants to merge 3 commits into
self-3933-icloud-sync-restorefrom
self-3934-3935-backup-error-hygiene
Open

fix(app): truthful Drive OAuth errors, visible backup-enable failures, frozen backup path (SELF-3934, SELF-3935)#2278
seshanthS wants to merge 3 commits into
self-3933-icloud-sync-restorefrom
self-3934-3935-backup-error-hygiene

Conversation

@seshanthS

Copy link
Copy Markdown
Collaborator

Closes SELF-3935. Part of SELF-3934 — its AC2 (GCP Console audit: client IDs per environment, registered SHA-1s vs the Play App Signing certificate, consent-screen status) cannot be done from the repo and stays open on the issue.

Stack: #2272#2273#2277 → this. Base is self-3933-icloud-sync-restore; retarget as the stack merges. Combined per reviewer agreement: the two issues touch the same files and share one theme.

SELF-3934 — every Drive OAuth error read as "user cancelled"

googleSignIn() caught everything authorize() threw and returned null; callers then reported "sign-in cancelled". Android carries 635 of 701 unique restore-failure users, and misconfiguration was invisible inside the cancel bucket.

  • googleSignIn() now returns null only for an actual cancellation, detected two ways (verified against RNAppAuthModule.java): message match (/cancel/i — Android cancel arrives as authentication_error / "User cancelled flow") and OAuth code access_denied (the user tapping Deny on Google's consent page — no "cancel" substring, but it IS a user cancel).
  • Everything else rethrows CloudBackupError('sign_in_failed') with the native code embedded in the message and the original error as cause. Network failures share the cancel code but not the cancel message (authentication_error / "Network error"), so they now surface as failures — pinned by a test.
  • The reason flows into the recovery choice screen (copy + analytics reason) through the existing CloudBackupErrorReason union — no screen changes.

SELF-3935 — silent enable failures + fragile backup path

  • Enable failures surface. The catch in CloudBackupScreen (previously console.error only — ~400 users in 30 days got nothing) now emits CLOUD_BACKUP_ENABLE_FAILED { reason, error } and shows an alert, matching the disable path's precedent. No alert when reason is sign_in_cancelled — the user dismissed the sheet themselves. The toggle already stayed off on failure (it flips only after the awaited upload); a test now pins that.
  • Frozen path. The backup folder is a literal '/@selfxyz/mobile-app', no longer derived from package.json's name (which already changed once, from openpassport — a rename would silently orphan every backup). Double leading slash removed; the effective resolved path is byte-identical (native sanitizePath strips ^/+), pinned by a test asserting the exact production path @selfxyz/mobile-app/encrypted-private-key. The iOS setProviderOptions(AppData) side effect is preserved.
  • New SDK event CLOUD_BACKUP_ENABLE_FAILED (additive; also added to the jest.setup analytics mock — along with CLOUD_RESTORE_STARTED, which fix(app): surface cloud restore failures to the user and telemetry (SELF-3932) #2273 missed there).

Notes for reviewers

  • iOS sign-in cancels are not message-detectable (generic "error -3") — moot in production since backup routes iOS to iCloud and never reaches the Google flow; documented on the matcher.
  • Side effect: real auth failures during disable now alert instead of silently "succeeding".
  • Deliberately untouched (pre-existing): cancel-during-disable flips the toggle without deleting the Drive file; CLOUD_BACKUP_DISABLE_STARTED double-fire (button prop + handler); iOS upload has no isCloudAvailable pre-check (cloud-off enable fails as unexpected_error after retries); getOrCreateMnemonic returning null still exits silently after ENABLE_STARTED.

Validation

pnpm --filter @selfxyz/mobile-sdk-alpha test/types/build   # 528 passed; madge clean
pnpm --filter @selfxyz/mobile-app run test                  # 1283 passed, 113 suites (11 net new)
pnpm --filter @selfxyz/mobile-app run types                 # clean
pnpm --filter @selfxyz/mobile-app run lint                  # 0 errors

New coverage: googleSignIn cancel/deny → null, coded failures → typed sign_in_failed with cause (incl. the network-shares-cancel-code case); CloudBackupScreen success/failure/cancel — alert shown or suppressed, event reasons, toggle untouched on failure; frozen-path pin; sign_in_failed rendering on the recovery screen.

Device QA (extends the run sheet in app/docs/RECOVERY_QA_RUNSHEET.md): Android — cancel the sign-in sheet → "dismissed" copy, reason: sign_in_cancelled; Deny on the consent page → also a cancel (confirms the access_denied assumption); wrong-client-ID build → sign_in_failed with a code, not "cancelled"; airplane mode → sign_in_failed. Either platform — airplane-mode enable → alert + CLOUD_BACKUP_ENABLE_FAILED, toggle stays off; restore a production-build backup after the path freeze → still found; enable → disable → file removed from the same location.

🤖 Generated with Claude Code

@coderabbitai

coderabbitai Bot commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

🗂️ Base branches to auto review (3)
  • main
  • dev
  • staging

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: d763479d-34f2-432f-888b-28d5f0d99b52

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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.

@vercel

vercel Bot commented Aug 24, 2026

Copy link
Copy Markdown

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

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
self-webview-app Ignored Ignored Preview Aug 24, 2026 2:19pm

Request Review

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c0573091a8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

error: error instanceof Error ? error.name : 'unknown',
});
// A dismissed sign-in sheet is the user's own doing — no alert for it.
if (reason !== 'sign_in_cancelled') {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Suppress the alert when biometric unlock is cancelled

When the user dismisses the biometric/keychain prompt opened by getOrCreateMnemonic(), authProvider.tsx recognizes the cancellation and rethrows it, but it is not a CloudBackupError; this catch therefore records it as unexpected_error and displays the new failure alert. Thus a routine user cancellation is both reported as a backup failure and followed by the alert that is deliberately suppressed for an OAuth cancellation. Detect the existing keychain cancellation shape here or propagate a typed cancellation reason before deciding to alert.

Useful? React with 👍 / 👎.

seshanthS and others added 3 commits August 24, 2026 19:49
…up enable errors, freeze backup path

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@seshanthS
seshanthS force-pushed the self-3934-3935-backup-error-hygiene branch from 5449b69 to df1dbb0 Compare August 24, 2026 14:19
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