Skip to content

Sign in and link Google through the Android app's native sheet - #6426

Merged
evanpelle merged 1 commit into
mainfrom
android-google-sign-in
Nov 14, 2026
Merged

evanpelle merged 1 commit into
mainfrom
android-google-sign-in

Conversation

@evanpelle

Copy link
Copy Markdown
Collaborator

Description:

Google blocks its web OAuth redirect inside a WebView, so "Sign in with Google" and "Link Google Account" can't work in the Android app today. This makes both buttons use the app shell's native Google sign-in instead.

  • Bridge. desktopGoogleSignIn() in DesktopShell.ts detects window.openfrontDesktop.google.signIn, the same way the other optional bridges are detected. It checks what the shell returns: a throw, a malformed result or an error code this client doesn't know all become failed.
  • Sign in. googleLogin() posts the sheet's ID token to POST /auth/google. On success the page reloads into the session the response's refresh cookie set. That is the same path the web redirect and the magic-link login already use, so nothing else in the client has to know how the player signed in. A 409 email_exists shows the existing "sign in to it, then link this account in settings" message, the same one the web shows for that outcome. A dismissed sheet shows nothing. Every other outcome shows a message.
  • Link. linkGoogle() posts the token with the session to POST /auth/google/link. On success it reloads with link=google, which is how the web link flow returns, so consumeLinkResult announces it and every surface shows the linked account. A 409 already_linked shows the existing "already linked to another player" message.
  • Older app. The client updates at runtime and the app updates through the Play Store, so the client can be newer than its app. In an Android app without the native sheet, both buttons now ask the player to update the app instead of opening the redirect, which only reaches Google's error page.
  • Unchanged. Google on the web, everything in the Steam app, and Discord and email sign-in everywhere.

New strings: account_modal.google_sign_in_{failed,needs_update,no_account,unavailable}.

Test plan

  • tests/DesktopShell.test.ts: bridge detection (no bridge, no google, non-function signIn), this binding, pass-through of every contract result, and failed for an unknown code, a missing, empty or non-string token, an unknown status, null, a string, a rejection and a synchronous throw.
  • tests/client/Auth.desktopLogin.test.ts:
    • sign-in success (body, credentials: "include", reload), cancelled, each sheet error code, email_exists, and 400/401/500, a 409 with another reason, and a network failure
    • link success (Bearer header, link=google, reload), already_linked, other refusal, cancelled, and logged out (returns false without opening the sheet)
    • Android app without the sheet shows the update message and does not navigate, for both buttons. This replaces the old assertion that it took the web redirect.
    • Existing web and Steam app tests pass unchanged.
  • npm test (742 files, 11234 passed, 1 skipped), npm run typecheck, npm run lint, npm run format:check
  • Not run in the real Android app. The shell side of the bridge is being built separately, so this has only been tested against a stubbed bridge.

Please complete the following:

  • I have added screenshots for all UI updates
  • I process any text displayed to the user through translateText() and I've added it to the en.json file
  • I have added relevant tests to the test directory

Please put your Discord username so you can be contacted if a bug or regression is found:

evan

🤖 Generated with Claude Code

@CLAassistant

CLAassistant commented Nov 13, 2026 •

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@github-actions

Copy link
Copy Markdown
Contributor

Thanks for the PR, @evanpelle!

When it's ready for a maintainer to review, comment /ready. That adds the ready-for-review label, which is how we find PRs waiting on us. Until then we assume you're still working on it.

  • Draft PRs can't be marked ready. Click Ready for review on the PR first, then comment /ready.
  • If we request changes, the label comes off. Push your fixes, then comment /ready again so we know to take another look. Pushing alone doesn't put it back in the queue.
  • Comment /unready to take it out of the queue yourself.

See CONTRIBUTING.md for the full process.

@coderabbitai

coderabbitai Bot commented Nov 13, 2026 •

Copy link
Copy Markdown
Contributor

Explain Change →

No actionable comments were generated in the recent review.

Walkthrough

Android Google login and account linking now use the shell’s native sign-in sheet and submit its ID token. The change adds a typed bridge result, localized error messages, and tests for success, cancellation, and failure cases. Web Google OAuth behavior remains unchanged.

Changes

Android Google authentication

Layer / File(s) Summary
Native sign-in bridge contract
src/client/DesktopShell.ts, tests/DesktopShell.test.ts
Adds a typed result and bridge accessor for native Google sign-in. Tests cover bridge detection, valid results, cancellations, malformed responses, and thrown or rejected calls.
Android login and account linking
src/client/Auth.ts, resources/lang/en.json, src/client/AccountModal.ts, tests/client/Auth.desktopLogin.test.ts
Android login and linking obtain native ID tokens and submit them to the API. Success reloads the page; cancellation sends no request. Localized alerts and tests cover missing bridge support, sheet errors, and API failures. Web OAuth remains in place for other environments.

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

Change: Feature

Sequence Diagram(s)

sequenceDiagram
  participant AuthClient
  participant DesktopShell
  participant GoogleSignInSheet
  participant GoogleAuthAPI
  AuthClient->>DesktopShell: Get native sign-in function
  DesktopShell->>GoogleSignInSheet: Call google.signIn()
  GoogleSignInSheet-->>DesktopShell: Return sign-in result and ID token
  DesktopShell-->>AuthClient: Return normalized result
  AuthClient->>GoogleAuthAPI: Submit ID token for login or linking
  GoogleAuthAPI-->>AuthClient: Return request response
Loading

Suggested reviewers: celant, ryanbarlow97

Merge Risk: Minimal · up to d641c

Android Google sign-in and linking now use the native sheet and submit its ID token, with localized errors and tests for the main outcomes. No concrete defect was found in the changed code. The remaining uncertainty is that the Android shell bridge has not been exercised in the real app. A reviewer still needs to assign a milestone for the CI check to pass.

Pre-merge checks: Passed 4

Check name Status Explanation
Title check Passed The title states the main change: Google sign-in and account linking move to the Android app's native sheet. It is specific, concise, and matches the changeset in Auth.ts, DesktopShell.ts, and the tes…
Description check Passed The description explains the problem (Google blocks the OAuth redirect in the Android WebView), the bridge detection, the sign-in and link flows, the older-app fallback, and the test plan. It matches …
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.
Full details: Title check

Explanation

The title states the main change: Google sign-in and account linking move to the Android app's native sheet. It is specific, concise, and matches the changeset in Auth.ts, DesktopShell.ts, and the tests.

Full details: Description check

Explanation

The description explains the problem (Google blocks the OAuth redirect in the Android WebView), the bridge detection, the sign-in and link flows, the older-app fallback, and the test plan. It matches the changeset closely.

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

A sheet opens, bright and clear
A token travels, drawing near
If cancelled, no request will fly
If linked, the page will reload nearby
Four new messages greet the try

Recent review info

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: c4a70a76-a8f7-4cf8-b7e2-0ef269e5a0bc
Commits

Reviewing files that changed from the base of the PR and between 2f8df64 and d641ca1.

Files selected for processing: 6

  • resources/lang/en.json
  • src/client/AccountModal.ts
  • src/client/Auth.ts
  • src/client/DesktopShell.ts
  • tests/DesktopShell.test.ts
  • tests/client/Auth.desktopLogin.test.ts

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 7 remain after this review.

Google refuses its web OAuth redirect inside a WebView, so in the Android
app the Google sign-in and link buttons now take an ID token from the
shell's native sheet (window.openfrontDesktop.google.signIn) and post it
to /auth/google or /auth/google/link. A successful sign-in reloads into
the session the response's refresh cookie set, as the web redirect and
magic-link logins do; a successful link reloads with link=google, as the
web link flow returns. An Android shell too old to have the sheet is told
to update the app instead of being sent to the redirect. The web and the
Steam shell are unchanged.

Co-Authored-By: Claude Code <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

🤖 Claude Code Review

Verdict: No issues found. Findings: 0 critical, 0 major, 0 minor.

No issues found. Checked for bugs and CLAUDE.md compliance.

Here is what I checked:

  • Translations: all four new account_modal.google_sign_in_* strings are added to en.json and shown through translateText(). No other translation file was changed.
  • Homepage loading: none of the changes adds a static import of the game client to the homepage.
  • link=google: the success redirect matches LINK_RESULT_KEYS.google and the existing hash handling in consumeLinkResult.
  • What linkGoogle() returns: the Android path returns true after it has already shown its own message, so the callers never show a second link_google_failed alert. It returns false only when the player is logged out, before the sheet opens.
  • Steam vs. Android: the Steam checks run before isDesktopShell(), so only the Android app reaches the native-sheet branch.
  • desktopGoogleSignIn(): it never rejects, and every error code it can return has a message.

@evanpelle evanpelle added this to the v37 milestone Nov 14, 2026
@evanpelle
evanpelle merged commit 7f34e15 into main Nov 14, 2026
19 of 20 checks passed
@evanpelle
evanpelle deleted the android-google-sign-in branch November 14, 2026 04:06
@github-project-automation github-project-automation Bot moved this from Triage to Complete in OpenFront Release Management Nov 14, 2026

This branch was successfully deployed

2 active deployments
backport — d641ca1d Deployed Nov 14, 2026 by evanpelle via Cherry-pick #1062
staging — d641ca1d Deployed Nov 13, 2026 by openfrontio[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Complete

Development

Successfully merging this pull request may close these issues.

2 participants